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 "strings"
15 )
16
17
18
19
20
21 func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
22 x.mode = invalid
23 x.expr = e
24
25
26
27 scope, obj := check.scope.LookupParent(e.Name, check.pos)
28 switch obj {
29 case nil:
30 if e.Name == "_" {
31
32
33
34 if tpar := check.recvTParamMap[e]; tpar != nil {
35 x.mode = typexpr
36 x.typ = tpar
37 } else {
38 check.error(e, _InvalidBlank, "cannot use _ as value or type")
39 }
40 } else {
41 check.errorf(e, _UndeclaredName, "undeclared name: %s", e.Name)
42 }
43 return
44 case universeAny, universeComparable:
45 if !check.allowVersion(check.pkg, 1, 18) {
46 check.versionErrorf(e, _UndeclaredName, "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 typ == Typ[Invalid] {
83 return
84 }
85 if obj == universeIota {
86 if check.iota == nil {
87 check.errorf(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.isBrokenAlias(obj) {
99 check.errorf(e, _InvalidDeclCycle, "invalid use of type alias %s in recursive type (see 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 typ == Typ[Invalid] {
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 *Named) 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, reason *string) Type {
194 typ := check.typInternal(e, nil)
195 assert(isTyped(typ))
196 if typ != Typ[Invalid] && !isGeneric(typ) {
197 if reason != nil {
198 *reason = 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 *Named) (T Type) {
216 if 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 def.setUnderlying(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)
259
260 switch x.mode {
261 case typexpr:
262 typ := x.typ
263 def.setUnderlying(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 if !check.allowVersion(check.pkg, 1, 18) {
276 check.softErrorf(inNode(e, ix.Lbrack), _UnsupportedFeature, "type instantiation requires go1.18 or later")
277 }
278 return check.instantiatedType(ix, def)
279
280 case *ast.ParenExpr:
281
282
283 return check.definedType(e.X, def)
284
285 case *ast.ArrayType:
286 if e.Len == nil {
287 typ := new(Slice)
288 def.setUnderlying(typ)
289 typ.elem = check.varType(e.Elt)
290 return typ
291 }
292
293 typ := new(Array)
294 def.setUnderlying(typ)
295 typ.len = check.arrayLength(e.Len)
296 typ.elem = check.varType(e.Elt)
297 if typ.len >= 0 {
298 return typ
299 }
300
301 case *ast.Ellipsis:
302
303
304 check.error(e, _InvalidDotDotDot, "invalid use of '...'")
305 check.use(e.Elt)
306
307 case *ast.StructType:
308 typ := new(Struct)
309 def.setUnderlying(typ)
310 check.structType(typ, e)
311 return typ
312
313 case *ast.StarExpr:
314 typ := new(Pointer)
315 typ.base = Typ[Invalid]
316 def.setUnderlying(typ)
317 typ.base = check.varType(e.X)
318 return typ
319
320 case *ast.FuncType:
321 typ := new(Signature)
322 def.setUnderlying(typ)
323 check.funcType(typ, nil, e)
324 return typ
325
326 case *ast.InterfaceType:
327 typ := check.newInterface()
328 def.setUnderlying(typ)
329 check.interfaceType(typ, e, def)
330 return typ
331
332 case *ast.MapType:
333 typ := new(Map)
334 def.setUnderlying(typ)
335
336 typ.key = check.varType(e.Key)
337 typ.elem = check.varType(e.Value)
338
339
340
341
342
343
344
345 check.later(func() {
346 if !Comparable(typ.key) {
347 var why string
348 if isTypeParam(typ.key) {
349 why = " (missing comparable constraint)"
350 }
351 check.errorf(e.Key, _IncomparableMapKey, "incomparable map key type %s%s", typ.key, why)
352 }
353 }).describef(e.Key, "check map key %s", typ.key)
354
355 return typ
356
357 case *ast.ChanType:
358 typ := new(Chan)
359 def.setUnderlying(typ)
360
361 dir := SendRecv
362 switch e.Dir {
363 case ast.SEND | ast.RECV:
364
365 case ast.SEND:
366 dir = SendOnly
367 case ast.RECV:
368 dir = RecvOnly
369 default:
370 check.invalidAST(e, "unknown channel direction %d", e.Dir)
371
372 }
373
374 typ.dir = dir
375 typ.elem = check.varType(e.Value)
376 return typ
377
378 default:
379 check.errorf(e0, _NotAType, "%s is not a type", e0)
380 }
381
382 typ := Typ[Invalid]
383 def.setUnderlying(typ)
384 return typ
385 }
386
387 func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (res Type) {
388 if trace {
389 check.trace(ix.Pos(), "-- instantiating type %s with %s", ix.X, ix.Indices)
390 check.indent++
391 defer func() {
392 check.indent--
393
394 check.trace(ix.Pos(), "=> %s", res)
395 }()
396 }
397
398 var reason string
399 gtyp := check.genericType(ix.X, &reason)
400 if reason != "" {
401 check.invalidOp(ix.Orig, _NotAGenericType, "%s (%s)", ix.Orig, reason)
402 }
403 if gtyp == Typ[Invalid] {
404 return gtyp
405 }
406
407 orig, _ := gtyp.(*Named)
408 if orig == nil {
409 panic(fmt.Sprintf("%v: cannot instantiate %v", ix.Pos(), gtyp))
410 }
411
412
413 targs := check.typeList(ix.Indices)
414 if targs == nil {
415 def.setUnderlying(Typ[Invalid])
416 return Typ[Invalid]
417 }
418
419
420 inst := check.instance(ix.Pos(), orig, targs, nil, check.context()).(*Named)
421 def.setUnderlying(inst)
422
423
424 check.later(func() {
425
426
427
428 check.recordInstance(ix.Orig, inst.TypeArgs().list(), inst)
429
430 if check.validateTArgLen(ix.Pos(), inst.TypeParams().Len(), inst.TypeArgs().Len()) {
431 if i, err := check.verify(ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), check.context()); err != nil {
432
433 pos := ix.Pos()
434 if i < len(ix.Indices) {
435 pos = ix.Indices[i].Pos()
436 }
437 check.softErrorf(atPos(pos), _InvalidTypeArg, err.Error())
438 } else {
439 check.mono.recordInstance(check.pkg, ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), ix.Indices)
440 }
441 }
442
443
444
445
446 check.validType(inst)
447 }).describef(ix, "resolve instance %s", inst)
448
449 return inst
450 }
451
452
453
454
455 func (check *Checker) arrayLength(e ast.Expr) int64 {
456
457
458
459
460 if name, _ := e.(*ast.Ident); name != nil {
461 obj := check.lookup(name.Name)
462 if obj == nil {
463 check.errorf(name, _InvalidArrayLen, "undeclared name %s for array length", name.Name)
464 return -1
465 }
466 if _, ok := obj.(*Const); !ok {
467 check.errorf(name, _InvalidArrayLen, "invalid array length %s", name.Name)
468 return -1
469 }
470 }
471
472 var x operand
473 check.expr(&x, e)
474 if x.mode != constant_ {
475 if x.mode != invalid {
476 check.errorf(&x, _InvalidArrayLen, "array length %s must be constant", &x)
477 }
478 return -1
479 }
480
481 if isUntyped(x.typ) || isInteger(x.typ) {
482 if val := constant.ToInt(x.val); val.Kind() == constant.Int {
483 if representableConst(val, check, Typ[Int], nil) {
484 if n, ok := constant.Int64Val(val); ok && n >= 0 {
485 return n
486 }
487 check.errorf(&x, _InvalidArrayLen, "invalid array length %s", &x)
488 return -1
489 }
490 }
491 }
492
493 check.errorf(&x, _InvalidArrayLen, "array length %s must be integer", &x)
494 return -1
495 }
496
497
498
499 func (check *Checker) typeList(list []ast.Expr) []Type {
500 res := make([]Type, len(list))
501 for i, x := range list {
502 t := check.varType(x)
503 if t == Typ[Invalid] {
504 res = nil
505 }
506 if res != nil {
507 res[i] = t
508 }
509 }
510 return res
511 }
512
View as plain text