Source file src/pkg/go/types/typexpr.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "go/ast"
11 "go/constant"
12 "go/token"
13 "sort"
14 "strconv"
15 )
16
17
18
19
20
21
22 func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
23 x.mode = invalid
24 x.expr = e
25
26
27
28 scope, obj := check.scope.LookupParent(e.Name, check.pos)
29 if obj == nil {
30 if e.Name == "_" {
31 check.errorf(e.Pos(), "cannot use _ as value or type")
32 } else {
33 check.errorf(e.Pos(), "undeclared name: %s", e.Name)
34 }
35 return
36 }
37 check.recordUse(e, obj)
38
39
40
41
42
43
44
45
46
47 typ := obj.Type()
48 if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
49 check.objDecl(obj, def)
50 typ = obj.Type()
51 }
52 assert(typ != nil)
53
54
55
56
57
58 if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil {
59 delete(check.unusedDotImports[scope], pkg)
60 }
61
62 switch obj := obj.(type) {
63 case *PkgName:
64 check.errorf(e.Pos(), "use of package %s not in selector", obj.name)
65 return
66
67 case *Const:
68 check.addDeclDep(obj)
69 if typ == Typ[Invalid] {
70 return
71 }
72 if obj == universeIota {
73 if check.iota == nil {
74 check.errorf(e.Pos(), "cannot use iota outside constant declaration")
75 return
76 }
77 x.val = check.iota
78 } else {
79 x.val = obj.val
80 }
81 assert(x.val != nil)
82 x.mode = constant_
83
84 case *TypeName:
85 x.mode = typexpr
86
87 case *Var:
88
89
90
91 if obj.pkg == check.pkg {
92 obj.used = true
93 }
94 check.addDeclDep(obj)
95 if typ == Typ[Invalid] {
96 return
97 }
98 x.mode = variable
99
100 case *Func:
101 check.addDeclDep(obj)
102 x.mode = value
103
104 case *Builtin:
105 x.id = obj.id
106 x.mode = builtin
107
108 case *Nil:
109 x.mode = value
110
111 default:
112 unreachable()
113 }
114
115 x.typ = typ
116 }
117
118
119 func (check *Checker) typ(e ast.Expr) Type {
120 return check.definedType(e, nil)
121 }
122
123
124
125
126
127
128 func (check *Checker) definedType(e ast.Expr, def *Named) (T Type) {
129 if trace {
130 check.trace(e.Pos(), "%s", e)
131 check.indent++
132 defer func() {
133 check.indent--
134 check.trace(e.Pos(), "=> %s", T)
135 }()
136 }
137
138 T = check.typInternal(e, def)
139 assert(isTyped(T))
140 check.recordTypeAndValue(e, typexpr, T, nil)
141
142 return
143 }
144
145
146
147
148
149 func (check *Checker) indirectType(e ast.Expr) Type {
150 check.push(indir)
151 defer check.pop()
152 return check.definedType(e, nil)
153 }
154
155
156 func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
157 scope := NewScope(check.scope, token.NoPos, token.NoPos, "function")
158 scope.isFunc = true
159 check.recordScope(ftyp, scope)
160
161 recvList, _ := check.collectParams(scope, recvPar, false)
162 params, variadic := check.collectParams(scope, ftyp.Params, true)
163 results, _ := check.collectParams(scope, ftyp.Results, false)
164
165 if recvPar != nil {
166
167
168
169 var recv *Var
170 switch len(recvList) {
171 case 0:
172 check.error(recvPar.Pos(), "method is missing receiver")
173 recv = NewParam(0, nil, "", Typ[Invalid])
174 default:
175
176 check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
177 fallthrough
178 case 1:
179 recv = recvList[0]
180 }
181
182
183 if t, _ := deref(recv.typ); t != Typ[Invalid] {
184 var err string
185 if T, _ := t.(*Named); T != nil {
186
187
188
189 if T.obj.pkg != check.pkg {
190 err = "type not defined in this package"
191 } else {
192
193 switch u := T.underlying.(type) {
194 case *Basic:
195
196 if u.kind == UnsafePointer {
197 err = "unsafe.Pointer"
198 }
199 case *Pointer, *Interface:
200 err = "pointer or interface type"
201 }
202 }
203 } else {
204 err = "basic or unnamed type"
205 }
206 if err != "" {
207 check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err)
208
209 }
210 }
211 sig.recv = recv
212 }
213
214 sig.scope = scope
215 sig.params = NewTuple(params...)
216 sig.results = NewTuple(results...)
217 sig.variadic = variadic
218 }
219
220
221
222
223 func (check *Checker) typInternal(e ast.Expr, def *Named) Type {
224 switch e := e.(type) {
225 case *ast.BadExpr:
226
227
228 case *ast.Ident:
229 var x operand
230 check.ident(&x, e, def, true)
231
232 switch x.mode {
233 case typexpr:
234 typ := x.typ
235 def.setUnderlying(typ)
236 return typ
237 case invalid:
238
239 case novalue:
240 check.errorf(x.pos(), "%s used as type", &x)
241 default:
242 check.errorf(x.pos(), "%s is not a type", &x)
243 }
244
245 case *ast.SelectorExpr:
246 var x operand
247 check.selector(&x, e)
248
249 switch x.mode {
250 case typexpr:
251 typ := x.typ
252 def.setUnderlying(typ)
253 return typ
254 case invalid:
255
256 case novalue:
257 check.errorf(x.pos(), "%s used as type", &x)
258 default:
259 check.errorf(x.pos(), "%s is not a type", &x)
260 }
261
262 case *ast.ParenExpr:
263 return check.definedType(e.X, def)
264
265 case *ast.ArrayType:
266 if e.Len != nil {
267 typ := new(Array)
268 def.setUnderlying(typ)
269 typ.len = check.arrayLength(e.Len)
270 typ.elem = check.typ(e.Elt)
271 return typ
272
273 } else {
274 typ := new(Slice)
275 def.setUnderlying(typ)
276 typ.elem = check.indirectType(e.Elt)
277 return typ
278 }
279
280 case *ast.StructType:
281 typ := new(Struct)
282 def.setUnderlying(typ)
283 check.structType(typ, e)
284 return typ
285
286 case *ast.StarExpr:
287 typ := new(Pointer)
288 def.setUnderlying(typ)
289 typ.base = check.indirectType(e.X)
290 return typ
291
292 case *ast.FuncType:
293 typ := new(Signature)
294 def.setUnderlying(typ)
295 check.funcType(typ, nil, e)
296 return typ
297
298 case *ast.InterfaceType:
299 typ := new(Interface)
300 def.setUnderlying(typ)
301 check.interfaceType(typ, e, def)
302 return typ
303
304 case *ast.MapType:
305 typ := new(Map)
306 def.setUnderlying(typ)
307
308 typ.key = check.indirectType(e.Key)
309 typ.elem = check.indirectType(e.Value)
310
311
312
313
314
315
316
317 check.later(func() {
318 if !Comparable(typ.key) {
319 check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key)
320 }
321 })
322
323 return typ
324
325 case *ast.ChanType:
326 typ := new(Chan)
327 def.setUnderlying(typ)
328
329 dir := SendRecv
330 switch e.Dir {
331 case ast.SEND | ast.RECV:
332
333 case ast.SEND:
334 dir = SendOnly
335 case ast.RECV:
336 dir = RecvOnly
337 default:
338 check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir)
339
340 }
341
342 typ.dir = dir
343 typ.elem = check.indirectType(e.Value)
344 return typ
345
346 default:
347 check.errorf(e.Pos(), "%s is not a type", e)
348 }
349
350 typ := Typ[Invalid]
351 def.setUnderlying(typ)
352 return typ
353 }
354
355
356
357
358
359 func (check *Checker) typOrNil(e ast.Expr) Type {
360 var x operand
361 check.rawExpr(&x, e, nil)
362 switch x.mode {
363 case invalid:
364
365 case novalue:
366 check.errorf(x.pos(), "%s used as type", &x)
367 case typexpr:
368 return x.typ
369 case value:
370 if x.isNil() {
371 return nil
372 }
373 fallthrough
374 default:
375 check.errorf(x.pos(), "%s is not a type", &x)
376 }
377 return Typ[Invalid]
378 }
379
380
381
382
383 func (check *Checker) arrayLength(e ast.Expr) int64 {
384 var x operand
385 check.expr(&x, e)
386 if x.mode != constant_ {
387 if x.mode != invalid {
388 check.errorf(x.pos(), "array length %s must be constant", &x)
389 }
390 return -1
391 }
392 if isUntyped(x.typ) || isInteger(x.typ) {
393 if val := constant.ToInt(x.val); val.Kind() == constant.Int {
394 if representableConst(val, check, Typ[Int], nil) {
395 if n, ok := constant.Int64Val(val); ok && n >= 0 {
396 return n
397 }
398 check.errorf(x.pos(), "invalid array length %s", &x)
399 return -1
400 }
401 }
402 }
403 check.errorf(x.pos(), "array length %s must be integer", &x)
404 return -1
405 }
406
407 func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
408 if list == nil {
409 return
410 }
411
412 var named, anonymous bool
413 for i, field := range list.List {
414 ftype := field.Type
415 if t, _ := ftype.(*ast.Ellipsis); t != nil {
416 ftype = t.Elt
417 if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
418 variadic = true
419 } else {
420 check.softErrorf(t.Pos(), "can only use ... with final parameter in list")
421
422 }
423 }
424 typ := check.indirectType(ftype)
425
426
427 if len(field.Names) > 0 {
428
429 for _, name := range field.Names {
430 if name.Name == "" {
431 check.invalidAST(name.Pos(), "anonymous parameter")
432
433 }
434 par := NewParam(name.Pos(), check.pkg, name.Name, typ)
435 check.declare(scope, name, par, scope.pos)
436 params = append(params, par)
437 }
438 named = true
439 } else {
440
441 par := NewParam(ftype.Pos(), check.pkg, "", typ)
442 check.recordImplicit(field, par)
443 params = append(params, par)
444 anonymous = true
445 }
446 }
447
448 if named && anonymous {
449 check.invalidAST(list.Pos(), "list contains both named and anonymous parameters")
450
451 }
452
453
454
455
456 if variadic {
457 last := params[len(params)-1]
458 last.typ = &Slice{elem: last.typ}
459 check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
460 }
461
462 return
463 }
464
465 func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
466 if alt := oset.insert(obj); alt != nil {
467 check.errorf(pos, "%s redeclared", obj.Name())
468 check.reportAltDecl(alt)
469 return false
470 }
471 return true
472 }
473
474 func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
475
476 if iface.Methods.List == nil {
477 ityp.allMethods = markComplete
478 return
479 }
480
481
482
483
484
485
486
487 interfaceContext := check.context
488 check.later(func() {
489 if trace {
490 check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %v", iface)
491 check.indent++
492 defer func() {
493 check.indent--
494 }()
495 }
496
497
498
499
500 defer func(ctxt context) {
501 check.context = ctxt
502 }(check.context)
503 check.context = interfaceContext
504
505 for _, f := range iface.Methods.List {
506 if len(f.Names) == 0 {
507 typ := check.indirectType(f.Type)
508
509
510
511 if typ == Typ[Invalid] {
512 continue
513 }
514 embed, _ := typ.Underlying().(*Interface)
515 if embed == nil {
516 check.errorf(f.Type.Pos(), "%s is not an interface", typ)
517 continue
518 }
519
520
521
522 if embed.allMethods == nil {
523 check.dump("%v: incomplete embedded interface %s", f.Type.Pos(), typ)
524 unreachable()
525 }
526
527 ityp.embeddeds = append(ityp.embeddeds, typ)
528 }
529 }
530
531
532 sort.Stable(byUniqueTypeName(ityp.embeddeds))
533 })
534
535
536 var tname *TypeName
537 var path []*TypeName
538 if def != nil {
539 tname = def.obj
540 path = []*TypeName{tname}
541 }
542 info := check.infoFromTypeLit(check.scope, iface, tname, path)
543 if info == nil || info == &emptyIfaceInfo {
544
545 ityp.allMethods = markComplete
546 return
547 }
548
549
550 var recvTyp Type = ityp
551 if def != nil {
552 recvTyp = def
553 }
554
555
556
557
558 check.later(func() {
559 for _, m := range ityp.methods {
560 m.typ.(*Signature).recv.typ = recvTyp
561 }
562 })
563
564
565 var sigfix []*methodInfo
566 for i, minfo := range info.methods {
567 fun := minfo.fun
568 if fun == nil {
569 name := minfo.src.Names[0]
570 pos := name.Pos()
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 sig := new(Signature)
598 sig.recv = NewVar(pos, check.pkg, "", recvTyp)
599 fun = NewFunc(pos, check.pkg, name.Name, sig)
600 minfo.fun = fun
601 check.recordDef(name, fun)
602 sigfix = append(sigfix, minfo)
603 }
604
605 if i < info.explicits {
606 ityp.methods = append(ityp.methods, fun)
607 }
608 ityp.allMethods = append(ityp.allMethods, fun)
609 }
610
611
612 savedContext := check.context
613 for _, minfo := range sigfix {
614
615
616 check.context = context{scope: minfo.scope}
617 typ := check.indirectType(minfo.src.Type)
618 sig, _ := typ.(*Signature)
619 if sig == nil {
620 if typ != Typ[Invalid] {
621 check.invalidAST(minfo.src.Type.Pos(), "%s is not a method signature", typ)
622 }
623 continue
624 }
625
626 old := minfo.fun.typ.(*Signature)
627 sig.recv = old.recv
628 *old = *sig
629 }
630 check.context = savedContext
631
632
633
634 sort.Sort(byUniqueMethodName(ityp.methods))
635
636 if ityp.allMethods == nil {
637 ityp.allMethods = markComplete
638 } else {
639 sort.Sort(byUniqueMethodName(ityp.allMethods))
640 }
641 }
642
643
644 type byUniqueTypeName []Type
645
646 func (a byUniqueTypeName) Len() int { return len(a) }
647 func (a byUniqueTypeName) Less(i, j int) bool { return sortName(a[i]) < sortName(a[j]) }
648 func (a byUniqueTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
649
650 func sortName(t Type) string {
651 if named, _ := t.(*Named); named != nil {
652 return named.obj.Id()
653 }
654 return ""
655 }
656
657
658 type byUniqueMethodName []*Func
659
660 func (a byUniqueMethodName) Len() int { return len(a) }
661 func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() }
662 func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
663
664 func (check *Checker) tag(t *ast.BasicLit) string {
665 if t != nil {
666 if t.Kind == token.STRING {
667 if val, err := strconv.Unquote(t.Value); err == nil {
668 return val
669 }
670 }
671 check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value)
672 }
673 return ""
674 }
675
676 func (check *Checker) structType(styp *Struct, e *ast.StructType) {
677 list := e.Fields
678 if list == nil {
679 return
680 }
681
682
683 var fields []*Var
684 var tags []string
685
686
687 var fset objset
688
689
690 var typ Type
691 var tag string
692 add := func(ident *ast.Ident, embedded bool, pos token.Pos) {
693 if tag != "" && tags == nil {
694 tags = make([]string, len(fields))
695 }
696 if tags != nil {
697 tags = append(tags, tag)
698 }
699
700 name := ident.Name
701 fld := NewField(pos, check.pkg, name, typ, embedded)
702
703 if name == "_" || check.declareInSet(&fset, pos, fld) {
704 fields = append(fields, fld)
705 check.recordDef(ident, fld)
706 }
707 }
708
709
710
711
712
713 addInvalid := func(ident *ast.Ident, pos token.Pos) {
714 typ = Typ[Invalid]
715 tag = ""
716 add(ident, true, pos)
717 }
718
719 for _, f := range list.List {
720 typ = check.typ(f.Type)
721 tag = check.tag(f.Tag)
722 if len(f.Names) > 0 {
723
724 for _, name := range f.Names {
725 add(name, false, name.Pos())
726 }
727 } else {
728
729
730
731 pos := f.Type.Pos()
732 name := embeddedFieldIdent(f.Type)
733 if name == nil {
734 check.invalidAST(pos, "embedded field type %s has no name", f.Type)
735 name = ast.NewIdent("_")
736 name.NamePos = pos
737 addInvalid(name, pos)
738 continue
739 }
740 t, isPtr := deref(typ)
741
742
743 switch t := t.Underlying().(type) {
744 case *Basic:
745 if t == Typ[Invalid] {
746
747 addInvalid(name, pos)
748 continue
749 }
750
751
752 if t.kind == UnsafePointer {
753 check.errorf(pos, "embedded field type cannot be unsafe.Pointer")
754 addInvalid(name, pos)
755 continue
756 }
757
758 case *Pointer:
759 check.errorf(pos, "embedded field type cannot be a pointer")
760 addInvalid(name, pos)
761 continue
762
763 case *Interface:
764 if isPtr {
765 check.errorf(pos, "embedded field type cannot be a pointer to an interface")
766 addInvalid(name, pos)
767 continue
768 }
769 }
770 add(name, true, pos)
771 }
772 }
773
774 styp.fields = fields
775 styp.tags = tags
776 }
777
778 func embeddedFieldIdent(e ast.Expr) *ast.Ident {
779 switch e := e.(type) {
780 case *ast.Ident:
781 return e
782 case *ast.StarExpr:
783
784 if _, ok := e.X.(*ast.StarExpr); !ok {
785 return embeddedFieldIdent(e.X)
786 }
787 case *ast.SelectorExpr:
788 return e.Sel
789 }
790 return nil
791 }
792
View as plain text