func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
	if variadic {
		n := params.Len()
		if n == 0 {
			panic("types.NewSignature: variadic function must have at least one parameter")
		}
		if _, ok := params.At(n - 1).typ.(*Slice); !ok {
			panic("types.NewSignature: variadic parameter must be of unnamed slice type")
		}
	}
	return &Signature{nil, nil, recv, nil, params, results, variadic}
}
NewSignature returns a new function type for the given receiver, parameters,
and results, either of which may be nil. If variadic is set, the function
is variadic, it must have at least one parameter, and the last parameter
must be of unnamed slice type.
package types
import "sort"
type Type interface {
	Underlying() Type
	String() string
}
type BasicKind int
const (
	Invalid BasicKind = iota  
	Bool
	Int
	Int8
	Int16
	Int32
	Int64
	Uint
	Uint8
	Uint16
	Uint32
	Uint64
	Uintptr
	Float32
	Float64
	Complex64
	Complex128
	String
	UnsafePointer
	UntypedBool
	UntypedInt
	UntypedRune
	UntypedFloat
	UntypedComplex
	UntypedString
	UntypedNil
	Byte = Uint8
	Rune = Int32
)
type BasicInfo int
const (
	IsBoolean BasicInfo = 1 << iota
	IsInteger
	IsUnsigned
	IsFloat
	IsComplex
	IsString
	IsUntyped
	IsOrdered   = IsInteger | IsFloat | IsString
	IsNumeric   = IsInteger | IsFloat | IsComplex
	IsConstType = IsBoolean | IsNumeric | IsString
)
type Basic struct {
	kind BasicKind
	info BasicInfo
	name string
}
func (b *Basic) Kind() BasicKind { return b.kind }
func (b *Basic) Info() BasicInfo { return b.info }
func (b *Basic) Name() string { return b.name }
type Array struct {
	len  int64
	elem Type
}
func NewArray(elem Type, len int64) *Array { return &Array{len, elem} }
func (a *Array) Len() int64 { return a.len }
func (a *Array) Elem() Type { return a.elem }
type Slice struct {
	elem Type
}
func NewSlice(elem Type) *Slice { return &Slice{elem} }
func (s *Slice) Elem() Type { return s.elem }
type Struct struct {
	fields []*Var
	tags   []string  
}
func NewStruct(fields []*Var, tags []string) *Struct {
	var fset objset
	for _, f := range fields {
		if f.name != "_" && fset.insert(f) != nil {
			panic("multiple fields with the same name")
		}
	}
	if len(tags) > len(fields) {
		panic("more tags than fields")
	}
	return &Struct{fields: fields, tags: tags}
}
func (s *Struct) NumFields() int { return len(s.fields) }
func (s *Struct) Field(i int) *Var { return s.fields[i] }
func (s *Struct) Tag(i int) string {
	if i < len(s.tags) {
		return s.tags[i]
	}
	return ""
}
type Pointer struct {
	base Type  
}
func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} }
func (p *Pointer) Elem() Type { return p.base }
type Tuple struct {
	vars []*Var
}
func NewTuple(x ...*Var) *Tuple {
	if len(x) > 0 {
		return &Tuple{x}
	}
	return nil
}
func (t *Tuple) Len() int {
	if t != nil {
		return len(t.vars)
	}
	return 0
}
func (t *Tuple) At(i int) *Var { return t.vars[i] }
type Signature struct {
	scope      *Scope        
	typeParams []*TypeParam  
	recv       *Var          
	unnamed    []*TypeParam  
	params     *Tuple        
	results    *Tuple        
	variadic   bool          
}