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