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 . "internal/types/errors"
15 "strings"
16 )
17
18
19
20
21
22 func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bool) {
23 x.mode = invalid
24 x.expr = e
25
26
27
28 scope, obj := check.scope.LookupParent(e.Name, check.pos)
29 switch obj {
30 case nil:
31 if e.Name == "_" {
32
33
34
35 if tpar := check.recvTParamMap[e]; tpar != nil {
36 x.mode = typexpr
37 x.typ = tpar
38 } else {
39 check.error(e, InvalidBlank, "cannot use _ as value or type")
40 }
41 } else {
42 check.errorf(e, UndeclaredName, "undefined: %s", e.Name)
43 }
44 return
45 case universeComparable:
46 if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Name) {
47 return
48 }
49 }
50
51
52 if obj.Name() == "any" && obj.Parent() == Universe {
53 if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Name) {
54 return
55 }
56 }
57 check.recordUse(e, obj)
58
59
60
61
62 _, gotType := obj.(*TypeName)
63 if !gotType && wantType {
64 check.errorf(e, NotAType, "%s is not a type", obj.Name())
65
66
67 if v, _ := obj.(*Var); v != nil && v.pkg == check.pkg {
68 v.used = true
69 }
70 return
71 }
72
73
74
75
76
77
78
79
80
81 typ := obj.Type()
82 if typ == nil || gotType && wantType {
83 check.objDecl(obj, def)
84 typ = obj.Type()
85 }
86 assert(typ != nil)
87
88
89
90
91
92 if pkgName := check.dotImportMap[dotImportKey{scope, obj.Name()}]; pkgName != nil {
93 pkgName.used = true
94 }
95
96 switch obj := obj.(type) {
97 case *PkgName:
98 check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
99 return
100
101 case *Const:
102 check.addDeclDep(obj)
103 if !isValid(typ) {
104 return
105 }
106 if obj == universeIota {
107 if check.iota == nil {
108 check.error(e, InvalidIota, "cannot use iota outside constant declaration")
109 return
110 }
111 x.val = check.iota
112 } else {
113 x.val = obj.val
114 }
115 assert(x.val != nil)
116 x.mode = constant_
117
118 case *TypeName:
119 if !check.conf._EnableAlias && check.isBrokenAlias(obj) {
120 check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name)
121 return
122 }
123 x.mode = typexpr
124
125 case *Var:
126
127
128
129 if obj.pkg == check.pkg {
130 obj.used = true
131 }
132 check.addDeclDep(obj)
133 if !isValid(typ) {
134 return
135 }
136 x.mode = variable
137
138 case *Func:
139 check.addDeclDep(obj)
140 x.mode = value
141
142 case *Builtin:
143 x.id = obj.id
144 x.mode = builtin
145
146 case *Nil:
147 x.mode = value
148
149 default:
150 panic("unreachable")
151 }
152
153 x.typ = typ
154 }
155
156
157
158 func (check *Checker) typ(e ast.Expr) Type {
159 return check.definedType(e, nil)
160 }
161
162
163
164
165 func (check *Checker) varType(e ast.Expr) Type {
166 typ := check.definedType(e, nil)
167 check.validVarType(e, typ)
168 return typ
169 }
170
171
172
173 func (check *Checker) validVarType(e ast.Expr, typ Type) {
174
175 if isTypeParam(typ) {
176 return
177 }
178
179
180
181
182 check.later(func() {
183 if t, _ := under(typ).(*Interface); t != nil {
184 tset := computeInterfaceTypeSet(check, e.Pos(), t)
185 if !tset.IsMethodSet() {
186 if tset.comparable {
187 check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
188 } else {
189 check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
190 }
191 }
192 }
193 }).describef(e, "check var type %s", typ)
194 }
195
196
197
198
199
200 func (check *Checker) definedType(e ast.Expr, def *TypeName) Type {
201 typ := check.typInternal(e, def)
202 assert(isTyped(typ))
203 if isGeneric(typ) {
204 check.errorf(e, WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
205 typ = Typ[Invalid]
206 }
207 check.recordTypeAndValue(e, typexpr, typ, nil)
208 return typ
209 }
210
211
212
213
214 func (check *Checker) genericType(e ast.Expr, cause *string) Type {
215 typ := check.typInternal(e, nil)
216 assert(isTyped(typ))
217 if isValid(typ) && !isGeneric(typ) {
218 if cause != nil {
219 *cause = check.sprintf("%s is not a generic type", typ)
220 }
221 typ = Typ[Invalid]
222 }
223
224 check.recordTypeAndValue(e, typexpr, typ, nil)
225 return typ
226 }
227
228
229
230 func goTypeName(typ Type) string {
231 return strings.ReplaceAll(fmt.Sprintf("%T", typ), "types.", "")
232 }
233
234
235
236 func (check *Checker) typInternal(e0 ast.Expr, def *TypeName) (T Type) {
237 if check.conf._Trace {
238 check.trace(e0.Pos(), "-- type %s", e0)
239 check.indent++
240 defer func() {
241 check.indent--
242 var under Type
243 if T != nil {
244
245
246 under = safeUnderlying(T)
247 }
248 if T == under {
249 check.trace(e0.Pos(), "=> %s // %s", T, goTypeName(T))
250 } else {
251 check.trace(e0.Pos(), "=> %s (under = %s) // %s", T, under, goTypeName(T))
252 }
253 }()
254 }
255
256 switch e := e0.(type) {
257 case *ast.BadExpr:
258
259
260 case *ast.Ident:
261 var x operand
262 check.ident(&x, e, def, true)
263
264 switch x.mode {
265 case typexpr:
266 typ := x.typ
267 setDefType(def, typ)
268 return typ
269 case invalid:
270
271 case novalue:
272 check.errorf(&x, NotAType, "%s used as type", &x)
273 default:
274 check.errorf(&x, NotAType, "%s is not a type", &x)
275 }
276
277 case *ast.SelectorExpr:
278 var x operand
279 check.selector(&x, e, def, true)
280
281 switch x.mode {
282 case typexpr:
283 typ := x.typ
284 setDefType(def, typ)
285 return typ
286 case invalid:
287
288 case novalue:
289 check.errorf(&x, NotAType, "%s used as type", &x)
290 default:
291 check.errorf(&x, NotAType, "%s is not a type", &x)
292 }
293
294 case *ast.IndexExpr, *ast.IndexListExpr:
295 ix := typeparams.UnpackIndexExpr(e)
296 check.verifyVersionf(inNode(e, ix.Lbrack), go1_18, "type instantiation")
297 return check.instantiatedType(ix, def)
298
299 case *ast.ParenExpr:
300
301
302 return check.definedType(e.X, def)
303
304 case *ast.ArrayType:
305 if e.Len == nil {
306 typ := new(Slice)
307 setDefType(def, typ)
308 typ.elem = check.varType(e.Elt)
309 return typ
310 }
311
312 typ := new(Array)
313 setDefType(def, typ)
314
315
316 if _, ok := e.Len.(*ast.Ellipsis); ok {
317 check.error(e.Len, BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
318 typ.len = -1
319 } else {
320 typ.len = check.arrayLength(e.Len)
321 }
322 typ.elem = check.varType(e.Elt)
323 if typ.len >= 0 {
324 return typ
325 }
326
327
328 case *ast.Ellipsis:
329
330
331 check.error(e, InvalidDotDotDot, "invalid use of '...'")
332 check.use(e.Elt)
333
334 case *ast.StructType:
335 typ := new(Struct)
336 setDefType(def, typ)
337 check.structType(typ, e)
338 return typ
339
340 case *ast.StarExpr:
341 typ := new(Pointer)
342 typ.base = Typ[Invalid]
343 setDefType(def, typ)
344 typ.base = check.varType(e.X)
345 return typ
346
347 case *ast.FuncType:
348 typ := new(Signature)
349 setDefType(def, typ)
350 check.funcType(typ, nil, e)
351 return typ
352
353 case *ast.InterfaceType:
354 typ := check.newInterface()
355 setDefType(def, typ)
356 check.interfaceType(typ, e, def)
357 return typ
358
359 case *ast.MapType:
360 typ := new(Map)
361 setDefType(def, typ)
362
363 typ.key = check.varType(e.Key)
364 typ.elem = check.varType(e.Value)
365
366
367
368
369
370
371
372 check.later(func() {
373 if !Comparable(typ.key) {
374 var why string
375 if isTypeParam(typ.key) {
376 why = " (missing comparable constraint)"
377 }
378 check.errorf(e.Key, IncomparableMapKey, "invalid map key type %s%s", typ.key, why)
379 }
380 }).describef(e.Key, "check map key %s", typ.key)
381
382 return typ
383
384 case *ast.ChanType:
385 typ := new(Chan)
386 setDefType(def, typ)
387
388 dir := SendRecv
389 switch e.Dir {
390 case ast.SEND | ast.RECV:
391
392 case ast.SEND:
393 dir = SendOnly
394 case ast.RECV:
395 dir = RecvOnly
396 default:
397 check.errorf(e, InvalidSyntaxTree, "unknown channel direction %d", e.Dir)
398
399 }
400
401 typ.dir = dir
402 typ.elem = check.varType(e.Value)
403 return typ
404
405 default:
406 check.errorf(e0, NotAType, "%s is not a type", e0)
407 check.use(e0)
408 }
409
410 typ := Typ[Invalid]
411 setDefType(def, typ)
412 return typ
413 }
414
415 func setDefType(def *TypeName, typ Type) {
416 if def != nil {
417 switch t := def.typ.(type) {
418 case *Alias:
419
420
421 if t.fromRHS != Typ[Invalid] && t.fromRHS != typ {
422 panic(sprintf(nil, nil, true, "t.fromRHS = %s, typ = %s\n", t.fromRHS, typ))
423 }
424 t.fromRHS = typ
425 case *Basic:
426 assert(t == Typ[Invalid])
427 case *Named:
428 t.underlying = typ
429 default:
430 panic(fmt.Sprintf("unexpected type %T", t))
431 }
432 }
433 }
434
435 func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *TypeName) (res Type) {
436 if check.conf._Trace {
437 check.trace(ix.Pos(), "-- instantiating type %s with %s", ix.X, ix.Indices)
438 check.indent++
439 defer func() {
440 check.indent--
441
442 check.trace(ix.Pos(), "=> %s", res)
443 }()
444 }
445
446 defer func() {
447 setDefType(def, res)
448 }()
449
450 var cause string
451 gtyp := check.genericType(ix.X, &cause)
452 if cause != "" {
453 check.errorf(ix.Orig, NotAGenericType, invalidOp+"%s (%s)", ix.Orig, cause)
454 }
455 if !isValid(gtyp) {
456 return gtyp
457 }
458
459
460 targs := check.typeList(ix.Indices)
461 if targs == nil {
462 return Typ[Invalid]
463 }
464
465 if orig, _ := gtyp.(*Alias); orig != nil {
466 return check.instance(ix.Pos(), orig, targs, nil, check.context())
467 }
468
469 orig := asNamed(gtyp)
470 if orig == nil {
471 panic(fmt.Sprintf("%v: cannot instantiate %v", ix.Pos(), gtyp))
472 }
473
474
475 inst := asNamed(check.instance(ix.Pos(), orig, targs, nil, check.context()))
476
477
478 check.later(func() {
479
480
481
482 check.recordInstance(ix.Orig, inst.TypeArgs().list(), inst)
483
484 if check.validateTArgLen(ix.Pos(), inst.obj.name, inst.TypeParams().Len(), inst.TypeArgs().Len()) {
485 if i, err := check.verify(ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), check.context()); err != nil {
486
487 pos := ix.Pos()
488 if i < len(ix.Indices) {
489 pos = ix.Indices[i].Pos()
490 }
491 check.softErrorf(atPos(pos), InvalidTypeArg, "%v", err)
492 } else {
493 check.mono.recordInstance(check.pkg, ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), ix.Indices)
494 }
495 }
496
497
498
499
500 check.validType(inst)
501 }).describef(ix, "resolve instance %s", inst)
502
503 return inst
504 }
505
506
507
508
509 func (check *Checker) arrayLength(e ast.Expr) int64 {
510
511
512
513
514 if name, _ := e.(*ast.Ident); name != nil {
515 obj := check.lookup(name.Name)
516 if obj == nil {
517 check.errorf(name, InvalidArrayLen, "undefined array length %s or missing type constraint", name.Name)
518 return -1
519 }
520 if _, ok := obj.(*Const); !ok {
521 check.errorf(name, InvalidArrayLen, "invalid array length %s", name.Name)
522 return -1
523 }
524 }
525
526 var x operand
527 check.expr(nil, &x, e)
528 if x.mode != constant_ {
529 if x.mode != invalid {
530 check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
531 }
532 return -1
533 }
534
535 if isUntyped(x.typ) || isInteger(x.typ) {
536 if val := constant.ToInt(x.val); val.Kind() == constant.Int {
537 if representableConst(val, check, Typ[Int], nil) {
538 if n, ok := constant.Int64Val(val); ok && n >= 0 {
539 return n
540 }
541 }
542 }
543 }
544
545 var msg string
546 if isInteger(x.typ) {
547 msg = "invalid array length %s"
548 } else {
549 msg = "array length %s must be integer"
550 }
551 check.errorf(&x, InvalidArrayLen, msg, &x)
552 return -1
553 }
554
555
556
557 func (check *Checker) typeList(list []ast.Expr) []Type {
558 res := make([]Type, len(list))
559 for i, x := range list {
560 t := check.varType(x)
561 if !isValid(t) {
562 res = nil
563 }
564 if res != nil {
565 res[i] = t
566 }
567 }
568 return res
569 }
570
View as plain text