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/token"
12 . "internal/types/errors"
13 )
14
15 func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
16
17
18
19
20 if obj.Name() != "_" {
21 if alt := scope.Insert(obj); alt != nil {
22 err := check.newError(DuplicateDecl)
23 err.addf(obj, "%s redeclared in this block", obj.Name())
24 err.addAltDecl(alt)
25 err.report()
26 return
27 }
28 obj.setScopePos(pos)
29 }
30 if id != nil {
31 check.recordDef(id, obj)
32 }
33 }
34
35
36 func pathString(path []Object) string {
37 var s string
38 for i, p := range path {
39 if i > 0 {
40 s += "->"
41 }
42 s += p.Name()
43 }
44 return s
45 }
46
47
48
49 func (check *Checker) objDecl(obj Object, def *TypeName) {
50 if check.conf._Trace && obj.Type() == nil {
51 if check.indent == 0 {
52 fmt.Println()
53 }
54 check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath))
55 check.indent++
56 defer func() {
57 check.indent--
58 check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color())
59 }()
60 }
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 if obj.color() == white && obj.Type() != nil {
90 obj.setColor(black)
91 return
92 }
93
94 switch obj.color() {
95 case white:
96 assert(obj.Type() == nil)
97
98
99
100 obj.setColor(grey + color(check.push(obj)))
101 defer func() {
102 check.pop().setColor(black)
103 }()
104
105 case black:
106 assert(obj.Type() != nil)
107 return
108
109 default:
110
111 fallthrough
112
113 case grey:
114
115
116
117
118
119
120
121
122
123
124 switch obj := obj.(type) {
125 case *Const:
126 if !check.validCycle(obj) || obj.typ == nil {
127 obj.typ = Typ[Invalid]
128 }
129
130 case *Var:
131 if !check.validCycle(obj) || obj.typ == nil {
132 obj.typ = Typ[Invalid]
133 }
134
135 case *TypeName:
136 if !check.validCycle(obj) {
137
138
139
140
141
142 obj.typ = Typ[Invalid]
143 }
144
145 case *Func:
146 if !check.validCycle(obj) {
147
148
149
150
151
152
153 }
154
155 default:
156 panic("unreachable")
157 }
158 assert(obj.Type() != nil)
159 return
160 }
161
162 d := check.objMap[obj]
163 if d == nil {
164 check.dump("%v: %s should have been declared", obj.Pos(), obj)
165 panic("unreachable")
166 }
167
168
169 defer func(env environment) {
170 check.environment = env
171 }(check.environment)
172 check.environment = environment{
173 scope: d.file,
174 }
175
176
177
178
179
180
181 switch obj := obj.(type) {
182 case *Const:
183 check.decl = d
184 check.constDecl(obj, d.vtyp, d.init, d.inherited)
185 case *Var:
186 check.decl = d
187 check.varDecl(obj, d.lhs, d.vtyp, d.init)
188 case *TypeName:
189
190 check.typeDecl(obj, d.tdecl, def)
191 check.collectMethods(obj)
192 case *Func:
193
194 check.funcDecl(obj, d)
195 default:
196 panic("unreachable")
197 }
198 }
199
200
201
202 func (check *Checker) validCycle(obj Object) (valid bool) {
203
204 if debug {
205 info := check.objMap[obj]
206 inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil)
207 isPkgObj := obj.Parent() == check.pkg.scope
208 if isPkgObj != inObjMap {
209 check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap)
210 panic("unreachable")
211 }
212 }
213
214
215 assert(obj.color() >= grey)
216 start := obj.color() - grey
217 cycle := check.objPath[start:]
218 tparCycle := false
219 nval := 0
220 ndef := 0
221 loop:
222 for _, obj := range cycle {
223 switch obj := obj.(type) {
224 case *Const, *Var:
225 nval++
226 case *TypeName:
227
228
229
230 if check.inTParamList && isGeneric(obj.typ) {
231 tparCycle = true
232 break loop
233 }
234
235
236
237
238
239
240
241
242
243
244 var alias bool
245 if check.conf._EnableAlias {
246 alias = obj.IsAlias()
247 } else {
248 if d := check.objMap[obj]; d != nil {
249 alias = d.tdecl.Assign.IsValid()
250 } else {
251 alias = obj.IsAlias()
252 }
253 }
254 if !alias {
255 ndef++
256 }
257 case *Func:
258
259 default:
260 panic("unreachable")
261 }
262 }
263
264 if check.conf._Trace {
265 check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle))
266 if tparCycle {
267 check.trace(obj.Pos(), "## cycle contains: generic type in a type parameter list")
268 } else {
269 check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef)
270 }
271 defer func() {
272 if valid {
273 check.trace(obj.Pos(), "=> cycle is valid")
274 } else {
275 check.trace(obj.Pos(), "=> error: cycle is invalid")
276 }
277 }()
278 }
279
280 if !tparCycle {
281
282
283
284 if nval == len(cycle) {
285 return true
286 }
287
288
289
290
291 if nval == 0 && ndef > 0 {
292 return true
293 }
294 }
295
296 check.cycleError(cycle, firstInSrc(cycle))
297 return false
298 }
299
300
301 func (check *Checker) cycleError(cycle []Object, start int) {
302
303
304
305
306 name := func(obj Object) string {
307 return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name()
308 }
309
310 obj := cycle[start]
311 objName := name(obj)
312
313 tname, _ := obj.(*TypeName)
314 if tname != nil && tname.IsAlias() {
315
316
317 if !check.conf._EnableAlias {
318 check.validAlias(tname, Typ[Invalid])
319 }
320 }
321
322
323 if len(cycle) == 1 {
324 if tname != nil {
325 check.errorf(obj, InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName)
326 } else {
327 check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName)
328 }
329 return
330 }
331
332 err := check.newError(InvalidDeclCycle)
333 if tname != nil {
334 err.addf(obj, "invalid recursive type %s", objName)
335 } else {
336 err.addf(obj, "invalid cycle in declaration of %s", objName)
337 }
338 i := start
339 for range cycle {
340 err.addf(obj, "%s refers to", objName)
341 i++
342 if i >= len(cycle) {
343 i = 0
344 }
345 obj = cycle[i]
346 objName = name(obj)
347 }
348 err.addf(obj, "%s", objName)
349 err.report()
350 }
351
352
353
354 func firstInSrc(path []Object) int {
355 fst, pos := 0, path[0].Pos()
356 for i, t := range path[1:] {
357 if cmpPos(t.Pos(), pos) < 0 {
358 fst, pos = i+1, t.Pos()
359 }
360 }
361 return fst
362 }
363
364 type (
365 decl interface {
366 node() ast.Node
367 }
368
369 importDecl struct{ spec *ast.ImportSpec }
370 constDecl struct {
371 spec *ast.ValueSpec
372 iota int
373 typ ast.Expr
374 init []ast.Expr
375 inherited bool
376 }
377 varDecl struct{ spec *ast.ValueSpec }
378 typeDecl struct{ spec *ast.TypeSpec }
379 funcDecl struct{ decl *ast.FuncDecl }
380 )
381
382 func (d importDecl) node() ast.Node { return d.spec }
383 func (d constDecl) node() ast.Node { return d.spec }
384 func (d varDecl) node() ast.Node { return d.spec }
385 func (d typeDecl) node() ast.Node { return d.spec }
386 func (d funcDecl) node() ast.Node { return d.decl }
387
388 func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) {
389 for _, d := range decls {
390 check.walkDecl(d, f)
391 }
392 }
393
394 func (check *Checker) walkDecl(d ast.Decl, f func(decl)) {
395 switch d := d.(type) {
396 case *ast.BadDecl:
397
398 case *ast.GenDecl:
399 var last *ast.ValueSpec
400 for iota, s := range d.Specs {
401 switch s := s.(type) {
402 case *ast.ImportSpec:
403 f(importDecl{s})
404 case *ast.ValueSpec:
405 switch d.Tok {
406 case token.CONST:
407
408 inherited := true
409 switch {
410 case s.Type != nil || len(s.Values) > 0:
411 last = s
412 inherited = false
413 case last == nil:
414 last = new(ast.ValueSpec)
415 inherited = false
416 }
417 check.arityMatch(s, last)
418 f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited})
419 case token.VAR:
420 check.arityMatch(s, nil)
421 f(varDecl{s})
422 default:
423 check.errorf(s, InvalidSyntaxTree, "invalid token %s", d.Tok)
424 }
425 case *ast.TypeSpec:
426 f(typeDecl{s})
427 default:
428 check.errorf(s, InvalidSyntaxTree, "unknown ast.Spec node %T", s)
429 }
430 }
431 case *ast.FuncDecl:
432 f(funcDecl{d})
433 default:
434 check.errorf(d, InvalidSyntaxTree, "unknown ast.Decl node %T", d)
435 }
436 }
437
438 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) {
439 assert(obj.typ == nil)
440
441
442 defer func(iota constant.Value, errpos positioner) {
443 check.iota = iota
444 check.errpos = errpos
445 }(check.iota, check.errpos)
446 check.iota = obj.val
447 check.errpos = nil
448
449
450 obj.val = constant.MakeUnknown()
451
452
453 if typ != nil {
454 t := check.typ(typ)
455 if !isConstType(t) {
456
457
458 if isValid(under(t)) {
459 check.errorf(typ, InvalidConstType, "invalid constant type %s", t)
460 }
461 obj.typ = Typ[Invalid]
462 return
463 }
464 obj.typ = t
465 }
466
467
468 var x operand
469 if init != nil {
470 if inherited {
471
472
473
474
475
476
477 check.errpos = atPos(obj.pos)
478 }
479 check.expr(nil, &x, init)
480 }
481 check.initConst(obj, &x)
482 }
483
484 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
485 assert(obj.typ == nil)
486
487
488 if typ != nil {
489 obj.typ = check.varType(typ)
490
491
492
493
494
495
496
497
498 }
499
500
501 if init == nil {
502 if typ == nil {
503
504 obj.typ = Typ[Invalid]
505 }
506 return
507 }
508
509 if lhs == nil || len(lhs) == 1 {
510 assert(lhs == nil || lhs[0] == obj)
511 var x operand
512 check.expr(newTarget(obj.typ, obj.name), &x, init)
513 check.initVar(obj, &x, "variable declaration")
514 return
515 }
516
517 if debug {
518
519 found := false
520 for _, lhs := range lhs {
521 if obj == lhs {
522 found = true
523 break
524 }
525 }
526 if !found {
527 panic("inconsistent lhs")
528 }
529 }
530
531
532
533
534
535 if typ != nil {
536 for _, lhs := range lhs {
537 lhs.typ = obj.typ
538 }
539 }
540
541 check.initVars(lhs, []ast.Expr{init}, nil)
542 }
543
544
545 func (check *Checker) isImportedConstraint(typ Type) bool {
546 named := asNamed(typ)
547 if named == nil || named.obj.pkg == check.pkg || named.obj.pkg == nil {
548 return false
549 }
550 u, _ := named.under().(*Interface)
551 return u != nil && !u.IsMethodSet()
552 }
553
554 func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *TypeName) {
555 assert(obj.typ == nil)
556
557
558 versionErr := false
559
560 var rhs Type
561 check.later(func() {
562 if t := asNamed(obj.typ); t != nil {
563 check.validType(t)
564 }
565
566 _ = !versionErr && check.isImportedConstraint(rhs) && check.verifyVersionf(tdecl.Type, go1_18, "using type constraint %s", rhs)
567 }).describef(obj, "validType(%s)", obj.Name())
568
569
570 var tparam0 *ast.Field
571 if tdecl.TypeParams.NumFields() > 0 {
572 tparam0 = tdecl.TypeParams.List[0]
573 }
574
575
576 if tdecl.Assign.IsValid() {
577
578
579 if !versionErr && tparam0 != nil && !check.verifyVersionf(tparam0, go1_23, "generic type alias") {
580 versionErr = true
581 }
582 if !versionErr && !check.verifyVersionf(atPos(tdecl.Assign), go1_9, "type alias") {
583 versionErr = true
584 }
585
586 if check.conf._EnableAlias {
587
588
589
590
591
592
593
594
595 alias := check.newAlias(obj, Typ[Invalid])
596 setDefType(def, alias)
597
598
599 if tparam0 != nil {
600 check.openScope(tdecl, "type parameters")
601 defer check.closeScope()
602 check.collectTypeParams(&alias.tparams, tdecl.TypeParams)
603 }
604
605 rhs = check.definedType(tdecl.Type, obj)
606 assert(rhs != nil)
607 alias.fromRHS = rhs
608 Unalias(alias)
609 } else {
610
611
612
613
614
615 gotypesalias.IncNonDefault()
616
617 if !versionErr && tparam0 != nil {
618 check.error(tdecl, UnsupportedFeature, "generic type alias requires GODEBUG=gotypesalias=1 or unset")
619 versionErr = true
620 }
621
622 check.brokenAlias(obj)
623 rhs = check.typ(tdecl.Type)
624 check.validAlias(obj, rhs)
625 }
626 return
627 }
628
629
630 if !versionErr && tparam0 != nil && !check.verifyVersionf(tparam0, go1_18, "type parameter") {
631 versionErr = true
632 }
633
634 named := check.newNamed(obj, nil, nil)
635 setDefType(def, named)
636
637 if tdecl.TypeParams != nil {
638 check.openScope(tdecl, "type parameters")
639 defer check.closeScope()
640 check.collectTypeParams(&named.tparams, tdecl.TypeParams)
641 }
642
643
644 rhs = check.definedType(tdecl.Type, obj)
645 assert(rhs != nil)
646 named.fromRHS = rhs
647
648
649
650 if named.underlying == nil {
651 named.underlying = Typ[Invalid]
652 }
653
654
655
656
657
658
659 if isTypeParam(rhs) {
660 check.error(tdecl.Type, MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
661 named.underlying = Typ[Invalid]
662 }
663 }
664
665 func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList) {
666 var tparams []*TypeParam
667
668
669
670 scopePos := list.Pos()
671 for _, f := range list.List {
672 tparams = check.declareTypeParams(tparams, f.Names, scopePos)
673 }
674
675
676
677
678 *dst = bindTParams(tparams)
679
680
681
682
683
684
685
686
687 assert(!check.inTParamList)
688 check.inTParamList = true
689 defer func() {
690 check.inTParamList = false
691 }()
692
693 index := 0
694 for _, f := range list.List {
695 var bound Type
696
697
698 if f.Type != nil {
699 bound = check.bound(f.Type)
700 if isTypeParam(bound) {
701
702
703
704
705 check.error(f.Type, MisplacedTypeParam, "cannot use a type parameter as constraint")
706 bound = Typ[Invalid]
707 }
708 } else {
709 bound = Typ[Invalid]
710 }
711 for i := range f.Names {
712 tparams[index+i].bound = bound
713 }
714 index += len(f.Names)
715 }
716 }
717
718 func (check *Checker) bound(x ast.Expr) Type {
719
720
721
722 wrap := false
723 switch op := x.(type) {
724 case *ast.UnaryExpr:
725 wrap = op.Op == token.TILDE
726 case *ast.BinaryExpr:
727 wrap = op.Op == token.OR
728 }
729 if wrap {
730 x = &ast.InterfaceType{Methods: &ast.FieldList{List: []*ast.Field{{Type: x}}}}
731 t := check.typ(x)
732
733 if t, _ := t.(*Interface); t != nil {
734 t.implicit = true
735 }
736 return t
737 }
738 return check.typ(x)
739 }
740
741 func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident, scopePos token.Pos) []*TypeParam {
742
743
744
745
746
747
748 for _, name := range names {
749 tname := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
750 tpar := check.newTypeParam(tname, Typ[Invalid])
751 check.declare(check.scope, name, tname, scopePos)
752 tparams = append(tparams, tpar)
753 }
754
755 if check.conf._Trace && len(names) > 0 {
756 check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):])
757 }
758
759 return tparams
760 }
761
762 func (check *Checker) collectMethods(obj *TypeName) {
763
764
765
766
767 methods := check.methods[obj]
768 if methods == nil {
769 return
770 }
771 delete(check.methods, obj)
772 assert(!check.objMap[obj].tdecl.Assign.IsValid())
773
774
775 var mset objset
776
777
778
779 base := asNamed(obj.typ)
780 if base != nil {
781 assert(base.TypeArgs().Len() == 0)
782
783
784
785 check.later(func() {
786 check.checkFieldUniqueness(base)
787 }).describef(obj, "verifying field uniqueness for %v", base)
788
789
790
791
792 for i := 0; i < base.NumMethods(); i++ {
793 m := base.Method(i)
794 assert(m.name != "_")
795 assert(mset.insert(m) == nil)
796 }
797 }
798
799
800 for _, m := range methods {
801
802
803 assert(m.name != "_")
804 if alt := mset.insert(m); alt != nil {
805 if alt.Pos().IsValid() {
806 check.errorf(m, DuplicateMethod, "method %s.%s already declared at %v", obj.Name(), m.name, alt.Pos())
807 } else {
808 check.errorf(m, DuplicateMethod, "method %s.%s already declared", obj.Name(), m.name)
809 }
810 continue
811 }
812
813 if base != nil {
814 base.AddMethod(m)
815 }
816 }
817 }
818
819 func (check *Checker) checkFieldUniqueness(base *Named) {
820 if t, _ := base.under().(*Struct); t != nil {
821 var mset objset
822 for i := 0; i < base.NumMethods(); i++ {
823 m := base.Method(i)
824 assert(m.name != "_")
825 assert(mset.insert(m) == nil)
826 }
827
828
829
830 for _, fld := range t.fields {
831 if fld.name != "_" {
832 if alt := mset.insert(fld); alt != nil {
833
834
835 _ = alt.(*Func)
836
837
838
839 err := check.newError(DuplicateFieldAndMethod)
840 err.addf(alt, "field and method with the same name %s", quote(fld.name))
841 err.addAltDecl(fld)
842 err.report()
843 }
844 }
845 }
846 }
847 }
848
849 func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
850 assert(obj.typ == nil)
851
852
853 assert(check.iota == nil)
854
855 sig := new(Signature)
856 obj.typ = sig
857
858
859
860
861
862
863
864 saved := obj.color_
865 obj.color_ = black
866 fdecl := decl.fdecl
867 check.funcType(sig, fdecl.Recv, fdecl.Type)
868 obj.color_ = saved
869
870
871
872 sig.scope.pos = fdecl.Pos()
873 sig.scope.end = fdecl.End()
874
875 if fdecl.Type.TypeParams.NumFields() > 0 && fdecl.Body == nil {
876 check.softErrorf(fdecl.Name, BadDecl, "generic function is missing function body")
877 }
878
879
880
881 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
882 check.later(func() {
883 check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
884 }).describef(obj, "func %s", obj.name)
885 }
886 }
887
888 func (check *Checker) declStmt(d ast.Decl) {
889 pkg := check.pkg
890
891 check.walkDecl(d, func(d decl) {
892 switch d := d.(type) {
893 case constDecl:
894 top := len(check.delayed)
895
896
897 lhs := make([]*Const, len(d.spec.Names))
898 for i, name := range d.spec.Names {
899 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota)))
900 lhs[i] = obj
901
902 var init ast.Expr
903 if i < len(d.init) {
904 init = d.init[i]
905 }
906
907 check.constDecl(obj, d.typ, init, d.inherited)
908 }
909
910
911 check.processDelayed(top)
912
913
914
915
916
917 scopePos := d.spec.End()
918 for i, name := range d.spec.Names {
919 check.declare(check.scope, name, lhs[i], scopePos)
920 }
921
922 case varDecl:
923 top := len(check.delayed)
924
925 lhs0 := make([]*Var, len(d.spec.Names))
926 for i, name := range d.spec.Names {
927 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
928 }
929
930
931 for i, obj := range lhs0 {
932 var lhs []*Var
933 var init ast.Expr
934 switch len(d.spec.Values) {
935 case len(d.spec.Names):
936
937 init = d.spec.Values[i]
938 case 1:
939
940 lhs = lhs0
941 init = d.spec.Values[0]
942 default:
943 if i < len(d.spec.Values) {
944 init = d.spec.Values[i]
945 }
946 }
947 check.varDecl(obj, lhs, d.spec.Type, init)
948 if len(d.spec.Values) == 1 {
949
950
951
952
953
954 if debug {
955 for _, obj := range lhs0 {
956 assert(obj.typ != nil)
957 }
958 }
959 break
960 }
961 }
962
963
964 check.processDelayed(top)
965
966
967
968 scopePos := d.spec.End()
969 for i, name := range d.spec.Names {
970
971 check.declare(check.scope, name, lhs0[i], scopePos)
972 }
973
974 case typeDecl:
975 obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
976
977
978
979 scopePos := d.spec.Name.Pos()
980 check.declare(check.scope, d.spec.Name, obj, scopePos)
981
982 obj.setColor(grey + color(check.push(obj)))
983 check.typeDecl(obj, d.spec, nil)
984 check.pop().setColor(black)
985 default:
986 check.errorf(d.node(), InvalidSyntaxTree, "unknown ast.Decl node %T", d.node())
987 }
988 })
989 }
990
View as plain text