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