1
2
3
4
5
6
7 package types2
8
9 import (
10 "bytes"
11 "cmd/compile/internal/syntax"
12 "fmt"
13 "go/constant"
14 . "internal/types/errors"
15 )
16
17
18 type operandMode byte
19
20 const (
21 invalid operandMode = iota
22 novalue
23 builtin
24 typexpr
25 constant_
26 variable
27 mapindex
28 value
29 nilvalue
30 commaok
31 commaerr
32 cgofunc
33 )
34
35 var operandModeString = [...]string{
36 invalid: "invalid operand",
37 novalue: "no value",
38 builtin: "built-in",
39 typexpr: "type",
40 constant_: "constant",
41 variable: "variable",
42 mapindex: "map index expression",
43 value: "value",
44 nilvalue: "nil",
45 commaok: "comma, ok expression",
46 commaerr: "comma, error expression",
47 cgofunc: "cgo function",
48 }
49
50
51
52
53
54
55 type operand struct {
56 mode_ operandMode
57 expr syntax.Expr
58 typ_ Type
59 val constant.Value
60 id builtinId
61 }
62
63 func (x *operand) mode() operandMode {
64 return x.mode_
65 }
66
67 func (x *operand) typ() Type {
68 return x.typ_
69 }
70
71 func (x *operand) isValid() bool {
72 return x.mode() != invalid
73 }
74
75 func (x *operand) invalidate() {
76 x.mode_ = invalid
77 }
78
79
80
81 func (x *operand) Pos() syntax.Pos {
82
83 if x.expr == nil {
84 return nopos
85 }
86 return x.expr.Pos()
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 func operandString(x *operand, qf Qualifier) string {
126
127 if isTypes2 {
128 if x.mode() == nilvalue {
129 switch x.typ() {
130 case nil, Typ[Invalid]:
131 return "nil (with invalid type)"
132 case Typ[UntypedNil]:
133 return "nil"
134 default:
135 return fmt.Sprintf("nil (of type %s)", TypeString(x.typ(), qf))
136 }
137 }
138 } else {
139 if x.mode() == value && x.typ() == Typ[UntypedNil] {
140 return "nil"
141 }
142 }
143
144 var buf bytes.Buffer
145
146 var expr string
147 if x.expr != nil {
148 expr = ExprString(x.expr)
149 } else {
150 switch x.mode() {
151 case builtin:
152 expr = predeclaredFuncs[x.id].name
153 case typexpr:
154 expr = TypeString(x.typ(), qf)
155 case constant_:
156 expr = x.val.String()
157 }
158 }
159
160
161 if expr != "" {
162 buf.WriteString(expr)
163 buf.WriteString(" (")
164 }
165
166
167 hasType := false
168 switch x.mode() {
169 case invalid, novalue, builtin, typexpr:
170
171 default:
172
173 if x.typ() != nil {
174 if isUntyped(x.typ()) {
175 buf.WriteString(x.typ().(*Basic).name)
176 buf.WriteByte(' ')
177 break
178 }
179 hasType = true
180 }
181 }
182
183
184 buf.WriteString(operandModeString[x.mode()])
185
186
187 if x.mode() == constant_ {
188 if s := x.val.String(); s != expr {
189 buf.WriteByte(' ')
190 buf.WriteString(s)
191 }
192 }
193
194
195 if hasType {
196 if isValid(x.typ()) {
197 var desc string
198 if isGeneric(x.typ()) {
199 desc = "generic "
200 }
201
202
203
204
205
206 tpar, _ := Unalias(x.typ()).(*TypeParam)
207 if tpar == nil {
208 switch x.typ().(type) {
209 case *Alias, *Named:
210 what := compositeKind(x.typ())
211 if what == "" {
212
213 what = x.typ().Underlying().(*Basic).name
214 }
215 desc += what + " "
216 }
217 }
218
219
220 buf.WriteString(" of " + desc + "type ")
221 WriteType(&buf, x.typ(), qf)
222
223 if tpar != nil {
224 buf.WriteString(" constrained by ")
225 WriteType(&buf, tpar.bound, qf)
226
227 if hasEmptyTypeset(tpar) {
228 buf.WriteString(" with empty type set")
229 }
230 }
231 } else {
232 buf.WriteString(" with invalid type")
233 }
234 }
235
236
237 if expr != "" {
238 buf.WriteByte(')')
239 }
240
241 return buf.String()
242 }
243
244
245
246
247 func compositeKind(typ Type) string {
248 switch typ.Underlying().(type) {
249 case *Basic:
250 return ""
251 case *Array:
252 return "array"
253 case *Slice:
254 return "slice"
255 case *Struct:
256 return "struct"
257 case *Pointer:
258 return "pointer"
259 case *Signature:
260 return "func"
261 case *Interface:
262 return "interface"
263 case *Map:
264 return "map"
265 case *Chan:
266 return "chan"
267 case *Tuple:
268 return "tuple"
269 case *Union:
270 return "union"
271 default:
272 panic("unreachable")
273 }
274 }
275
276 func (x *operand) String() string {
277 return operandString(x, nil)
278 }
279
280
281 func (x *operand) setConst(k syntax.LitKind, lit string) {
282 var kind BasicKind
283 switch k {
284 case syntax.IntLit:
285 kind = UntypedInt
286 case syntax.FloatLit:
287 kind = UntypedFloat
288 case syntax.ImagLit:
289 kind = UntypedComplex
290 case syntax.RuneLit:
291 kind = UntypedRune
292 case syntax.StringLit:
293 kind = UntypedString
294 default:
295 panic("unreachable")
296 }
297
298 val := makeFromLiteral(lit, k)
299 if val.Kind() == constant.Unknown {
300 x.invalidate()
301 x.typ_ = Typ[Invalid]
302 return
303 }
304 x.mode_ = constant_
305 x.typ_ = Typ[kind]
306 x.val = val
307 }
308
309
310 func (x *operand) isNil() bool {
311 if isTypes2 {
312 return x.mode() == nilvalue
313 } else {
314 return x.mode() == value && x.typ() == Typ[UntypedNil]
315 }
316 }
317
318
319
320
321
322
323
324 func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
325 if !x.isValid() || !isValid(T) {
326 return true, 0
327 }
328
329 origT := T
330 V := Unalias(x.typ())
331 T = Unalias(T)
332
333
334 if Identical(V, T) {
335 return true, 0
336 }
337
338 Vu := V.Underlying()
339 Tu := T.Underlying()
340 Vp, _ := V.(*TypeParam)
341 Tp, _ := T.(*TypeParam)
342
343
344 if isUntyped(Vu) {
345 assert(Vp == nil)
346 if Tp != nil {
347
348
349 return Tp.is(func(t *term) bool {
350 if t == nil {
351 return false
352 }
353
354
355
356 newType, _, _ := check.implicitTypeAndValue(x, t.typ)
357 return newType != nil
358 }), IncompatibleAssign
359 }
360 newType, _, _ := check.implicitTypeAndValue(x, T)
361 return newType != nil, IncompatibleAssign
362 }
363
364
365
366
367
368 if Identical(Vu, Tu) && (!hasName(V) || !hasName(T)) && Vp == nil && Tp == nil {
369 return true, 0
370 }
371
372
373
374
375 if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
376 if check.implements(V, T, false, cause) {
377 return true, 0
378 }
379
380
381 if Vp == nil {
382 return false, InvalidIfaceAssign
383 }
384 if cause != nil {
385 *cause = ""
386 }
387 }
388
389
390 if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
391 if check.implements(T, V, false, nil) {
392
393 if cause != nil {
394 *cause = "need type assertion"
395 }
396 return false, IncompatibleAssign
397 }
398 }
399
400
401
402
403 if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
404 if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
405 return !hasName(V) || !hasName(T), InvalidChanAssign
406 }
407 }
408
409
410 if Vp == nil && Tp == nil {
411 return false, IncompatibleAssign
412 }
413
414 errorf := func(format string, args ...any) {
415 if check != nil && cause != nil {
416 msg := check.sprintf(format, args...)
417 if *cause != "" {
418 msg += "\n\t" + *cause
419 }
420 *cause = msg
421 }
422 }
423
424
425
426 if !hasName(V) && Tp != nil {
427 ok := false
428 code := IncompatibleAssign
429 Tp.is(func(T *term) bool {
430 if T == nil {
431 return false
432 }
433 ok, code = x.assignableTo(check, T.typ, cause)
434 if !ok {
435 errorf("cannot assign %s to %s (in %s)", x.typ(), T.typ, Tp)
436 return false
437 }
438 return true
439 })
440 return ok, code
441 }
442
443
444
445
446 if Vp != nil && !hasName(T) {
447 x := *x
448 ok := false
449 code := IncompatibleAssign
450 Vp.is(func(V *term) bool {
451 if V == nil {
452 return false
453 }
454 x.typ_ = V.typ
455 ok, code = x.assignableTo(check, T, cause)
456 if !ok {
457 errorf("cannot assign %s (in %s) to %s", V.typ, Vp, origT)
458 return false
459 }
460 return true
461 })
462 return ok, code
463 }
464
465 return false, IncompatibleAssign
466 }
467
View as plain text