github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/internal/reflectlite/type.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package reflectlite implements lightweight version of reflect, not using
     6  // any package except for "runtime" and "unsafe".
     7  package reflectlite
     8  
     9  import (
    10  	"unsafe"
    11  )
    12  
    13  // Type is the representation of a Go type.
    14  //
    15  // Not all methods apply to all kinds of types. Restrictions,
    16  // if any, are noted in the documentation for each method.
    17  // Use the Kind method to find out the kind of type before
    18  // calling kind-specific methods. Calling a method
    19  // inappropriate to the kind of type causes a run-time panic.
    20  //
    21  // Type values are comparable, such as with the == operator,
    22  // so they can be used as map keys.
    23  // Two Type values are equal if they represent identical types.
    24  type Type interface {
    25  	// Methods applicable to all types.
    26  
    27  	// Name returns the type's name within its package for a defined type.
    28  	// For other (non-defined) types it returns the empty string.
    29  	Name() string
    30  
    31  	// PkgPath returns a defined type's package path, that is, the import path
    32  	// that uniquely identifies the package, such as "encoding/base64".
    33  	// If the type was predeclared (string, error) or not defined (*T, struct{},
    34  	// []int, or A where A is an alias for a non-defined type), the package path
    35  	// will be the empty string.
    36  	PkgPath() string
    37  
    38  	// Size returns the number of bytes needed to store
    39  	// a value of the given type; it is analogous to unsafe.Sizeof.
    40  	Size() uintptr
    41  
    42  	// Kind returns the specific kind of this type.
    43  	Kind() Kind
    44  
    45  	// Implements reports whether the type implements the interface type u.
    46  	Implements(u Type) bool
    47  
    48  	// AssignableTo reports whether a value of the type is assignable to type u.
    49  	AssignableTo(u Type) bool
    50  
    51  	// Comparable reports whether values of this type are comparable.
    52  	Comparable() bool
    53  
    54  	// String returns a string representation of the type.
    55  	// The string representation may use shortened package names
    56  	// (e.g., base64 instead of "encoding/base64") and is not
    57  	// guaranteed to be unique among types. To test for type identity,
    58  	// compare the Types directly.
    59  	String() string
    60  
    61  	// Elem returns a type's element type.
    62  	// It panics if the type's Kind is not Ptr.
    63  	Elem() Type
    64  
    65  	common() *rtype
    66  	uncommon() *uncommonType
    67  }
    68  
    69  /*
    70   * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go).
    71   * A few are known to ../runtime/type.go to convey to debuggers.
    72   * They are also known to ../runtime/type.go.
    73   */
    74  
    75  // A Kind represents the specific kind of type that a Type represents.
    76  // The zero Kind is not a valid kind.
    77  type Kind uint
    78  
    79  const (
    80  	Invalid Kind = iota
    81  	Bool
    82  	Int
    83  	Int8
    84  	Int16
    85  	Int32
    86  	Int64
    87  	Uint
    88  	Uint8
    89  	Uint16
    90  	Uint32
    91  	Uint64
    92  	Uintptr
    93  	Float32
    94  	Float64
    95  	Complex64
    96  	Complex128
    97  	Array
    98  	Chan
    99  	Func
   100  	Interface
   101  	Map
   102  	Ptr
   103  	Slice
   104  	String
   105  	Struct
   106  	UnsafePointer
   107  )
   108  
   109  // tflag is used by an rtype to signal what extra type information is
   110  // available in the memory directly following the rtype value.
   111  //
   112  // tflag values must be kept in sync with copies in:
   113  //	go/types.cc
   114  //	runtime/type.go
   115  type tflag uint8
   116  
   117  const (
   118  	// tflagRegularMemory means that equal and hash functions can treat
   119  	// this type as a single region of t.size bytes.
   120  	tflagRegularMemory tflag = 1 << 3
   121  )
   122  
   123  // rtype is the common implementation of most values.
   124  // It is embedded in other struct types.
   125  //
   126  // rtype must be kept in sync with ../runtime/type.go:/^type._type.
   127  type rtype struct {
   128  	size       uintptr
   129  	ptrdata    uintptr // number of bytes in the type that can contain pointers
   130  	hash       uint32  // hash of type; avoids computation in hash tables
   131  	tflag      tflag   // extra type information flags
   132  	align      uint8   // alignment of variable with this type
   133  	fieldAlign uint8   // alignment of struct field with this type
   134  	kind       uint8   // enumeration for C
   135  	// function for comparing objects of this type
   136  	// (ptr to object A, ptr to object B) -> ==?
   137  	equal         func(unsafe.Pointer, unsafe.Pointer) bool
   138  	gcdata        *byte   // garbage collection data
   139  	string        *string // string form; unnecessary but undeniably useful
   140  	*uncommonType         // (relatively) uncommon fields
   141  	ptrToThis     *rtype  // type for pointer to this type, may be zero
   142  }
   143  
   144  // Method on non-interface type
   145  type method struct {
   146  	name    *string        // name of method
   147  	pkgPath *string        // nil for exported Names; otherwise import path
   148  	mtyp    *rtype         // method type (without receiver)
   149  	typ     *rtype         // .(*FuncType) underneath (with receiver)
   150  	tfn     unsafe.Pointer // fn used for normal method call
   151  }
   152  
   153  // uncommonType is present only for defined types or types with methods
   154  // (if T is a defined type, the uncommonTypes for T and *T have methods).
   155  // Using a pointer to this struct reduces the overall size required
   156  // to describe a non-defined type with no methods.
   157  type uncommonType struct {
   158  	name    *string  // name of type
   159  	pkgPath *string  // import path; nil for built-in types like int, string
   160  	methods []method // methods associated with type
   161  }
   162  
   163  // chanDir represents a channel type's direction.
   164  type chanDir int
   165  
   166  const (
   167  	recvDir chanDir             = 1 << iota // <-chan
   168  	sendDir                                 // chan<-
   169  	bothDir = recvDir | sendDir             // chan
   170  )
   171  
   172  // arrayType represents a fixed array type.
   173  type arrayType struct {
   174  	rtype
   175  	elem  *rtype // array element type
   176  	slice *rtype // slice type
   177  	len   uintptr
   178  }
   179  
   180  // chanType represents a channel type.
   181  type chanType struct {
   182  	rtype
   183  	elem *rtype  // channel element type
   184  	dir  uintptr // channel direction (chanDir)
   185  }
   186  
   187  // funcType represents a function type.
   188  type funcType struct {
   189  	rtype
   190  	dotdotdot bool     // last input parameter is ...
   191  	in        []*rtype // input parameter types
   192  	out       []*rtype // output parameter types
   193  }
   194  
   195  // imethod represents a method on an interface type
   196  type imethod struct {
   197  	name    *string // name of method
   198  	pkgPath *string // nil for exported Names; otherwise import path
   199  	typ     *rtype  // .(*FuncType) underneath
   200  }
   201  
   202  // interfaceType represents an interface type.
   203  type interfaceType struct {
   204  	rtype
   205  	methods []imethod // sorted by hash
   206  }
   207  
   208  // mapType represents a map type.
   209  type mapType struct {
   210  	rtype
   211  	key        *rtype // map key type
   212  	elem       *rtype // map element (value) type
   213  	bucket     *rtype // internal bucket structure
   214  	keysize    uint8  // size of key slot
   215  	valuesize  uint8  // size of value slot
   216  	bucketsize uint16 // size of bucket
   217  	flags      uint32
   218  }
   219  
   220  // ptrType represents a pointer type.
   221  type ptrType struct {
   222  	rtype
   223  	elem *rtype // pointer element (pointed at) type
   224  }
   225  
   226  // sliceType represents a slice type.
   227  type sliceType struct {
   228  	rtype
   229  	elem *rtype // slice element type
   230  }
   231  
   232  // Struct field
   233  type structField struct {
   234  	name        *string // name is always non-empty
   235  	pkgPath     *string // nil for exported Names; otherwise import path
   236  	typ         *rtype  // type of field
   237  	tag         *string // nil if no tag
   238  	offsetEmbed uintptr // byte offset of field<<1 | isAnonymous
   239  }
   240  
   241  func (f *structField) offset() uintptr {
   242  	return f.offsetEmbed >> 1
   243  }
   244  
   245  func (f *structField) embedded() bool {
   246  	return f.offsetEmbed&1 != 0
   247  }
   248  
   249  // structType represents a struct type.
   250  type structType struct {
   251  	rtype
   252  	fields []structField // sorted by offset
   253  }
   254  
   255  /*
   256   * The compiler knows the exact layout of all the data structures above.
   257   * The compiler does not know about the data structures and methods below.
   258   */
   259  
   260  const (
   261  	kindDirectIface = 1 << 5
   262  	kindGCProg      = 1 << 6 // Type.gc points to GC program
   263  	kindMask        = (1 << 5) - 1
   264  )
   265  
   266  func (t *uncommonType) exportedMethods() []method {
   267  	allm := t.methods
   268  	allExported := true
   269  	for _, m := range allm {
   270  		if m.pkgPath != nil {
   271  			allExported = false
   272  			break
   273  		}
   274  	}
   275  	var methods []method
   276  	if allExported {
   277  		methods = allm
   278  	} else {
   279  		methods = make([]method, 0, len(allm))
   280  		for _, m := range allm {
   281  			if m.pkgPath == nil {
   282  				methods = append(methods, m)
   283  			}
   284  		}
   285  		methods = methods[:len(methods):len(methods)]
   286  	}
   287  
   288  	return methods
   289  }
   290  
   291  func (t *uncommonType) uncommon() *uncommonType {
   292  	return t
   293  }
   294  
   295  func (t *uncommonType) PkgPath() string {
   296  	if t == nil || t.pkgPath == nil {
   297  		return ""
   298  	}
   299  	return *t.pkgPath
   300  }
   301  
   302  func (t *uncommonType) Name() string {
   303  	if t == nil || t.name == nil {
   304  		return ""
   305  	}
   306  	return *t.name
   307  }
   308  
   309  func (t *rtype) String() string {
   310  	// For gccgo, strip out quoted strings.
   311  	s := *t.string
   312  	var q bool
   313  	r := make([]byte, len(s))
   314  	j := 0
   315  	for i := 0; i < len(s); i++ {
   316  		if s[i] == '\t' {
   317  			q = !q
   318  		} else if !q {
   319  			r[j] = s[i]
   320  			j++
   321  		}
   322  	}
   323  	return string(r[:j])
   324  }
   325  
   326  func (t *rtype) Size() uintptr { return t.size }
   327  
   328  func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
   329  
   330  func (t *rtype) pointers() bool { return t.ptrdata != 0 }
   331  
   332  func (t *rtype) common() *rtype { return t }
   333  
   334  func (t *rtype) exportedMethods() []method {
   335  	ut := t.uncommon()
   336  	if ut == nil {
   337  		return nil
   338  	}
   339  	return ut.exportedMethods()
   340  }
   341  
   342  func (t *rtype) NumMethod() int {
   343  	if t.Kind() == Interface {
   344  		tt := (*interfaceType)(unsafe.Pointer(t))
   345  		return tt.NumMethod()
   346  	}
   347  	return len(t.exportedMethods())
   348  }
   349  
   350  func (t *rtype) PkgPath() string {
   351  	return t.uncommonType.PkgPath()
   352  }
   353  
   354  func (t *rtype) hasName() bool {
   355  	return t.uncommonType != nil && t.uncommonType.name != nil
   356  }
   357  
   358  func (t *rtype) Name() string {
   359  	return t.uncommonType.Name()
   360  }
   361  
   362  func (t *rtype) chanDir() chanDir {
   363  	if t.Kind() != Chan {
   364  		panic("reflect: chanDir of non-chan type")
   365  	}
   366  	tt := (*chanType)(unsafe.Pointer(t))
   367  	return chanDir(tt.dir)
   368  }
   369  
   370  func (t *rtype) Elem() Type {
   371  	switch t.Kind() {
   372  	case Array:
   373  		tt := (*arrayType)(unsafe.Pointer(t))
   374  		return toType(tt.elem)
   375  	case Chan:
   376  		tt := (*chanType)(unsafe.Pointer(t))
   377  		return toType(tt.elem)
   378  	case Map:
   379  		tt := (*mapType)(unsafe.Pointer(t))
   380  		return toType(tt.elem)
   381  	case Ptr:
   382  		tt := (*ptrType)(unsafe.Pointer(t))
   383  		return toType(tt.elem)
   384  	case Slice:
   385  		tt := (*sliceType)(unsafe.Pointer(t))
   386  		return toType(tt.elem)
   387  	}
   388  	panic("reflect: Elem of invalid type")
   389  }
   390  
   391  func (t *rtype) In(i int) Type {
   392  	if t.Kind() != Func {
   393  		panic("reflect: In of non-func type")
   394  	}
   395  	tt := (*funcType)(unsafe.Pointer(t))
   396  	return toType(tt.in[i])
   397  }
   398  
   399  func (t *rtype) Key() Type {
   400  	if t.Kind() != Map {
   401  		panic("reflect: Key of non-map type")
   402  	}
   403  	tt := (*mapType)(unsafe.Pointer(t))
   404  	return toType(tt.key)
   405  }
   406  
   407  func (t *rtype) Len() int {
   408  	if t.Kind() != Array {
   409  		panic("reflect: Len of non-array type")
   410  	}
   411  	tt := (*arrayType)(unsafe.Pointer(t))
   412  	return int(tt.len)
   413  }
   414  
   415  func (t *rtype) NumField() int {
   416  	if t.Kind() != Struct {
   417  		panic("reflect: NumField of non-struct type")
   418  	}
   419  	tt := (*structType)(unsafe.Pointer(t))
   420  	return len(tt.fields)
   421  }
   422  
   423  func (t *rtype) NumIn() int {
   424  	if t.Kind() != Func {
   425  		panic("reflect: NumIn of non-func type")
   426  	}
   427  	tt := (*funcType)(unsafe.Pointer(t))
   428  	return len(tt.in)
   429  }
   430  
   431  func (t *rtype) NumOut() int {
   432  	if t.Kind() != Func {
   433  		panic("reflect: NumOut of non-func type")
   434  	}
   435  	tt := (*funcType)(unsafe.Pointer(t))
   436  	return len(tt.out)
   437  }
   438  
   439  func (t *rtype) Out(i int) Type {
   440  	if t.Kind() != Func {
   441  		panic("reflect: Out of non-func type")
   442  	}
   443  	tt := (*funcType)(unsafe.Pointer(t))
   444  	return toType(tt.out[i])
   445  }
   446  
   447  // add returns p+x.
   448  //
   449  // The whySafe string is ignored, so that the function still inlines
   450  // as efficiently as p+x, but all call sites should use the string to
   451  // record why the addition is safe, which is to say why the addition
   452  // does not cause x to advance to the very end of p's allocation
   453  // and therefore point incorrectly at the next block in memory.
   454  func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
   455  	return unsafe.Pointer(uintptr(p) + x)
   456  }
   457  
   458  // NumMethod returns the number of interface methods in the type's method set.
   459  func (t *interfaceType) NumMethod() int { return len(t.methods) }
   460  
   461  // TypeOf returns the reflection Type that represents the dynamic type of i.
   462  // If i is a nil interface value, TypeOf returns nil.
   463  func TypeOf(i interface{}) Type {
   464  	eface := *(*emptyInterface)(unsafe.Pointer(&i))
   465  	return toType(eface.typ)
   466  }
   467  
   468  func (t *rtype) Implements(u Type) bool {
   469  	if u == nil {
   470  		panic("reflect: nil type passed to Type.Implements")
   471  	}
   472  	if u.Kind() != Interface {
   473  		panic("reflect: non-interface type passed to Type.Implements")
   474  	}
   475  	return implements(u.(*rtype), t)
   476  }
   477  
   478  func (t *rtype) AssignableTo(u Type) bool {
   479  	if u == nil {
   480  		panic("reflect: nil type passed to Type.AssignableTo")
   481  	}
   482  	uu := u.(*rtype)
   483  	return directlyAssignable(uu, t) || implements(uu, t)
   484  }
   485  
   486  func (t *rtype) Comparable() bool {
   487  	switch t.Kind() {
   488  	case Bool, Int, Int8, Int16, Int32, Int64,
   489  		Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
   490  		Float32, Float64, Complex64, Complex128,
   491  		Chan, Interface, Ptr, String, UnsafePointer:
   492  		return true
   493  
   494  	case Func, Map, Slice:
   495  		return false
   496  
   497  	case Array:
   498  		return (*arrayType)(unsafe.Pointer(t)).elem.Comparable()
   499  
   500  	case Struct:
   501  		tt := (*structType)(unsafe.Pointer(t))
   502  		for i := range tt.fields {
   503  			if !tt.fields[i].typ.Comparable() {
   504  				return false
   505  			}
   506  		}
   507  		return true
   508  
   509  	default:
   510  		panic("reflectlite: impossible")
   511  	}
   512  }
   513  
   514  // implements reports whether the type V implements the interface type T.
   515  func implements(T, V *rtype) bool {
   516  	if T.Kind() != Interface {
   517  		return false
   518  	}
   519  	t := (*interfaceType)(unsafe.Pointer(T))
   520  	if len(t.methods) == 0 {
   521  		return true
   522  	}
   523  
   524  	// The same algorithm applies in both cases, but the
   525  	// method tables for an interface type and a concrete type
   526  	// are different, so the code is duplicated.
   527  	// In both cases the algorithm is a linear scan over the two
   528  	// lists - T's methods and V's methods - simultaneously.
   529  	// Since method tables are stored in a unique sorted order
   530  	// (alphabetical, with no duplicate method names), the scan
   531  	// through V's methods must hit a match for each of T's
   532  	// methods along the way, or else V does not implement T.
   533  	// This lets us run the scan in overall linear time instead of
   534  	// the quadratic time  a naive search would require.
   535  	// See also ../runtime/iface.go.
   536  	if V.Kind() == Interface {
   537  		v := (*interfaceType)(unsafe.Pointer(V))
   538  		i := 0
   539  		for j := 0; j < len(v.methods); j++ {
   540  			tm := &t.methods[i]
   541  			vm := &v.methods[j]
   542  			if *vm.name == *tm.name && (vm.pkgPath == tm.pkgPath || (vm.pkgPath != nil && tm.pkgPath != nil && *vm.pkgPath == *tm.pkgPath)) && toType(vm.typ).common() == toType(tm.typ).common() {
   543  				if i++; i >= len(t.methods) {
   544  					return true
   545  				}
   546  			}
   547  		}
   548  		return false
   549  	}
   550  
   551  	v := V.uncommon()
   552  	if v == nil {
   553  		return false
   554  	}
   555  	i := 0
   556  	for j := 0; j < len(v.methods); j++ {
   557  		tm := &t.methods[i]
   558  		vm := &v.methods[j]
   559  		if *vm.name == *tm.name && (vm.pkgPath == tm.pkgPath || (vm.pkgPath != nil && tm.pkgPath != nil && *vm.pkgPath == *tm.pkgPath)) && toType(vm.mtyp).common() == toType(tm.typ).common() {
   560  			if i++; i >= len(t.methods) {
   561  				return true
   562  			}
   563  		}
   564  	}
   565  	return false
   566  }
   567  
   568  // directlyAssignable reports whether a value x of type V can be directly
   569  // assigned (using memmove) to a value of type T.
   570  // https://golang.org/doc/go_spec.html#Assignability
   571  // Ignoring the interface rules (implemented elsewhere)
   572  // and the ideal constant rules (no ideal constants at run time).
   573  func directlyAssignable(T, V *rtype) bool {
   574  	// x's type V is identical to T?
   575  	if T == V {
   576  		return true
   577  	}
   578  
   579  	// Otherwise at least one of T and V must not be defined
   580  	// and they must have the same kind.
   581  	if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
   582  		return false
   583  	}
   584  
   585  	// x's type T and V must  have identical underlying types.
   586  	return haveIdenticalUnderlyingType(T, V, true)
   587  }
   588  
   589  func haveIdenticalType(T, V Type, cmpTags bool) bool {
   590  	if cmpTags {
   591  		return T == V
   592  	}
   593  
   594  	if T.Name() != V.Name() || T.Kind() != V.Kind() {
   595  		return false
   596  	}
   597  
   598  	return haveIdenticalUnderlyingType(T.common(), V.common(), false)
   599  }
   600  
   601  func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
   602  	if T == V {
   603  		return true
   604  	}
   605  
   606  	kind := T.Kind()
   607  	if kind != V.Kind() {
   608  		return false
   609  	}
   610  
   611  	// Non-composite types of equal kind have same underlying type
   612  	// (the predefined instance of the type).
   613  	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
   614  		return true
   615  	}
   616  
   617  	// Composite types.
   618  	switch kind {
   619  	case Array:
   620  		return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   621  
   622  	case Chan:
   623  		// Special case:
   624  		// x is a bidirectional channel value, T is a channel type,
   625  		// and x's type V and T have identical element types.
   626  		if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
   627  			return true
   628  		}
   629  
   630  		// Otherwise continue test for identical underlying type.
   631  		return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   632  
   633  	case Func:
   634  		t := (*funcType)(unsafe.Pointer(T))
   635  		v := (*funcType)(unsafe.Pointer(V))
   636  		if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) {
   637  			return false
   638  		}
   639  		for i, typ := range t.in {
   640  			if !haveIdenticalType(typ, v.in[i], cmpTags) {
   641  				return false
   642  			}
   643  		}
   644  		for i, typ := range t.out {
   645  			if !haveIdenticalType(typ, v.out[i], cmpTags) {
   646  				return false
   647  			}
   648  		}
   649  		return true
   650  
   651  	case Interface:
   652  		t := (*interfaceType)(unsafe.Pointer(T))
   653  		v := (*interfaceType)(unsafe.Pointer(V))
   654  		if len(t.methods) == 0 && len(v.methods) == 0 {
   655  			return true
   656  		}
   657  		// Might have the same methods but still
   658  		// need a run time conversion.
   659  		return false
   660  
   661  	case Map:
   662  		return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   663  
   664  	case Ptr, Slice:
   665  		return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
   666  
   667  	case Struct:
   668  		t := (*structType)(unsafe.Pointer(T))
   669  		v := (*structType)(unsafe.Pointer(V))
   670  		if len(t.fields) != len(v.fields) {
   671  			return false
   672  		}
   673  		for i := range t.fields {
   674  			tf := &t.fields[i]
   675  			vf := &v.fields[i]
   676  			if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) {
   677  				return false
   678  			}
   679  			if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) {
   680  				return false
   681  			}
   682  			if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
   683  				return false
   684  			}
   685  			if cmpTags && tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) {
   686  				return false
   687  			}
   688  			if tf.offsetEmbed != vf.offsetEmbed {
   689  				return false
   690  			}
   691  		}
   692  		return true
   693  	}
   694  
   695  	return false
   696  }
   697  
   698  // toType converts from a *rtype to a Type that can be returned
   699  // to the client of package reflect. In gc, the only concern is that
   700  // a nil *rtype must be replaced by a nil Type, but in gccgo this
   701  // function takes care of ensuring that multiple *rtype for the same
   702  // type are coalesced into a single Type.
   703  func toType(t *rtype) Type {
   704  	if t == nil {
   705  		return nil
   706  	}
   707  	return t
   708  }
   709  
   710  // ifaceIndir reports whether t is stored indirectly in an interface value.
   711  func ifaceIndir(t *rtype) bool {
   712  	return t.kind&kindDirectIface == 0
   713  }