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 t.underlying = Typ[Invalid]
347 return t.info
348 }
349 }
350 panic("internal error: cycle start not found")
351 }
352 return t.info
353
354 case *instance:
355 return check.validType(t.expand(), path)
356 }
357
358 return valid
359 }
360
361
362
363 func (check *Checker) cycleError(cycle []Object) {
364
365
366
367 i := firstInSrc(cycle)
368 obj := cycle[i]
369 check.errorf(obj, _InvalidDeclCycle, "illegal cycle in declaration of %s", obj.Name())
370 for range cycle {
371 check.errorf(obj, _InvalidDeclCycle, "\t%s refers to", obj.Name())
372 i++
373 if i >= len(cycle) {
374 i = 0
375 }
376 obj = cycle[i]
377 }
378 check.errorf(obj, _InvalidDeclCycle, "\t%s", obj.Name())
379 }
380
381
382
383 func firstInSrc(path []Object) int {
384 fst, pos := 0, path[0].Pos()
385 for i, t := range path[1:] {
386 if t.Pos() < pos {
387 fst, pos = i+1, t.Pos()
388 }
389 }
390 return fst
391 }
392
393 type (
394 decl interface {
395 node() ast.Node
396 }
397
398 importDecl struct{ spec *ast.ImportSpec }
399 constDecl struct {
400 spec *ast.ValueSpec
401 iota int
402 typ ast.Expr
403 init []ast.Expr
404 inherited bool
405 }
406 varDecl struct{ spec *ast.ValueSpec }
407 typeDecl struct{ spec *ast.TypeSpec }
408 funcDecl struct{ decl *ast.FuncDecl }
409 )
410
411 func (d importDecl) node() ast.Node { return d.spec }
412 func (d constDecl) node() ast.Node { return d.spec }
413 func (d varDecl) node() ast.Node { return d.spec }
414 func (d typeDecl) node() ast.Node { return d.spec }
415 func (d funcDecl) node() ast.Node { return d.decl }
416
417 func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) {
418 for _, d := range decls {
419 check.walkDecl(d, f)
420 }
421 }
422
423 func (check *Checker) walkDecl(d ast.Decl, f func(decl)) {
424 switch d := d.(type) {
425 case *ast.BadDecl:
426
427 case *ast.GenDecl:
428 var last *ast.ValueSpec
429 for iota, s := range d.Specs {
430 switch s := s.(type) {
431 case *ast.ImportSpec:
432 f(importDecl{s})
433 case *ast.ValueSpec:
434 switch d.Tok {
435 case token.CONST:
436
437 inherited := true
438 switch {
439 case s.Type != nil || len(s.Values) > 0:
440 last = s
441 inherited = false
442 case last == nil:
443 last = new(ast.ValueSpec)
444 inherited = false
445 }
446 check.arityMatch(s, last)
447 f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited})
448 case token.VAR:
449 check.arityMatch(s, nil)
450 f(varDecl{s})
451 default:
452 check.invalidAST(s, "invalid token %s", d.Tok)
453 }
454 case *ast.TypeSpec:
455 f(typeDecl{s})
456 default:
457 check.invalidAST(s, "unknown ast.Spec node %T", s)
458 }
459 }
460 case *ast.FuncDecl:
461 f(funcDecl{d})
462 default:
463 check.invalidAST(d, "unknown ast.Decl node %T", d)
464 }
465 }
466
467 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) {
468 assert(obj.typ == nil)
469
470
471 defer func(iota constant.Value, errpos positioner) {
472 check.iota = iota
473 check.errpos = errpos
474 }(check.iota, check.errpos)
475 check.iota = obj.val
476 check.errpos = nil
477
478
479 obj.val = constant.MakeUnknown()
480
481
482 if typ != nil {
483 t := check.typ(typ)
484 if !isConstType(t) {
485
486
487 if under(t) != Typ[Invalid] {
488 check.errorf(typ, _InvalidConstType, "invalid constant type %s", t)
489 }
490 obj.typ = Typ[Invalid]
491 return
492 }
493 obj.typ = t
494 }
495
496
497 var x operand
498 if init != nil {
499 if inherited {
500
501
502
503
504
505
506 check.errpos = atPos(obj.pos)
507 }
508 check.expr(&x, init)
509 }
510 check.initConst(obj, &x)
511 }
512
513 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
514 assert(obj.typ == nil)
515
516
517 if typ != nil {
518 obj.typ = check.varType(typ)
519
520
521
522
523
524
525
526
527 }
528
529
530 if init == nil {
531 if typ == nil {
532
533 obj.typ = Typ[Invalid]
534 }
535 return
536 }
537
538 if lhs == nil || len(lhs) == 1 {
539 assert(lhs == nil || lhs[0] == obj)
540 var x operand
541 check.expr(&x, init)
542 check.initVar(obj, &x, "variable declaration")
543 return
544 }
545
546 if debug {
547
548 found := false
549 for _, lhs := range lhs {
550 if obj == lhs {
551 found = true
552 break
553 }
554 }
555 if !found {
556 panic("inconsistent lhs")
557 }
558 }
559
560
561
562
563
564 if typ != nil {
565 for _, lhs := range lhs {
566 lhs.typ = obj.typ
567 }
568 }
569
570 check.initVars(lhs, []ast.Expr{init}, token.NoPos)
571 }
572
573
574
575
576
577
578
579 func (n0 *Named) under() Type {
580 u := n0.underlying
581
582 if u == Typ[Invalid] {
583 return u
584 }
585
586
587
588
589 switch u.(type) {
590 case nil:
591 return Typ[Invalid]
592 default:
593
594 return u
595 case *Named, *instance:
596
597 }
598
599 if n0.check == nil {
600 panic("internal error: Named.check == nil but type is incomplete")
601 }
602
603
604
605 check := n0.check
606
607
608 n := asNamed(u)
609 if n == nil {
610 n0.underlying = Typ[Invalid]
611 return n0.underlying
612 }
613
614
615 seen := map[*Named]int{n0: 0}
616 path := []Object{n0.obj}
617 for {
618 u = n.underlying
619 if u == nil {
620 u = Typ[Invalid]
621 break
622 }
623 var n1 *Named
624 switch u1 := u.(type) {
625 case *Named:
626 n1 = u1
627 case *instance:
628 n1, _ = u1.expand().(*Named)
629 if n1 == nil {
630 u = Typ[Invalid]
631 }
632 }
633 if n1 == nil {
634 break
635 }
636
637 seen[n] = len(seen)
638 path = append(path, n.obj)
639 n = n1
640
641 if i, ok := seen[n]; ok {
642
643 check.cycleError(path[i:])
644 u = Typ[Invalid]
645 break
646 }
647 }
648
649 for n := range seen {
650
651
652
653
654 if n.obj.pkg != check.pkg {
655 panic("internal error: imported type with unresolved underlying type")
656 }
657 n.underlying = u
658 }
659
660 return u
661 }
662
663 func (n *Named) setUnderlying(typ Type) {
664 if n != nil {
665 n.underlying = typ
666 }
667 }
668
669 func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
670 assert(obj.typ == nil)
671
672 check.later(func() {
673 check.validType(obj.typ, nil)
674 })
675
676 alias := tdecl.Assign.IsValid()
677 if alias && typeparams.Get(tdecl) != nil {
678
679
680 check.error(atPos(tdecl.Assign), 0, "generic type cannot be alias")
681 alias = false
682 }
683
684 if alias {
685
686 if !check.allowVersion(check.pkg, 1, 9) {
687 check.errorf(atPos(tdecl.Assign), _BadDecl, "type aliases requires go1.9 or later")
688 }
689
690 obj.typ = Typ[Invalid]
691 obj.typ = check.anyType(tdecl.Type)
692
693 } else {
694
695
696 named := check.newNamed(obj, nil, nil)
697 def.setUnderlying(named)
698 obj.typ = named
699
700 if tparams := typeparams.Get(tdecl); tparams != nil {
701 check.openScope(tdecl, "type parameters")
702 defer check.closeScope()
703 named.tparams = check.collectTypeParams(tparams)
704 }
705
706
707 named.orig = check.definedType(tdecl.Type, named)
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724 named.underlying = under(named)
725 }
726
727 }
728
729 func (check *Checker) collectTypeParams(list *ast.FieldList) (tparams []*TypeName) {
730
731
732 if list.NumFields() == 0 {
733 return
734 }
735
736
737
738
739 for _, f := range list.List {
740 tparams = check.declareTypeParams(tparams, f.Names)
741 }
742
743 setBoundAt := func(at int, bound Type) {
744 assert(IsInterface(bound))
745 tparams[at].typ.(*_TypeParam).bound = bound
746 }
747
748 index := 0
749 var bound Type
750 for _, f := range list.List {
751 if f.Type == nil {
752 goto next
753 }
754
755
756
757
758 if tident, _ := unparen(f.Type).(*ast.Ident); tident != nil && tident.Name == "any" && check.lookup("any") == nil {
759 bound = universeAny
760 } else {
761 bound = check.typ(f.Type)
762 }
763
764
765
766
767
768
769 if _, ok := under(bound).(*Interface); ok {
770
771 for i := range f.Names {
772 setBoundAt(index+i, bound)
773 }
774 } else if bound != Typ[Invalid] {
775 check.errorf(f.Type, _Todo, "%s is not an interface", bound)
776 }
777
778 next:
779 index += len(f.Names)
780 }
781
782 return
783 }
784
785 func (check *Checker) declareTypeParams(tparams []*TypeName, names []*ast.Ident) []*TypeName {
786 for _, name := range names {
787 tpar := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
788 check.newTypeParam(tpar, len(tparams), &emptyInterface)
789 check.declare(check.scope, name, tpar, check.scope.pos)
790 tparams = append(tparams, tpar)
791 }
792
793 if trace && len(names) > 0 {
794 check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):])
795 }
796
797 return tparams
798 }
799
800 func (check *Checker) collectMethods(obj *TypeName) {
801
802
803
804
805 methods := check.methods[obj]
806 if methods == nil {
807 return
808 }
809 delete(check.methods, obj)
810 assert(!check.objMap[obj].tdecl.Assign.IsValid())
811
812
813 var mset objset
814
815
816
817 base := asNamed(obj.typ)
818 if base != nil {
819 if t, _ := base.underlying.(*Struct); t != nil {
820 for _, fld := range t.fields {
821 if fld.name != "_" {
822 assert(mset.insert(fld) == nil)
823 }
824 }
825 }
826
827
828
829
830 for _, m := range base.methods {
831 assert(m.name != "_")
832 assert(mset.insert(m) == nil)
833 }
834 }
835
836
837 for _, m := range methods {
838
839
840 assert(m.name != "_")
841 if alt := mset.insert(m); alt != nil {
842 switch alt.(type) {
843 case *Var:
844 check.errorf(m, _DuplicateFieldAndMethod, "field and method with the same name %s", m.name)
845 case *Func:
846 check.errorf(m, _DuplicateMethod, "method %s already declared for %s", m.name, obj)
847 default:
848 unreachable()
849 }
850 check.reportAltDecl(alt)
851 continue
852 }
853
854 if base != nil {
855 base.methods = append(base.methods, m)
856 }
857 }
858 }
859
860 func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
861 assert(obj.typ == nil)
862
863
864 assert(check.iota == nil)
865
866 sig := new(Signature)
867 obj.typ = sig
868
869
870
871
872
873
874
875 saved := obj.color_
876 obj.color_ = black
877 fdecl := decl.fdecl
878 check.funcType(sig, fdecl.Recv, fdecl.Type)
879 obj.color_ = saved
880
881
882
883 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
884 check.later(func() {
885 check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
886 })
887 }
888 }
889
890 func (check *Checker) declStmt(d ast.Decl) {
891 pkg := check.pkg
892
893 check.walkDecl(d, func(d decl) {
894 switch d := d.(type) {
895 case constDecl:
896 top := len(check.delayed)
897
898
899 lhs := make([]*Const, len(d.spec.Names))
900 for i, name := range d.spec.Names {
901 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota)))
902 lhs[i] = obj
903
904 var init ast.Expr
905 if i < len(d.init) {
906 init = d.init[i]
907 }
908
909 check.constDecl(obj, d.typ, init, d.inherited)
910 }
911
912
913 check.processDelayed(top)
914
915
916
917
918
919 scopePos := d.spec.End()
920 for i, name := range d.spec.Names {
921 check.declare(check.scope, name, lhs[i], scopePos)
922 }
923
924 case varDecl:
925 top := len(check.delayed)
926
927 lhs0 := make([]*Var, len(d.spec.Names))
928 for i, name := range d.spec.Names {
929 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
930 }
931
932
933 for i, obj := range lhs0 {
934 var lhs []*Var
935 var init ast.Expr
936 switch len(d.spec.Values) {
937 case len(d.spec.Names):
938
939 init = d.spec.Values[i]
940 case 1:
941
942 lhs = lhs0
943 init = d.spec.Values[0]
944 default:
945 if i < len(d.spec.Values) {
946 init = d.spec.Values[i]
947 }
948 }
949 check.varDecl(obj, lhs, d.spec.Type, init)
950 if len(d.spec.Values) == 1 {
951
952
953
954
955
956 if debug {
957 for _, obj := range lhs0 {
958 assert(obj.typ != nil)
959 }
960 }
961 break
962 }
963 }
964
965
966 check.processDelayed(top)
967
968
969
970 scopePos := d.spec.End()
971 for i, name := range d.spec.Names {
972
973 check.declare(check.scope, name, lhs0[i], scopePos)
974 }
975
976 case typeDecl:
977 obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
978
979
980
981 scopePos := d.spec.Name.Pos()
982 check.declare(check.scope, d.spec.Name, obj, scopePos)
983
984 obj.setColor(grey + color(check.push(obj)))
985 check.typeDecl(obj, d.spec, nil)
986 check.pop().setColor(black)
987 default:
988 check.invalidAST(d.node(), "unknown ast.Decl node %T", d.node())
989 }
990 })
991 }
992
View as plain text