...

Source file src/go/types/decl.go

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

View as plain text