Black Lives Matter. Support the Equal Justice Initiative.

Source file src/go/types/decl.go

Documentation: go/types

     1  // Copyright 2014 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 types
     6  
     7  import (
     8  	"go/ast"
     9  	"go/constant"
    10  	"go/token"
    11  )
    12  
    13  func (check *Checker) reportAltDecl(obj Object) {
    14  	if pos := obj.Pos(); pos.IsValid() {
    15  		// We use "other" rather than "previous" here because
    16  		// the first declaration seen may not be textually
    17  		// earlier in the source.
    18  		check.errorf(pos, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
    19  	}
    20  }
    21  
    22  func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
    23  	// spec: "The blank identifier, represented by the underscore
    24  	// character _, may be used in a declaration like any other
    25  	// identifier but the declaration does not introduce a new
    26  	// binding."
    27  	if obj.Name() != "_" {
    28  		if alt := scope.Insert(obj); alt != nil {
    29  			check.errorf(obj.Pos(), "%s redeclared in this block", obj.Name())
    30  			check.reportAltDecl(alt)
    31  			return
    32  		}
    33  		obj.setScopePos(pos)
    34  	}
    35  	if id != nil {
    36  		check.recordDef(id, obj)
    37  	}
    38  }
    39  
    40  // pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g].
    41  func pathString(path []Object) string {
    42  	var s string
    43  	for i, p := range path {
    44  		if i > 0 {
    45  			s += "->"
    46  		}
    47  		s += p.Name()
    48  	}
    49  	return s
    50  }
    51  
    52  // objDecl type-checks the declaration of obj in its respective (file) context.
    53  // For the meaning of def, see Checker.definedType, in typexpr.go.
    54  func (check *Checker) objDecl(obj Object, def *Named) {
    55  	if trace {
    56  		check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath))
    57  		check.indent++
    58  		defer func() {
    59  			check.indent--
    60  			check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color())
    61  		}()
    62  	}
    63  
    64  	// Checking the declaration of obj means inferring its type
    65  	// (and possibly its value, for constants).
    66  	// An object's type (and thus the object) may be in one of
    67  	// three states which are expressed by colors:
    68  	//
    69  	// - an object whose type is not yet known is painted white (initial color)
    70  	// - an object whose type is in the process of being inferred is painted grey
    71  	// - an object whose type is fully inferred is painted black
    72  	//
    73  	// During type inference, an object's color changes from white to grey
    74  	// to black (pre-declared objects are painted black from the start).
    75  	// A black object (i.e., its type) can only depend on (refer to) other black
    76  	// ones. White and grey objects may depend on white and black objects.
    77  	// A dependency on a grey object indicates a cycle which may or may not be
    78  	// valid.
    79  	//
    80  	// When objects turn grey, they are pushed on the object path (a stack);
    81  	// they are popped again when they turn black. Thus, if a grey object (a
    82  	// cycle) is encountered, it is on the object path, and all the objects
    83  	// it depends on are the remaining objects on that path. Color encoding
    84  	// is such that the color value of a grey object indicates the index of
    85  	// that object in the object path.
    86  
    87  	// During type-checking, white objects may be assigned a type without
    88  	// traversing through objDecl; e.g., when initializing constants and
    89  	// variables. Update the colors of those objects here (rather than
    90  	// everywhere where we set the type) to satisfy the color invariants.
    91  	if obj.color() == white && obj.Type() != nil {
    92  		obj.setColor(black)
    93  		return
    94  	}
    95  
    96  	switch obj.color() {
    97  	case white:
    98  		assert(obj.Type() == nil)
    99  		// All color values other than white and black are considered grey.
   100  		// Because black and white are < grey, all values >= grey are grey.
   101  		// Use those values to encode the object's index into the object path.
   102  		obj.setColor(grey + color(check.push(obj)))
   103  		defer func() {
   104  			check.pop().setColor(black)
   105  		}()
   106  
   107  	case black:
   108  		assert(obj.Type() != nil)
   109  		return
   110  
   111  	default:
   112  		// Color values other than white or black are considered grey.
   113  		fallthrough
   114  
   115  	case grey:
   116  		// We have a cycle.
   117  		// In the existing code, this is marked by a non-nil type
   118  		// for the object except for constants and variables whose
   119  		// type may be non-nil (known), or nil if it depends on the
   120  		// not-yet known initialization value.
   121  		// In the former case, set the type to Typ[Invalid] because
   122  		// we have an initialization cycle. The cycle error will be
   123  		// reported later, when determining initialization order.
   124  		// TODO(gri) Report cycle here and simplify initialization
   125  		// order code.
   126  		switch obj := obj.(type) {
   127  		case *Const:
   128  			if check.cycle(obj) || obj.typ == nil {
   129  				obj.typ = Typ[Invalid]
   130  			}
   131  
   132  		case *Var:
   133  			if check.cycle(obj) || obj.typ == nil {
   134  				obj.typ = Typ[Invalid]
   135  			}
   136  
   137  		case *TypeName:
   138  			if check.cycle(obj) {
   139  				// break cycle
   140  				// (without this, calling underlying()
   141  				// below may lead to an endless loop
   142  				// if we have a cycle for a defined
   143  				// (*Named) type)
   144  				obj.typ = Typ[Invalid]
   145  			}
   146  
   147  		case *Func:
   148  			if check.cycle(obj) {
   149  				// Don't set obj.typ to Typ[Invalid] here
   150  				// because plenty of code type-asserts that
   151  				// functions have a *Signature type. Grey
   152  				// functions have their type set to an empty
   153  				// signature which makes it impossible to
   154  				// initialize a variable with the function.
   155  			}
   156  
   157  		default:
   158  			unreachable()
   159  		}
   160  		assert(obj.Type() != nil)
   161  		return
   162  	}
   163  
   164  	d := check.objMap[obj]
   165  	if d == nil {
   166  		check.dump("%v: %s should have been declared", obj.Pos(), obj)
   167  		unreachable()
   168  	}
   169  
   170  	// save/restore current context and setup object context
   171  	defer func(ctxt context) {
   172  		check.context = ctxt
   173  	}(check.context)
   174  	check.context = context{
   175  		scope: d.file,
   176  	}
   177  
   178  	// Const and var declarations must not have initialization
   179  	// cycles. We track them by remembering the current declaration
   180  	// in check.decl. Initialization expressions depending on other
   181  	// consts, vars, or functions, add dependencies to the current
   182  	// check.decl.
   183  	switch obj := obj.(type) {
   184  	case *Const:
   185  		check.decl = d // new package-level const decl
   186  		check.constDecl(obj, d.typ, d.init)
   187  	case *Var:
   188  		check.decl = d // new package-level var decl
   189  		check.varDecl(obj, d.lhs, d.typ, d.init)
   190  	case *TypeName:
   191  		// invalid recursive types are detected via path
   192  		check.typeDecl(obj, d.typ, def, d.alias)
   193  	case *Func:
   194  		// functions may be recursive - no need to track dependencies
   195  		check.funcDecl(obj, d)
   196  	default:
   197  		unreachable()
   198  	}
   199  }
   200  
   201  // cycle checks if the cycle starting with obj is valid and
   202  // reports an error if it is not.
   203  func (check *Checker) cycle(obj Object) (isCycle bool) {
   204  	// The object map contains the package scope objects and the non-interface methods.
   205  	if debug {
   206  		info := check.objMap[obj]
   207  		inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil) // exclude methods
   208  		isPkgObj := obj.Parent() == check.pkg.scope
   209  		if isPkgObj != inObjMap {
   210  			check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap)
   211  			unreachable()
   212  		}
   213  	}
   214  
   215  	// Count cycle objects.
   216  	assert(obj.color() >= grey)
   217  	start := obj.color() - grey // index of obj in objPath
   218  	cycle := check.objPath[start:]
   219  	nval := 0 // number of (constant or variable) values in the cycle
   220  	ndef := 0 // number of type definitions in the cycle
   221  	for _, obj := range cycle {
   222  		switch obj := obj.(type) {
   223  		case *Const, *Var:
   224  			nval++
   225  		case *TypeName:
   226  			// Determine if the type name is an alias or not. For
   227  			// package-level objects, use the object map which
   228  			// provides syntactic information (which doesn't rely
   229  			// on the order in which the objects are set up). For
   230  			// local objects, we can rely on the order, so use
   231  			// the object's predicate.
   232  			// TODO(gri) It would be less fragile to always access
   233  			// the syntactic information. We should consider storing
   234  			// this information explicitly in the object.
   235  			var alias bool
   236  			if d := check.objMap[obj]; d != nil {
   237  				alias = d.alias // package-level object
   238  			} else {
   239  				alias = obj.IsAlias() // function local object
   240  			}
   241  			if !alias {
   242  				ndef++
   243  			}
   244  		case *Func:
   245  			// ignored for now
   246  		default:
   247  			unreachable()
   248  		}
   249  	}
   250  
   251  	if trace {
   252  		check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle))
   253  		check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef)
   254  		defer func() {
   255  			if isCycle {
   256  				check.trace(obj.Pos(), "=> error: cycle is invalid")
   257  			}
   258  		}()
   259  	}
   260  
   261  	// A cycle involving only constants and variables is invalid but we
   262  	// ignore them here because they are reported via the initialization
   263  	// cycle check.
   264  	if nval == len(cycle) {
   265  		return false
   266  	}
   267  
   268  	// A cycle involving only types (and possibly functions) must have at least
   269  	// one type definition to be permitted: If there is no type definition, we
   270  	// have a sequence of alias type names which will expand ad infinitum.
   271  	if nval == 0 && ndef > 0 {
   272  		return false // cycle is permitted
   273  	}
   274  
   275  	check.cycleError(cycle)
   276  
   277  	return true
   278  }
   279  
   280  type typeInfo uint
   281  
   282  // validType verifies that the given type does not "expand" infinitely
   283  // producing a cycle in the type graph. Cycles are detected by marking
   284  // defined types.
   285  // (Cycles involving alias types, as in "type A = [10]A" are detected
   286  // earlier, via the objDecl cycle detection mechanism.)
   287  func (check *Checker) validType(typ Type, path []Object) typeInfo {
   288  	const (
   289  		unknown typeInfo = iota
   290  		marked
   291  		valid
   292  		invalid
   293  	)
   294  
   295  	switch t := typ.(type) {
   296  	case *Array:
   297  		return check.validType(t.elem, path)
   298  
   299  	case *Struct:
   300  		for _, f := range t.fields {
   301  			if check.validType(f.typ, path) == invalid {
   302  				return invalid
   303  			}
   304  		}
   305  
   306  	case *Interface:
   307  		for _, etyp := range t.embeddeds {
   308  			if check.validType(etyp, path) == invalid {
   309  				return invalid
   310  			}
   311  		}
   312  
   313  	case *Named:
   314  		// don't touch the type if it is from a different package or the Universe scope
   315  		// (doing so would lead to a race condition - was issue #35049)
   316  		if t.obj.pkg != check.pkg {
   317  			return valid
   318  		}
   319  
   320  		// don't report a 2nd error if we already know the type is invalid
   321  		// (e.g., if a cycle was detected earlier, via Checker.underlying).
   322  		if t.underlying == Typ[Invalid] {
   323  			t.info = invalid
   324  			return invalid
   325  		}
   326  
   327  		switch t.info {
   328  		case unknown:
   329  			t.info = marked
   330  			t.info = check.validType(t.orig, append(path, t.obj)) // only types of current package added to path
   331  		case marked:
   332  			// cycle detected
   333  			for i, tn := range path {
   334  				if t.obj.pkg != check.pkg {
   335  					panic("internal error: type cycle via package-external type")
   336  				}
   337  				if tn == t.obj {
   338  					check.cycleError(path[i:])
   339  					t.info = invalid
   340  					t.underlying = Typ[Invalid]
   341  					return t.info
   342  				}
   343  			}
   344  			panic("internal error: cycle start not found")
   345  		}
   346  		return t.info
   347  	}
   348  
   349  	return valid
   350  }
   351  
   352  // cycleError reports a declaration cycle starting with
   353  // the object in cycle that is "first" in the source.
   354  func (check *Checker) cycleError(cycle []Object) {
   355  	// TODO(gri) Should we start with the last (rather than the first) object in the cycle
   356  	//           since that is the earliest point in the source where we start seeing the
   357  	//           cycle? That would be more consistent with other error messages.
   358  	i := firstInSrc(cycle)
   359  	obj := cycle[i]
   360  	check.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name())
   361  	for range cycle {
   362  		check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented
   363  		i++
   364  		if i >= len(cycle) {
   365  			i = 0
   366  		}
   367  		obj = cycle[i]
   368  	}
   369  	check.errorf(obj.Pos(), "\t%s", obj.Name())
   370  }
   371  
   372  // firstInSrc reports the index of the object with the "smallest"
   373  // source position in path. path must not be empty.
   374  func firstInSrc(path []Object) int {
   375  	fst, pos := 0, path[0].Pos()
   376  	for i, t := range path[1:] {
   377  		if t.Pos() < pos {
   378  			fst, pos = i+1, t.Pos()
   379  		}
   380  	}
   381  	return fst
   382  }
   383  
   384  func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
   385  	assert(obj.typ == nil)
   386  
   387  	// use the correct value of iota
   388  	defer func(iota constant.Value) { check.iota = iota }(check.iota)
   389  	check.iota = obj.val
   390  
   391  	// provide valid constant value under all circumstances
   392  	obj.val = constant.MakeUnknown()
   393  
   394  	// determine type, if any
   395  	if typ != nil {
   396  		t := check.typ(typ)
   397  		if !isConstType(t) {
   398  			// don't report an error if the type is an invalid C (defined) type
   399  			// (issue #22090)
   400  			if t.Underlying() != Typ[Invalid] {
   401  				check.errorf(typ.Pos(), "invalid constant type %s", t)
   402  			}
   403  			obj.typ = Typ[Invalid]
   404  			return
   405  		}
   406  		obj.typ = t
   407  	}
   408  
   409  	// check initialization
   410  	var x operand
   411  	if init != nil {
   412  		check.expr(&x, init)
   413  	}
   414  	check.initConst(obj, &x)
   415  }
   416  
   417  func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
   418  	assert(obj.typ == nil)
   419  
   420  	// determine type, if any
   421  	if typ != nil {
   422  		obj.typ = check.typ(typ)
   423  		// We cannot spread the type to all lhs variables if there
   424  		// are more than one since that would mark them as checked
   425  		// (see Checker.objDecl) and the assignment of init exprs,
   426  		// if any, would not be checked.
   427  		//
   428  		// TODO(gri) If we have no init expr, we should distribute
   429  		// a given type otherwise we need to re-evalate the type
   430  		// expr for each lhs variable, leading to duplicate work.
   431  	}
   432  
   433  	// check initialization
   434  	if init == nil {
   435  		if typ == nil {
   436  			// error reported before by arityMatch
   437  			obj.typ = Typ[Invalid]
   438  		}
   439  		return
   440  	}
   441  
   442  	if lhs == nil || len(lhs) == 1 {
   443  		assert(lhs == nil || lhs[0] == obj)
   444  		var x operand
   445  		check.expr(&x, init)
   446  		check.initVar(obj, &x, "variable declaration")
   447  		return
   448  	}
   449  
   450  	if debug {
   451  		// obj must be one of lhs
   452  		found := false
   453  		for _, lhs := range lhs {
   454  			if obj == lhs {
   455  				found = true
   456  				break
   457  			}
   458  		}
   459  		if !found {
   460  			panic("inconsistent lhs")
   461  		}
   462  	}
   463  
   464  	// We have multiple variables on the lhs and one init expr.
   465  	// Make sure all variables have been given the same type if
   466  	// one was specified, otherwise they assume the type of the
   467  	// init expression values (was issue #15755).
   468  	if typ != nil {
   469  		for _, lhs := range lhs {
   470  			lhs.typ = obj.typ
   471  		}
   472  	}
   473  
   474  	check.initVars(lhs, []ast.Expr{init}, token.NoPos)
   475  }
   476  
   477  // underlying returns the underlying type of typ; possibly by following
   478  // forward chains of named types. Such chains only exist while named types
   479  // are incomplete. If an underlying type is found, resolve the chain by
   480  // setting the underlying type for each defined type in the chain before
   481  // returning it.
   482  //
   483  // If no underlying type is found, a cycle error is reported and Typ[Invalid]
   484  // is used as underlying type for each defined type in the chain and returned
   485  // as result.
   486  func (check *Checker) underlying(typ Type) Type {
   487  	// If typ is not a defined type, its underlying type is itself.
   488  	n0, _ := typ.(*Named)
   489  	if n0 == nil {
   490  		return typ // nothing to do
   491  	}
   492  
   493  	// If the underlying type of a defined type is not a defined
   494  	// type, then that is the desired underlying type.
   495  	typ = n0.underlying
   496  	n, _ := typ.(*Named)
   497  	if n == nil {
   498  		return typ // common case
   499  	}
   500  
   501  	// Otherwise, follow the forward chain.
   502  	seen := map[*Named]int{n0: 0}
   503  	path := []Object{n0.obj}
   504  	for {
   505  		typ = n.underlying
   506  		n1, _ := typ.(*Named)
   507  		if n1 == nil {
   508  			break // end of chain
   509  		}
   510  
   511  		seen[n] = len(seen)
   512  		path = append(path, n.obj)
   513  		n = n1
   514  
   515  		if i, ok := seen[n]; ok {
   516  			// cycle
   517  			check.cycleError(path[i:])
   518  			typ = Typ[Invalid]
   519  			break
   520  		}
   521  	}
   522  
   523  	for n := range seen {
   524  		// We should never have to update the underlying type of an imported type;
   525  		// those underlying types should have been resolved during the import.
   526  		// Also, doing so would lead to a race condition (was issue #31749).
   527  		if n.obj.pkg != check.pkg {
   528  			panic("internal error: imported type with unresolved underlying type")
   529  		}
   530  		n.underlying = typ
   531  	}
   532  
   533  	return typ
   534  }
   535  
   536  func (n *Named) setUnderlying(typ Type) {
   537  	if n != nil {
   538  		n.underlying = typ
   539  	}
   540  }
   541  
   542  func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bool) {
   543  	assert(obj.typ == nil)
   544  
   545  	check.later(func() {
   546  		check.validType(obj.typ, nil)
   547  	})
   548  
   549  	if alias {
   550  
   551  		obj.typ = Typ[Invalid]
   552  		obj.typ = check.typ(typ)
   553  
   554  	} else {
   555  
   556  		named := &Named{obj: obj}
   557  		def.setUnderlying(named)
   558  		obj.typ = named // make sure recursive type declarations terminate
   559  
   560  		// determine underlying type of named
   561  		named.orig = check.definedType(typ, named)
   562  
   563  		// The underlying type of named may be itself a named type that is
   564  		// incomplete:
   565  		//
   566  		//	type (
   567  		//		A B
   568  		//		B *C
   569  		//		C A
   570  		//	)
   571  		//
   572  		// The type of C is the (named) type of A which is incomplete,
   573  		// and which has as its underlying type the named type B.
   574  		// Determine the (final, unnamed) underlying type by resolving
   575  		// any forward chain.
   576  		named.underlying = check.underlying(named)
   577  
   578  	}
   579  
   580  	check.addMethodDecls(obj)
   581  }
   582  
   583  func (check *Checker) addMethodDecls(obj *TypeName) {
   584  	// get associated methods
   585  	// (Checker.collectObjects only collects methods with non-blank names;
   586  	// Checker.resolveBaseTypeName ensures that obj is not an alias name
   587  	// if it has attached methods.)
   588  	methods := check.methods[obj]
   589  	if methods == nil {
   590  		return
   591  	}
   592  	delete(check.methods, obj)
   593  	assert(!check.objMap[obj].alias) // don't use TypeName.IsAlias (requires fully set up object)
   594  
   595  	// use an objset to check for name conflicts
   596  	var mset objset
   597  
   598  	// spec: "If the base type is a struct type, the non-blank method
   599  	// and field names must be distinct."
   600  	base, _ := obj.typ.(*Named) // shouldn't fail but be conservative
   601  	if base != nil {
   602  		if t, _ := base.underlying.(*Struct); t != nil {
   603  			for _, fld := range t.fields {
   604  				if fld.name != "_" {
   605  					assert(mset.insert(fld) == nil)
   606  				}
   607  			}
   608  		}
   609  
   610  		// Checker.Files may be called multiple times; additional package files
   611  		// may add methods to already type-checked types. Add pre-existing methods
   612  		// so that we can detect redeclarations.
   613  		for _, m := range base.methods {
   614  			assert(m.name != "_")
   615  			assert(mset.insert(m) == nil)
   616  		}
   617  	}
   618  
   619  	// add valid methods
   620  	for _, m := range methods {
   621  		// spec: "For a base type, the non-blank names of methods bound
   622  		// to it must be unique."
   623  		assert(m.name != "_")
   624  		if alt := mset.insert(m); alt != nil {
   625  			switch alt.(type) {
   626  			case *Var:
   627  				check.errorf(m.pos, "field and method with the same name %s", m.name)
   628  			case *Func:
   629  				check.errorf(m.pos, "method %s already declared for %s", m.name, obj)
   630  			default:
   631  				unreachable()
   632  			}
   633  			check.reportAltDecl(alt)
   634  			continue
   635  		}
   636  
   637  		if base != nil {
   638  			base.methods = append(base.methods, m)
   639  		}
   640  	}
   641  }
   642  
   643  func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
   644  	assert(obj.typ == nil)
   645  
   646  	// func declarations cannot use iota
   647  	assert(check.iota == nil)
   648  
   649  	sig := new(Signature)
   650  	obj.typ = sig // guard against cycles
   651  	fdecl := decl.fdecl
   652  	check.funcType(sig, fdecl.Recv, fdecl.Type)
   653  	if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) {
   654  		check.errorf(fdecl.Pos(), "func init must have no arguments and no return values")
   655  		// ok to continue
   656  	}
   657  
   658  	// function body must be type-checked after global declarations
   659  	// (functions implemented elsewhere have no body)
   660  	if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
   661  		check.later(func() {
   662  			check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
   663  		})
   664  	}
   665  }
   666  
   667  func (check *Checker) declStmt(decl ast.Decl) {
   668  	pkg := check.pkg
   669  
   670  	switch d := decl.(type) {
   671  	case *ast.BadDecl:
   672  		// ignore
   673  
   674  	case *ast.GenDecl:
   675  		var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
   676  		for iota, spec := range d.Specs {
   677  			switch s := spec.(type) {
   678  			case *ast.ValueSpec:
   679  				switch d.Tok {
   680  				case token.CONST:
   681  					top := len(check.delayed)
   682  
   683  					// determine which init exprs to use
   684  					switch {
   685  					case s.Type != nil || len(s.Values) > 0:
   686  						last = s
   687  					case last == nil:
   688  						last = new(ast.ValueSpec) // make sure last exists
   689  					}
   690  
   691  					// declare all constants
   692  					lhs := make([]*Const, len(s.Names))
   693  					for i, name := range s.Names {
   694  						obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota)))
   695  						lhs[i] = obj
   696  
   697  						var init ast.Expr
   698  						if i < len(last.Values) {
   699  							init = last.Values[i]
   700  						}
   701  
   702  						check.constDecl(obj, last.Type, init)
   703  					}
   704  
   705  					check.arityMatch(s, last)
   706  
   707  					// process function literals in init expressions before scope changes
   708  					check.processDelayed(top)
   709  
   710  					// spec: "The scope of a constant or variable identifier declared
   711  					// inside a function begins at the end of the ConstSpec or VarSpec
   712  					// (ShortVarDecl for short variable declarations) and ends at the
   713  					// end of the innermost containing block."
   714  					scopePos := s.End()
   715  					for i, name := range s.Names {
   716  						check.declare(check.scope, name, lhs[i], scopePos)
   717  					}
   718  
   719  				case token.VAR:
   720  					top := len(check.delayed)
   721  
   722  					lhs0 := make([]*Var, len(s.Names))
   723  					for i, name := range s.Names {
   724  						lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
   725  					}
   726  
   727  					// initialize all variables
   728  					for i, obj := range lhs0 {
   729  						var lhs []*Var
   730  						var init ast.Expr
   731  						switch len(s.Values) {
   732  						case len(s.Names):
   733  							// lhs and rhs match
   734  							init = s.Values[i]
   735  						case 1:
   736  							// rhs is expected to be a multi-valued expression
   737  							lhs = lhs0
   738  							init = s.Values[0]
   739  						default:
   740  							if i < len(s.Values) {
   741  								init = s.Values[i]
   742  							}
   743  						}
   744  						check.varDecl(obj, lhs, s.Type, init)
   745  						if len(s.Values) == 1 {
   746  							// If we have a single lhs variable we are done either way.
   747  							// If we have a single rhs expression, it must be a multi-
   748  							// valued expression, in which case handling the first lhs
   749  							// variable will cause all lhs variables to have a type
   750  							// assigned, and we are done as well.
   751  							if debug {
   752  								for _, obj := range lhs0 {
   753  									assert(obj.typ != nil)
   754  								}
   755  							}
   756  							break
   757  						}
   758  					}
   759  
   760  					check.arityMatch(s, nil)
   761  
   762  					// process function literals in init expressions before scope changes
   763  					check.processDelayed(top)
   764  
   765  					// declare all variables
   766  					// (only at this point are the variable scopes (parents) set)
   767  					scopePos := s.End() // see constant declarations
   768  					for i, name := range s.Names {
   769  						// see constant declarations
   770  						check.declare(check.scope, name, lhs0[i], scopePos)
   771  					}
   772  
   773  				default:
   774  					check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
   775  				}
   776  
   777  			case *ast.TypeSpec:
   778  				obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
   779  				// spec: "The scope of a type identifier declared inside a function
   780  				// begins at the identifier in the TypeSpec and ends at the end of
   781  				// the innermost containing block."
   782  				scopePos := s.Name.Pos()
   783  				check.declare(check.scope, s.Name, obj, scopePos)
   784  				// mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl)
   785  				obj.setColor(grey + color(check.push(obj)))
   786  				check.typeDecl(obj, s.Type, nil, s.Assign.IsValid())
   787  				check.pop().setColor(black)
   788  			default:
   789  				check.invalidAST(s.Pos(), "const, type, or var declaration expected")
   790  			}
   791  		}
   792  
   793  	default:
   794  		check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
   795  	}
   796  }
   797  

View as plain text