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