...
Run Format

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  // TODO(gri) remove once we don't need the old cycle detection (explicitly passed
    42  //           []*TypeName path) anymore
    43  func pathString(path []*TypeName) string {
    44  	var s string
    45  	for i, p := range path {
    46  		if i > 0 {
    47  			s += "->"
    48  		}
    49  		s += p.Name()
    50  	}
    51  	return s
    52  }
    53  
    54  // objPathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g].
    55  // TODO(gri) s/objPathString/pathString/ once we got rid of pathString above
    56  func objPathString(path []Object) string {
    57  	var s string
    58  	for i, p := range path {
    59  		if i > 0 {
    60  			s += "->"
    61  		}
    62  		s += p.Name()
    63  	}
    64  	return s
    65  }
    66  
    67  // useCycleMarking enables the new coloring-based cycle marking scheme
    68  // for package-level objects. Set this flag to false to disable this
    69  // code quickly and revert to the existing mechanism (and comment out
    70  // some of the new tests in cycles5.src that will fail again).
    71  // TODO(gri) remove this for Go 1.12
    72  const useCycleMarking = true
    73  
    74  // objDecl type-checks the declaration of obj in its respective (file) context.
    75  // See check.typ for the details on def and path.
    76  func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
    77  	if trace {
    78  		check.trace(obj.Pos(), "-- checking %s %s (path = %s, objPath = %s)", obj.color(), obj, pathString(path), check.pathString())
    79  		check.indent++
    80  		defer func() {
    81  			check.indent--
    82  			check.trace(obj.Pos(), "=> %s", obj)
    83  		}()
    84  	}
    85  
    86  	// Checking the declaration of obj means inferring its type
    87  	// (and possibly its value, for constants).
    88  	// An object's type (and thus the object) may be in one of
    89  	// three states which are expressed by colors:
    90  	//
    91  	// - an object whose type is not yet known is painted white (initial color)
    92  	// - an object whose type is in the process of being inferred is painted grey
    93  	// - an object whose type is fully inferred is painted black
    94  	//
    95  	// During type inference, an object's color changes from white to grey
    96  	// to black (pre-declared objects are painted black from the start).
    97  	// A black object (i.e., its type) can only depend on (refer to) other black
    98  	// ones. White and grey objects may depend on white and black objects.
    99  	// A dependency on a grey object indicates a cycle which may or may not be
   100  	// valid.
   101  	//
   102  	// When objects turn grey, they are pushed on the object path (a stack);
   103  	// they are popped again when they turn black. Thus, if a grey object (a
   104  	// cycle) is encountered, it is on the object path, and all the objects
   105  	// it depends on are the remaining objects on that path. Color encoding
   106  	// is such that the color value of a grey object indicates the index of
   107  	// that object in the object path.
   108  
   109  	// During type-checking, white objects may be assigned a type without
   110  	// traversing through objDecl; e.g., when initializing constants and
   111  	// variables. Update the colors of those objects here (rather than
   112  	// everywhere where we set the type) to satisfy the color invariants.
   113  	if obj.color() == white && obj.Type() != nil {
   114  		obj.setColor(black)
   115  		return
   116  	}
   117  
   118  	switch obj.color() {
   119  	case white:
   120  		assert(obj.Type() == nil)
   121  		// All color values other than white and black are considered grey.
   122  		// Because black and white are < grey, all values >= grey are grey.
   123  		// Use those values to encode the object's index into the object path.
   124  		obj.setColor(grey + color(check.push(obj)))
   125  		defer func() {
   126  			check.pop().setColor(black)
   127  		}()
   128  
   129  	case black:
   130  		assert(obj.Type() != nil)
   131  		return
   132  
   133  	default:
   134  		// Color values other than white or black are considered grey.
   135  		fallthrough
   136  
   137  	case grey:
   138  		// We have a cycle.
   139  		// In the existing code, this is marked by a non-nil type
   140  		// for the object except for constants and variables whose
   141  		// type may be non-nil (known), or nil if it depends on the
   142  		// not-yet known initialization value.
   143  		// In the former case, set the type to Typ[Invalid] because
   144  		// we have an initialization cycle. The cycle error will be
   145  		// reported later, when determining initialization order.
   146  		// TODO(gri) Report cycle here and simplify initialization
   147  		// order code.
   148  		switch obj := obj.(type) {
   149  		case *Const:
   150  			if useCycleMarking && check.typeCycle(obj) {
   151  				obj.typ = Typ[Invalid]
   152  				break
   153  			}
   154  			if obj.typ == nil {
   155  				obj.typ = Typ[Invalid]
   156  			}
   157  
   158  		case *Var:
   159  			if useCycleMarking && check.typeCycle(obj) {
   160  				obj.typ = Typ[Invalid]
   161  				break
   162  			}
   163  			if obj.typ == nil {
   164  				obj.typ = Typ[Invalid]
   165  			}
   166  
   167  		case *TypeName:
   168  			// fixFor26390 enables a temporary work-around to handle alias type names
   169  			// that have not been given a type yet even though the underlying type
   170  			// is already known. See testdata/issue26390.src for a simple example.
   171  			// Set this flag to false to disable this code quickly (and comment
   172  			// out the new test in decls4.src that will fail again).
   173  			// TODO(gri) remove this for Go 1.12 in favor of a more comprehensive fix
   174  			const fixFor26390 = true
   175  			if fixFor26390 {
   176  				// If we have a package-level alias type name that has not been
   177  				// given a type yet but the underlying type is a type name that
   178  				// has been given a type already, don't report a cycle but use
   179  				// the underlying type name's type instead. The cycle shouldn't
   180  				// exist in the first place in this case and is due to the way
   181  				// methods are type-checked at the moment. See also the comment
   182  				// at the end of Checker.typeDecl below.
   183  				if d := check.objMap[obj]; d != nil && d.alias && obj.typ == Typ[Invalid] {
   184  					// If we can find the underlying type name syntactically
   185  					// and it has a type, use that type.
   186  					if tname := check.resolveBaseTypeName(ast.NewIdent(obj.name)); tname != nil && tname.typ != nil {
   187  						obj.typ = tname.typ
   188  						break
   189  					}
   190  				}
   191  			}
   192  
   193  			if useCycleMarking && check.typeCycle(obj) {
   194  				// break cycle
   195  				// (without this, calling underlying()
   196  				// below may lead to an endless loop
   197  				// if we have a cycle for a defined
   198  				// (*Named) type)
   199  				obj.typ = Typ[Invalid]
   200  			}
   201  
   202  		case *Func:
   203  			if useCycleMarking && check.typeCycle(obj) {
   204  				// Don't set obj.typ to Typ[Invalid] here
   205  				// because plenty of code type-asserts that
   206  				// functions have a *Signature type. Grey
   207  				// functions have their type set to an empty
   208  				// signature which makes it impossible to
   209  				// initialize a variable with the function.
   210  			}
   211  
   212  		default:
   213  			unreachable()
   214  		}
   215  		assert(obj.Type() != nil)
   216  		return
   217  	}
   218  
   219  	d := check.objMap[obj]
   220  	if d == nil {
   221  		check.dump("%v: %s should have been declared", obj.Pos(), obj)
   222  		unreachable()
   223  	}
   224  
   225  	// save/restore current context and setup object context
   226  	defer func(ctxt context) {
   227  		check.context = ctxt
   228  	}(check.context)
   229  	check.context = context{
   230  		scope: d.file,
   231  	}
   232  
   233  	// Const and var declarations must not have initialization
   234  	// cycles. We track them by remembering the current declaration
   235  	// in check.decl. Initialization expressions depending on other
   236  	// consts, vars, or functions, add dependencies to the current
   237  	// check.decl.
   238  	switch obj := obj.(type) {
   239  	case *Const:
   240  		check.decl = d // new package-level const decl
   241  		check.constDecl(obj, d.typ, d.init)
   242  	case *Var:
   243  		check.decl = d // new package-level var decl
   244  		check.varDecl(obj, d.lhs, d.typ, d.init)
   245  	case *TypeName:
   246  		// invalid recursive types are detected via path
   247  		check.typeDecl(obj, d.typ, def, path, d.alias)
   248  	case *Func:
   249  		// functions may be recursive - no need to track dependencies
   250  		check.funcDecl(obj, d)
   251  	default:
   252  		unreachable()
   253  	}
   254  }
   255  
   256  // indir is a sentinel type name that is pushed onto the object path
   257  // to indicate an "indirection" in the dependency from one type name
   258  // to the next. For instance, for "type p *p" the object path contains
   259  // p followed by indir, indicating that there's an indirection *p.
   260  // Indirections are used to break type cycles.
   261  var indir = NewTypeName(token.NoPos, nil, "*", nil)
   262  
   263  // cutCycle is a sentinel type name that is pushed onto the object path
   264  // to indicate that a cycle doesn't actually exist. This is currently
   265  // needed to break cycles formed via method declarations because they
   266  // are type-checked together with their receiver base types. Once methods
   267  // are type-checked separately (see also TODO in Checker.typeDecl), we
   268  // can get rid of this.
   269  var cutCycle = NewTypeName(token.NoPos, nil, "!", nil)
   270  
   271  // typeCycle checks if the cycle starting with obj is valid and
   272  // reports an error if it is not.
   273  // TODO(gri) rename s/typeCycle/cycle/ once we don't need the other
   274  // cycle method anymore.
   275  func (check *Checker) typeCycle(obj Object) (isCycle bool) {
   276  	d := check.objMap[obj]
   277  	if d == nil {
   278  		check.dump("%v: %s should have been declared", obj.Pos(), obj)
   279  		unreachable()
   280  	}
   281  
   282  	// Given the number of constants and variables (nval) in the cycle
   283  	// and the cycle length (ncycle = number of named objects in the cycle),
   284  	// we distinguish between cycles involving only constants and variables
   285  	// (nval = ncycle), cycles involving types (and functions) only
   286  	// (nval == 0), and mixed cycles (nval != 0 && nval != ncycle).
   287  	// We ignore functions at the moment (taking them into account correctly
   288  	// is complicated and it doesn't improve error reporting significantly).
   289  	//
   290  	// A cycle must have at least one indirection and one type definition
   291  	// to be permitted: If there is no indirection, the size of the type
   292  	// cannot be computed (it's either infinite or 0); if there is no type
   293  	// definition, we have a sequence of alias type names which will expand
   294  	// ad infinitum.
   295  	var nval, ncycle int
   296  	var hasIndir, hasTDef bool
   297  	assert(obj.color() >= grey)
   298  	start := obj.color() - grey // index of obj in objPath
   299  	cycle := check.objPath[start:]
   300  	ncycle = len(cycle) // including indirections
   301  	for _, obj := range cycle {
   302  		switch obj := obj.(type) {
   303  		case *Const, *Var:
   304  			nval++
   305  		case *TypeName:
   306  			switch {
   307  			case obj == indir:
   308  				ncycle-- // don't count (indirections are not objects)
   309  				hasIndir = true
   310  			case obj == cutCycle:
   311  				// The cycle is not real and only caused by the fact
   312  				// that we type-check methods when we type-check their
   313  				// receiver base types.
   314  				return false
   315  			case !check.objMap[obj].alias:
   316  				hasTDef = true
   317  			}
   318  		case *Func:
   319  			// ignored for now
   320  		default:
   321  			unreachable()
   322  		}
   323  	}
   324  
   325  	if trace {
   326  		check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", objPathString(cycle), obj.Name(), ncycle)
   327  		check.trace(obj.Pos(), "## cycle contains: %d values, has indirection = %v, has type definition = %v", nval, hasIndir, hasTDef)
   328  		defer func() {
   329  			if isCycle {
   330  				check.trace(obj.Pos(), "=> error: cycle is invalid")
   331  			}
   332  		}()
   333  	}
   334  
   335  	// A cycle involving only constants and variables is invalid but we
   336  	// ignore them here because they are reported via the initialization
   337  	// cycle check.
   338  	if nval == ncycle {
   339  		return false
   340  	}
   341  
   342  	// A cycle involving only types (and possibly functions) must have at
   343  	// least one indirection and one type definition to be permitted: If
   344  	// there is no indirection, the size of the type cannot be computed
   345  	// (it's either infinite or 0); if there is no type definition, we
   346  	// have a sequence of alias type names which will expand ad infinitum.
   347  	if nval == 0 && hasIndir && hasTDef {
   348  		return false // cycle is permitted
   349  	}
   350  
   351  	// report cycle
   352  	check.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name())
   353  	for _, obj := range cycle {
   354  		if obj == indir {
   355  			continue // don't print indir sentinels
   356  		}
   357  		check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented
   358  	}
   359  	check.errorf(obj.Pos(), "\t%s", obj.Name())
   360  
   361  	return true
   362  }
   363  
   364  func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
   365  	assert(obj.typ == nil)
   366  
   367  	// use the correct value of iota
   368  	check.iota = obj.val
   369  	defer func() { check.iota = nil }()
   370  
   371  	// provide valid constant value under all circumstances
   372  	obj.val = constant.MakeUnknown()
   373  
   374  	// determine type, if any
   375  	if typ != nil {
   376  		t := check.typExpr(typ, nil, nil)
   377  		if !isConstType(t) {
   378  			// don't report an error if the type is an invalid C (defined) type
   379  			// (issue #22090)
   380  			if t.Underlying() != Typ[Invalid] {
   381  				check.errorf(typ.Pos(), "invalid constant type %s", t)
   382  			}
   383  			obj.typ = Typ[Invalid]
   384  			return
   385  		}
   386  		obj.typ = t
   387  	}
   388  
   389  	// check initialization
   390  	var x operand
   391  	if init != nil {
   392  		check.expr(&x, init)
   393  	}
   394  	check.initConst(obj, &x)
   395  }
   396  
   397  func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
   398  	assert(obj.typ == nil)
   399  
   400  	// determine type, if any
   401  	if typ != nil {
   402  		obj.typ = check.typExpr(typ, nil, nil)
   403  		// We cannot spread the type to all lhs variables if there
   404  		// are more than one since that would mark them as checked
   405  		// (see Checker.objDecl) and the assignment of init exprs,
   406  		// if any, would not be checked.
   407  		//
   408  		// TODO(gri) If we have no init expr, we should distribute
   409  		// a given type otherwise we need to re-evalate the type
   410  		// expr for each lhs variable, leading to duplicate work.
   411  	}
   412  
   413  	// check initialization
   414  	if init == nil {
   415  		if typ == nil {
   416  			// error reported before by arityMatch
   417  			obj.typ = Typ[Invalid]
   418  		}
   419  		return
   420  	}
   421  
   422  	if lhs == nil || len(lhs) == 1 {
   423  		assert(lhs == nil || lhs[0] == obj)
   424  		var x operand
   425  		check.expr(&x, init)
   426  		check.initVar(obj, &x, "variable declaration")
   427  		return
   428  	}
   429  
   430  	if debug {
   431  		// obj must be one of lhs
   432  		found := false
   433  		for _, lhs := range lhs {
   434  			if obj == lhs {
   435  				found = true
   436  				break
   437  			}
   438  		}
   439  		if !found {
   440  			panic("inconsistent lhs")
   441  		}
   442  	}
   443  
   444  	// We have multiple variables on the lhs and one init expr.
   445  	// Make sure all variables have been given the same type if
   446  	// one was specified, otherwise they assume the type of the
   447  	// init expression values (was issue #15755).
   448  	if typ != nil {
   449  		for _, lhs := range lhs {
   450  			lhs.typ = obj.typ
   451  		}
   452  	}
   453  
   454  	check.initVars(lhs, []ast.Expr{init}, token.NoPos)
   455  }
   456  
   457  // underlying returns the underlying type of typ; possibly by following
   458  // forward chains of named types. Such chains only exist while named types
   459  // are incomplete.
   460  func underlying(typ Type) Type {
   461  	for {
   462  		n, _ := typ.(*Named)
   463  		if n == nil {
   464  			break
   465  		}
   466  		typ = n.underlying
   467  	}
   468  	return typ
   469  }
   470  
   471  func (n *Named) setUnderlying(typ Type) {
   472  	if n != nil {
   473  		n.underlying = typ
   474  	}
   475  }
   476  
   477  func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName, alias bool) {
   478  	assert(obj.typ == nil)
   479  
   480  	if alias {
   481  
   482  		obj.typ = Typ[Invalid]
   483  		obj.typ = check.typExpr(typ, nil, append(path, obj))
   484  
   485  	} else {
   486  
   487  		named := &Named{obj: obj}
   488  		def.setUnderlying(named)
   489  		obj.typ = named // make sure recursive type declarations terminate
   490  
   491  		// determine underlying type of named
   492  		check.typExpr(typ, named, append(path, obj))
   493  
   494  		// The underlying type of named may be itself a named type that is
   495  		// incomplete:
   496  		//
   497  		//	type (
   498  		//		A B
   499  		//		B *C
   500  		//		C A
   501  		//	)
   502  		//
   503  		// The type of C is the (named) type of A which is incomplete,
   504  		// and which has as its underlying type the named type B.
   505  		// Determine the (final, unnamed) underlying type by resolving
   506  		// any forward chain (they always end in an unnamed type).
   507  		named.underlying = underlying(named.underlying)
   508  
   509  	}
   510  
   511  	// check and add associated methods
   512  	// TODO(gri) It's easy to create pathological cases where the
   513  	// current approach is incorrect: In general we need to know
   514  	// and add all methods _before_ type-checking the type.
   515  	// See https://play.golang.org/p/WMpE0q2wK8
   516  	check.addMethodDecls(obj)
   517  }
   518  
   519  func (check *Checker) addMethodDecls(obj *TypeName) {
   520  	// get associated methods
   521  	// (Checker.collectObjects only collects methods with non-blank names;
   522  	// Checker.resolveBaseTypeName ensures that obj is not an alias name
   523  	// if it has attached methods.)
   524  	methods := check.methods[obj]
   525  	if methods == nil {
   526  		return
   527  	}
   528  	delete(check.methods, obj)
   529  	assert(!check.objMap[obj].alias) // don't use TypeName.IsAlias (requires fully set up object)
   530  
   531  	// use an objset to check for name conflicts
   532  	var mset objset
   533  
   534  	// spec: "If the base type is a struct type, the non-blank method
   535  	// and field names must be distinct."
   536  	base, _ := obj.typ.(*Named) // shouldn't fail but be conservative
   537  	if base != nil {
   538  		if t, _ := base.underlying.(*Struct); t != nil {
   539  			for _, fld := range t.fields {
   540  				if fld.name != "_" {
   541  					assert(mset.insert(fld) == nil)
   542  				}
   543  			}
   544  		}
   545  
   546  		// Checker.Files may be called multiple times; additional package files
   547  		// may add methods to already type-checked types. Add pre-existing methods
   548  		// so that we can detect redeclarations.
   549  		for _, m := range base.methods {
   550  			assert(m.name != "_")
   551  			assert(mset.insert(m) == nil)
   552  		}
   553  	}
   554  
   555  	if useCycleMarking {
   556  		// Suppress detection of type cycles occurring through method
   557  		// declarations - they wouldn't exist if methods were type-
   558  		// checked separately from their receiver base types. See also
   559  		// comment at the end of Checker.typeDecl.
   560  		// TODO(gri) Remove this once methods are type-checked separately.
   561  		check.push(cutCycle)
   562  		defer check.pop()
   563  	}
   564  
   565  	// type-check methods
   566  	for _, m := range methods {
   567  		// spec: "For a base type, the non-blank names of methods bound
   568  		// to it must be unique."
   569  		assert(m.name != "_")
   570  		if alt := mset.insert(m); alt != nil {
   571  			switch alt.(type) {
   572  			case *Var:
   573  				check.errorf(m.pos, "field and method with the same name %s", m.name)
   574  			case *Func:
   575  				check.errorf(m.pos, "method %s already declared for %s", m.name, obj)
   576  			default:
   577  				unreachable()
   578  			}
   579  			check.reportAltDecl(alt)
   580  			continue
   581  		}
   582  
   583  		// type-check
   584  		check.objDecl(m, nil, nil)
   585  
   586  		if base != nil {
   587  			base.methods = append(base.methods, m)
   588  		}
   589  	}
   590  }
   591  
   592  func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
   593  	assert(obj.typ == nil)
   594  
   595  	// func declarations cannot use iota
   596  	assert(check.iota == nil)
   597  
   598  	sig := new(Signature)
   599  	obj.typ = sig // guard against cycles
   600  	fdecl := decl.fdecl
   601  	check.funcType(sig, fdecl.Recv, fdecl.Type)
   602  	if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) {
   603  		check.errorf(fdecl.Pos(), "func init must have no arguments and no return values")
   604  		// ok to continue
   605  	}
   606  
   607  	// function body must be type-checked after global declarations
   608  	// (functions implemented elsewhere have no body)
   609  	if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
   610  		check.later(func() {
   611  			check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
   612  		})
   613  	}
   614  }
   615  
   616  func (check *Checker) declStmt(decl ast.Decl) {
   617  	pkg := check.pkg
   618  
   619  	switch d := decl.(type) {
   620  	case *ast.BadDecl:
   621  		// ignore
   622  
   623  	case *ast.GenDecl:
   624  		var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
   625  		for iota, spec := range d.Specs {
   626  			switch s := spec.(type) {
   627  			case *ast.ValueSpec:
   628  				switch d.Tok {
   629  				case token.CONST:
   630  					top := len(check.delayed)
   631  
   632  					// determine which init exprs to use
   633  					switch {
   634  					case s.Type != nil || len(s.Values) > 0:
   635  						last = s
   636  					case last == nil:
   637  						last = new(ast.ValueSpec) // make sure last exists
   638  					}
   639  
   640  					// declare all constants
   641  					lhs := make([]*Const, len(s.Names))
   642  					for i, name := range s.Names {
   643  						obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota)))
   644  						lhs[i] = obj
   645  
   646  						var init ast.Expr
   647  						if i < len(last.Values) {
   648  							init = last.Values[i]
   649  						}
   650  
   651  						check.constDecl(obj, last.Type, init)
   652  					}
   653  
   654  					check.arityMatch(s, last)
   655  
   656  					// process function literals in init expressions before scope changes
   657  					check.processDelayed(top)
   658  
   659  					// spec: "The scope of a constant or variable identifier declared
   660  					// inside a function begins at the end of the ConstSpec or VarSpec
   661  					// (ShortVarDecl for short variable declarations) and ends at the
   662  					// end of the innermost containing block."
   663  					scopePos := s.End()
   664  					for i, name := range s.Names {
   665  						check.declare(check.scope, name, lhs[i], scopePos)
   666  					}
   667  
   668  				case token.VAR:
   669  					top := len(check.delayed)
   670  
   671  					lhs0 := make([]*Var, len(s.Names))
   672  					for i, name := range s.Names {
   673  						lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
   674  					}
   675  
   676  					// initialize all variables
   677  					for i, obj := range lhs0 {
   678  						var lhs []*Var
   679  						var init ast.Expr
   680  						switch len(s.Values) {
   681  						case len(s.Names):
   682  							// lhs and rhs match
   683  							init = s.Values[i]
   684  						case 1:
   685  							// rhs is expected to be a multi-valued expression
   686  							lhs = lhs0
   687  							init = s.Values[0]
   688  						default:
   689  							if i < len(s.Values) {
   690  								init = s.Values[i]
   691  							}
   692  						}
   693  						check.varDecl(obj, lhs, s.Type, init)
   694  						if len(s.Values) == 1 {
   695  							// If we have a single lhs variable we are done either way.
   696  							// If we have a single rhs expression, it must be a multi-
   697  							// valued expression, in which case handling the first lhs
   698  							// variable will cause all lhs variables to have a type
   699  							// assigned, and we are done as well.
   700  							if debug {
   701  								for _, obj := range lhs0 {
   702  									assert(obj.typ != nil)
   703  								}
   704  							}
   705  							break
   706  						}
   707  					}
   708  
   709  					check.arityMatch(s, nil)
   710  
   711  					// process function literals in init expressions before scope changes
   712  					check.processDelayed(top)
   713  
   714  					// declare all variables
   715  					// (only at this point are the variable scopes (parents) set)
   716  					scopePos := s.End() // see constant declarations
   717  					for i, name := range s.Names {
   718  						// see constant declarations
   719  						check.declare(check.scope, name, lhs0[i], scopePos)
   720  					}
   721  
   722  				default:
   723  					check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
   724  				}
   725  
   726  			case *ast.TypeSpec:
   727  				obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
   728  				// spec: "The scope of a type identifier declared inside a function
   729  				// begins at the identifier in the TypeSpec and ends at the end of
   730  				// the innermost containing block."
   731  				scopePos := s.Name.Pos()
   732  				check.declare(check.scope, s.Name, obj, scopePos)
   733  				check.typeDecl(obj, s.Type, nil, nil, s.Assign.IsValid())
   734  
   735  			default:
   736  				check.invalidAST(s.Pos(), "const, type, or var declaration expected")
   737  			}
   738  		}
   739  
   740  	default:
   741  		check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
   742  	}
   743  }
   744  

View as plain text