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