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