Source file
src/go/types/typexpr.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "fmt"
11 "go/ast"
12 "go/constant"
13 "go/internal/typeparams"
14 "go/token"
15 "sort"
16 "strconv"
17 "strings"
18 )
19
20
21
22
23
24
25 func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
26 x.mode = invalid
27 x.expr = e
28
29
30
31 scope, obj := check.scope.LookupParent(e.Name, check.pos)
32 if obj == nil {
33 if e.Name == "_" {
34 check.errorf(e, _InvalidBlank, "cannot use _ as value or type")
35 } else {
36 check.errorf(e, _UndeclaredName, "undeclared name: %s", e.Name)
37 }
38 return
39 }
40 check.recordUse(e, obj)
41
42
43
44
45
46
47
48
49
50 typ := obj.Type()
51 if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
52 check.objDecl(obj, def)
53 typ = obj.Type()
54 }
55 assert(typ != nil)
56
57
58
59
60
61 if pkgName := check.dotImportMap[dotImportKey{scope, obj}]; pkgName != nil {
62 pkgName.used = true
63 }
64
65 switch obj := obj.(type) {
66 case *PkgName:
67 check.errorf(e, _InvalidPkgUse, "use of package %s not in selector", obj.name)
68 return
69
70 case *Const:
71 check.addDeclDep(obj)
72 if typ == Typ[Invalid] {
73 return
74 }
75 if obj == universeIota {
76 if check.iota == nil {
77 check.errorf(e, _InvalidIota, "cannot use iota outside constant declaration")
78 return
79 }
80 x.val = check.iota
81 } else {
82 x.val = obj.val
83 }
84 assert(x.val != nil)
85 x.mode = constant_
86
87 case *TypeName:
88 x.mode = typexpr
89
90 case *Var:
91
92
93
94 if obj.pkg == check.pkg {
95 obj.used = true
96 }
97 check.addDeclDep(obj)
98 if typ == Typ[Invalid] {
99 return
100 }
101 x.mode = variable
102
103 case *Func:
104 check.addDeclDep(obj)
105 x.mode = value
106
107 case *Builtin:
108 x.id = obj.id
109 x.mode = builtin
110
111 case *Nil:
112 x.mode = value
113
114 default:
115 unreachable()
116 }
117
118 x.typ = typ
119 }
120
121
122
123 func (check *Checker) typ(e ast.Expr) Type {
124 return check.definedType(e, nil)
125 }
126
127
128
129
130 func (check *Checker) varType(e ast.Expr) Type {
131 typ := check.definedType(e, nil)
132 check.ordinaryType(e, typ)
133 return typ
134 }
135
136
137
138 func (check *Checker) ordinaryType(pos positioner, typ Type) {
139
140
141
142
143 check.later(func() {
144 if t := asInterface(typ); t != nil {
145 check.completeInterface(pos.Pos(), t)
146 if t.allTypes != nil {
147 check.softErrorf(pos, _Todo, "interface contains type constraints (%s)", t.allTypes)
148 return
149 }
150 if t._IsComparable() {
151 check.softErrorf(pos, _Todo, "interface is (or embeds) comparable")
152 }
153 }
154 })
155 }
156
157
158
159 func (check *Checker) anyType(e ast.Expr) Type {
160 typ := check.typInternal(e, nil)
161 assert(isTyped(typ))
162 check.recordTypeAndValue(e, typexpr, typ, nil)
163 return typ
164 }
165
166
167
168
169
170
171 func (check *Checker) definedType(e ast.Expr, def *Named) Type {
172 typ := check.typInternal(e, def)
173 assert(isTyped(typ))
174 if isGeneric(typ) {
175 check.errorf(e, _Todo, "cannot use generic type %s without instantiation", typ)
176 typ = Typ[Invalid]
177 }
178 check.recordTypeAndValue(e, typexpr, typ, nil)
179 return typ
180 }
181
182
183 func (check *Checker) genericType(e ast.Expr, reportErr bool) Type {
184 typ := check.typInternal(e, nil)
185 assert(isTyped(typ))
186 if typ != Typ[Invalid] && !isGeneric(typ) {
187 if reportErr {
188 check.errorf(e, _Todo, "%s is not a generic type", typ)
189 }
190 typ = Typ[Invalid]
191 }
192
193 check.recordTypeAndValue(e, typexpr, typ, nil)
194 return typ
195 }
196
197
198
199 func isubst(x ast.Expr, smap map[*ast.Ident]*ast.Ident) ast.Expr {
200 switch n := x.(type) {
201 case *ast.Ident:
202 if alt := smap[n]; alt != nil {
203 return alt
204 }
205 case *ast.StarExpr:
206 X := isubst(n.X, smap)
207 if X != n.X {
208 new := *n
209 new.X = X
210 return &new
211 }
212 case *ast.IndexExpr:
213 elems := typeparams.UnpackExpr(n.Index)
214 var newElems []ast.Expr
215 for i, elem := range elems {
216 new := isubst(elem, smap)
217 if new != elem {
218 if newElems == nil {
219 newElems = make([]ast.Expr, len(elems))
220 copy(newElems, elems)
221 }
222 newElems[i] = new
223 }
224 }
225 if newElems != nil {
226 index := typeparams.PackExpr(newElems)
227 new := *n
228 new.Index = index
229 return &new
230 }
231 case *ast.ParenExpr:
232 return isubst(n.X, smap)
233 default:
234
235
236
237 }
238 return x
239 }
240
241
242 func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
243 check.openScope(ftyp, "function")
244 check.scope.isFunc = true
245 check.recordScope(ftyp, check.scope)
246 sig.scope = check.scope
247 defer check.closeScope()
248
249 var recvTyp ast.Expr
250 if recvPar != nil && len(recvPar.List) > 0 {
251
252
253
254 _, rname, rparams := check.unpackRecv(recvPar.List[0].Type, true)
255 if len(rparams) > 0 {
256
257
258
259
260
261 var smap map[*ast.Ident]*ast.Ident
262 for i, p := range rparams {
263 if p.Name == "_" {
264 new := *p
265 new.Name = fmt.Sprintf("%d_", i)
266 rparams[i] = &new
267 if smap == nil {
268 smap = make(map[*ast.Ident]*ast.Ident)
269 }
270 smap[p] = &new
271 }
272 }
273 if smap != nil {
274
275 recvTyp = isubst(recvPar.List[0].Type, smap)
276 }
277 sig.rparams = check.declareTypeParams(nil, rparams)
278
279
280 var recvTParams []*TypeName
281 if rname != nil {
282
283
284
285
286 if recv := asNamed(check.genericType(rname, false)); recv != nil {
287 recvTParams = recv.tparams
288 }
289 }
290
291
292 if len(sig.rparams) == len(recvTParams) {
293
294 list := make([]Type, len(sig.rparams))
295 for i, t := range sig.rparams {
296 list[i] = t.typ
297 }
298 smap := makeSubstMap(recvTParams, list)
299 for i, tname := range sig.rparams {
300 bound := recvTParams[i].typ.(*_TypeParam).bound
301
302
303
304
305
306 if bound != nil {
307 bound = check.subst(tname.pos, bound, smap)
308 tname.typ.(*_TypeParam).bound = bound
309 }
310 }
311 }
312 }
313 }
314
315 if tparams := typeparams.Get(ftyp); tparams != nil {
316 sig.tparams = check.collectTypeParams(tparams)
317
318
319
320 if recvPar != nil {
321 check.errorf(tparams, _Todo, "methods cannot have type parameters")
322 }
323 }
324
325
326
327
328 scope := NewScope(check.scope, token.NoPos, token.NoPos, "function body (temp. scope)")
329 recvList, _ := check.collectParams(scope, recvPar, recvTyp, false)
330 params, variadic := check.collectParams(scope, ftyp.Params, nil, true)
331 results, _ := check.collectParams(scope, ftyp.Results, nil, false)
332 scope.squash(func(obj, alt Object) {
333 check.errorf(obj, _DuplicateDecl, "%s redeclared in this block", obj.Name())
334 check.reportAltDecl(alt)
335 })
336
337 if recvPar != nil {
338
339
340
341 var recv *Var
342 switch len(recvList) {
343 case 0:
344
345 recv = NewParam(0, nil, "", Typ[Invalid])
346 default:
347
348 check.error(recvList[len(recvList)-1], _BadRecv, "method must have exactly one receiver")
349 fallthrough
350 case 1:
351 recv = recvList[0]
352 }
353
354
355
356 rtyp, _ := deref(recv.typ)
357 rtyp = expand(rtyp)
358
359
360
361 if t := rtyp; t != Typ[Invalid] {
362 var err string
363 if T := asNamed(t); T != nil {
364
365
366
367 if T.obj.pkg != check.pkg {
368 err = "type not defined in this package"
369 } else {
370 switch u := optype(T).(type) {
371 case *Basic:
372
373 if u.kind == UnsafePointer {
374 err = "unsafe.Pointer"
375 }
376 case *Pointer, *Interface:
377 err = "pointer or interface type"
378 }
379 }
380 } else {
381 err = "basic or unnamed type"
382 }
383 if err != "" {
384 check.errorf(recv, _InvalidRecv, "invalid receiver %s (%s)", recv.typ, err)
385
386 }
387 }
388 sig.recv = recv
389 }
390
391 sig.params = NewTuple(params...)
392 sig.results = NewTuple(results...)
393 sig.variadic = variadic
394 }
395
396
397
398 func goTypeName(typ Type) string {
399 return strings.ReplaceAll(fmt.Sprintf("%T", typ), "types.", "")
400 }
401
402
403
404
405 func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
406 if trace {
407 check.trace(e0.Pos(), "type %s", e0)
408 check.indent++
409 defer func() {
410 check.indent--
411 var under Type
412 if T != nil {
413
414
415
416
417 under = T.Underlying()
418 }
419 if T == under {
420 check.trace(e0.Pos(), "=> %s // %s", T, goTypeName(T))
421 } else {
422 check.trace(e0.Pos(), "=> %s (under = %s) // %s", T, under, goTypeName(T))
423 }
424 }()
425 }
426
427 switch e := e0.(type) {
428 case *ast.BadExpr:
429
430
431 case *ast.Ident:
432 var x operand
433 check.ident(&x, e, def, true)
434
435 switch x.mode {
436 case typexpr:
437 typ := x.typ
438 def.setUnderlying(typ)
439 return typ
440 case invalid:
441
442 case novalue:
443 check.errorf(&x, _NotAType, "%s used as type", &x)
444 default:
445 check.errorf(&x, _NotAType, "%s is not a type", &x)
446 }
447
448 case *ast.SelectorExpr:
449 var x operand
450 check.selector(&x, e)
451
452 switch x.mode {
453 case typexpr:
454 typ := x.typ
455 def.setUnderlying(typ)
456 return typ
457 case invalid:
458
459 case novalue:
460 check.errorf(&x, _NotAType, "%s used as type", &x)
461 default:
462 check.errorf(&x, _NotAType, "%s is not a type", &x)
463 }
464
465 case *ast.IndexExpr:
466 if typeparams.Enabled {
467 exprs := typeparams.UnpackExpr(e.Index)
468 return check.instantiatedType(e.X, exprs, def)
469 }
470 check.errorf(e0, _NotAType, "%s is not a type", e0)
471 check.use(e.X)
472
473 case *ast.ParenExpr:
474
475
476 return check.definedType(e.X, def)
477
478 case *ast.ArrayType:
479 if e.Len != nil {
480 typ := new(Array)
481 def.setUnderlying(typ)
482 typ.len = check.arrayLength(e.Len)
483 typ.elem = check.varType(e.Elt)
484 return typ
485 }
486
487 typ := new(Slice)
488 def.setUnderlying(typ)
489 typ.elem = check.varType(e.Elt)
490 return typ
491
492 case *ast.Ellipsis:
493
494
495 check.error(e, _InvalidDotDotDot, "invalid use of '...'")
496 check.use(e.Elt)
497
498 case *ast.StructType:
499 typ := new(Struct)
500 def.setUnderlying(typ)
501 check.structType(typ, e)
502 return typ
503
504 case *ast.StarExpr:
505 typ := new(Pointer)
506 def.setUnderlying(typ)
507 typ.base = check.varType(e.X)
508 return typ
509
510 case *ast.FuncType:
511 typ := new(Signature)
512 def.setUnderlying(typ)
513 check.funcType(typ, nil, e)
514 return typ
515
516 case *ast.InterfaceType:
517 typ := new(Interface)
518 def.setUnderlying(typ)
519 if def != nil {
520 typ.obj = def.obj
521 }
522 check.interfaceType(typ, e, def)
523 return typ
524
525 case *ast.MapType:
526 typ := new(Map)
527 def.setUnderlying(typ)
528
529 typ.key = check.varType(e.Key)
530 typ.elem = check.varType(e.Value)
531
532
533
534
535
536
537
538 check.later(func() {
539 if !Comparable(typ.key) {
540 var why string
541 if asTypeParam(typ.key) != nil {
542 why = " (missing comparable constraint)"
543 }
544 check.errorf(e.Key, _IncomparableMapKey, "incomparable map key type %s%s", typ.key, why)
545 }
546 })
547
548 return typ
549
550 case *ast.ChanType:
551 typ := new(Chan)
552 def.setUnderlying(typ)
553
554 dir := SendRecv
555 switch e.Dir {
556 case ast.SEND | ast.RECV:
557
558 case ast.SEND:
559 dir = SendOnly
560 case ast.RECV:
561 dir = RecvOnly
562 default:
563 check.invalidAST(e, "unknown channel direction %d", e.Dir)
564
565 }
566
567 typ.dir = dir
568 typ.elem = check.varType(e.Value)
569 return typ
570
571 default:
572 check.errorf(e0, _NotAType, "%s is not a type", e0)
573 }
574
575 typ := Typ[Invalid]
576 def.setUnderlying(typ)
577 return typ
578 }
579
580
581
582
583
584
585 func (check *Checker) typeOrNil(e ast.Expr) Type {
586 var x operand
587 check.rawExpr(&x, e, nil)
588 switch x.mode {
589 case invalid:
590
591 case novalue:
592 check.errorf(&x, _NotAType, "%s used as type", &x)
593 case typexpr:
594 check.instantiatedOperand(&x)
595 return x.typ
596 case value:
597 if x.isNil() {
598 return nil
599 }
600 fallthrough
601 default:
602 check.errorf(&x, _NotAType, "%s is not a type", &x)
603 }
604 return Typ[Invalid]
605 }
606
607 func (check *Checker) instantiatedType(x ast.Expr, targs []ast.Expr, def *Named) Type {
608 b := check.genericType(x, true)
609 if b == Typ[Invalid] {
610 return b
611 }
612 base := asNamed(b)
613 if base == nil {
614 unreachable()
615 }
616
617
618
619
620 typ := new(instance)
621 def.setUnderlying(typ)
622
623 typ.check = check
624 typ.pos = x.Pos()
625 typ.base = base
626
627
628 typ.targs = check.typeList(targs)
629 if typ.targs == nil {
630 def.setUnderlying(Typ[Invalid])
631 return Typ[Invalid]
632 }
633
634
635 typ.poslist = make([]token.Pos, len(targs))
636 for i, arg := range targs {
637 typ.poslist[i] = arg.Pos()
638 }
639
640
641
642 check.later(func() {
643 t := typ.expand()
644 check.validType(t, nil)
645 })
646
647 return typ
648 }
649
650
651
652
653 func (check *Checker) arrayLength(e ast.Expr) int64 {
654 var x operand
655 check.expr(&x, e)
656 if x.mode != constant_ {
657 if x.mode != invalid {
658 check.errorf(&x, _InvalidArrayLen, "array length %s must be constant", &x)
659 }
660 return -1
661 }
662 if isUntyped(x.typ) || isInteger(x.typ) {
663 if val := constant.ToInt(x.val); val.Kind() == constant.Int {
664 if representableConst(val, check, Typ[Int], nil) {
665 if n, ok := constant.Int64Val(val); ok && n >= 0 {
666 return n
667 }
668 check.errorf(&x, _InvalidArrayLen, "invalid array length %s", &x)
669 return -1
670 }
671 }
672 }
673 check.errorf(&x, _InvalidArrayLen, "array length %s must be integer", &x)
674 return -1
675 }
676
677
678
679 func (check *Checker) typeList(list []ast.Expr) []Type {
680 res := make([]Type, len(list))
681 for i, x := range list {
682 t := check.varType(x)
683 if t == Typ[Invalid] {
684 res = nil
685 }
686 if res != nil {
687 res[i] = t
688 }
689 }
690 return res
691 }
692
693
694
695 func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, type0 ast.Expr, variadicOk bool) (params []*Var, variadic bool) {
696 if list == nil {
697 return
698 }
699
700 var named, anonymous bool
701 for i, field := range list.List {
702 ftype := field.Type
703 if i == 0 && type0 != nil {
704 ftype = type0
705 }
706 if t, _ := ftype.(*ast.Ellipsis); t != nil {
707 ftype = t.Elt
708 if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
709 variadic = true
710 } else {
711 check.softErrorf(t, _MisplacedDotDotDot, "can only use ... with final parameter in list")
712
713 }
714 }
715 typ := check.varType(ftype)
716
717
718 if len(field.Names) > 0 {
719
720 for _, name := range field.Names {
721 if name.Name == "" {
722 check.invalidAST(name, "anonymous parameter")
723
724 }
725 par := NewParam(name.Pos(), check.pkg, name.Name, typ)
726 check.declare(scope, name, par, scope.pos)
727 params = append(params, par)
728 }
729 named = true
730 } else {
731
732 par := NewParam(ftype.Pos(), check.pkg, "", typ)
733 check.recordImplicit(field, par)
734 params = append(params, par)
735 anonymous = true
736 }
737 }
738
739 if named && anonymous {
740 check.invalidAST(list, "list contains both named and anonymous parameters")
741
742 }
743
744
745
746
747 if variadic {
748 last := params[len(params)-1]
749 last.typ = &Slice{elem: last.typ}
750 check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
751 }
752
753 return
754 }
755
756 func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
757 if alt := oset.insert(obj); alt != nil {
758 check.errorf(atPos(pos), _DuplicateDecl, "%s redeclared", obj.Name())
759 check.reportAltDecl(alt)
760 return false
761 }
762 return true
763 }
764
765 func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
766 var tlist *ast.Ident
767 var types []ast.Expr
768 for _, f := range iface.Methods.List {
769 if len(f.Names) > 0 {
770
771
772
773
774 name := f.Names[0]
775 if name.Name == "_" {
776 check.errorf(name, _BlankIfaceMethod, "invalid method name _")
777 continue
778 }
779
780 if name.Name == "type" {
781
782
783
784 types = append(types, f.Type)
785 if tlist != nil && tlist != name {
786 check.errorf(name, _Todo, "cannot have multiple type lists in an interface")
787 }
788 tlist = name
789 continue
790 }
791
792 typ := check.typ(f.Type)
793 sig, _ := typ.(*Signature)
794 if sig == nil {
795 if typ != Typ[Invalid] {
796 check.invalidAST(f.Type, "%s is not a method signature", typ)
797 }
798 continue
799 }
800
801
802
803
804 if sig.tparams != nil {
805 var at positioner = f.Type
806 if tparams := typeparams.Get(f.Type); tparams != nil {
807 at = tparams
808 }
809 check.errorf(at, _Todo, "methods cannot have type parameters")
810 }
811
812
813 var recvTyp Type = ityp
814 if def != nil {
815 recvTyp = def
816 }
817 sig.recv = NewVar(name.Pos(), check.pkg, "", recvTyp)
818
819 m := NewFunc(name.Pos(), check.pkg, name.Name, sig)
820 check.recordDef(name, m)
821 ityp.methods = append(ityp.methods, m)
822 } else {
823
824
825 ityp.embeddeds = append(ityp.embeddeds, check.typ(f.Type))
826 check.posMap[ityp] = append(check.posMap[ityp], f.Type.Pos())
827 }
828 }
829
830
831 ityp.types = _NewSum(check.collectTypeConstraints(iface.Pos(), types))
832
833 if len(ityp.methods) == 0 && ityp.types == nil && len(ityp.embeddeds) == 0 {
834
835 ityp.allMethods = markComplete
836 return
837 }
838
839
840 sortMethods(ityp.methods)
841 sortTypes(ityp.embeddeds)
842
843 check.later(func() { check.completeInterface(iface.Pos(), ityp) })
844 }
845
846 func (check *Checker) completeInterface(pos token.Pos, ityp *Interface) {
847 if ityp.allMethods != nil {
848 return
849 }
850
851
852
853
854
855 if check == nil {
856 panic("internal error: incomplete interface")
857 }
858
859 if trace {
860
861
862
863 if !pos.IsValid() && len(ityp.methods) > 0 {
864 pos = ityp.methods[0].pos
865 }
866
867 check.trace(pos, "complete %s", ityp)
868 check.indent++
869 defer func() {
870 check.indent--
871 check.trace(pos, "=> %s (methods = %v, types = %v)", ityp, ityp.allMethods, ityp.allTypes)
872 }()
873 }
874
875
876
877
878
879
880 ityp.allMethods = markComplete
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895 var seen objset
896 var methods []*Func
897 mpos := make(map[*Func]token.Pos)
898 addMethod := func(pos token.Pos, m *Func, explicit bool) {
899 switch other := seen.insert(m); {
900 case other == nil:
901 methods = append(methods, m)
902 mpos[m] = pos
903 case explicit:
904 check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name)
905 check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name)
906 default:
907
908
909
910
911
912 check.later(func() {
913 if !check.allowVersion(m.pkg, 1, 14) || !check.identical(m.typ, other.Type()) {
914 check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name)
915 check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name)
916 }
917 })
918 }
919 }
920
921 for _, m := range ityp.methods {
922 addMethod(m.pos, m, true)
923 }
924
925
926 allTypes := ityp.types
927
928 posList := check.posMap[ityp]
929 for i, typ := range ityp.embeddeds {
930 pos := posList[i]
931 utyp := under(typ)
932 etyp := asInterface(utyp)
933 if etyp == nil {
934 if utyp != Typ[Invalid] {
935 var format string
936 if _, ok := utyp.(*_TypeParam); ok {
937 format = "%s is a type parameter, not an interface"
938 } else {
939 format = "%s is not an interface"
940 }
941
942 check.errorf(atPos(pos), _InvalidIfaceEmbed, format, typ)
943 }
944 continue
945 }
946 check.completeInterface(pos, etyp)
947 for _, m := range etyp.allMethods {
948 addMethod(pos, m, false)
949 }
950 allTypes = intersect(allTypes, etyp.allTypes)
951 }
952
953 if methods != nil {
954 sort.Sort(byUniqueMethodName(methods))
955 ityp.allMethods = methods
956 }
957 ityp.allTypes = allTypes
958 }
959
960
961
962
963 func intersect(x, y Type) (r Type) {
964 defer func() {
965 if r == theTop {
966 r = nil
967 }
968 }()
969
970 switch {
971 case x == theBottom || y == theBottom:
972 return theBottom
973 case x == nil || x == theTop:
974 return y
975 case y == nil || x == theTop:
976 return x
977 }
978
979 xtypes := unpackType(x)
980 ytypes := unpackType(y)
981
982
983
984
985 var rtypes []Type
986 for _, x := range xtypes {
987 if includes(ytypes, x) {
988 rtypes = append(rtypes, x)
989 }
990 }
991
992 if rtypes == nil {
993 return theBottom
994 }
995 return _NewSum(rtypes)
996 }
997
998 func sortTypes(list []Type) {
999 sort.Stable(byUniqueTypeName(list))
1000 }
1001
1002
1003 type byUniqueTypeName []Type
1004
1005 func (a byUniqueTypeName) Len() int { return len(a) }
1006 func (a byUniqueTypeName) Less(i, j int) bool { return sortName(a[i]) < sortName(a[j]) }
1007 func (a byUniqueTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
1008
1009 func sortName(t Type) string {
1010 if named := asNamed(t); named != nil {
1011 return named.obj.Id()
1012 }
1013 return ""
1014 }
1015
1016 func sortMethods(list []*Func) {
1017 sort.Sort(byUniqueMethodName(list))
1018 }
1019
1020 func assertSortedMethods(list []*Func) {
1021 if !debug {
1022 panic("internal error: assertSortedMethods called outside debug mode")
1023 }
1024 if !sort.IsSorted(byUniqueMethodName(list)) {
1025 panic("internal error: methods not sorted")
1026 }
1027 }
1028
1029
1030 type byUniqueMethodName []*Func
1031
1032 func (a byUniqueMethodName) Len() int { return len(a) }
1033 func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() }
1034 func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
1035
1036 func (check *Checker) tag(t *ast.BasicLit) string {
1037 if t != nil {
1038 if t.Kind == token.STRING {
1039 if val, err := strconv.Unquote(t.Value); err == nil {
1040 return val
1041 }
1042 }
1043 check.invalidAST(t, "incorrect tag syntax: %q", t.Value)
1044 }
1045 return ""
1046 }
1047
1048 func (check *Checker) structType(styp *Struct, e *ast.StructType) {
1049 list := e.Fields
1050 if list == nil {
1051 return
1052 }
1053
1054
1055 var fields []*Var
1056 var tags []string
1057
1058
1059 var fset objset
1060
1061
1062 var typ Type
1063 var tag string
1064 add := func(ident *ast.Ident, embedded bool, pos token.Pos) {
1065 if tag != "" && tags == nil {
1066 tags = make([]string, len(fields))
1067 }
1068 if tags != nil {
1069 tags = append(tags, tag)
1070 }
1071
1072 name := ident.Name
1073 fld := NewField(pos, check.pkg, name, typ, embedded)
1074
1075 if name == "_" || check.declareInSet(&fset, pos, fld) {
1076 fields = append(fields, fld)
1077 check.recordDef(ident, fld)
1078 }
1079 }
1080
1081
1082
1083
1084
1085 addInvalid := func(ident *ast.Ident, pos token.Pos) {
1086 typ = Typ[Invalid]
1087 tag = ""
1088 add(ident, true, pos)
1089 }
1090
1091 for _, f := range list.List {
1092 typ = check.varType(f.Type)
1093 tag = check.tag(f.Tag)
1094 if len(f.Names) > 0 {
1095
1096 for _, name := range f.Names {
1097 add(name, false, name.Pos())
1098 }
1099 } else {
1100
1101
1102
1103
1104 pos := f.Type.Pos()
1105 name := embeddedFieldIdent(f.Type)
1106 if name == nil {
1107
1108
1109 check.errorf(f.Type, _Todo, "invalid AST: embedded field type %s has no name", f.Type)
1110 name = ast.NewIdent("_")
1111 name.NamePos = pos
1112 addInvalid(name, pos)
1113 continue
1114 }
1115 add(name, true, pos)
1116
1117
1118
1119
1120
1121
1122
1123 embeddedTyp := typ
1124 embeddedPos := f.Type
1125
1126 check.later(func() {
1127 t, isPtr := deref(embeddedTyp)
1128 switch t := optype(t).(type) {
1129 case *Basic:
1130 if t == Typ[Invalid] {
1131
1132 return
1133 }
1134
1135 if t.kind == UnsafePointer {
1136 check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
1137 }
1138 case *Pointer:
1139 check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer")
1140 case *Interface:
1141 if isPtr {
1142 check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
1143 }
1144 }
1145 })
1146 }
1147 }
1148
1149 styp.fields = fields
1150 styp.tags = tags
1151 }
1152
1153 func embeddedFieldIdent(e ast.Expr) *ast.Ident {
1154 switch e := e.(type) {
1155 case *ast.Ident:
1156 return e
1157 case *ast.StarExpr:
1158
1159 if _, ok := e.X.(*ast.StarExpr); !ok {
1160 return embeddedFieldIdent(e.X)
1161 }
1162 case *ast.SelectorExpr:
1163 return e.Sel
1164 case *ast.IndexExpr:
1165 return embeddedFieldIdent(e.X)
1166 }
1167 return nil
1168 }
1169
1170 func (check *Checker) collectTypeConstraints(pos token.Pos, types []ast.Expr) []Type {
1171 list := make([]Type, 0, len(types))
1172 for _, texpr := range types {
1173 if texpr == nil {
1174 check.invalidAST(atPos(pos), "missing type constraint")
1175 continue
1176 }
1177 list = append(list, check.varType(texpr))
1178 }
1179
1180
1181
1182
1183
1184 check.later(func() {
1185 for i, t := range list {
1186 if t := asInterface(t); t != nil {
1187 check.completeInterface(types[i].Pos(), t)
1188 }
1189 if includes(list[:i], t) {
1190 check.softErrorf(types[i], _Todo, "duplicate type %s in type list", t)
1191 }
1192 }
1193 })
1194
1195 return list
1196 }
1197
1198
1199 func includes(list []Type, typ Type) bool {
1200 for _, e := range list {
1201 if Identical(typ, e) {
1202 return true
1203 }
1204 }
1205 return false
1206 }
1207
View as plain text