1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 "fmt"
12 "go/constant"
13 . "internal/types/errors"
14 "strings"
15 )
16
17
18
19
20
21 func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType bool) {
22 x.mode = invalid
23 x.expr = e
24
25
26
27 scope, obj := check.scope.LookupParent(e.Value, check.pos)
28 switch obj {
29 case nil:
30 if e.Value == "_" {
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, "undefined: %s", e.Value)
42 }
43 return
44 case universeAny, universeComparable:
45 if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Value) {
46 return
47 }
48 }
49 check.recordUse(e, obj)
50
51
52
53
54
55
56
57
58
59 typ := obj.Type()
60 if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
61 check.objDecl(obj, def)
62 typ = obj.Type()
63 }
64 assert(typ != nil)
65
66
67
68
69
70 if pkgName := check.dotImportMap[dotImportKey{scope, obj.Name()}]; pkgName != nil {
71 pkgName.used = true
72 }
73
74 switch obj := obj.(type) {
75 case *PkgName:
76 check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
77 return
78
79 case *Const:
80 check.addDeclDep(obj)
81 if !isValid(typ) {
82 return
83 }
84 if obj == universeIota {
85 if check.iota == nil {
86 check.error(e, InvalidIota, "cannot use iota outside constant declaration")
87 return
88 }
89 x.val = check.iota
90 } else {
91 x.val = obj.val
92 }
93 assert(x.val != nil)
94 x.mode = constant_
95
96 case *TypeName:
97 if !check.enableAlias && check.isBrokenAlias(obj) {
98 check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name)
99 return
100 }
101 x.mode = typexpr
102
103 case *Var:
104
105
106
107 if obj.pkg == check.pkg {
108 obj.used = true
109 }
110 check.addDeclDep(obj)
111 if !isValid(typ) {
112 return
113 }
114 x.mode = variable
115
116 case *Func:
117 check.addDeclDep(obj)
118 x.mode = value
119
120 case *Builtin:
121 x.id = obj.id
122 x.mode = builtin
123
124 case *Nil:
125 x.mode = nilvalue
126
127 default:
128 unreachable()
129 }
130
131 x.typ = typ
132 }
133
134
135
136 func (check *Checker) typ(e syntax.Expr) Type {
137 return check.definedType(e, nil)
138 }
139
140
141
142
143 func (check *Checker) varType(e syntax.Expr) Type {
144 typ := check.definedType(e, nil)
145 check.validVarType(e, typ)
146 return typ
147 }
148
149
150
151 func (check *Checker) validVarType(e syntax.Expr, typ Type) {
152
153 if isTypeParam(typ) {
154 return
155 }
156
157
158
159
160 check.later(func() {
161 if t, _ := under(typ).(*Interface); t != nil {
162 pos := syntax.StartPos(e)
163 tset := computeInterfaceTypeSet(check, pos, t)
164 if !tset.IsMethodSet() {
165 if tset.comparable {
166 check.softErrorf(pos, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
167 } else {
168 check.softErrorf(pos, 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 syntax.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 syntax.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), "types2.", "")
211 }
212
213
214
215 func (check *Checker) typInternal(e0 syntax.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 *syntax.BadExpr:
237
238
239 case *syntax.Name:
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 *syntax.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 *syntax.IndexExpr:
274 check.verifyVersionf(e, go1_18, "type instantiation")
275 return check.instantiatedType(e.X, syntax.UnpackListExpr(e.Index), def)
276
277 case *syntax.ParenExpr:
278
279
280 return check.definedType(e.X, def)
281
282 case *syntax.ArrayType:
283 typ := new(Array)
284 setDefType(def, typ)
285 if e.Len != nil {
286 typ.len = check.arrayLength(e.Len)
287 } else {
288
289 check.error(e, BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
290 typ.len = -1
291 }
292 typ.elem = check.varType(e.Elem)
293 if typ.len >= 0 {
294 return typ
295 }
296
297
298 case *syntax.SliceType:
299 typ := new(Slice)
300 setDefType(def, typ)
301 typ.elem = check.varType(e.Elem)
302 return typ
303
304 case *syntax.DotsType:
305
306
307 check.error(e, InvalidDotDotDot, "invalid use of '...'")
308 check.use(e.Elem)
309
310 case *syntax.StructType:
311 typ := new(Struct)
312 setDefType(def, typ)
313 check.structType(typ, e)
314 return typ
315
316 case *syntax.Operation:
317 if e.Op == syntax.Mul && e.Y == nil {
318 typ := new(Pointer)
319 typ.base = Typ[Invalid]
320 setDefType(def, typ)
321 typ.base = check.varType(e.X)
322
323
324
325
326 if !isValid(typ.base) {
327 return Typ[Invalid]
328 }
329 return typ
330 }
331
332 check.errorf(e0, NotAType, "%s is not a type", e0)
333 check.use(e0)
334
335 case *syntax.FuncType:
336 typ := new(Signature)
337 setDefType(def, typ)
338 check.funcType(typ, nil, nil, e)
339 return typ
340
341 case *syntax.InterfaceType:
342 typ := check.newInterface()
343 setDefType(def, typ)
344 check.interfaceType(typ, e, def)
345 return typ
346
347 case *syntax.MapType:
348 typ := new(Map)
349 setDefType(def, typ)
350
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 *syntax.ChanType:
373 typ := new(Chan)
374 setDefType(def, typ)
375
376 dir := SendRecv
377 switch e.Dir {
378 case 0:
379
380 case syntax.SendOnly:
381 dir = SendOnly
382 case syntax.RecvOnly:
383 dir = RecvOnly
384 default:
385 check.errorf(e, InvalidSyntaxTree, "unknown channel direction %d", e.Dir)
386
387 }
388
389 typ.dir = dir
390 typ.elem = check.varType(e.Elem)
391 return typ
392
393 default:
394 check.errorf(e0, NotAType, "%s is not a type", e0)
395 check.use(e0)
396 }
397
398 typ := Typ[Invalid]
399 setDefType(def, typ)
400 return typ
401 }
402
403 func setDefType(def *TypeName, typ Type) {
404 if def != nil {
405 switch t := def.typ.(type) {
406 case *Alias:
407
408
409 if t.fromRHS != Typ[Invalid] && t.fromRHS != typ {
410 panic(sprintf(nil, true, "t.fromRHS = %s, typ = %s\n", t.fromRHS, typ))
411 }
412 t.fromRHS = typ
413 case *Basic:
414 assert(t == Typ[Invalid])
415 case *Named:
416 t.underlying = typ
417 default:
418 panic(fmt.Sprintf("unexpected type %T", t))
419 }
420 }
421 }
422
423 func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *TypeName) (res Type) {
424 if check.conf.Trace {
425 check.trace(x.Pos(), "-- instantiating type %s with %s", x, xlist)
426 check.indent++
427 defer func() {
428 check.indent--
429
430 check.trace(x.Pos(), "=> %s", res)
431 }()
432 }
433
434 var cause string
435 gtyp := check.genericType(x, &cause)
436 if cause != "" {
437 check.errorf(x, NotAGenericType, invalidOp+"%s%s (%s)", x, xlist, cause)
438 }
439 if !isValid(gtyp) {
440 return gtyp
441 }
442
443 orig := asNamed(gtyp)
444 if orig == nil {
445 panic(fmt.Sprintf("%v: cannot instantiate %v", x.Pos(), gtyp))
446 }
447
448
449 targs := check.typeList(xlist)
450 if targs == nil {
451 setDefType(def, Typ[Invalid])
452 return Typ[Invalid]
453 }
454
455
456 inst := asNamed(check.instance(x.Pos(), orig, targs, nil, check.context()))
457 setDefType(def, inst)
458
459
460 check.later(func() {
461
462
463
464 check.recordInstance(x, inst.TypeArgs().list(), inst)
465
466 if check.validateTArgLen(x.Pos(), inst.obj.name, inst.TypeParams().Len(), inst.TypeArgs().Len()) {
467 if i, err := check.verify(x.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), check.context()); err != nil {
468
469 pos := x.Pos()
470 if i < len(xlist) {
471 pos = syntax.StartPos(xlist[i])
472 }
473 check.softErrorf(pos, InvalidTypeArg, "%s", err)
474 } else {
475 check.mono.recordInstance(check.pkg, x.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), xlist)
476 }
477 }
478
479
480
481
482 check.validType(inst)
483 }).describef(x, "resolve instance %s", inst)
484
485 return inst
486 }
487
488
489
490
491 func (check *Checker) arrayLength(e syntax.Expr) int64 {
492
493
494
495
496 if name, _ := e.(*syntax.Name); name != nil {
497 obj := check.lookup(name.Value)
498 if obj == nil {
499 check.errorf(name, InvalidArrayLen, "undefined array length %s or missing type constraint", name.Value)
500 return -1
501 }
502 if _, ok := obj.(*Const); !ok {
503 check.errorf(name, InvalidArrayLen, "invalid array length %s", name.Value)
504 return -1
505 }
506 }
507
508 var x operand
509 check.expr(nil, &x, e)
510 if x.mode != constant_ {
511 if x.mode != invalid {
512 check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
513 }
514 return -1
515 }
516
517 if isUntyped(x.typ) || isInteger(x.typ) {
518 if val := constant.ToInt(x.val); val.Kind() == constant.Int {
519 if representableConst(val, check, Typ[Int], nil) {
520 if n, ok := constant.Int64Val(val); ok && n >= 0 {
521 return n
522 }
523 }
524 }
525 }
526
527 var msg string
528 if isInteger(x.typ) {
529 msg = "invalid array length %s"
530 } else {
531 msg = "array length %s must be integer"
532 }
533 check.errorf(&x, InvalidArrayLen, msg, &x)
534 return -1
535 }
536
537
538
539 func (check *Checker) typeList(list []syntax.Expr) []Type {
540 res := make([]Type, len(list))
541 for i, x := range list {
542 t := check.varType(x)
543 if !isValid(t) {
544 res = nil
545 }
546 if res != nil {
547 res[i] = t
548 }
549 }
550 return res
551 }
552
View as plain text