1
2
3
4
5 package types2
6
7 import (
8 "cmd/compile/internal/syntax"
9 "fmt"
10 "go/constant"
11 )
12
13 func (err *error_) recordAltDecl(obj Object) {
14 if pos := obj.Pos(); pos.IsKnown() {
15
16
17
18 err.errorf(pos, "other declaration of %s", obj.Name())
19 }
20 }
21
22 func (check *Checker) declare(scope *Scope, id *syntax.Name, obj Object, pos syntax.Pos) {
23
24
25
26
27 if obj.Name() != "_" {
28 if alt := scope.Insert(obj); alt != nil {
29 var err error_
30 err.errorf(obj, "%s redeclared in this block", obj.Name())
31 err.recordAltDecl(alt)
32 check.report(&err)
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 check.conf.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.Alias
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 check.conf.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 i := firstInSrc(cycle)
310 obj := cycle[i]
311
312 tname, _ := obj.(*TypeName)
313 if tname != nil && tname.IsAlias() {
314 check.validAlias(tname, Typ[Invalid])
315 }
316 var err error_
317 if tname != nil && check.conf.CompilerErrorMessages {
318 err.errorf(obj, "invalid recursive type %s", obj.Name())
319 } else {
320 err.errorf(obj, "illegal cycle in declaration of %s", obj.Name())
321 }
322 for range cycle {
323 err.errorf(obj, "%s refers to", obj.Name())
324 i++
325 if i >= len(cycle) {
326 i = 0
327 }
328 obj = cycle[i]
329 }
330 err.errorf(obj, "%s", obj.Name())
331 check.report(&err)
332 }
333
334
335
336 func firstInSrc(path []Object) int {
337 fst, pos := 0, path[0].Pos()
338 for i, t := range path[1:] {
339 if t.Pos().Cmp(pos) < 0 {
340 fst, pos = i+1, t.Pos()
341 }
342 }
343 return fst
344 }
345
346 func (check *Checker) constDecl(obj *Const, typ, init syntax.Expr, inherited bool) {
347 assert(obj.typ == nil)
348
349
350 defer func(iota constant.Value, errpos syntax.Pos) {
351 check.iota = iota
352 check.errpos = errpos
353 }(check.iota, check.errpos)
354 check.iota = obj.val
355 check.errpos = nopos
356
357
358 obj.val = constant.MakeUnknown()
359
360
361 if typ != nil {
362 t := check.typ(typ)
363 if !isConstType(t) {
364
365
366 if under(t) != Typ[Invalid] {
367 check.errorf(typ, "invalid constant type %s", t)
368 }
369 obj.typ = Typ[Invalid]
370 return
371 }
372 obj.typ = t
373 }
374
375
376 var x operand
377 if init != nil {
378 if inherited {
379
380
381
382
383
384
385 check.errpos = obj.pos
386 }
387 check.expr(&x, init)
388 }
389 check.initConst(obj, &x)
390 }
391
392 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init syntax.Expr) {
393 assert(obj.typ == nil)
394
395
396
397
398 defer func() {
399 if obj.typ == Typ[Invalid] {
400 obj.used = true
401 }
402 for _, lhs := range lhs {
403 if lhs.typ == Typ[Invalid] {
404 lhs.used = true
405 }
406 }
407 }()
408
409
410 if typ != nil {
411 obj.typ = check.varType(typ)
412
413
414
415
416
417
418
419
420 }
421
422
423 if init == nil {
424 if typ == nil {
425
426 obj.typ = Typ[Invalid]
427 }
428 return
429 }
430
431 if lhs == nil || len(lhs) == 1 {
432 assert(lhs == nil || lhs[0] == obj)
433 var x operand
434 check.expr(&x, init)
435 check.initVar(obj, &x, "variable declaration")
436 return
437 }
438
439 if debug {
440
441 found := false
442 for _, lhs := range lhs {
443 if obj == lhs {
444 found = true
445 break
446 }
447 }
448 if !found {
449 panic("inconsistent lhs")
450 }
451 }
452
453
454
455
456
457 if typ != nil {
458 for _, lhs := range lhs {
459 lhs.typ = obj.typ
460 }
461 }
462
463 check.initVars(lhs, []syntax.Expr{init}, nil)
464 }
465
466
467 func (check *Checker) isImportedConstraint(typ Type) bool {
468 named, _ := typ.(*Named)
469 if named == nil || named.obj.pkg == check.pkg || named.obj.pkg == nil {
470 return false
471 }
472 u, _ := named.under().(*Interface)
473 return u != nil && !u.IsMethodSet()
474 }
475
476 func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named) {
477 assert(obj.typ == nil)
478
479 var rhs Type
480 check.later(func() {
481 if t, _ := obj.typ.(*Named); t != nil {
482 check.validType(t)
483 }
484
485 if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) {
486 check.versionErrorf(tdecl.Type, "go1.18", "using type constraint %s", rhs)
487 }
488 }).describef(obj, "validType(%s)", obj.Name())
489
490 alias := tdecl.Alias
491 if alias && tdecl.TParamList != nil {
492
493
494 check.error(tdecl, "generic type cannot be alias")
495 alias = false
496 }
497
498
499 if alias {
500 if !check.allowVersion(check.pkg, 1, 9) {
501 check.versionErrorf(tdecl, "go1.9", "type aliases")
502 }
503
504 check.brokenAlias(obj)
505 rhs = check.varType(tdecl.Type)
506 check.validAlias(obj, rhs)
507 return
508 }
509
510
511 named := check.newNamed(obj, nil, nil, nil, nil)
512 def.setUnderlying(named)
513
514 if tdecl.TParamList != nil {
515 check.openScope(tdecl, "type parameters")
516 defer check.closeScope()
517 check.collectTypeParams(&named.tparams, tdecl.TParamList)
518 }
519
520
521 rhs = check.definedType(tdecl.Type, named)
522 assert(rhs != nil)
523 named.fromRHS = rhs
524
525
526
527 if named.underlying == nil {
528 named.underlying = Typ[Invalid]
529 }
530
531
532
533
534
535
536 if isTypeParam(rhs) {
537 check.error(tdecl.Type, "cannot use a type parameter as RHS in type declaration")
538 named.underlying = Typ[Invalid]
539 }
540 }
541
542 func (check *Checker) collectTypeParams(dst **TypeParamList, list []*syntax.Field) {
543 tparams := make([]*TypeParam, len(list))
544
545
546
547
548 for i, f := range list {
549 tparams[i] = check.declareTypeParam(f.Name)
550 }
551
552
553
554
555 *dst = bindTParams(tparams)
556
557
558
559
560
561
562
563
564 assert(!check.inTParamList)
565 check.inTParamList = true
566 defer func() {
567 check.inTParamList = false
568 }()
569
570
571 var bound Type
572 for i, f := range list {
573
574
575
576 if i == 0 || f.Type != list[i-1].Type {
577 bound = check.bound(f.Type)
578 if isTypeParam(bound) {
579
580
581
582
583 check.error(f.Type, "cannot use a type parameter as constraint")
584 bound = Typ[Invalid]
585 }
586 }
587 tparams[i].bound = bound
588 }
589 }
590
591 func (check *Checker) bound(x syntax.Expr) Type {
592
593
594
595 if op, _ := x.(*syntax.Operation); op != nil && (op.Op == syntax.Tilde || op.Op == syntax.Or) {
596 t := check.typ(&syntax.InterfaceType{MethodList: []*syntax.Field{{Type: x}}})
597
598 if t, _ := t.(*Interface); t != nil {
599 t.implicit = true
600 }
601 return t
602 }
603 return check.typ(x)
604 }
605
606 func (check *Checker) declareTypeParam(name *syntax.Name) *TypeParam {
607
608
609
610
611
612
613 tname := NewTypeName(name.Pos(), check.pkg, name.Value, nil)
614 tpar := check.newTypeParam(tname, Typ[Invalid])
615 check.declare(check.scope, name, tname, check.scope.pos)
616 return tpar
617 }
618
619 func (check *Checker) collectMethods(obj *TypeName) {
620
621
622
623
624 methods := check.methods[obj]
625 if methods == nil {
626 return
627 }
628 delete(check.methods, obj)
629 assert(!check.objMap[obj].tdecl.Alias)
630
631
632 var mset objset
633
634
635
636 base, _ := obj.typ.(*Named)
637 if base != nil {
638 assert(base.targs.Len() == 0)
639
640
641
642 check.later(func() {
643 check.checkFieldUniqueness(base)
644 }).describef(obj, "verifying field uniqueness for %v", base)
645
646
647
648
649 for i := 0; i < base.methods.Len(); i++ {
650 m := base.methods.At(i, nil)
651 assert(m.name != "_")
652 assert(mset.insert(m) == nil)
653 }
654 }
655
656
657 for _, m := range methods {
658
659
660 assert(m.name != "_")
661 if alt := mset.insert(m); alt != nil {
662 var err error_
663 if check.conf.CompilerErrorMessages {
664 err.errorf(m.pos, "%s.%s redeclared in this block", obj.Name(), m.name)
665 } else {
666 err.errorf(m.pos, "method %s already declared for %s", m.name, obj)
667 }
668 err.recordAltDecl(alt)
669 check.report(&err)
670 continue
671 }
672
673 if base != nil {
674 base.resolve(nil)
675 base.AddMethod(m)
676 }
677 }
678 }
679
680 func (check *Checker) checkFieldUniqueness(base *Named) {
681 if t, _ := base.under().(*Struct); t != nil {
682 var mset objset
683 for i := 0; i < base.methods.Len(); i++ {
684 m := base.methods.At(i, nil)
685 assert(m.name != "_")
686 assert(mset.insert(m) == nil)
687 }
688
689
690
691 for _, fld := range t.fields {
692 if fld.name != "_" {
693 if alt := mset.insert(fld); alt != nil {
694
695
696 _ = alt.(*Func)
697
698
699
700 var err error_
701 err.errorf(alt, "field and method with the same name %s", fld.name)
702 err.recordAltDecl(fld)
703 check.report(&err)
704 }
705 }
706 }
707 }
708 }
709
710 func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
711 assert(obj.typ == nil)
712
713
714 assert(check.iota == nil)
715
716 sig := new(Signature)
717 obj.typ = sig
718
719
720
721
722
723
724
725 saved := obj.color_
726 obj.color_ = black
727 fdecl := decl.fdecl
728 check.funcType(sig, fdecl.Recv, fdecl.TParamList, fdecl.Type)
729 obj.color_ = saved
730
731 if len(fdecl.TParamList) > 0 && fdecl.Body == nil {
732 check.softErrorf(fdecl, "parameterized function is missing function body")
733 }
734
735
736
737 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
738 check.later(func() {
739 check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
740 })
741 }
742 }
743
744 func (check *Checker) declStmt(list []syntax.Decl) {
745 pkg := check.pkg
746
747 first := -1
748 var last *syntax.ConstDecl
749 for index, decl := range list {
750 if _, ok := decl.(*syntax.ConstDecl); !ok {
751 first = -1
752 }
753
754 switch s := decl.(type) {
755 case *syntax.ConstDecl:
756 top := len(check.delayed)
757
758
759 if first < 0 || s.Group == nil || list[index-1].(*syntax.ConstDecl).Group != s.Group {
760 first = index
761 last = nil
762 }
763 iota := constant.MakeInt64(int64(index - first))
764
765
766 inherited := true
767 switch {
768 case s.Type != nil || s.Values != nil:
769 last = s
770 inherited = false
771 case last == nil:
772 last = new(syntax.ConstDecl)
773 inherited = false
774 }
775
776
777 lhs := make([]*Const, len(s.NameList))
778 values := unpackExpr(last.Values)
779 for i, name := range s.NameList {
780 obj := NewConst(name.Pos(), pkg, name.Value, nil, iota)
781 lhs[i] = obj
782
783 var init syntax.Expr
784 if i < len(values) {
785 init = values[i]
786 }
787
788 check.constDecl(obj, last.Type, init, inherited)
789 }
790
791
792 check.arity(s.Pos(), s.NameList, values, true, inherited)
793
794
795 check.processDelayed(top)
796
797
798
799
800
801 scopePos := syntax.EndPos(s)
802 for i, name := range s.NameList {
803 check.declare(check.scope, name, lhs[i], scopePos)
804 }
805
806 case *syntax.VarDecl:
807 top := len(check.delayed)
808
809 lhs0 := make([]*Var, len(s.NameList))
810 for i, name := range s.NameList {
811 lhs0[i] = NewVar(name.Pos(), pkg, name.Value, nil)
812 }
813
814
815 values := unpackExpr(s.Values)
816 for i, obj := range lhs0 {
817 var lhs []*Var
818 var init syntax.Expr
819 switch len(values) {
820 case len(s.NameList):
821
822 init = values[i]
823 case 1:
824
825 lhs = lhs0
826 init = values[0]
827 default:
828 if i < len(values) {
829 init = values[i]
830 }
831 }
832 check.varDecl(obj, lhs, s.Type, init)
833 if len(values) == 1 {
834
835
836
837
838
839 if debug {
840 for _, obj := range lhs0 {
841 assert(obj.typ != nil)
842 }
843 }
844 break
845 }
846 }
847
848
849 if s.Type == nil || values != nil {
850 check.arity(s.Pos(), s.NameList, values, false, false)
851 }
852
853
854 check.processDelayed(top)
855
856
857
858 scopePos := syntax.EndPos(s)
859 for i, name := range s.NameList {
860
861 check.declare(check.scope, name, lhs0[i], scopePos)
862 }
863
864 case *syntax.TypeDecl:
865 obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Value, nil)
866
867
868
869 scopePos := s.Name.Pos()
870 check.declare(check.scope, s.Name, obj, scopePos)
871
872 obj.setColor(grey + color(check.push(obj)))
873 check.typeDecl(obj, s, nil)
874 check.pop().setColor(black)
875
876 default:
877 check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
878 }
879 }
880 }
881
View as plain text