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