Source file
src/go/types/decl.go
1
2
3
4
5 package types
6
7 import (
8 "fmt"
9 "go/ast"
10 "go/constant"
11 "go/internal/typeparams"
12 "go/token"
13 )
14
15 func (check *Checker) reportAltDecl(obj Object) {
16 if pos := obj.Pos(); pos.IsValid() {
17
18
19
20 check.errorf(obj, _DuplicateDecl, "\tother declaration of %s", obj.Name())
21 }
22 }
23
24 func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
25
26
27
28
29 if obj.Name() != "_" {
30 if alt := scope.Insert(obj); alt != nil {
31 check.errorf(obj, _DuplicateDecl, "%s redeclared in this block", obj.Name())
32 check.reportAltDecl(alt)
33 return
34 }
35 obj.setScopePos(pos)
36 }
37 if id != nil {
38 check.recordDef(id, obj)
39 }
40 }
41
42
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
55
56 func (check *Checker) objDecl(obj Object, def *Named) {
57 if trace && obj.Type() == nil {
58 if check.indent == 0 {
59 fmt.Println()
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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
105
106
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
118 fallthrough
119
120 case grey:
121
122
123
124
125
126
127
128
129
130
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
145
146
147
148
149 obj.typ = Typ[Invalid]
150 }
151
152 case *Func:
153 if check.cycle(obj) {
154
155
156
157
158
159
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
176 defer func(ctxt context) {
177 check.context = ctxt
178 }(check.context)
179 check.context = context{
180 scope: d.file,
181 }
182
183
184
185
186
187
188 switch obj := obj.(type) {
189 case *Const:
190 check.decl = d
191 check.constDecl(obj, d.vtyp, d.init, d.inherited)
192 case *Var:
193 check.decl = d
194 check.varDecl(obj, d.lhs, d.vtyp, d.init)
195 case *TypeName:
196
197 check.typeDecl(obj, d.tdecl, def)
198 check.collectMethods(obj)
199 case *Func:
200
201 check.funcDecl(obj, d)
202 default:
203 unreachable()
204 }
205 }
206
207
208
209 func (check *Checker) cycle(obj Object) (isCycle bool) {
210
211 if debug {
212 info := check.objMap[obj]
213 inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil)
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
222 assert(obj.color() >= grey)
223 start := obj.color() - grey
224 cycle := check.objPath[start:]
225 nval := 0
226 ndef := 0
227 for _, obj := range cycle {
228 switch obj := obj.(type) {
229 case *Const, *Var:
230 nval++
231 case *TypeName:
232
233
234
235
236
237
238
239
240
241 var alias bool
242 if d := check.objMap[obj]; d != nil {
243 alias = d.tdecl.Assign.IsValid()
244 } else {
245 alias = obj.IsAlias()
246 }
247 if !alias {
248 ndef++
249 }
250 case *Func:
251
252 default:
253 unreachable()
254 }
255 }
256
257 if 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
268
269
270 if nval == len(cycle) {
271 return false
272 }
273
274
275
276
277 if nval == 0 && ndef > 0 {
278 return false
279 }
280
281 check.cycleError(cycle)
282
283 return true
284 }
285
286 type typeInfo uint
287
288
289
290
291
292
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
321
322 if t.obj.pkg != check.pkg {
323 return valid
324 }
325
326
327
328 if t.underlying == Typ[Invalid] {
329 t.info = invalid
330 return invalid
331 }
332
333 switch t.info {
334 case unknown:
335 t.info = marked
336 t.info = check.validType(t.orig, append(path, t.obj))
337 case marked:
338
339 for i, tn := range path {
340 if t.obj.pkg != check.pkg {
341 panic("internal error: type cycle via package-external type")
342 }
343 if tn == t.obj {
344 check.cycleError(path[i:])
345 t.info = invalid
346 return t.info
347 }
348 }
349 panic("internal error: cycle start not found")
350 }
351 return t.info
352
353 case *instance:
354 return check.validType(t.expand(), path)
355 }
356
357 return valid
358 }
359
360
361
362 func (check *Checker) cycleError(cycle []Object) {
363
364
365
366 i := firstInSrc(cycle)
367 obj := cycle[i]
368 check.errorf(obj, _InvalidDeclCycle, "illegal cycle in declaration of %s", obj.Name())
369 for range cycle {
370 check.errorf(obj, _InvalidDeclCycle, "\t%s refers to", obj.Name())
371 i++
372 if i >= len(cycle) {
373 i = 0
374 }
375 obj = cycle[i]
376 }
377 check.errorf(obj, _InvalidDeclCycle, "\t%s", obj.Name())
378 }
379
380
381
382 func firstInSrc(path []Object) int {
383 fst, pos := 0, path[0].Pos()
384 for i, t := range path[1:] {
385 if t.Pos() < pos {
386 fst, pos = i+1, t.Pos()
387 }
388 }
389 return fst
390 }
391
392 type (
393 decl interface {
394 node() ast.Node
395 }
396
397 importDecl struct{ spec *ast.ImportSpec }
398 constDecl struct {
399 spec *ast.ValueSpec
400 iota int
401 typ ast.Expr
402 init []ast.Expr
403 inherited bool
404 }
405 varDecl struct{ spec *ast.ValueSpec }
406 typeDecl struct{ spec *ast.TypeSpec }
407 funcDecl struct{ decl *ast.FuncDecl }
408 )
409
410 func (d importDecl) node() ast.Node { return d.spec }
411 func (d constDecl) node() ast.Node { return d.spec }
412 func (d varDecl) node() ast.Node { return d.spec }
413 func (d typeDecl) node() ast.Node { return d.spec }
414 func (d funcDecl) node() ast.Node { return d.decl }
415
416 func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) {
417 for _, d := range decls {
418 check.walkDecl(d, f)
419 }
420 }
421
422 func (check *Checker) walkDecl(d ast.Decl, f func(decl)) {
423 switch d := d.(type) {
424 case *ast.BadDecl:
425
426 case *ast.GenDecl:
427 var last *ast.ValueSpec
428 for iota, s := range d.Specs {
429 switch s := s.(type) {
430 case *ast.ImportSpec:
431 f(importDecl{s})
432 case *ast.ValueSpec:
433 switch d.Tok {
434 case token.CONST:
435
436 inherited := true
437 switch {
438 case s.Type != nil || len(s.Values) > 0:
439 last = s
440 inherited = false
441 case last == nil:
442 last = new(ast.ValueSpec)
443 inherited = false
444 }
445 check.arityMatch(s, last)
446 f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited})
447 case token.VAR:
448 check.arityMatch(s, nil)
449 f(varDecl{s})
450 default:
451 check.invalidAST(s, "invalid token %s", d.Tok)
452 }
453 case *ast.TypeSpec:
454 f(typeDecl{s})
455 default:
456 check.invalidAST(s, "unknown ast.Spec node %T", s)
457 }
458 }
459 case *ast.FuncDecl:
460 f(funcDecl{d})
461 default:
462 check.invalidAST(d, "unknown ast.Decl node %T", d)
463 }
464 }
465
466 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) {
467 assert(obj.typ == nil)
468
469
470 defer func(iota constant.Value, errpos positioner) {
471 check.iota = iota
472 check.errpos = errpos
473 }(check.iota, check.errpos)
474 check.iota = obj.val
475 check.errpos = nil
476
477
478 obj.val = constant.MakeUnknown()
479
480
481 if typ != nil {
482 t := check.typ(typ)
483 if !isConstType(t) {
484
485
486 if under(t) != Typ[Invalid] {
487 check.errorf(typ, _InvalidConstType, "invalid constant type %s", t)
488 }
489 obj.typ = Typ[Invalid]
490 return
491 }
492 obj.typ = t
493 }
494
495
496 var x operand
497 if init != nil {
498 if inherited {
499
500
501
502
503
504
505 check.errpos = atPos(obj.pos)
506 }
507 check.expr(&x, init)
508 }
509 check.initConst(obj, &x)
510 }
511
512 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
513 assert(obj.typ == nil)
514
515
516 if typ != nil {
517 obj.typ = check.varType(typ)
518
519
520
521
522
523
524
525
526 }
527
528
529 if init == nil {
530 if typ == nil {
531
532 obj.typ = Typ[Invalid]
533 }
534 return
535 }
536
537 if lhs == nil || len(lhs) == 1 {
538 assert(lhs == nil || lhs[0] == obj)
539 var x operand
540 check.expr(&x, init)
541 check.initVar(obj, &x, "variable declaration")
542 return
543 }
544
545 if debug {
546
547 found := false
548 for _, lhs := range lhs {
549 if obj == lhs {
550 found = true
551 break
552 }
553 }
554 if !found {
555 panic("inconsistent lhs")
556 }
557 }
558
559
560
561
562
563 if typ != nil {
564 for _, lhs := range lhs {
565 lhs.typ = obj.typ
566 }
567 }
568
569 check.initVars(lhs, []ast.Expr{init}, token.NoPos)
570 }
571
572
573
574
575
576
577
578 func (n0 *Named) under() Type {
579 u := n0.underlying
580
581 if u == Typ[Invalid] {
582 return u
583 }
584
585
586
587
588 switch u.(type) {
589 case nil:
590 return Typ[Invalid]
591 default:
592
593 return u
594 case *Named, *instance:
595
596 }
597
598 if n0.check == nil {
599 panic("internal error: Named.check == nil but type is incomplete")
600 }
601
602
603
604 check := n0.check
605
606
607 n := asNamed(u)
608 if n == nil {
609 n0.underlying = Typ[Invalid]
610 return n0.underlying
611 }
612
613
614 seen := map[*Named]int{n0: 0}
615 path := []Object{n0.obj}
616 for {
617 u = n.underlying
618 if u == nil {
619 u = Typ[Invalid]
620 break
621 }
622 var n1 *Named
623 switch u1 := u.(type) {
624 case *Named:
625 n1 = u1
626 case *instance:
627 n1, _ = u1.expand().(*Named)
628 if n1 == nil {
629 u = Typ[Invalid]
630 }
631 }
632 if n1 == nil {
633 break
634 }
635
636 seen[n] = len(seen)
637 path = append(path, n.obj)
638 n = n1
639
640 if i, ok := seen[n]; ok {
641
642 check.cycleError(path[i:])
643 u = Typ[Invalid]
644 break
645 }
646 }
647
648 for n := range seen {
649
650
651
652
653 if n.obj.pkg != check.pkg {
654 panic("internal error: imported type with unresolved underlying type")
655 }
656 n.underlying = u
657 }
658
659 return u
660 }
661
662 func (n *Named) setUnderlying(typ Type) {
663 if n != nil {
664 n.underlying = typ
665 }
666 }
667
668 func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
669 assert(obj.typ == nil)
670
671 check.later(func() {
672 check.validType(obj.typ, nil)
673 })
674
675 alias := tdecl.Assign.IsValid()
676 if alias && typeparams.Get(tdecl) != nil {
677
678
679 check.error(atPos(tdecl.Assign), 0, "generic type cannot be alias")
680 alias = false
681 }
682
683 if alias {
684
685 if !check.allowVersion(check.pkg, 1, 9) {
686 check.errorf(atPos(tdecl.Assign), _BadDecl, "type aliases requires go1.9 or later")
687 }
688
689 obj.typ = Typ[Invalid]
690 obj.typ = check.anyType(tdecl.Type)
691
692 } else {
693
694
695 named := check.newNamed(obj, nil, nil)
696 def.setUnderlying(named)
697 obj.typ = named
698
699 if tparams := typeparams.Get(tdecl); tparams != nil {
700 check.openScope(tdecl, "type parameters")
701 defer check.closeScope()
702 named.tparams = check.collectTypeParams(tparams)
703 }
704
705
706 named.orig = check.definedType(tdecl.Type, named)
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723 named.underlying = under(named)
724 }
725
726 }
727
728 func (check *Checker) collectTypeParams(list *ast.FieldList) (tparams []*TypeName) {
729
730
731 if list.NumFields() == 0 {
732 return
733 }
734
735
736
737
738 for _, f := range list.List {
739 tparams = check.declareTypeParams(tparams, f.Names)
740 }
741
742 setBoundAt := func(at int, bound Type) {
743 assert(IsInterface(bound))
744 tparams[at].typ.(*_TypeParam).bound = bound
745 }
746
747 index := 0
748 var bound Type
749 for _, f := range list.List {
750 if f.Type == nil {
751 goto next
752 }
753
754
755
756
757 if tident, _ := unparen(f.Type).(*ast.Ident); tident != nil && tident.Name == "any" && check.lookup("any") == nil {
758 bound = universeAny
759 } else {
760 bound = check.typ(f.Type)
761 }
762
763
764
765
766
767
768 if _, ok := under(bound).(*Interface); ok {
769
770 for i := range f.Names {
771 setBoundAt(index+i, bound)
772 }
773 } else if bound != Typ[Invalid] {
774 check.errorf(f.Type, _Todo, "%s is not an interface", bound)
775 }
776
777 next:
778 index += len(f.Names)
779 }
780
781 return
782 }
783
784 func (check *Checker) declareTypeParams(tparams []*TypeName, names []*ast.Ident) []*TypeName {
785 for _, name := range names {
786 tpar := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
787 check.newTypeParam(tpar, len(tparams), &emptyInterface)
788 check.declare(check.scope, name, tpar, check.scope.pos)
789 tparams = append(tparams, tpar)
790 }
791
792 if trace && len(names) > 0 {
793 check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):])
794 }
795
796 return tparams
797 }
798
799 func (check *Checker) collectMethods(obj *TypeName) {
800
801
802
803
804 methods := check.methods[obj]
805 if methods == nil {
806 return
807 }
808 delete(check.methods, obj)
809 assert(!check.objMap[obj].tdecl.Assign.IsValid())
810
811
812 var mset objset
813
814
815
816 base := asNamed(obj.typ)
817 if base != nil {
818 if t, _ := base.underlying.(*Struct); t != nil {
819 for _, fld := range t.fields {
820 if fld.name != "_" {
821 assert(mset.insert(fld) == nil)
822 }
823 }
824 }
825
826
827
828
829 for _, m := range base.methods {
830 assert(m.name != "_")
831 assert(mset.insert(m) == nil)
832 }
833 }
834
835
836 for _, m := range methods {
837
838
839 assert(m.name != "_")
840 if alt := mset.insert(m); alt != nil {
841 switch alt.(type) {
842 case *Var:
843 check.errorf(m, _DuplicateFieldAndMethod, "field and method with the same name %s", m.name)
844 case *Func:
845 check.errorf(m, _DuplicateMethod, "method %s already declared for %s", m.name, obj)
846 default:
847 unreachable()
848 }
849 check.reportAltDecl(alt)
850 continue
851 }
852
853 if base != nil {
854 base.methods = append(base.methods, m)
855 }
856 }
857 }
858
859 func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
860 assert(obj.typ == nil)
861
862
863 assert(check.iota == nil)
864
865 sig := new(Signature)
866 obj.typ = sig
867
868
869
870
871
872
873
874 saved := obj.color_
875 obj.color_ = black
876 fdecl := decl.fdecl
877 check.funcType(sig, fdecl.Recv, fdecl.Type)
878 obj.color_ = saved
879
880
881
882 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
883 check.later(func() {
884 check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
885 })
886 }
887 }
888
889 func (check *Checker) declStmt(d ast.Decl) {
890 pkg := check.pkg
891
892 check.walkDecl(d, func(d decl) {
893 switch d := d.(type) {
894 case constDecl:
895 top := len(check.delayed)
896
897
898 lhs := make([]*Const, len(d.spec.Names))
899 for i, name := range d.spec.Names {
900 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota)))
901 lhs[i] = obj
902
903 var init ast.Expr
904 if i < len(d.init) {
905 init = d.init[i]
906 }
907
908 check.constDecl(obj, d.typ, init, d.inherited)
909 }
910
911
912 check.processDelayed(top)
913
914
915
916
917
918 scopePos := d.spec.End()
919 for i, name := range d.spec.Names {
920 check.declare(check.scope, name, lhs[i], scopePos)
921 }
922
923 case varDecl:
924 top := len(check.delayed)
925
926 lhs0 := make([]*Var, len(d.spec.Names))
927 for i, name := range d.spec.Names {
928 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
929 }
930
931
932 for i, obj := range lhs0 {
933 var lhs []*Var
934 var init ast.Expr
935 switch len(d.spec.Values) {
936 case len(d.spec.Names):
937
938 init = d.spec.Values[i]
939 case 1:
940
941 lhs = lhs0
942 init = d.spec.Values[0]
943 default:
944 if i < len(d.spec.Values) {
945 init = d.spec.Values[i]
946 }
947 }
948 check.varDecl(obj, lhs, d.spec.Type, init)
949 if len(d.spec.Values) == 1 {
950
951
952
953
954
955 if debug {
956 for _, obj := range lhs0 {
957 assert(obj.typ != nil)
958 }
959 }
960 break
961 }
962 }
963
964
965 check.processDelayed(top)
966
967
968
969 scopePos := d.spec.End()
970 for i, name := range d.spec.Names {
971
972 check.declare(check.scope, name, lhs0[i], scopePos)
973 }
974
975 case typeDecl:
976 obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
977
978
979
980 scopePos := d.spec.Name.Pos()
981 check.declare(check.scope, d.spec.Name, obj, scopePos)
982
983 obj.setColor(grey + color(check.push(obj)))
984 check.typeDecl(obj, d.spec, nil)
985 check.pop().setColor(black)
986 default:
987 check.invalidAST(d.node(), "unknown ast.Decl node %T", d.node())
988 }
989 })
990 }
991
View as plain text