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.
14 func (check
*Checker
) reportAltDecl(obj Object
) {
15 if pos
:= obj
.Pos(); pos
.IsValid() {
16 // We use "other" rather than "previous" here because
17 // the first declaration seen may not be textually
18 // earlier in the source.
19 check
.errorf(obj
, _DuplicateDecl
, "\tother declaration of %s", obj
.Name()) // secondary error, \t indented
23 func (check
*Checker
) declare(scope
*Scope
, id
*ast
.Ident
, obj Object
, pos token
.Pos
) {
24 // spec: "The blank identifier, represented by the underscore
25 // character _, may be used in a declaration like any other
26 // identifier but the declaration does not introduce a new
28 if obj
.Name() != "_" {
29 if alt
:= scope
.Insert(obj
); alt
!= nil {
30 check
.errorf(obj
, _DuplicateDecl
, "%s redeclared in this block", obj
.Name())
31 check
.reportAltDecl(alt
)
37 check
.recordDef(id
, obj
)
41 // pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g].
42 func pathString(path
[]Object
) string {
44 for i
, p
:= range path
{
53 // objDecl type-checks the declaration of obj in its respective (file) environment.
54 // For the meaning of def, see Checker.definedType, in typexpr.go.
55 func (check
*Checker
) objDecl(obj Object
, def
*Named
) {
56 if trace
&& obj
.Type() == nil {
57 if check
.indent
== 0 {
58 fmt
.Println() // empty line between top-level objects for readability
60 check
.trace(obj
.Pos(), "-- checking %s (%s, objPath = %s)", obj
, obj
.color(), pathString(check
.objPath
))
64 check
.trace(obj
.Pos(), "=> %s (%s)", obj
, obj
.color())
68 // Checking the declaration of obj means inferring its type
69 // (and possibly its value, for constants).
70 // An object's type (and thus the object) may be in one of
71 // three states which are expressed by colors:
73 // - an object whose type is not yet known is painted white (initial color)
74 // - an object whose type is in the process of being inferred is painted grey
75 // - an object whose type is fully inferred is painted black
77 // During type inference, an object's color changes from white to grey
78 // to black (pre-declared objects are painted black from the start).
79 // A black object (i.e., its type) can only depend on (refer to) other black
80 // ones. White and grey objects may depend on white and black objects.
81 // A dependency on a grey object indicates a cycle which may or may not be
84 // When objects turn grey, they are pushed on the object path (a stack);
85 // they are popped again when they turn black. Thus, if a grey object (a
86 // cycle) is encountered, it is on the object path, and all the objects
87 // it depends on are the remaining objects on that path. Color encoding
88 // is such that the color value of a grey object indicates the index of
89 // that object in the object path.
91 // During type-checking, white objects may be assigned a type without
92 // traversing through objDecl; e.g., when initializing constants and
93 // variables. Update the colors of those objects here (rather than
94 // everywhere where we set the type) to satisfy the color invariants.
95 if obj
.color() == white
&& obj
.Type() != nil {
102 assert(obj
.Type() == nil)
103 // All color values other than white and black are considered grey.
104 // Because black and white are < grey, all values >= grey are grey.
105 // Use those values to encode the object's index into the object path.
106 obj
.setColor(grey
+ color(check
.push(obj
)))
108 check
.pop().setColor(black
)
112 assert(obj
.Type() != nil)
116 // Color values other than white or black are considered grey.
120 // We have a (possibly invalid) cycle.
121 // In the existing code, this is marked by a non-nil type
122 // for the object except for constants and variables whose
123 // type may be non-nil (known), or nil if it depends on the
124 // not-yet known initialization value.
125 // In the former case, set the type to Typ[Invalid] because
126 // we have an initialization cycle. The cycle error will be
127 // reported later, when determining initialization order.
128 // TODO(gri) Report cycle here and simplify initialization
130 switch obj
:= obj
.(type) {
132 if !check
.validCycle(obj
) || obj
.typ
== nil {
133 obj
.typ
= Typ
[Invalid
]
137 if !check
.validCycle(obj
) || obj
.typ
== nil {
138 obj
.typ
= Typ
[Invalid
]
142 if !check
.validCycle(obj
) {
144 // (without this, calling underlying()
145 // below may lead to an endless loop
146 // if we have a cycle for a defined
148 obj
.typ
= Typ
[Invalid
]
152 if !check
.validCycle(obj
) {
153 // Don't set obj.typ to Typ[Invalid] here
154 // because plenty of code type-asserts that
155 // functions have a *Signature type. Grey
156 // functions have their type set to an empty
157 // signature which makes it impossible to
158 // initialize a variable with the function.
164 assert(obj
.Type() != nil)
168 d
:= check
.objMap
[obj
]
170 check
.dump("%v: %s should have been declared", obj
.Pos(), obj
)
174 // save/restore current environment and set up object environment
175 defer func(env environment
) {
176 check
.environment
= env
178 check
.environment
= environment
{
182 // Const and var declarations must not have initialization
183 // cycles. We track them by remembering the current declaration
184 // in check.decl. Initialization expressions depending on other
185 // consts, vars, or functions, add dependencies to the current
187 switch obj
:= obj
.(type) {
189 check
.decl
= d
// new package-level const decl
190 check
.constDecl(obj
, d
.vtyp
, d
.init
, d
.inherited
)
192 check
.decl
= d
// new package-level var decl
193 check
.varDecl(obj
, d
.lhs
, d
.vtyp
, d
.init
)
195 // invalid recursive types are detected via path
196 check
.typeDecl(obj
, d
.tdecl
, def
)
197 check
.collectMethods(obj
) // methods can only be added to top-level types
199 // functions may be recursive - no need to track dependencies
200 check
.funcDecl(obj
, d
)
206 // validCycle checks if the cycle starting with obj is valid and
207 // reports an error if it is not.
208 func (check
*Checker
) validCycle(obj Object
) (valid
bool) {
209 // The object map contains the package scope objects and the non-interface methods.
211 info
:= check
.objMap
[obj
]
212 inObjMap
:= info
!= nil && (info
.fdecl
== nil || info
.fdecl
.Recv
== nil) // exclude methods
213 isPkgObj
:= obj
.Parent() == check
.pkg
.scope
214 if isPkgObj
!= inObjMap
{
215 check
.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj
.Pos(), obj
, isPkgObj
, inObjMap
)
220 // Count cycle objects.
221 assert(obj
.color() >= grey
)
222 start
:= obj
.color() - grey
// index of obj in objPath
223 cycle
:= check
.objPath
[start
:]
224 tparCycle
:= false // if set, the cycle is through a type parameter list
225 nval
:= 0 // number of (constant or variable) values in the cycle; valid if !generic
226 ndef
:= 0 // number of type definitions in the cycle; valid if !generic
228 for _
, obj
:= range cycle
{
229 switch obj
:= obj
.(type) {
233 // If we reach a generic type that is part of a cycle
234 // and we are in a type parameter list, we have a cycle
235 // through a type parameter list, which is invalid.
236 if check
.inTParamList
&& isGeneric(obj
.typ
) {
241 // Determine if the type name is an alias or not. For
242 // package-level objects, use the object map which
243 // provides syntactic information (which doesn't rely
244 // on the order in which the objects are set up). For
245 // local objects, we can rely on the order, so use
246 // the object's predicate.
247 // TODO(gri) It would be less fragile to always access
248 // the syntactic information. We should consider storing
249 // this information explicitly in the object.
251 if d
:= check
.objMap
[obj
]; d
!= nil {
252 alias
= d
.tdecl
.Assign
.IsValid() // package-level object
254 alias
= obj
.IsAlias() // function local object
267 check
.trace(obj
.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle
), obj
.Name(), len(cycle
))
269 check
.trace(obj
.Pos(), "## cycle contains: generic type in a type parameter list")
271 check
.trace(obj
.Pos(), "## cycle contains: %d values, %d type definitions", nval
, ndef
)
275 check
.trace(obj
.Pos(), "=> cycle is valid")
277 check
.trace(obj
.Pos(), "=> error: cycle is invalid")
283 // A cycle involving only constants and variables is invalid but we
284 // ignore them here because they are reported via the initialization
286 if nval
== len(cycle
) {
290 // A cycle involving only types (and possibly functions) must have at least
291 // one type definition to be permitted: If there is no type definition, we
292 // have a sequence of alias type names which will expand ad infinitum.
293 if nval
== 0 && ndef
> 0 {
298 check
.cycleError(cycle
)
302 // cycleError reports a declaration cycle starting with
303 // the object in cycle that is "first" in the source.
304 func (check
*Checker
) cycleError(cycle
[]Object
) {
305 // TODO(gri) Should we start with the last (rather than the first) object in the cycle
306 // since that is the earliest point in the source where we start seeing the
307 // cycle? That would be more consistent with other error messages.
308 i
:= firstInSrc(cycle
)
310 // If obj is a type alias, mark it as valid (not broken) in order to avoid follow-on errors.
311 tname
, _
:= obj
.(*TypeName
)
312 if tname
!= nil && tname
.IsAlias() {
313 check
.validAlias(tname
, Typ
[Invalid
])
315 if tname
!= nil && compilerErrorMessages
{
316 check
.errorf(obj
, _InvalidDeclCycle
, "invalid recursive type %s", obj
.Name())
318 check
.errorf(obj
, _InvalidDeclCycle
, "illegal cycle in declaration of %s", obj
.Name())
321 check
.errorf(obj
, _InvalidDeclCycle
, "\t%s refers to", obj
.Name()) // secondary error, \t indented
328 check
.errorf(obj
, _InvalidDeclCycle
, "\t%s", obj
.Name())
331 // firstInSrc reports the index of the object with the "smallest"
332 // source position in path. path must not be empty.
333 func firstInSrc(path
[]Object
) int {
334 fst
, pos
:= 0, path
[0].Pos()
335 for i
, t
:= range path
[1:] {
337 fst
, pos
= i
+1, t
.Pos()
348 importDecl
struct{ spec
*ast
.ImportSpec
}
356 varDecl
struct{ spec
*ast
.ValueSpec
}
357 typeDecl
struct{ spec
*ast
.TypeSpec
}
358 funcDecl
struct{ decl
*ast
.FuncDecl
}
361 func (d importDecl
) node() ast
.Node
{ return d
.spec
}
362 func (d constDecl
) node() ast
.Node
{ return d
.spec
}
363 func (d varDecl
) node() ast
.Node
{ return d
.spec
}
364 func (d typeDecl
) node() ast
.Node
{ return d
.spec
}
365 func (d funcDecl
) node() ast
.Node
{ return d
.decl
}
367 func (check
*Checker
) walkDecls(decls
[]ast
.Decl
, f
func(decl
)) {
368 for _
, d
:= range decls
{
373 func (check
*Checker
) walkDecl(d ast
.Decl
, f
func(decl
)) {
374 switch d
:= d
.(type) {
378 var last
*ast
.ValueSpec
// last ValueSpec with type or init exprs seen
379 for iota, s
:= range d
.Specs
{
380 switch s
:= s
.(type) {
381 case *ast
.ImportSpec
:
386 // determine which initialization expressions to use
389 case s
.Type
!= nil ||
len(s
.Values
) > 0:
393 last
= new(ast
.ValueSpec
) // make sure last exists
396 check
.arityMatch(s
, last
)
397 f(constDecl
{spec
: s
, iota: iota, typ
: last
.Type
, init
: last
.Values
, inherited
: inherited
})
399 check
.arityMatch(s
, nil)
402 check
.invalidAST(s
, "invalid token %s", d
.Tok
)
407 check
.invalidAST(s
, "unknown ast.Spec node %T", s
)
413 check
.invalidAST(d
, "unknown ast.Decl node %T", d
)
417 func (check
*Checker
) constDecl(obj
*Const
, typ
, init ast
.Expr
, inherited
bool) {
418 assert(obj
.typ
== nil)
420 // use the correct value of iota
421 defer func(iota constant
.Value
, errpos positioner
) {
423 check
.errpos
= errpos
424 }(check
.iota, check
.errpos
)
428 // provide valid constant value under all circumstances
429 obj
.val
= constant
.MakeUnknown()
431 // determine type, if any
435 // don't report an error if the type is an invalid C (defined) type
437 if under(t
) != Typ
[Invalid
] {
438 check
.errorf(typ
, _InvalidConstType
, "invalid constant type %s", t
)
440 obj
.typ
= Typ
[Invalid
]
446 // check initialization
450 // The initialization expression is inherited from a previous
451 // constant declaration, and (error) positions refer to that
452 // expression and not the current constant declaration. Use
453 // the constant identifier position for any errors during
454 // init expression evaluation since that is all we have
455 // (see issues #42991, #42992).
456 check
.errpos
= atPos(obj
.pos
)
460 check
.initConst(obj
, &x
)
463 func (check
*Checker
) varDecl(obj
*Var
, lhs
[]*Var
, typ
, init ast
.Expr
) {
464 assert(obj
.typ
== nil)
466 // determine type, if any
468 obj
.typ
= check
.varType(typ
)
469 // We cannot spread the type to all lhs variables if there
470 // are more than one since that would mark them as checked
471 // (see Checker.objDecl) and the assignment of init exprs,
472 // if any, would not be checked.
474 // TODO(gri) If we have no init expr, we should distribute
475 // a given type otherwise we need to re-evalate the type
476 // expr for each lhs variable, leading to duplicate work.
479 // check initialization
482 // error reported before by arityMatch
483 obj
.typ
= Typ
[Invalid
]
488 if lhs
== nil ||
len(lhs
) == 1 {
489 assert(lhs
== nil || lhs
[0] == obj
)
492 check
.initVar(obj
, &x
, "variable declaration")
497 // obj must be one of lhs
499 for _
, lhs
:= range lhs
{
506 panic("inconsistent lhs")
510 // We have multiple variables on the lhs and one init expr.
511 // Make sure all variables have been given the same type if
512 // one was specified, otherwise they assume the type of the
513 // init expression values (was issue #15755).
515 for _
, lhs
:= range lhs
{
520 check
.initVars(lhs
, []ast
.Expr
{init
}, nil)
523 // isImportedConstraint reports whether typ is an imported type constraint.
524 func (check
*Checker
) isImportedConstraint(typ Type
) bool {
525 named
, _
:= typ
.(*Named
)
526 if named
== nil || named
.obj
.pkg
== check
.pkg || named
.obj
.pkg
== nil {
529 u
, _
:= named
.under().(*Interface
)
530 return u
!= nil && !u
.IsMethodSet()
533 func (check
*Checker
) typeDecl(obj
*TypeName
, tdecl
*ast
.TypeSpec
, def
*Named
) {
534 assert(obj
.typ
== nil)
538 if t
, _
:= obj
.typ
.(*Named
); t
!= nil { // type may be invalid
541 // If typ is local, an error was already reported where typ is specified/defined.
542 if check
.isImportedConstraint(rhs
) && !check
.allowVersion(check
.pkg
, 1, 18) {
543 check
.errorf(tdecl
.Type
, _UnsupportedFeature
, "using type constraint %s requires go1.18 or later", rhs
)
545 }).describef(obj
, "validType(%s)", obj
.Name())
547 alias
:= tdecl
.Assign
.IsValid()
548 if alias
&& tdecl
.TypeParams
.NumFields() != 0 {
549 // The parser will ensure this but we may still get an invalid AST.
550 // Complain and continue as regular type definition.
551 check
.error(atPos(tdecl
.Assign
), _BadDecl
, "generic type cannot be alias")
557 if !check
.allowVersion(check
.pkg
, 1, 9) {
558 check
.errorf(atPos(tdecl
.Assign
), _BadDecl
, "type aliases requires go1.9 or later")
561 check
.brokenAlias(obj
)
562 rhs
= check
.varType(tdecl
.Type
)
563 check
.validAlias(obj
, rhs
)
567 // type definition or generic type declaration
568 named
:= check
.newNamed(obj
, nil, nil, nil, nil)
569 def
.setUnderlying(named
)
571 if tdecl
.TypeParams
!= nil {
572 check
.openScope(tdecl
, "type parameters")
573 defer check
.closeScope()
574 check
.collectTypeParams(&named
.tparams
, tdecl
.TypeParams
)
577 // determine underlying type of named
578 rhs
= check
.definedType(tdecl
.Type
, named
)
582 // If the underlying was not set while type-checking the right-hand side, it
583 // is invalid and an error should have been reported elsewhere.
584 if named
.underlying
== nil {
585 named
.underlying
= Typ
[Invalid
]
588 // Disallow a lone type parameter as the RHS of a type declaration (issue #45639).
589 // We don't need this restriction anymore if we make the underlying type of a type
590 // parameter its constraint interface: if the RHS is a lone type parameter, we will
591 // use its underlying type (like we do for any RHS in a type declaration), and its
592 // underlying type is an interface and the type declaration is well defined.
593 if isTypeParam(rhs
) {
594 check
.error(tdecl
.Type
, _MisplacedTypeParam
, "cannot use a type parameter as RHS in type declaration")
595 named
.underlying
= Typ
[Invalid
]
599 func (check
*Checker
) collectTypeParams(dst
**TypeParamList
, list
*ast
.FieldList
) {
600 var tparams
[]*TypeParam
601 // Declare type parameters up-front, with empty interface as type bound.
602 // The scope of type parameters starts at the beginning of the type parameter
603 // list (so we can have mutually recursive parameterized interfaces).
604 for _
, f
:= range list
.List
{
605 tparams
= check
.declareTypeParams(tparams
, f
.Names
)
608 // Set the type parameters before collecting the type constraints because
609 // the parameterized type may be used by the constraints (issue #47887).
610 // Example: type T[P T[P]] interface{}
611 *dst
= bindTParams(tparams
)
613 // Signal to cycle detection that we are in a type parameter list.
614 // We can only be inside one type parameter list at any given time:
615 // function closures may appear inside a type parameter list but they
616 // cannot be generic, and their bodies are processed in delayed and
617 // sequential fashion. Note that with each new declaration, we save
618 // the existing environment and restore it when done; thus inTPList is
619 // true exactly only when we are in a specific type parameter list.
620 assert(!check
.inTParamList
)
621 check
.inTParamList
= true
623 check
.inTParamList
= false
627 for _
, f
:= range list
.List
{
629 // NOTE: we may be able to assert that f.Type != nil here, but this is not
630 // an invariant of the AST, so we are cautious.
632 bound
= check
.bound(f
.Type
)
633 if isTypeParam(bound
) {
634 // We may be able to allow this since it is now well-defined what
635 // the underlying type and thus type set of a type parameter is.
636 // But we may need some additional form of cycle detection within
637 // type parameter lists.
638 check
.error(f
.Type
, _MisplacedTypeParam
, "cannot use a type parameter as constraint")
644 for i
:= range f
.Names
{
645 tparams
[index
+i
].bound
= bound
647 index
+= len(f
.Names
)
651 func (check
*Checker
) bound(x ast
.Expr
) Type
{
652 // A type set literal of the form ~T and A|B may only appear as constraint;
653 // embed it in an implicit interface so that only interface type-checking
654 // needs to take care of such type expressions.
656 switch op
:= x
.(type) {
658 wrap
= op
.Op
== token
.TILDE
659 case *ast
.BinaryExpr
:
660 wrap
= op
.Op
== token
.OR
663 x
= &ast
.InterfaceType
{Methods
: &ast
.FieldList
{List
: []*ast
.Field
{{Type
: x
}}}}
665 // mark t as implicit interface if all went well
666 if t
, _
:= t
.(*Interface
); t
!= nil {
674 func (check
*Checker
) declareTypeParams(tparams
[]*TypeParam
, names
[]*ast
.Ident
) []*TypeParam
{
675 // Use Typ[Invalid] for the type constraint to ensure that a type
676 // is present even if the actual constraint has not been assigned
678 // TODO(gri) Need to systematically review all uses of type parameter
679 // constraints to make sure we don't rely on them if they
680 // are not properly set yet.
681 for _
, name
:= range names
{
682 tname
:= NewTypeName(name
.Pos(), check
.pkg
, name
.Name
, nil)
683 tpar
:= check
.newTypeParam(tname
, Typ
[Invalid
]) // assigns type to tpar as a side-effect
684 check
.declare(check
.scope
, name
, tname
, check
.scope
.pos
) // TODO(gri) check scope position
685 tparams
= append(tparams
, tpar
)
688 if trace
&& len(names
) > 0 {
689 check
.trace(names
[0].Pos(), "type params = %v", tparams
[len(tparams
)-len(names
):])
695 func (check
*Checker
) collectMethods(obj
*TypeName
) {
696 // get associated methods
697 // (Checker.collectObjects only collects methods with non-blank names;
698 // Checker.resolveBaseTypeName ensures that obj is not an alias name
699 // if it has attached methods.)
700 methods
:= check
.methods
[obj
]
704 delete(check
.methods
, obj
)
705 assert(!check
.objMap
[obj
].tdecl
.Assign
.IsValid()) // don't use TypeName.IsAlias (requires fully set up object)
707 // use an objset to check for name conflicts
710 // spec: "If the base type is a struct type, the non-blank method
711 // and field names must be distinct."
712 base
, _
:= obj
.typ
.(*Named
) // shouldn't fail but be conservative
714 assert(base
.targs
.Len() == 0) // collectMethods should not be called on an instantiated type
716 if t
, _
:= u
.(*Struct
); t
!= nil {
717 for _
, fld
:= range t
.fields
{
719 assert(mset
.insert(fld
) == nil)
724 // Checker.Files may be called multiple times; additional package files
725 // may add methods to already type-checked types. Add pre-existing methods
726 // so that we can detect redeclarations.
727 for i
:= 0; i
< base
.methods
.Len(); i
++ {
728 m
:= base
.methods
.At(i
, nil)
729 assert(m
.name
!= "_")
730 assert(mset
.insert(m
) == nil)
735 for _
, m
:= range methods
{
736 // spec: "For a base type, the non-blank names of methods bound
737 // to it must be unique."
738 assert(m
.name
!= "_")
739 if alt
:= mset
.insert(m
); alt
!= nil {
742 check
.errorf(m
, _DuplicateFieldAndMethod
, "field and method with the same name %s", m
.name
)
744 check
.errorf(m
, _DuplicateMethod
, "method %s already declared for %s", m
.name
, obj
)
748 check
.reportAltDecl(alt
)
753 base
.resolve(nil) // TODO(mdempsky): Probably unnecessary.
759 func (check
*Checker
) funcDecl(obj
*Func
, decl
*declInfo
) {
760 assert(obj
.typ
== nil)
762 // func declarations cannot use iota
763 assert(check
.iota == nil)
765 sig
:= new(Signature
)
766 obj
.typ
= sig
// guard against cycles
768 // Avoid cycle error when referring to method while type-checking the signature.
769 // This avoids a nuisance in the best case (non-parameterized receiver type) and
770 // since the method is not a type, we get an error. If we have a parameterized
771 // receiver type, instantiating the receiver type leads to the instantiation of
772 // its methods, and we don't want a cycle error in that case.
773 // TODO(gri) review if this is correct and/or whether we still need this?
777 check
.funcType(sig
, fdecl
.Recv
, fdecl
.Type
)
780 if fdecl
.Type
.TypeParams
.NumFields() > 0 && fdecl
.Body
== nil {
781 check
.softErrorf(fdecl
.Name
, _BadDecl
, "parameterized function is missing function body")
784 // function body must be type-checked after global declarations
785 // (functions implemented elsewhere have no body)
786 if !check
.conf
.IgnoreFuncBodies
&& fdecl
.Body
!= nil {
788 check
.funcBody(decl
, obj
.name
, sig
, fdecl
.Body
, nil)
793 func (check
*Checker
) declStmt(d ast
.Decl
) {
796 check
.walkDecl(d
, func(d decl
) {
797 switch d
:= d
.(type) {
799 top
:= len(check
.delayed
)
801 // declare all constants
802 lhs
:= make([]*Const
, len(d
.spec
.Names
))
803 for i
, name
:= range d
.spec
.Names
{
804 obj
:= NewConst(name
.Pos(), pkg
, name
.Name
, nil, constant
.MakeInt64(int64(d
.iota)))
812 check
.constDecl(obj
, d
.typ
, init
, d
.inherited
)
815 // process function literals in init expressions before scope changes
816 check
.processDelayed(top
)
818 // spec: "The scope of a constant or variable identifier declared
819 // inside a function begins at the end of the ConstSpec or VarSpec
820 // (ShortVarDecl for short variable declarations) and ends at the
821 // end of the innermost containing block."
822 scopePos
:= d
.spec
.End()
823 for i
, name
:= range d
.spec
.Names
{
824 check
.declare(check
.scope
, name
, lhs
[i
], scopePos
)
828 top
:= len(check
.delayed
)
830 lhs0
:= make([]*Var
, len(d
.spec
.Names
))
831 for i
, name
:= range d
.spec
.Names
{
832 lhs0
[i
] = NewVar(name
.Pos(), pkg
, name
.Name
, nil)
835 // initialize all variables
836 for i
, obj
:= range lhs0
{
839 switch len(d
.spec
.Values
) {
840 case len(d
.spec
.Names
):
842 init
= d
.spec
.Values
[i
]
844 // rhs is expected to be a multi-valued expression
846 init
= d
.spec
.Values
[0]
848 if i
< len(d
.spec
.Values
) {
849 init
= d
.spec
.Values
[i
]
852 check
.varDecl(obj
, lhs
, d
.spec
.Type
, init
)
853 if len(d
.spec
.Values
) == 1 {
854 // If we have a single lhs variable we are done either way.
855 // If we have a single rhs expression, it must be a multi-
856 // valued expression, in which case handling the first lhs
857 // variable will cause all lhs variables to have a type
858 // assigned, and we are done as well.
860 for _
, obj
:= range lhs0
{
861 assert(obj
.typ
!= nil)
868 // process function literals in init expressions before scope changes
869 check
.processDelayed(top
)
871 // declare all variables
872 // (only at this point are the variable scopes (parents) set)
873 scopePos
:= d
.spec
.End() // see constant declarations
874 for i
, name
:= range d
.spec
.Names
{
875 // see constant declarations
876 check
.declare(check
.scope
, name
, lhs0
[i
], scopePos
)
880 obj
:= NewTypeName(d
.spec
.Name
.Pos(), pkg
, d
.spec
.Name
.Name
, nil)
881 // spec: "The scope of a type identifier declared inside a function
882 // begins at the identifier in the TypeSpec and ends at the end of
883 // the innermost containing block."
884 scopePos
:= d
.spec
.Name
.Pos()
885 check
.declare(check
.scope
, d
.spec
.Name
, obj
, scopePos
)
886 // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl)
887 obj
.setColor(grey
+ color(check
.push(obj
)))
888 check
.typeDecl(obj
, d
.spec
, nil)
889 check
.pop().setColor(black
)
891 check
.invalidAST(d
.node(), "unknown ast.Decl node %T", d
.node())