Source file src/go/types/typexpr.go

Documentation: go/types

     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