SH: Fix outage caused by recently added 2nd combine pass after reg alloc
[official-gcc.git] / libgo / go / go / types / decl.go
blob93a37d76ce0d78021708de8ae7806e41f205d85a
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.
5 package types
7 import (
8 "fmt"
9 "go/ast"
10 "go/constant"
11 "go/token"
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
27 // binding."
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)
32 return
34 obj.setScopePos(pos)
36 if id != nil {
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 {
43 var s string
44 for i, p := range path {
45 if i > 0 {
46 s += "->"
48 s += p.Name()
50 return s
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))
61 check.indent++
62 defer func() {
63 check.indent--
64 check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color())
65 }()
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
82 // valid.
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 {
96 obj.setColor(black)
97 return
100 switch obj.color() {
101 case white:
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)))
107 defer func() {
108 check.pop().setColor(black)
111 case black:
112 assert(obj.Type() != nil)
113 return
115 default:
116 // Color values other than white or black are considered grey.
117 fallthrough
119 case 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
129 // order code.
130 switch obj := obj.(type) {
131 case *Const:
132 if !check.validCycle(obj) || obj.typ == nil {
133 obj.typ = Typ[Invalid]
136 case *Var:
137 if !check.validCycle(obj) || obj.typ == nil {
138 obj.typ = Typ[Invalid]
141 case *TypeName:
142 if !check.validCycle(obj) {
143 // break cycle
144 // (without this, calling underlying()
145 // below may lead to an endless loop
146 // if we have a cycle for a defined
147 // (*Named) type)
148 obj.typ = Typ[Invalid]
151 case *Func:
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.
161 default:
162 unreachable()
164 assert(obj.Type() != nil)
165 return
168 d := check.objMap[obj]
169 if d == nil {
170 check.dump("%v: %s should have been declared", obj.Pos(), obj)
171 unreachable()
174 // save/restore current environment and set up object environment
175 defer func(env environment) {
176 check.environment = env
177 }(check.environment)
178 check.environment = environment{
179 scope: d.file,
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
186 // check.decl.
187 switch obj := obj.(type) {
188 case *Const:
189 check.decl = d // new package-level const decl
190 check.constDecl(obj, d.vtyp, d.init, d.inherited)
191 case *Var:
192 check.decl = d // new package-level var decl
193 check.varDecl(obj, d.lhs, d.vtyp, d.init)
194 case *TypeName:
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
198 case *Func:
199 // functions may be recursive - no need to track dependencies
200 check.funcDecl(obj, d)
201 default:
202 unreachable()
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.
210 if debug {
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)
216 unreachable()
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
227 loop:
228 for _, obj := range cycle {
229 switch obj := obj.(type) {
230 case *Const, *Var:
231 nval++
232 case *TypeName:
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) {
237 tparCycle = true
238 break loop
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.
250 var alias bool
251 if d := check.objMap[obj]; d != nil {
252 alias = d.tdecl.Assign.IsValid() // package-level object
253 } else {
254 alias = obj.IsAlias() // function local object
256 if !alias {
257 ndef++
259 case *Func:
260 // ignored for now
261 default:
262 unreachable()
266 if trace {
267 check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle))
268 if tparCycle {
269 check.trace(obj.Pos(), "## cycle contains: generic type in a type parameter list")
270 } else {
271 check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef)
273 defer func() {
274 if valid {
275 check.trace(obj.Pos(), "=> cycle is valid")
276 } else {
277 check.trace(obj.Pos(), "=> error: cycle is invalid")
282 if !tparCycle {
283 // A cycle involving only constants and variables is invalid but we
284 // ignore them here because they are reported via the initialization
285 // cycle check.
286 if nval == len(cycle) {
287 return true
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 {
294 return true
298 check.cycleError(cycle)
299 return false
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)
309 obj := cycle[i]
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())
317 } else {
318 check.errorf(obj, _InvalidDeclCycle, "illegal cycle in declaration of %s", obj.Name())
320 for range cycle {
321 check.errorf(obj, _InvalidDeclCycle, "\t%s refers to", obj.Name()) // secondary error, \t indented
323 if i >= len(cycle) {
324 i = 0
326 obj = cycle[i]
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:] {
336 if t.Pos() < pos {
337 fst, pos = i+1, t.Pos()
340 return fst
343 type (
344 decl interface {
345 node() ast.Node
348 importDecl struct{ spec *ast.ImportSpec }
349 constDecl struct {
350 spec *ast.ValueSpec
351 iota int
352 typ ast.Expr
353 init []ast.Expr
354 inherited bool
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 {
369 check.walkDecl(d, f)
373 func (check *Checker) walkDecl(d ast.Decl, f func(decl)) {
374 switch d := d.(type) {
375 case *ast.BadDecl:
376 // ignore
377 case *ast.GenDecl:
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:
382 f(importDecl{s})
383 case *ast.ValueSpec:
384 switch d.Tok {
385 case token.CONST:
386 // determine which initialization expressions to use
387 inherited := true
388 switch {
389 case s.Type != nil || len(s.Values) > 0:
390 last = s
391 inherited = false
392 case last == nil:
393 last = new(ast.ValueSpec) // make sure last exists
394 inherited = false
396 check.arityMatch(s, last)
397 f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited})
398 case token.VAR:
399 check.arityMatch(s, nil)
400 f(varDecl{s})
401 default:
402 check.invalidAST(s, "invalid token %s", d.Tok)
404 case *ast.TypeSpec:
405 f(typeDecl{s})
406 default:
407 check.invalidAST(s, "unknown ast.Spec node %T", s)
410 case *ast.FuncDecl:
411 f(funcDecl{d})
412 default:
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) {
422 check.iota = iota
423 check.errpos = errpos
424 }(check.iota, check.errpos)
425 check.iota = obj.val
426 check.errpos = nil
428 // provide valid constant value under all circumstances
429 obj.val = constant.MakeUnknown()
431 // determine type, if any
432 if typ != nil {
433 t := check.typ(typ)
434 if !isConstType(t) {
435 // don't report an error if the type is an invalid C (defined) type
436 // (issue #22090)
437 if under(t) != Typ[Invalid] {
438 check.errorf(typ, _InvalidConstType, "invalid constant type %s", t)
440 obj.typ = Typ[Invalid]
441 return
443 obj.typ = t
446 // check initialization
447 var x operand
448 if init != nil {
449 if inherited {
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)
458 check.expr(&x, init)
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
467 if typ != nil {
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
480 if init == nil {
481 if typ == nil {
482 // error reported before by arityMatch
483 obj.typ = Typ[Invalid]
485 return
488 if lhs == nil || len(lhs) == 1 {
489 assert(lhs == nil || lhs[0] == obj)
490 var x operand
491 check.expr(&x, init)
492 check.initVar(obj, &x, "variable declaration")
493 return
496 if debug {
497 // obj must be one of lhs
498 found := false
499 for _, lhs := range lhs {
500 if obj == lhs {
501 found = true
502 break
505 if !found {
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).
514 if typ != nil {
515 for _, lhs := range lhs {
516 lhs.typ = obj.typ
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 {
527 return false
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)
536 var rhs Type
537 check.later(func() {
538 if t, _ := obj.typ.(*Named); t != nil { // type may be invalid
539 check.validType(t)
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")
552 alias = false
555 // alias declaration
556 if 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)
564 return
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)
579 assert(rhs != nil)
580 named.fromRHS = rhs
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
622 defer func() {
623 check.inTParamList = false
626 index := 0
627 for _, f := range list.List {
628 var bound Type
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.
631 if f.Type != nil {
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")
639 bound = Typ[Invalid]
641 } else {
642 bound = Typ[Invalid]
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.
655 wrap := false
656 switch op := x.(type) {
657 case *ast.UnaryExpr:
658 wrap = op.Op == token.TILDE
659 case *ast.BinaryExpr:
660 wrap = op.Op == token.OR
662 if wrap {
663 x = &ast.InterfaceType{Methods: &ast.FieldList{List: []*ast.Field{{Type: x}}}}
664 t := check.typ(x)
665 // mark t as implicit interface if all went well
666 if t, _ := t.(*Interface); t != nil {
667 t.implicit = true
669 return t
671 return check.typ(x)
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
677 // yet.
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):])
692 return tparams
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]
701 if methods == nil {
702 return
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
708 var mset objset
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
713 if base != nil {
714 assert(base.targs.Len() == 0) // collectMethods should not be called on an instantiated type
715 u := base.under()
716 if t, _ := u.(*Struct); t != nil {
717 for _, fld := range t.fields {
718 if fld.name != "_" {
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)
734 // add valid methods
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 {
740 switch alt.(type) {
741 case *Var:
742 check.errorf(m, _DuplicateFieldAndMethod, "field and method with the same name %s", m.name)
743 case *Func:
744 check.errorf(m, _DuplicateMethod, "method %s already declared for %s", m.name, obj)
745 default:
746 unreachable()
748 check.reportAltDecl(alt)
749 continue
752 if base != nil {
753 base.resolve(nil) // TODO(mdempsky): Probably unnecessary.
754 base.AddMethod(m)
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?
774 saved := obj.color_
775 obj.color_ = black
776 fdecl := decl.fdecl
777 check.funcType(sig, fdecl.Recv, fdecl.Type)
778 obj.color_ = saved
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 {
787 check.later(func() {
788 check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
793 func (check *Checker) declStmt(d ast.Decl) {
794 pkg := check.pkg
796 check.walkDecl(d, func(d decl) {
797 switch d := d.(type) {
798 case constDecl:
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)))
805 lhs[i] = obj
807 var init ast.Expr
808 if i < len(d.init) {
809 init = d.init[i]
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)
827 case varDecl:
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 {
837 var lhs []*Var
838 var init ast.Expr
839 switch len(d.spec.Values) {
840 case len(d.spec.Names):
841 // lhs and rhs match
842 init = d.spec.Values[i]
843 case 1:
844 // rhs is expected to be a multi-valued expression
845 lhs = lhs0
846 init = d.spec.Values[0]
847 default:
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.
859 if debug {
860 for _, obj := range lhs0 {
861 assert(obj.typ != nil)
864 break
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)
879 case typeDecl:
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)
890 default:
891 check.invalidAST(d.node(), "unknown ast.Decl node %T", d.node())