github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/go/types/typexpr.go (about)

     1  // Copyright 2013 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  // This file implements type-checking of identifiers and type expressions.
     6  
     7  package types
     8  
     9  import (
    10  	"go/ast"
    11  	"go/exact"
    12  	"go/token"
    13  	"sort"
    14  	"strconv"
    15  )
    16  
    17  // ident type-checks identifier e and initializes x with the value or type of e.
    18  // If an error occurred, x.mode is set to invalid.
    19  // For the meaning of def and path, see check.typ, below.
    20  //
    21  func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeName) {
    22  	x.mode = invalid
    23  	x.expr = e
    24  
    25  	scope, obj := check.scope.LookupParent(e.Name)
    26  	if obj == nil {
    27  		if e.Name == "_" {
    28  			check.errorf(e.Pos(), "cannot use _ as value or type")
    29  		} else {
    30  			check.errorf(e.Pos(), "undeclared name: %s", e.Name)
    31  		}
    32  		return
    33  	}
    34  	check.recordUse(e, obj)
    35  
    36  	check.objDecl(obj, def, path)
    37  	typ := obj.Type()
    38  	assert(typ != nil)
    39  
    40  	// The object may be dot-imported: If so, remove its package from
    41  	// the map of unused dot imports for the respective file scope.
    42  	// (This code is only needed for dot-imports. Without them,
    43  	// we only have to mark variables, see *Var case below).
    44  	if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil {
    45  		delete(check.unusedDotImports[scope], pkg)
    46  	}
    47  
    48  	switch obj := obj.(type) {
    49  	case *PkgName:
    50  		check.errorf(e.Pos(), "use of package %s not in selector", obj.name)
    51  		return
    52  
    53  	case *Const:
    54  		check.addDeclDep(obj)
    55  		if typ == Typ[Invalid] {
    56  			return
    57  		}
    58  		if obj == universeIota {
    59  			if check.iota == nil {
    60  				check.errorf(e.Pos(), "cannot use iota outside constant declaration")
    61  				return
    62  			}
    63  			x.val = check.iota
    64  		} else {
    65  			x.val = obj.val
    66  		}
    67  		assert(x.val != nil)
    68  		x.mode = constant
    69  
    70  	case *TypeName:
    71  		x.mode = typexpr
    72  		// check for cycle
    73  		// (it's ok to iterate forward because each named type appears at most once in path)
    74  		for i, prev := range path {
    75  			if prev == obj {
    76  				check.errorf(obj.pos, "illegal cycle in declaration of %s", obj.name)
    77  				// print cycle
    78  				for _, obj := range path[i:] {
    79  					check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented
    80  				}
    81  				check.errorf(obj.Pos(), "\t%s", obj.Name())
    82  				// maintain x.mode == typexpr despite error
    83  				typ = Typ[Invalid]
    84  				break
    85  			}
    86  		}
    87  
    88  	case *Var:
    89  		if obj.pkg == check.pkg {
    90  			obj.used = true
    91  		}
    92  		check.addDeclDep(obj)
    93  		if typ == Typ[Invalid] {
    94  			return
    95  		}
    96  		x.mode = variable
    97  
    98  	case *Func:
    99  		check.addDeclDep(obj)
   100  		x.mode = value
   101  
   102  	case *Builtin:
   103  		x.id = obj.id
   104  		x.mode = builtin
   105  
   106  	case *Nil:
   107  		x.mode = value
   108  
   109  	default:
   110  		unreachable()
   111  	}
   112  
   113  	x.typ = typ
   114  }
   115  
   116  // typExpr type-checks the type expression e and returns its type, or Typ[Invalid].
   117  // If def != nil, e is the type specification for the named type def, declared
   118  // in a type declaration, and def.underlying will be set to the type of e before
   119  // any components of e are type-checked. Path contains the path of named types
   120  // referring to this type.
   121  //
   122  func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type) {
   123  	if trace {
   124  		check.trace(e.Pos(), "%s", e)
   125  		check.indent++
   126  		defer func() {
   127  			check.indent--
   128  			check.trace(e.Pos(), "=> %s", T)
   129  		}()
   130  	}
   131  
   132  	T = check.typExprInternal(e, def, path)
   133  	assert(isTyped(T))
   134  	check.recordTypeAndValue(e, typexpr, T, nil)
   135  
   136  	return
   137  }
   138  
   139  func (check *Checker) typ(e ast.Expr) Type {
   140  	return check.typExpr(e, nil, nil)
   141  }
   142  
   143  // funcType type-checks a function or method type and returns its signature.
   144  func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) *Signature {
   145  	scope := NewScope(check.scope, "function")
   146  	check.recordScope(ftyp, scope)
   147  
   148  	recvList, _ := check.collectParams(scope, recvPar, false)
   149  	params, variadic := check.collectParams(scope, ftyp.Params, true)
   150  	results, _ := check.collectParams(scope, ftyp.Results, false)
   151  
   152  	if recvPar != nil {
   153  		// recv parameter list present (may be empty)
   154  		// spec: "The receiver is specified via an extra parameter section preceeding the
   155  		// method name. That parameter section must declare a single parameter, the receiver."
   156  		var recv *Var
   157  		switch len(recvList) {
   158  		case 0:
   159  			check.error(recvPar.Pos(), "method is missing receiver")
   160  			recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below
   161  		default:
   162  			// more than one receiver
   163  			check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
   164  			fallthrough // continue with first receiver
   165  		case 1:
   166  			recv = recvList[0]
   167  		}
   168  		// spec: "The receiver type must be of the form T or *T where T is a type name."
   169  		// (ignore invalid types - error was reported before)
   170  		if t, _ := deref(recv.typ); t != Typ[Invalid] {
   171  			var err string
   172  			if T, _ := t.(*Named); T != nil {
   173  				// spec: "The type denoted by T is called the receiver base type; it must not
   174  				// be a pointer or interface type and it must be declared in the same package
   175  				// as the method."
   176  				if T.obj.pkg != check.pkg {
   177  					err = "type not defined in this package"
   178  				} else {
   179  					// TODO(gri) This is not correct if the underlying type is unknown yet.
   180  					switch u := T.underlying.(type) {
   181  					case *Basic:
   182  						// unsafe.Pointer is treated like a regular pointer
   183  						if u.kind == UnsafePointer {
   184  							err = "unsafe.Pointer"
   185  						}
   186  					case *Pointer, *Interface:
   187  						err = "pointer or interface type"
   188  					}
   189  				}
   190  			} else {
   191  				err = "basic or unnamed type"
   192  			}
   193  			if err != "" {
   194  				check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err)
   195  				// ok to continue
   196  			}
   197  		}
   198  		sig.recv = recv
   199  	}
   200  
   201  	sig.scope = scope
   202  	sig.params = NewTuple(params...)
   203  	sig.results = NewTuple(results...)
   204  	sig.variadic = variadic
   205  
   206  	return sig
   207  }
   208  
   209  // typExprInternal drives type checking of types.
   210  // Must only be called by typExpr.
   211  //
   212  func (check *Checker) typExprInternal(e ast.Expr, def *Named, path []*TypeName) Type {
   213  	switch e := e.(type) {
   214  	case *ast.BadExpr:
   215  		// ignore - error reported before
   216  
   217  	case *ast.Ident:
   218  		var x operand
   219  		check.ident(&x, e, def, path)
   220  
   221  		switch x.mode {
   222  		case typexpr:
   223  			typ := x.typ
   224  			def.setUnderlying(typ)
   225  			return typ
   226  		case invalid:
   227  			// ignore - error reported before
   228  		case novalue:
   229  			check.errorf(x.pos(), "%s used as type", &x)
   230  		default:
   231  			check.errorf(x.pos(), "%s is not a type", &x)
   232  		}
   233  
   234  	case *ast.SelectorExpr:
   235  		var x operand
   236  		check.selector(&x, e)
   237  
   238  		switch x.mode {
   239  		case typexpr:
   240  			typ := x.typ
   241  			def.setUnderlying(typ)
   242  			return typ
   243  		case invalid:
   244  			// ignore - error reported before
   245  		case novalue:
   246  			check.errorf(x.pos(), "%s used as type", &x)
   247  		default:
   248  			check.errorf(x.pos(), "%s is not a type", &x)
   249  		}
   250  
   251  	case *ast.ParenExpr:
   252  		return check.typExpr(e.X, def, path)
   253  
   254  	case *ast.ArrayType:
   255  		if e.Len != nil {
   256  			typ := new(Array)
   257  			def.setUnderlying(typ)
   258  			typ.len = check.arrayLength(e.Len)
   259  			typ.elem = check.typExpr(e.Elt, nil, path)
   260  			return typ
   261  
   262  		} else {
   263  			typ := new(Slice)
   264  			def.setUnderlying(typ)
   265  			typ.elem = check.typ(e.Elt)
   266  			return typ
   267  		}
   268  
   269  	case *ast.StructType:
   270  		typ := new(Struct)
   271  		def.setUnderlying(typ)
   272  		check.structType(typ, e, path)
   273  		return typ
   274  
   275  	case *ast.StarExpr:
   276  		typ := new(Pointer)
   277  		def.setUnderlying(typ)
   278  		typ.base = check.typ(e.X)
   279  		return typ
   280  
   281  	case *ast.FuncType:
   282  		typ := new(Signature)
   283  		def.setUnderlying(typ)
   284  		check.funcType(typ, nil, e)
   285  		return typ
   286  
   287  	case *ast.InterfaceType:
   288  		typ := new(Interface)
   289  		def.setUnderlying(typ)
   290  		check.interfaceType(typ, e, def, path)
   291  		return typ
   292  
   293  	case *ast.MapType:
   294  		typ := new(Map)
   295  		def.setUnderlying(typ)
   296  
   297  		typ.key = check.typ(e.Key)
   298  		typ.elem = check.typ(e.Value)
   299  
   300  		// spec: "The comparison operators == and != must be fully defined
   301  		// for operands of the key type; thus the key type must not be a
   302  		// function, map, or slice."
   303  		//
   304  		// Delay this check because it requires fully setup types;
   305  		// it is safe to continue in any case (was issue 6667).
   306  		check.delay(func() {
   307  			if !Comparable(typ.key) {
   308  				check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key)
   309  			}
   310  		})
   311  
   312  		return typ
   313  
   314  	case *ast.ChanType:
   315  		typ := new(Chan)
   316  		def.setUnderlying(typ)
   317  
   318  		dir := SendRecv
   319  		switch e.Dir {
   320  		case ast.SEND | ast.RECV:
   321  			// nothing to do
   322  		case ast.SEND:
   323  			dir = SendOnly
   324  		case ast.RECV:
   325  			dir = RecvOnly
   326  		default:
   327  			check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir)
   328  			// ok to continue
   329  		}
   330  
   331  		typ.dir = dir
   332  		typ.elem = check.typ(e.Value)
   333  		return typ
   334  
   335  	default:
   336  		check.errorf(e.Pos(), "%s is not a type", e)
   337  	}
   338  
   339  	typ := Typ[Invalid]
   340  	def.setUnderlying(typ)
   341  	return typ
   342  }
   343  
   344  // typeOrNil type-checks the type expression (or nil value) e
   345  // and returns the typ of e, or nil.
   346  // If e is neither a type nor nil, typOrNil returns Typ[Invalid].
   347  //
   348  func (check *Checker) typOrNil(e ast.Expr) Type {
   349  	var x operand
   350  	check.rawExpr(&x, e, nil)
   351  	switch x.mode {
   352  	case invalid:
   353  		// ignore - error reported before
   354  	case novalue:
   355  		check.errorf(x.pos(), "%s used as type", &x)
   356  	case typexpr:
   357  		return x.typ
   358  	case value:
   359  		if x.isNil() {
   360  			return nil
   361  		}
   362  		fallthrough
   363  	default:
   364  		check.errorf(x.pos(), "%s is not a type", &x)
   365  	}
   366  	return Typ[Invalid]
   367  }
   368  
   369  func (check *Checker) arrayLength(e ast.Expr) int64 {
   370  	var x operand
   371  	check.expr(&x, e)
   372  	if x.mode != constant {
   373  		if x.mode != invalid {
   374  			check.errorf(x.pos(), "array length %s must be constant", &x)
   375  		}
   376  		return 0
   377  	}
   378  	if !x.isInteger() {
   379  		check.errorf(x.pos(), "array length %s must be integer", &x)
   380  		return 0
   381  	}
   382  	n, ok := exact.Int64Val(x.val)
   383  	if !ok || n < 0 {
   384  		check.errorf(x.pos(), "invalid array length %s", &x)
   385  		return 0
   386  	}
   387  	return n
   388  }
   389  
   390  func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
   391  	if list == nil {
   392  		return
   393  	}
   394  
   395  	var named, anonymous bool
   396  	for i, field := range list.List {
   397  		ftype := field.Type
   398  		if t, _ := ftype.(*ast.Ellipsis); t != nil {
   399  			ftype = t.Elt
   400  			if variadicOk && i == len(list.List)-1 {
   401  				variadic = true
   402  			} else {
   403  				check.invalidAST(field.Pos(), "... not permitted")
   404  				// ignore ... and continue
   405  			}
   406  		}
   407  		typ := check.typ(ftype)
   408  		// The parser ensures that f.Tag is nil and we don't
   409  		// care if a constructed AST contains a non-nil tag.
   410  		if len(field.Names) > 0 {
   411  			// named parameter
   412  			for _, name := range field.Names {
   413  				if name.Name == "" {
   414  					check.invalidAST(name.Pos(), "anonymous parameter")
   415  					// ok to continue
   416  				}
   417  				par := NewParam(name.Pos(), check.pkg, name.Name, typ)
   418  				check.declare(scope, name, par)
   419  				params = append(params, par)
   420  			}
   421  			named = true
   422  		} else {
   423  			// anonymous parameter
   424  			par := NewParam(ftype.Pos(), check.pkg, "", typ)
   425  			check.recordImplicit(field, par)
   426  			params = append(params, par)
   427  			anonymous = true
   428  		}
   429  	}
   430  
   431  	if named && anonymous {
   432  		check.invalidAST(list.Pos(), "list contains both named and anonymous parameters")
   433  		// ok to continue
   434  	}
   435  
   436  	// For a variadic function, change the last parameter's type from T to []T.
   437  	if variadic && len(params) > 0 {
   438  		last := params[len(params)-1]
   439  		last.typ = &Slice{elem: last.typ}
   440  	}
   441  
   442  	return
   443  }
   444  
   445  func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
   446  	if alt := oset.insert(obj); alt != nil {
   447  		check.errorf(pos, "%s redeclared", obj.Name())
   448  		check.reportAltDecl(alt)
   449  		return false
   450  	}
   451  	return true
   452  }
   453  
   454  func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, def *Named, path []*TypeName) {
   455  	// empty interface: common case
   456  	if ityp.Methods == nil {
   457  		return
   458  	}
   459  
   460  	// The parser ensures that field tags are nil and we don't
   461  	// care if a constructed AST contains non-nil tags.
   462  
   463  	// use named receiver type if available (for better error messages)
   464  	var recvTyp Type = iface
   465  	if def != nil {
   466  		recvTyp = def
   467  	}
   468  
   469  	// Phase 1: Collect explicitly declared methods, the corresponding
   470  	//          signature (AST) expressions, and the list of embedded
   471  	//          type (AST) expressions. Do not resolve signatures or
   472  	//          embedded types yet to avoid cycles referring to this
   473  	//          interface.
   474  
   475  	var (
   476  		mset       objset
   477  		signatures []ast.Expr // list of corresponding method signatures
   478  		embedded   []ast.Expr // list of embedded types
   479  	)
   480  	for _, f := range ityp.Methods.List {
   481  		if len(f.Names) > 0 {
   482  			// The parser ensures that there's only one method
   483  			// and we don't care if a constructed AST has more.
   484  			name := f.Names[0]
   485  			pos := name.Pos()
   486  			// spec: "As with all method sets, in an interface type,
   487  			// each method must have a unique non-blank name."
   488  			if name.Name == "_" {
   489  				check.errorf(pos, "invalid method name _")
   490  				continue
   491  			}
   492  			// Don't type-check signature yet - use an
   493  			// empty signature now and update it later.
   494  			// Since we know the receiver, set it up now
   495  			// (required to avoid crash in ptrRecv; see
   496  			// e.g. test case for issue 6638).
   497  			// TODO(gri) Consider marking methods signatures
   498  			// as incomplete, for better error messages. See
   499  			// also the T4 and T5 tests in testdata/cycles2.src.
   500  			sig := new(Signature)
   501  			sig.recv = NewVar(pos, check.pkg, "", recvTyp)
   502  			m := NewFunc(pos, check.pkg, name.Name, sig)
   503  			if check.declareInSet(&mset, pos, m) {
   504  				iface.methods = append(iface.methods, m)
   505  				iface.allMethods = append(iface.allMethods, m)
   506  				signatures = append(signatures, f.Type)
   507  				check.recordDef(name, m)
   508  			}
   509  		} else {
   510  			// embedded type
   511  			embedded = append(embedded, f.Type)
   512  		}
   513  	}
   514  
   515  	// Phase 2: Resolve embedded interfaces. Because an interface must not
   516  	//          embed itself (directly or indirectly), each embedded interface
   517  	//          can be fully resolved without depending on any method of this
   518  	//          interface (if there is a cycle or another error, the embedded
   519  	//          type resolves to an invalid type and is ignored).
   520  	//          In particular, the list of methods for each embedded interface
   521  	//          must be complete (it cannot depend on this interface), and so
   522  	//          those methods can be added to the list of all methods of this
   523  	//          interface.
   524  
   525  	for _, e := range embedded {
   526  		pos := e.Pos()
   527  		typ := check.typExpr(e, nil, path)
   528  		named, _ := typ.(*Named)
   529  		if named == nil {
   530  			if typ != Typ[Invalid] {
   531  				check.invalidAST(pos, "%s is not named type", typ)
   532  			}
   533  			continue
   534  		}
   535  		// determine underlying (possibly incomplete) type
   536  		// by following its forward chain
   537  		u := underlying(named)
   538  		embed, _ := u.(*Interface)
   539  		if embed == nil {
   540  			if u != Typ[Invalid] {
   541  				check.errorf(pos, "%s is not an interface", named)
   542  			}
   543  			continue
   544  		}
   545  		iface.embeddeds = append(iface.embeddeds, named)
   546  		// collect embedded methods
   547  		for _, m := range embed.allMethods {
   548  			if check.declareInSet(&mset, pos, m) {
   549  				iface.allMethods = append(iface.allMethods, m)
   550  			}
   551  		}
   552  	}
   553  
   554  	// Phase 3: At this point all methods have been collected for this interface.
   555  	//          It is now safe to type-check the signatures of all explicitly
   556  	//          declared methods, even if they refer to this interface via a cycle
   557  	//          and embed the methods of this interface in a parameter of interface
   558  	//          type.
   559  
   560  	for i, m := range iface.methods {
   561  		expr := signatures[i]
   562  		typ := check.typ(expr)
   563  		sig, _ := typ.(*Signature)
   564  		if sig == nil {
   565  			if typ != Typ[Invalid] {
   566  				check.invalidAST(expr.Pos(), "%s is not a method signature", typ)
   567  			}
   568  			continue // keep method with empty method signature
   569  		}
   570  		// update signature, but keep recv that was set up before
   571  		old := m.typ.(*Signature)
   572  		sig.recv = old.recv
   573  		*old = *sig // update signature (don't replace it!)
   574  	}
   575  
   576  	// TODO(gri) The list of explicit methods is only sorted for now to
   577  	// produce the same Interface as NewInterface. We may be able to
   578  	// claim source order in the future. Revisit.
   579  	sort.Sort(byUniqueMethodName(iface.methods))
   580  
   581  	// TODO(gri) The list of embedded types is only sorted for now to
   582  	// produce the same Interface as NewInterface. We may be able to
   583  	// claim source order in the future. Revisit.
   584  	sort.Sort(byUniqueTypeName(iface.embeddeds))
   585  
   586  	sort.Sort(byUniqueMethodName(iface.allMethods))
   587  }
   588  
   589  // byUniqueTypeName named type lists can be sorted by their unique type names.
   590  type byUniqueTypeName []*Named
   591  
   592  func (a byUniqueTypeName) Len() int           { return len(a) }
   593  func (a byUniqueTypeName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() }
   594  func (a byUniqueTypeName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   595  
   596  // byUniqueMethodName method lists can be sorted by their unique method names.
   597  type byUniqueMethodName []*Func
   598  
   599  func (a byUniqueMethodName) Len() int           { return len(a) }
   600  func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() }
   601  func (a byUniqueMethodName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   602  
   603  func (check *Checker) tag(t *ast.BasicLit) string {
   604  	if t != nil {
   605  		if t.Kind == token.STRING {
   606  			if val, err := strconv.Unquote(t.Value); err == nil {
   607  				return val
   608  			}
   609  		}
   610  		check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value)
   611  	}
   612  	return ""
   613  }
   614  
   615  func (check *Checker) structType(styp *Struct, e *ast.StructType, path []*TypeName) {
   616  	list := e.Fields
   617  	if list == nil {
   618  		return
   619  	}
   620  
   621  	// struct fields and tags
   622  	var fields []*Var
   623  	var tags []string
   624  
   625  	// for double-declaration checks
   626  	var fset objset
   627  
   628  	// current field typ and tag
   629  	var typ Type
   630  	var tag string
   631  	// anonymous != nil indicates an anonymous field.
   632  	add := func(field *ast.Field, ident *ast.Ident, anonymous *TypeName, pos token.Pos) {
   633  		if tag != "" && tags == nil {
   634  			tags = make([]string, len(fields))
   635  		}
   636  		if tags != nil {
   637  			tags = append(tags, tag)
   638  		}
   639  
   640  		name := ident.Name
   641  		fld := NewField(pos, check.pkg, name, typ, anonymous != nil)
   642  		// spec: "Within a struct, non-blank field names must be unique."
   643  		if name == "_" || check.declareInSet(&fset, pos, fld) {
   644  			fields = append(fields, fld)
   645  			check.recordDef(ident, fld)
   646  		}
   647  		if anonymous != nil {
   648  			check.recordUse(ident, anonymous)
   649  		}
   650  	}
   651  
   652  	for _, f := range list.List {
   653  		typ = check.typExpr(f.Type, nil, path)
   654  		tag = check.tag(f.Tag)
   655  		if len(f.Names) > 0 {
   656  			// named fields
   657  			for _, name := range f.Names {
   658  				add(f, name, nil, name.Pos())
   659  			}
   660  		} else {
   661  			// anonymous field
   662  			name := anonymousFieldIdent(f.Type)
   663  			pos := f.Type.Pos()
   664  			t, isPtr := deref(typ)
   665  			switch t := t.(type) {
   666  			case *Basic:
   667  				if t == Typ[Invalid] {
   668  					// error was reported before
   669  					continue
   670  				}
   671  				// unsafe.Pointer is treated like a regular pointer
   672  				if t.kind == UnsafePointer {
   673  					check.errorf(pos, "anonymous field type cannot be unsafe.Pointer")
   674  					continue
   675  				}
   676  				add(f, name, Universe.Lookup(t.name).(*TypeName), pos)
   677  
   678  			case *Named:
   679  				// spec: "An embedded type must be specified as a type name
   680  				// T or as a pointer to a non-interface type name *T, and T
   681  				// itself may not be a pointer type."
   682  				switch u := t.underlying.(type) {
   683  				case *Basic:
   684  					// unsafe.Pointer is treated like a regular pointer
   685  					if u.kind == UnsafePointer {
   686  						check.errorf(pos, "anonymous field type cannot be unsafe.Pointer")
   687  						continue
   688  					}
   689  				case *Pointer:
   690  					check.errorf(pos, "anonymous field type cannot be a pointer")
   691  					continue
   692  				case *Interface:
   693  					if isPtr {
   694  						check.errorf(pos, "anonymous field type cannot be a pointer to an interface")
   695  						continue
   696  					}
   697  				}
   698  				add(f, name, t.obj, pos)
   699  
   700  			default:
   701  				check.invalidAST(pos, "anonymous field type %s must be named", typ)
   702  			}
   703  		}
   704  	}
   705  
   706  	styp.fields = fields
   707  	styp.tags = tags
   708  }
   709  
   710  func anonymousFieldIdent(e ast.Expr) *ast.Ident {
   711  	switch e := e.(type) {
   712  	case *ast.Ident:
   713  		return e
   714  	case *ast.StarExpr:
   715  		return anonymousFieldIdent(e.X)
   716  	case *ast.SelectorExpr:
   717  		return e.Sel
   718  	}
   719  	return nil // invalid anonymous field
   720  }