1 // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
2 // Source: ../../cmd/compile/internal/types2/operand.go
3 4 // Copyright 2012 The Go Authors. All rights reserved.
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file.
7 8 // This file defines operands and associated operations.
9 10 package types
11 12 import (
13 "bytes"
14 "fmt"
15 "go/ast"
16 "go/constant"
17 "go/token"
18 . "internal/types/errors"
19 )
20 21 // An operandMode specifies the (addressing) mode of an operand.
22 type operandMode byte
23 24 const (
25 invalid operandMode = iota // operand is invalid
26 novalue // operand represents no value (result of a function call w/o result)
27 builtin // operand is a built-in function
28 typexpr // operand is a type
29 constant_ // operand is a constant; the operand's typ is a Basic type
30 variable // operand is an addressable variable
31 mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
32 value // operand is a computed value
33 nilvalue // operand is the nil value - only used by types2
34 commaok // like value, but operand may be used in a comma,ok expression
35 commaerr // like commaok, but second value is error, not boolean
36 cgofunc // operand is a cgo function
37 )
38 39 var operandModeString = [...]string{
40 invalid: "invalid operand",
41 novalue: "no value",
42 builtin: "built-in",
43 typexpr: "type",
44 constant_: "constant",
45 variable: "variable",
46 mapindex: "map index expression",
47 value: "value",
48 nilvalue: "nil", // only used by types2
49 commaok: "comma, ok expression",
50 commaerr: "comma, error expression",
51 cgofunc: "cgo function",
52 }
53 54 // An operand represents an intermediate value during type checking.
55 // Operands have an (addressing) mode, the expression evaluating to
56 // the operand, the operand's type, a value for constants, and an id
57 // for built-in functions.
58 // The zero value of operand is a ready to use invalid operand.
59 type operand struct {
60 mode operandMode
61 expr ast.Expr
62 typ Type
63 val constant.Value
64 id builtinId
65 }
66 67 // Pos returns the position of the expression corresponding to x.
68 // If x is invalid the position is nopos.
69 func (x *operand) Pos() token.Pos {
70 // x.expr may not be set if x is invalid
71 if x.expr == nil {
72 return nopos
73 }
74 return x.expr.Pos()
75 }
76 77 // Operand string formats
78 // (not all "untyped" cases can appear due to the type system,
79 // but they fall out naturally here)
80 //
81 // mode format
82 //
83 // invalid <expr> ( <mode> )
84 // novalue <expr> ( <mode> )
85 // builtin <expr> ( <mode> )
86 // typexpr <expr> ( <mode> )
87 //
88 // constant <expr> (<untyped kind> <mode> )
89 // constant <expr> ( <mode> of type <typ>)
90 // constant <expr> (<untyped kind> <mode> <val> )
91 // constant <expr> ( <mode> <val> of type <typ>)
92 //
93 // variable <expr> (<untyped kind> <mode> )
94 // variable <expr> ( <mode> of type <typ>)
95 //
96 // mapindex <expr> (<untyped kind> <mode> )
97 // mapindex <expr> ( <mode> of type <typ>)
98 //
99 // value <expr> (<untyped kind> <mode> )
100 // value <expr> ( <mode> of type <typ>)
101 //
102 // nilvalue untyped nil
103 // nilvalue nil ( of type <typ>)
104 //
105 // commaok <expr> (<untyped kind> <mode> )
106 // commaok <expr> ( <mode> of type <typ>)
107 //
108 // commaerr <expr> (<untyped kind> <mode> )
109 // commaerr <expr> ( <mode> of type <typ>)
110 //
111 // cgofunc <expr> (<untyped kind> <mode> )
112 // cgofunc <expr> ( <mode> of type <typ>)
113 func operandString(x *operand, qf Qualifier) string {
114 // special-case nil
115 if isTypes2 {
116 if x.mode == nilvalue {
117 switch x.typ {
118 case nil, Typ[Invalid]:
119 return "nil (with invalid type)"
120 case Typ[UntypedNil]:
121 return "nil"
122 default:
123 return fmt.Sprintf("nil (of type %s)", TypeString(x.typ, qf))
124 }
125 }
126 } else { // go/types
127 if x.mode == value && x.typ == Typ[UntypedNil] {
128 return "nil"
129 }
130 }
131 132 var buf bytes.Buffer
133 134 var expr string
135 if x.expr != nil {
136 expr = ExprString(x.expr)
137 } else {
138 switch x.mode {
139 case builtin:
140 expr = predeclaredFuncs[x.id].name
141 case typexpr:
142 expr = TypeString(x.typ, qf)
143 case constant_:
144 expr = x.val.String()
145 }
146 }
147 148 // <expr> (
149 if expr != "" {
150 buf.WriteString(expr)
151 buf.WriteString(" (")
152 }
153 154 // <untyped kind>
155 hasType := false
156 switch x.mode {
157 case invalid, novalue, builtin, typexpr:
158 // no type
159 default:
160 // should have a type, but be cautious (don't crash during printing)
161 if x.typ != nil {
162 if isUntyped(x.typ) {
163 buf.WriteString(x.typ.(*Basic).name)
164 buf.WriteByte(' ')
165 break
166 }
167 hasType = true
168 }
169 }
170 171 // <mode>
172 buf.WriteString(operandModeString[x.mode])
173 174 // <val>
175 if x.mode == constant_ {
176 if s := x.val.String(); s != expr {
177 buf.WriteByte(' ')
178 buf.WriteString(s)
179 }
180 }
181 182 // <typ>
183 if hasType {
184 if isValid(x.typ) {
185 var desc string
186 if isGeneric(x.typ) {
187 desc = "generic "
188 }
189 190 // Describe the type structure if it is an *Alias or *Named type.
191 // If the type is a renamed basic type, describe the basic type,
192 // as in "int32 type MyInt" for a *Named type MyInt.
193 // If it is a type parameter, describe the constraint instead.
194 tpar, _ := Unalias(x.typ).(*TypeParam)
195 if tpar == nil {
196 switch x.typ.(type) {
197 case *Alias, *Named:
198 what := compositeKind(x.typ)
199 if what == "" {
200 // x.typ must be basic type
201 what = under(x.typ).(*Basic).name
202 }
203 desc += what + " "
204 }
205 }
206 // desc is "" or has a trailing space at the end
207 208 buf.WriteString(" of " + desc + "type ")
209 WriteType(&buf, x.typ, qf)
210 211 if tpar != nil {
212 buf.WriteString(" constrained by ")
213 WriteType(&buf, tpar.bound, qf) // do not compute interface type sets here
214 // If we have the type set and it's empty, say so for better error messages.
215 if hasEmptyTypeset(tpar) {
216 buf.WriteString(" with empty type set")
217 }
218 }
219 } else {
220 buf.WriteString(" with invalid type")
221 }
222 }
223 224 // )
225 if expr != "" {
226 buf.WriteByte(')')
227 }
228 229 return buf.String()
230 }
231 232 // compositeKind returns the kind of the given composite type
233 // ("array", "slice", etc.) or the empty string if typ is not
234 // composite but a basic type.
235 func compositeKind(typ Type) string {
236 switch under(typ).(type) {
237 case *Basic:
238 return ""
239 case *Array:
240 return "array"
241 case *Slice:
242 return "slice"
243 case *Struct:
244 return "struct"
245 case *Pointer:
246 return "pointer"
247 case *Signature:
248 return "func"
249 case *Interface:
250 return "interface"
251 case *Map:
252 return "map"
253 case *Chan:
254 return "chan"
255 case *Tuple:
256 return "tuple"
257 case *Union:
258 return "union"
259 default:
260 panic("unreachable")
261 }
262 }
263 264 func (x *operand) String() string {
265 return operandString(x, nil)
266 }
267 268 // setConst sets x to the untyped constant for literal lit.
269 func (x *operand) setConst(k token.Token, lit string) {
270 var kind BasicKind
271 switch k {
272 case token.INT:
273 kind = UntypedInt
274 case token.FLOAT:
275 kind = UntypedFloat
276 case token.IMAG:
277 kind = UntypedComplex
278 case token.CHAR:
279 kind = UntypedRune
280 case token.STRING:
281 kind = UntypedString
282 default:
283 panic("unreachable")
284 }
285 286 val := makeFromLiteral(lit, k)
287 if val.Kind() == constant.Unknown {
288 x.mode = invalid
289 x.typ = Typ[Invalid]
290 return
291 }
292 x.mode = constant_
293 x.typ = Typ[kind]
294 x.val = val
295 }
296 297 // isNil reports whether x is the (untyped) nil value.
298 func (x *operand) isNil() bool {
299 if isTypes2 {
300 return x.mode == nilvalue
301 } else { // go/types
302 return x.mode == value && x.typ == Typ[UntypedNil]
303 }
304 }
305 306 // assignableTo reports whether x is assignable to a variable of type T. If the
307 // result is false and a non-nil cause is provided, it may be set to a more
308 // detailed explanation of the failure (result != ""). The returned error code
309 // is only valid if the (first) result is false. The check parameter may be nil
310 // if assignableTo is invoked through an exported API call, i.e., when all
311 // methods have been type-checked.
312 func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
313 if x.mode == invalid || !isValid(T) {
314 return true, 0 // avoid spurious errors
315 }
316 317 origT := T
318 V := Unalias(x.typ)
319 T = Unalias(T)
320 321 // x's type is identical to T
322 if Identical(V, T) {
323 return true, 0
324 }
325 326 Vu := under(V)
327 Tu := under(T)
328 Vp, _ := V.(*TypeParam)
329 Tp, _ := T.(*TypeParam)
330 331 // x is an untyped value representable by a value of type T.
332 if isUntyped(Vu) {
333 assert(Vp == nil)
334 if Tp != nil {
335 // T is a type parameter: x is assignable to T if it is
336 // representable by each specific type in the type set of T.
337 return Tp.is(func(t *term) bool {
338 if t == nil {
339 return false
340 }
341 // A term may be a tilde term but the underlying
342 // type of an untyped value doesn't change so we
343 // don't need to do anything special.
344 newType, _, _ := check.implicitTypeAndValue(x, t.typ)
345 return newType != nil
346 }), IncompatibleAssign
347 }
348 newType, _, _ := check.implicitTypeAndValue(x, T)
349 return newType != nil, IncompatibleAssign
350 }
351 // Vu is typed
352 353 // x's type V and T have identical underlying types
354 // and at least one of V or T is not a named type
355 // and neither V nor T is a type parameter.
356 if Identical(Vu, Tu) && (!hasName(V) || !hasName(T)) && Vp == nil && Tp == nil {
357 return true, 0
358 }
359 360 // Moxie: string and []byte are mutually assignable.
361 if (isString(Vu) && isByteSlice(Tu)) || (isByteSlice(Vu) && isString(Tu)) {
362 return true, 0
363 }
364 365 // T is an interface type, but not a type parameter, and V implements T.
366 // Also handle the case where T is a pointer to an interface so that we get
367 // the Checker.implements error cause.
368 if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
369 if check.implements(V, T, false, cause) {
370 return true, 0
371 }
372 // V doesn't implement T but V may still be assignable to T if V
373 // is a type parameter; do not report an error in that case yet.
374 if Vp == nil {
375 return false, InvalidIfaceAssign
376 }
377 if cause != nil {
378 *cause = ""
379 }
380 }
381 382 // If V is an interface, check if a missing type assertion is the problem.
383 if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
384 if check.implements(T, V, false, nil) {
385 // T implements V, so give hint about type assertion.
386 if cause != nil {
387 *cause = "need type assertion"
388 }
389 return false, IncompatibleAssign
390 }
391 }
392 393 // x is a bidirectional channel value, T is a channel
394 // type, x's type V and T have identical element types,
395 // and at least one of V or T is not a named type.
396 if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
397 if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
398 return !hasName(V) || !hasName(T), InvalidChanAssign
399 }
400 }
401 402 // optimization: if we don't have type parameters, we're done
403 if Vp == nil && Tp == nil {
404 return false, IncompatibleAssign
405 }
406 407 errorf := func(format string, args ...any) {
408 if check != nil && cause != nil {
409 msg := check.sprintf(format, args...)
410 if *cause != "" {
411 msg += "\n\t" + *cause
412 }
413 *cause = msg
414 }
415 }
416 417 // x's type V is not a named type and T is a type parameter, and
418 // x is assignable to each specific type in T's type set.
419 if !hasName(V) && Tp != nil {
420 ok := false
421 code := IncompatibleAssign
422 Tp.is(func(T *term) bool {
423 if T == nil {
424 return false // no specific types
425 }
426 ok, code = x.assignableTo(check, T.typ, cause)
427 if !ok {
428 errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
429 return false
430 }
431 return true
432 })
433 return ok, code
434 }
435 436 // x's type V is a type parameter and T is not a named type,
437 // and values x' of each specific type in V's type set are
438 // assignable to T.
439 if Vp != nil && !hasName(T) {
440 x := *x // don't clobber outer x
441 ok := false
442 code := IncompatibleAssign
443 Vp.is(func(V *term) bool {
444 if V == nil {
445 return false // no specific types
446 }
447 x.typ = V.typ
448 ok, code = x.assignableTo(check, T, cause)
449 if !ok {
450 errorf("cannot assign %s (in %s) to %s", V.typ, Vp, origT)
451 return false
452 }
453 return true
454 })
455 return ok, code
456 }
457 458 return false, IncompatibleAssign
459 }
460