]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/types2/typexpr.go
cabf4eb856a0d5b5ba96e03ee2b0d54cca029688
[gostls13.git] / src / cmd / compile / internal / types2 / typexpr.go
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file implements type-checking of identifiers and type expressions.
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 // ident type-checks identifier e and initializes x with the value or type of e.
18 // If an error occurred, x.mode is set to invalid.
19 // For the meaning of def, see Checker.definedType, below.
20 // If wantType is set, the identifier e is expected to denote a type.
21 func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType bool) {
22         x.mode = invalid
23         x.expr = e
24
25         // Note that we cannot use check.lookup here because the returned scope
26         // may be different from obj.Parent(). See also Scope.LookupParent doc.
27         scope, obj := check.scope.LookupParent(e.Value, check.pos)
28         switch obj {
29         case nil:
30                 if e.Value == "_" {
31                         // Blank identifiers are never declared, but the current identifier may
32                         // be a placeholder for a receiver type parameter. In this case we can
33                         // resolve its type and object from Checker.recvTParamMap.
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 // avoid follow-on errors
47                 }
48         }
49         check.recordUse(e, obj)
50
51         // Type-check the object.
52         // Only call Checker.objDecl if the object doesn't have a type yet
53         // (in which case we must actually determine it) or the object is a
54         // TypeName and we also want a type (in which case we might detect
55         // a cycle which needs to be reported). Otherwise we can skip the
56         // call and avoid a possible cycle error in favor of the more
57         // informative "not a type/value" error that this function's caller
58         // will issue (see go.dev/issue/25790).
59         typ := obj.Type()
60         if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
61                 check.objDecl(obj, def)
62                 typ = obj.Type() // type must have been assigned by Checker.objDecl
63         }
64         assert(typ != nil)
65
66         // The object may have been dot-imported.
67         // If so, mark the respective package as used.
68         // (This code is only needed for dot-imports. Without them,
69         // we only have to mark variables, see *Var case below).
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.conf._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                 // It's ok to mark non-local variables, but ignore variables
105                 // from other packages to avoid potential race conditions with
106                 // dot-imported variables.
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 // typ type-checks the type expression e and returns its type, or Typ[Invalid].
135 // The type must not be an (uninstantiated) generic type.
136 func (check *Checker) typ(e syntax.Expr) Type {
137         return check.definedType(e, nil)
138 }
139
140 // varType type-checks the type expression e and returns its type, or Typ[Invalid].
141 // The type must not be an (uninstantiated) generic type and it must not be a
142 // constraint interface.
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 // validVarType reports an error if typ is a constraint interface.
150 // The expression e is used for error reporting, if any.
151 func (check *Checker) validVarType(e syntax.Expr, typ Type) {
152         // If we have a type parameter there's nothing to do.
153         if isTypeParam(typ) {
154                 return
155         }
156
157         // We don't want to call under() or complete interfaces while we are in
158         // the middle of type-checking parameter declarations that might belong
159         // to interface methods. Delay this check to the end of type-checking.
160         check.later(func() {
161                 if t, _ := under(typ).(*Interface); t != nil {
162                         pos := syntax.StartPos(e)
163                         tset := computeInterfaceTypeSet(check, pos, t) // TODO(gri) is this the correct position?
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 // definedType is like typ but also accepts a type name def.
176 // If def != nil, e is the type specification for the type named def, declared
177 // in a type declaration, and def.typ.underlying will be set to the type of e
178 // before any components of e are type-checked.
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 // genericType is like typ but the type must be an (uninstantiated) generic
191 // type. If cause is non-nil and the type expression was a valid type but not
192 // generic, cause will be populated with a message describing the error.
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         // TODO(gri) what is the correct call below?
203         check.recordTypeAndValue(e, typexpr, typ, nil)
204         return typ
205 }
206
207 // goTypeName returns the Go type name for typ and
208 // removes any occurrences of "types2." from that name.
209 func goTypeName(typ Type) string {
210         return strings.ReplaceAll(fmt.Sprintf("%T", typ), "types2.", "")
211 }
212
213 // typInternal drives type checking of types.
214 // Must only be called by definedType or genericType.
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                                 // Calling under() here may lead to endless instantiations.
224                                 // Test case: type T[P any] *T[P]
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                 // ignore - error reported before
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                         // ignore - error reported before
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                         // ignore - error reported before
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                 // Generic types must be instantiated before they can be used in any form.
279                 // Consequently, generic types cannot be parenthesized.
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                         // [...]array
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                 // report error if we encountered [...]
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                 // dots are handled explicitly where they are legal
306                 // (array composite literals and parameter lists)
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] // avoid nil base in invalid recursive type declaration
320                         setDefType(def, typ)
321                         typ.base = check.varType(e.X)
322                         // If typ.base is invalid, it's unlikely that *base is particularly
323                         // useful - even a valid dereferenciation will lead to an invalid
324                         // type again, and in some cases we get unexpected follow-on errors
325                         // (e.g., go.dev/issue/49005). Return an invalid type instead.
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                 // spec: "The comparison operators == and != must be fully defined
355                 // for operands of the key type; thus the key type must not be a
356                 // function, map, or slice."
357                 //
358                 // Delay this check because it requires fully setup types;
359                 // it is safe to continue in any case (was go.dev/issue/6667).
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                         // nothing to do
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                         // ok to continue
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                         // t.fromRHS should always be set, either to an invalid type
408                         // in the beginning, or to typ in certain cyclic declarations.
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                         // Don't format the underlying here. It will always be nil.
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 // error already reported
441         }
442
443         orig := asNamed(gtyp)
444         if orig == nil {
445                 panic(fmt.Sprintf("%v: cannot instantiate %v", x.Pos(), gtyp))
446         }
447
448         // evaluate arguments
449         targs := check.typeList(xlist)
450         if targs == nil {
451                 setDefType(def, Typ[Invalid]) // avoid errors later due to lazy instantiation
452                 return Typ[Invalid]
453         }
454
455         // create the instance
456         inst := asNamed(check.instance(x.Pos(), orig, targs, nil, check.context()))
457         setDefType(def, inst)
458
459         // orig.tparams may not be set up, so we need to do expansion later.
460         check.later(func() {
461                 // This is an instance from the source, not from recursive substitution,
462                 // and so it must be resolved during type-checking so that we can report
463                 // errors.
464                 check.recordInstance(x, inst.TypeArgs().list(), inst)
465
466                 if check.validateTArgLen(x.Pos(), 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                                 // best position for error reporting
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                 // TODO(rfindley): remove this call: we don't need to call validType here,
480                 // as cycles can only occur for types used inside a Named type declaration,
481                 // and so it suffices to call validType from declared types.
482                 check.validType(inst)
483         }).describef(x, "resolve instance %s", inst)
484
485         return inst
486 }
487
488 // arrayLength type-checks the array length expression e
489 // and returns the constant length >= 0, or a value < 0
490 // to indicate an error (and thus an unknown length).
491 func (check *Checker) arrayLength(e syntax.Expr) int64 {
492         // If e is an identifier, the array declaration might be an
493         // attempt at a parameterized type declaration with missing
494         // constraint. Provide an error message that mentions array
495         // length.
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 // typeList provides the list of types corresponding to the incoming expression list.
538 // If an error occurred, the result is nil, but all list elements were type-checked.
539 func (check *Checker) typeList(list []syntax.Expr) []Type {
540         res := make([]Type, len(list)) // res != nil even if len(list) == 0
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 }