...

Source file src/pkg/go/types/typexpr.go

     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/constant"
    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, see Checker.definedType, below.
    20	// If wantType is set, the identifier e is expected to denote a type.
    21	//
    22	func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
    23		x.mode = invalid
    24		x.expr = e
    25	
    26		// Note that we cannot use check.lookup here because the returned scope
    27		// may be different from obj.Parent(). See also Scope.LookupParent doc.
    28		scope, obj := check.scope.LookupParent(e.Name, check.pos)
    29		if obj == nil {
    30			if e.Name == "_" {
    31				check.errorf(e.Pos(), "cannot use _ as value or type")
    32			} else {
    33				check.errorf(e.Pos(), "undeclared name: %s", e.Name)
    34			}
    35			return
    36		}
    37		check.recordUse(e, obj)
    38	
    39		// Type-check the object.
    40		// Only call Checker.objDecl if the object doesn't have a type yet
    41		// (in which case we must actually determine it) or the object is a
    42		// TypeName and we also want a type (in which case we might detect
    43		// a cycle which needs to be reported). Otherwise we can skip the
    44		// call and avoid a possible cycle error in favor of the more
    45		// informative "not a type/value" error that this function's caller
    46		// will issue (see issue #25790).
    47		typ := obj.Type()
    48		if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
    49			check.objDecl(obj, def)
    50			typ = obj.Type() // type must have been assigned by Checker.objDecl
    51		}
    52		assert(typ != nil)
    53	
    54		// The object may be dot-imported: If so, remove its package from
    55		// the map of unused dot imports for the respective file scope.
    56		// (This code is only needed for dot-imports. Without them,
    57		// we only have to mark variables, see *Var case below).
    58		if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil {
    59			delete(check.unusedDotImports[scope], pkg)
    60		}
    61	
    62		switch obj := obj.(type) {
    63		case *PkgName:
    64			check.errorf(e.Pos(), "use of package %s not in selector", obj.name)
    65			return
    66	
    67		case *Const:
    68			check.addDeclDep(obj)
    69			if typ == Typ[Invalid] {
    70				return
    71			}
    72			if obj == universeIota {
    73				if check.iota == nil {
    74					check.errorf(e.Pos(), "cannot use iota outside constant declaration")
    75					return
    76				}
    77				x.val = check.iota
    78			} else {
    79				x.val = obj.val
    80			}
    81			assert(x.val != nil)
    82			x.mode = constant_
    83	
    84		case *TypeName:
    85			x.mode = typexpr
    86	
    87		case *Var:
    88			// It's ok to mark non-local variables, but ignore variables
    89			// from other packages to avoid potential race conditions with
    90			// dot-imported variables.
    91			if obj.pkg == check.pkg {
    92				obj.used = true
    93			}
    94			check.addDeclDep(obj)
    95			if typ == Typ[Invalid] {
    96				return
    97			}
    98			x.mode = variable
    99	
   100		case *Func:
   101			check.addDeclDep(obj)
   102			x.mode = value
   103	
   104		case *Builtin:
   105			x.id = obj.id
   106			x.mode = builtin
   107	
   108		case *Nil:
   109			x.mode = value
   110	
   111		default:
   112			unreachable()
   113		}
   114	
   115		x.typ = typ
   116	}
   117	
   118	// typ type-checks the type expression e and returns its type, or Typ[Invalid].
   119	func (check *Checker) typ(e ast.Expr) Type {
   120		return check.definedType(e, nil)
   121	}
   122	
   123	// definedType is like typ but also accepts a type name def.
   124	// If def != nil, e is the type specification for the defined type def, declared
   125	// in a type declaration, and def.underlying will be set to the type of e before
   126	// any components of e are type-checked.
   127	//
   128	func (check *Checker) definedType(e ast.Expr, def *Named) (T Type) {
   129		if trace {
   130			check.trace(e.Pos(), "%s", e)
   131			check.indent++
   132			defer func() {
   133				check.indent--
   134				check.trace(e.Pos(), "=> %s", T)
   135			}()
   136		}
   137	
   138		T = check.typInternal(e, def)
   139		assert(isTyped(T))
   140		check.recordTypeAndValue(e, typexpr, T, nil)
   141	
   142		return
   143	}
   144	
   145	// indirectType is like typ but it also breaks the (otherwise) infinite size of recursive
   146	// types by introducing an indirection. It should be called for components of types that
   147	// are not laid out in place in memory, such as pointer base types, slice or map element
   148	// types, function parameter types, etc.
   149	func (check *Checker) indirectType(e ast.Expr) Type {
   150		check.push(indir)
   151		defer check.pop()
   152		return check.definedType(e, nil)
   153	}
   154	
   155	// funcType type-checks a function or method type.
   156	func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
   157		scope := NewScope(check.scope, token.NoPos, token.NoPos, "function")
   158		scope.isFunc = true
   159		check.recordScope(ftyp, scope)
   160	
   161		recvList, _ := check.collectParams(scope, recvPar, false)
   162		params, variadic := check.collectParams(scope, ftyp.Params, true)
   163		results, _ := check.collectParams(scope, ftyp.Results, false)
   164	
   165		if recvPar != nil {
   166			// recv parameter list present (may be empty)
   167			// spec: "The receiver is specified via an extra parameter section preceding the
   168			// method name. That parameter section must declare a single parameter, the receiver."
   169			var recv *Var
   170			switch len(recvList) {
   171			case 0:
   172				check.error(recvPar.Pos(), "method is missing receiver")
   173				recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below
   174			default:
   175				// more than one receiver
   176				check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
   177				fallthrough // continue with first receiver
   178			case 1:
   179				recv = recvList[0]
   180			}
   181			// spec: "The receiver type must be of the form T or *T where T is a type name."
   182			// (ignore invalid types - error was reported before)
   183			if t, _ := deref(recv.typ); t != Typ[Invalid] {
   184				var err string
   185				if T, _ := t.(*Named); T != nil {
   186					// spec: "The type denoted by T is called the receiver base type; it must not
   187					// be a pointer or interface type and it must be declared in the same package
   188					// as the method."
   189					if T.obj.pkg != check.pkg {
   190						err = "type not defined in this package"
   191					} else {
   192						// TODO(gri) This is not correct if the underlying type is unknown yet.
   193						switch u := T.underlying.(type) {
   194						case *Basic:
   195							// unsafe.Pointer is treated like a regular pointer
   196							if u.kind == UnsafePointer {
   197								err = "unsafe.Pointer"
   198							}
   199						case *Pointer, *Interface:
   200							err = "pointer or interface type"
   201						}
   202					}
   203				} else {
   204					err = "basic or unnamed type"
   205				}
   206				if err != "" {
   207					check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err)
   208					// ok to continue
   209				}
   210			}
   211			sig.recv = recv
   212		}
   213	
   214		sig.scope = scope
   215		sig.params = NewTuple(params...)
   216		sig.results = NewTuple(results...)
   217		sig.variadic = variadic
   218	}
   219	
   220	// typInternal drives type checking of types.
   221	// Must only be called by definedType.
   222	//
   223	func (check *Checker) typInternal(e ast.Expr, def *Named) Type {
   224		switch e := e.(type) {
   225		case *ast.BadExpr:
   226			// ignore - error reported before
   227	
   228		case *ast.Ident:
   229			var x operand
   230			check.ident(&x, e, def, true)
   231	
   232			switch x.mode {
   233			case typexpr:
   234				typ := x.typ
   235				def.setUnderlying(typ)
   236				return typ
   237			case invalid:
   238				// ignore - error reported before
   239			case novalue:
   240				check.errorf(x.pos(), "%s used as type", &x)
   241			default:
   242				check.errorf(x.pos(), "%s is not a type", &x)
   243			}
   244	
   245		case *ast.SelectorExpr:
   246			var x operand
   247			check.selector(&x, e)
   248	
   249			switch x.mode {
   250			case typexpr:
   251				typ := x.typ
   252				def.setUnderlying(typ)
   253				return typ
   254			case invalid:
   255				// ignore - error reported before
   256			case novalue:
   257				check.errorf(x.pos(), "%s used as type", &x)
   258			default:
   259				check.errorf(x.pos(), "%s is not a type", &x)
   260			}
   261	
   262		case *ast.ParenExpr:
   263			return check.definedType(e.X, def)
   264	
   265		case *ast.ArrayType:
   266			if e.Len != nil {
   267				typ := new(Array)
   268				def.setUnderlying(typ)
   269				typ.len = check.arrayLength(e.Len)
   270				typ.elem = check.typ(e.Elt)
   271				return typ
   272	
   273			} else {
   274				typ := new(Slice)
   275				def.setUnderlying(typ)
   276				typ.elem = check.indirectType(e.Elt)
   277				return typ
   278			}
   279	
   280		case *ast.StructType:
   281			typ := new(Struct)
   282			def.setUnderlying(typ)
   283			check.structType(typ, e)
   284			return typ
   285	
   286		case *ast.StarExpr:
   287			typ := new(Pointer)
   288			def.setUnderlying(typ)
   289			typ.base = check.indirectType(e.X)
   290			return typ
   291	
   292		case *ast.FuncType:
   293			typ := new(Signature)
   294			def.setUnderlying(typ)
   295			check.funcType(typ, nil, e)
   296			return typ
   297	
   298		case *ast.InterfaceType:
   299			typ := new(Interface)
   300			def.setUnderlying(typ)
   301			check.interfaceType(typ, e, def)
   302			return typ
   303	
   304		case *ast.MapType:
   305			typ := new(Map)
   306			def.setUnderlying(typ)
   307	
   308			typ.key = check.indirectType(e.Key)
   309			typ.elem = check.indirectType(e.Value)
   310	
   311			// spec: "The comparison operators == and != must be fully defined
   312			// for operands of the key type; thus the key type must not be a
   313			// function, map, or slice."
   314			//
   315			// Delay this check because it requires fully setup types;
   316			// it is safe to continue in any case (was issue 6667).
   317			check.later(func() {
   318				if !Comparable(typ.key) {
   319					check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key)
   320				}
   321			})
   322	
   323			return typ
   324	
   325		case *ast.ChanType:
   326			typ := new(Chan)
   327			def.setUnderlying(typ)
   328	
   329			dir := SendRecv
   330			switch e.Dir {
   331			case ast.SEND | ast.RECV:
   332				// nothing to do
   333			case ast.SEND:
   334				dir = SendOnly
   335			case ast.RECV:
   336				dir = RecvOnly
   337			default:
   338				check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir)
   339				// ok to continue
   340			}
   341	
   342			typ.dir = dir
   343			typ.elem = check.indirectType(e.Value)
   344			return typ
   345	
   346		default:
   347			check.errorf(e.Pos(), "%s is not a type", e)
   348		}
   349	
   350		typ := Typ[Invalid]
   351		def.setUnderlying(typ)
   352		return typ
   353	}
   354	
   355	// typeOrNil type-checks the type expression (or nil value) e
   356	// and returns the typ of e, or nil.
   357	// If e is neither a type nor nil, typOrNil returns Typ[Invalid].
   358	//
   359	func (check *Checker) typOrNil(e ast.Expr) Type {
   360		var x operand
   361		check.rawExpr(&x, e, nil)
   362		switch x.mode {
   363		case invalid:
   364			// ignore - error reported before
   365		case novalue:
   366			check.errorf(x.pos(), "%s used as type", &x)
   367		case typexpr:
   368			return x.typ
   369		case value:
   370			if x.isNil() {
   371				return nil
   372			}
   373			fallthrough
   374		default:
   375			check.errorf(x.pos(), "%s is not a type", &x)
   376		}
   377		return Typ[Invalid]
   378	}
   379	
   380	// arrayLength type-checks the array length expression e
   381	// and returns the constant length >= 0, or a value < 0
   382	// to indicate an error (and thus an unknown length).
   383	func (check *Checker) arrayLength(e ast.Expr) int64 {
   384		var x operand
   385		check.expr(&x, e)
   386		if x.mode != constant_ {
   387			if x.mode != invalid {
   388				check.errorf(x.pos(), "array length %s must be constant", &x)
   389			}
   390			return -1
   391		}
   392		if isUntyped(x.typ) || isInteger(x.typ) {
   393			if val := constant.ToInt(x.val); val.Kind() == constant.Int {
   394				if representableConst(val, check, Typ[Int], nil) {
   395					if n, ok := constant.Int64Val(val); ok && n >= 0 {
   396						return n
   397					}
   398					check.errorf(x.pos(), "invalid array length %s", &x)
   399					return -1
   400				}
   401			}
   402		}
   403		check.errorf(x.pos(), "array length %s must be integer", &x)
   404		return -1
   405	}
   406	
   407	func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
   408		if list == nil {
   409			return
   410		}
   411	
   412		var named, anonymous bool
   413		for i, field := range list.List {
   414			ftype := field.Type
   415			if t, _ := ftype.(*ast.Ellipsis); t != nil {
   416				ftype = t.Elt
   417				if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
   418					variadic = true
   419				} else {
   420					check.softErrorf(t.Pos(), "can only use ... with final parameter in list")
   421					// ignore ... and continue
   422				}
   423			}
   424			typ := check.indirectType(ftype)
   425			// The parser ensures that f.Tag is nil and we don't
   426			// care if a constructed AST contains a non-nil tag.
   427			if len(field.Names) > 0 {
   428				// named parameter
   429				for _, name := range field.Names {
   430					if name.Name == "" {
   431						check.invalidAST(name.Pos(), "anonymous parameter")
   432						// ok to continue
   433					}
   434					par := NewParam(name.Pos(), check.pkg, name.Name, typ)
   435					check.declare(scope, name, par, scope.pos)
   436					params = append(params, par)
   437				}
   438				named = true
   439			} else {
   440				// anonymous parameter
   441				par := NewParam(ftype.Pos(), check.pkg, "", typ)
   442				check.recordImplicit(field, par)
   443				params = append(params, par)
   444				anonymous = true
   445			}
   446		}
   447	
   448		if named && anonymous {
   449			check.invalidAST(list.Pos(), "list contains both named and anonymous parameters")
   450			// ok to continue
   451		}
   452	
   453		// For a variadic function, change the last parameter's type from T to []T.
   454		// Since we type-checked T rather than ...T, we also need to retro-actively
   455		// record the type for ...T.
   456		if variadic {
   457			last := params[len(params)-1]
   458			last.typ = &Slice{elem: last.typ}
   459			check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
   460		}
   461	
   462		return
   463	}
   464	
   465	func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
   466		if alt := oset.insert(obj); alt != nil {
   467			check.errorf(pos, "%s redeclared", obj.Name())
   468			check.reportAltDecl(alt)
   469			return false
   470		}
   471		return true
   472	}
   473	
   474	func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
   475		// fast-track empty interface
   476		if iface.Methods.List == nil {
   477			ityp.allMethods = markComplete
   478			return
   479		}
   480	
   481		// collect embedded interfaces
   482		// Only needed for printing and API. Delay collection
   483		// to end of type-checking (for package-global interfaces)
   484		// when all types are complete. Local interfaces are handled
   485		// after each statement (as each statement processes delayed
   486		// functions).
   487		interfaceContext := check.context // capture for use in closure below
   488		check.later(func() {
   489			if trace {
   490				check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %v", iface)
   491				check.indent++
   492				defer func() {
   493					check.indent--
   494				}()
   495			}
   496	
   497			// The context must be restored since for local interfaces
   498			// delayed functions are processed after each statement
   499			// (was issue #24140).
   500			defer func(ctxt context) {
   501				check.context = ctxt
   502			}(check.context)
   503			check.context = interfaceContext
   504	
   505			for _, f := range iface.Methods.List {
   506				if len(f.Names) == 0 {
   507					typ := check.indirectType(f.Type)
   508					// typ should be a named type denoting an interface
   509					// (the parser will make sure it's a named type but
   510					// constructed ASTs may be wrong).
   511					if typ == Typ[Invalid] {
   512						continue // error reported before
   513					}
   514					embed, _ := typ.Underlying().(*Interface)
   515					if embed == nil {
   516						check.errorf(f.Type.Pos(), "%s is not an interface", typ)
   517						continue
   518					}
   519					// Correct embedded interfaces must be complete -
   520					// don't just assert, but report error since this
   521					// used to be the underlying cause for issue #18395.
   522					if embed.allMethods == nil {
   523						check.dump("%v: incomplete embedded interface %s", f.Type.Pos(), typ)
   524						unreachable()
   525					}
   526					// collect interface
   527					ityp.embeddeds = append(ityp.embeddeds, typ)
   528				}
   529			}
   530			// sort to match NewInterface/NewInterface2
   531			// TODO(gri) we may be able to switch to source order
   532			sort.Stable(byUniqueTypeName(ityp.embeddeds))
   533		})
   534	
   535		// compute method set
   536		var tname *TypeName
   537		var path []*TypeName
   538		if def != nil {
   539			tname = def.obj
   540			path = []*TypeName{tname}
   541		}
   542		info := check.infoFromTypeLit(check.scope, iface, tname, path)
   543		if info == nil || info == &emptyIfaceInfo {
   544			// we got an error or the empty interface - exit early
   545			ityp.allMethods = markComplete
   546			return
   547		}
   548	
   549		// use named receiver type if available (for better error messages)
   550		var recvTyp Type = ityp
   551		if def != nil {
   552			recvTyp = def
   553		}
   554	
   555		// Correct receiver type for all methods explicitly declared
   556		// by this interface after we're done with type-checking at
   557		// this level. See comment below for details.
   558		check.later(func() {
   559			for _, m := range ityp.methods {
   560				m.typ.(*Signature).recv.typ = recvTyp
   561			}
   562		})
   563	
   564		// collect methods
   565		var sigfix []*methodInfo
   566		for i, minfo := range info.methods {
   567			fun := minfo.fun
   568			if fun == nil {
   569				name := minfo.src.Names[0]
   570				pos := name.Pos()
   571				// Don't type-check signature yet - use an
   572				// empty signature now and update it later.
   573				// But set up receiver since we know it and
   574				// its position, and because interface method
   575				// signatures don't get a receiver via regular
   576				// type-checking (there isn't a receiver in the
   577				// method's AST). Setting the receiver type is
   578				// also important for ptrRecv() (see methodset.go).
   579				//
   580				// Note: For embedded methods, the receiver type
   581				// should be the type of the interface that declared
   582				// the methods in the first place. Since we get the
   583				// methods here via methodInfo, which may be computed
   584				// before we have all relevant interface types, we use
   585				// the current interface's type (recvType). This may be
   586				// the type of the interface embedding the interface that
   587				// declared the methods. This doesn't matter for type-
   588				// checking (we only care about the receiver type for
   589				// the ptrRecv predicate, and it's never a pointer recv
   590				// for interfaces), but it matters for go/types clients
   591				// and for printing. We correct the receiver after type-
   592				// checking.
   593				//
   594				// TODO(gri) Consider marking methods signatures
   595				// as incomplete, for better error messages. See
   596				// also the T4 and T5 tests in testdata/cycles2.src.
   597				sig := new(Signature)
   598				sig.recv = NewVar(pos, check.pkg, "", recvTyp)
   599				fun = NewFunc(pos, check.pkg, name.Name, sig)
   600				minfo.fun = fun
   601				check.recordDef(name, fun)
   602				sigfix = append(sigfix, minfo)
   603			}
   604			// fun != nil
   605			if i < info.explicits {
   606				ityp.methods = append(ityp.methods, fun)
   607			}
   608			ityp.allMethods = append(ityp.allMethods, fun)
   609		}
   610	
   611		// fix signatures now that we have collected all methods
   612		savedContext := check.context
   613		for _, minfo := range sigfix {
   614			// (possibly embedded) methods must be type-checked within their scope and
   615			// type-checking them must not affect the current context (was issue #23914)
   616			check.context = context{scope: minfo.scope}
   617			typ := check.indirectType(minfo.src.Type)
   618			sig, _ := typ.(*Signature)
   619			if sig == nil {
   620				if typ != Typ[Invalid] {
   621					check.invalidAST(minfo.src.Type.Pos(), "%s is not a method signature", typ)
   622				}
   623				continue // keep method with empty method signature
   624			}
   625			// update signature, but keep recv that was set up before
   626			old := minfo.fun.typ.(*Signature)
   627			sig.recv = old.recv
   628			*old = *sig // update signature (don't replace pointer!)
   629		}
   630		check.context = savedContext
   631	
   632		// sort to match NewInterface/NewInterface2
   633		// TODO(gri) we may be able to switch to source order
   634		sort.Sort(byUniqueMethodName(ityp.methods))
   635	
   636		if ityp.allMethods == nil {
   637			ityp.allMethods = markComplete
   638		} else {
   639			sort.Sort(byUniqueMethodName(ityp.allMethods))
   640		}
   641	}
   642	
   643	// byUniqueTypeName named type lists can be sorted by their unique type names.
   644	type byUniqueTypeName []Type
   645	
   646	func (a byUniqueTypeName) Len() int           { return len(a) }
   647	func (a byUniqueTypeName) Less(i, j int) bool { return sortName(a[i]) < sortName(a[j]) }
   648	func (a byUniqueTypeName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   649	
   650	func sortName(t Type) string {
   651		if named, _ := t.(*Named); named != nil {
   652			return named.obj.Id()
   653		}
   654		return ""
   655	}
   656	
   657	// byUniqueMethodName method lists can be sorted by their unique method names.
   658	type byUniqueMethodName []*Func
   659	
   660	func (a byUniqueMethodName) Len() int           { return len(a) }
   661	func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() }
   662	func (a byUniqueMethodName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   663	
   664	func (check *Checker) tag(t *ast.BasicLit) string {
   665		if t != nil {
   666			if t.Kind == token.STRING {
   667				if val, err := strconv.Unquote(t.Value); err == nil {
   668					return val
   669				}
   670			}
   671			check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value)
   672		}
   673		return ""
   674	}
   675	
   676	func (check *Checker) structType(styp *Struct, e *ast.StructType) {
   677		list := e.Fields
   678		if list == nil {
   679			return
   680		}
   681	
   682		// struct fields and tags
   683		var fields []*Var
   684		var tags []string
   685	
   686		// for double-declaration checks
   687		var fset objset
   688	
   689		// current field typ and tag
   690		var typ Type
   691		var tag string
   692		add := func(ident *ast.Ident, embedded bool, pos token.Pos) {
   693			if tag != "" && tags == nil {
   694				tags = make([]string, len(fields))
   695			}
   696			if tags != nil {
   697				tags = append(tags, tag)
   698			}
   699	
   700			name := ident.Name
   701			fld := NewField(pos, check.pkg, name, typ, embedded)
   702			// spec: "Within a struct, non-blank field names must be unique."
   703			if name == "_" || check.declareInSet(&fset, pos, fld) {
   704				fields = append(fields, fld)
   705				check.recordDef(ident, fld)
   706			}
   707		}
   708	
   709		// addInvalid adds an embedded field of invalid type to the struct for
   710		// fields with errors; this keeps the number of struct fields in sync
   711		// with the source as long as the fields are _ or have different names
   712		// (issue #25627).
   713		addInvalid := func(ident *ast.Ident, pos token.Pos) {
   714			typ = Typ[Invalid]
   715			tag = ""
   716			add(ident, true, pos)
   717		}
   718	
   719		for _, f := range list.List {
   720			typ = check.typ(f.Type)
   721			tag = check.tag(f.Tag)
   722			if len(f.Names) > 0 {
   723				// named fields
   724				for _, name := range f.Names {
   725					add(name, false, name.Pos())
   726				}
   727			} else {
   728				// embedded field
   729				// spec: "An embedded type must be specified as a type name T or as a pointer
   730				// to a non-interface type name *T, and T itself may not be a pointer type."
   731				pos := f.Type.Pos()
   732				name := embeddedFieldIdent(f.Type)
   733				if name == nil {
   734					check.invalidAST(pos, "embedded field type %s has no name", f.Type)
   735					name = ast.NewIdent("_")
   736					name.NamePos = pos
   737					addInvalid(name, pos)
   738					continue
   739				}
   740				t, isPtr := deref(typ)
   741				// Because we have a name, typ must be of the form T or *T, where T is the name
   742				// of a (named or alias) type, and t (= deref(typ)) must be the type of T.
   743				switch t := t.Underlying().(type) {
   744				case *Basic:
   745					if t == Typ[Invalid] {
   746						// error was reported before
   747						addInvalid(name, pos)
   748						continue
   749					}
   750	
   751					// unsafe.Pointer is treated like a regular pointer
   752					if t.kind == UnsafePointer {
   753						check.errorf(pos, "embedded field type cannot be unsafe.Pointer")
   754						addInvalid(name, pos)
   755						continue
   756					}
   757	
   758				case *Pointer:
   759					check.errorf(pos, "embedded field type cannot be a pointer")
   760					addInvalid(name, pos)
   761					continue
   762	
   763				case *Interface:
   764					if isPtr {
   765						check.errorf(pos, "embedded field type cannot be a pointer to an interface")
   766						addInvalid(name, pos)
   767						continue
   768					}
   769				}
   770				add(name, true, pos)
   771			}
   772		}
   773	
   774		styp.fields = fields
   775		styp.tags = tags
   776	}
   777	
   778	func embeddedFieldIdent(e ast.Expr) *ast.Ident {
   779		switch e := e.(type) {
   780		case *ast.Ident:
   781			return e
   782		case *ast.StarExpr:
   783			// *T is valid, but **T is not
   784			if _, ok := e.X.(*ast.StarExpr); !ok {
   785				return embeddedFieldIdent(e.X)
   786			}
   787		case *ast.SelectorExpr:
   788			return e.Sel
   789		}
   790		return nil // invalid embedded field
   791	}
   792	

View as plain text