Source file
src/go/types/literals.go
1
2
3
4
5
6
7
8
9
10 package types
11
12 import (
13 "go/ast"
14 "go/token"
15 . "internal/types/errors"
16 "strings"
17 )
18
19
20
21 func (check *Checker) langCompat(lit *ast.BasicLit) {
22 s := lit.Value
23 if len(s) <= 2 || check.allowVersion(go1_13) {
24 return
25 }
26
27 if strings.Contains(s, "_") {
28 check.versionErrorf(lit, go1_13, "underscore in numeric literal")
29 return
30 }
31 if s[0] != '0' {
32 return
33 }
34 radix := s[1]
35 if radix == 'b' || radix == 'B' {
36 check.versionErrorf(lit, go1_13, "binary literal")
37 return
38 }
39 if radix == 'o' || radix == 'O' {
40 check.versionErrorf(lit, go1_13, "0o/0O-style octal literal")
41 return
42 }
43 if lit.Kind != token.INT && (radix == 'x' || radix == 'X') {
44 check.versionErrorf(lit, go1_13, "hexadecimal floating-point literal")
45 }
46 }
47
48 func (check *Checker) basicLit(x *operand, e *ast.BasicLit) {
49 switch e.Kind {
50 case token.INT, token.FLOAT, token.IMAG:
51 check.langCompat(e)
52
53
54
55
56
57
58
59
60
61 const limit = 10000
62 if len(e.Value) > limit {
63 check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
64 x.invalidate()
65 return
66 }
67 }
68 x.setConst(e.Kind, e.Value)
69 if !x.isValid() {
70
71
72
73
74 check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
75 x.invalidate()
76 return
77 }
78
79 x.expr = e
80 check.overflow(x, opPos(x.expr))
81 }
82
83 func (check *Checker) funcLit(x *operand, e *ast.FuncLit) {
84 if sig, ok := check.typ(e.Type).(*Signature); ok {
85
86
87 sig.scope.pos = e.Pos()
88 sig.scope.end = endPos(e)
89 if !check.conf.IgnoreFuncBodies && e.Body != nil {
90
91
92
93 decl := check.decl
94 iota := check.iota
95
96
97
98
99 check.later(func() {
100 check.funcBody(decl, "<function literal>", sig, e.Body, iota)
101 }).describef(e, "func literal")
102 }
103 x.mode_ = value
104 x.typ_ = sig
105 } else {
106 check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e)
107 x.invalidate()
108 }
109 }
110
111 func (check *Checker) compositeLit(U Type, x *operand, e *ast.CompositeLit, hint Type) {
112 var typ, base Type
113 var isElem bool
114
115 switch {
116 case e.Type != nil:
117
118
119
120 if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && isdddArray(atyp) {
121
122
123
124 typ = &Array{len: -1, elem: check.varType(atyp.Elt)}
125 base = typ
126 break
127 }
128 typ = check.typ(e.Type)
129 base = typ
130
131
132
133 case hint != nil:
134
135 typ = hint
136 base = typ
137
138 u, _ := commonUnder(base, nil)
139 if b, ok := deref(u); ok {
140 base = b
141 }
142 isElem = true
143
144 default:
145
146 if U != nil {
147
148 check.verifyVersionf(e, go1_28, "missing type in composite literal")
149
150 typ = U
151 base = typ
152
153 u, _ := commonUnder(base, nil)
154 if b, ok := deref(u); ok {
155 base = b
156 }
157 } else {
158
159 check.error(e, UntypedLit, "missing type in composite literal")
160
161 typ = Typ[Invalid]
162 base = typ
163 }
164 }
165
166
167 if !check.isComplete(base) {
168 x.invalidate()
169 return
170 }
171
172 switch u, _ := commonUnder(base, nil); utyp := u.(type) {
173 case *Struct:
174 if len(e.Elts) == 0 {
175 break
176 }
177
178
179
180 fields := utyp.fields
181 if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
182
183 visited := make(trie[*Var])
184 for _, e := range e.Elts {
185 kv, _ := e.(*ast.KeyValueExpr)
186 if kv == nil {
187 check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
188 continue
189 }
190 key, _ := kv.Key.(*ast.Ident)
191
192
193 if key == nil {
194 check.genericExpr(nil, x, kv.Value, nil)
195 check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
196 continue
197 }
198 obj, index, indirect := lookupFieldOrMethod(utyp, false, check.pkg, key.Name, false)
199 if obj == nil {
200 check.genericExpr(nil, x, kv.Value, nil)
201 alt, _, _ := lookupFieldOrMethod(utyp, false, check.pkg, key.Name, true)
202 msg := check.lookupError(base, key.Name, alt, true)
203 check.error(kv.Key, MissingLitField, msg)
204 continue
205 }
206 fld, _ := obj.(*Var)
207 if fld == nil {
208 check.genericExpr(nil, x, kv.Value, nil)
209 check.errorf(kv.Key, MissingLitField, "%s is not a field", kv.Key)
210 continue
211 }
212
213 etyp := fld.typ
214 check.genericExpr(etyp, x, kv.Value, nil)
215 if len(index) > 1 && !check.verifyVersionf(kv.Key, go1_27, "use of promoted field %s in struct literal of type %s", fieldPath(utyp, index), base) {
216 continue
217 }
218 if indirect {
219 check.errorf(kv.Key, InvalidLitField, "invalid implicit pointer indirection to reach %s", kv.Key)
220 continue
221 }
222 check.recordUse(key, fld)
223 check.assignment(x, etyp, "struct literal")
224 if alt, n := visited.insert(index, fld); n != 0 {
225 if fld == alt {
226 check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", fld.name)
227 } else if n < len(index) {
228 check.errorf(kv, DuplicateLitField, "cannot specify promoted field %s and enclosing embedded field %s", fld.name, alt.name)
229 } else {
230 check.errorf(kv, DuplicateLitField, "cannot specify embedded field %s and enclosed promoted field %s", fld.name, alt.name)
231 }
232 }
233 }
234 } else {
235
236 for i, e := range e.Elts {
237 if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
238 check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
239 continue
240 }
241 if i >= len(fields) {
242 check.genericExpr(nil, x, e, nil)
243 check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
244 break
245 }
246
247 fld := fields[i]
248 etyp := fld.typ
249 check.genericExpr(etyp, x, e, nil)
250 if !fld.Exported() && fld.pkg != check.pkg {
251 check.errorf(x, UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
252 continue
253 }
254 check.assignment(x, etyp, "struct literal")
255 }
256 if len(e.Elts) < len(fields) {
257 var hint string
258 for _, fld := range fields {
259 if !fld.Exported() && fld.pkg != check.pkg {
260 hint = " (type has unexported fields - use key:value pairs)"
261 break
262 }
263 }
264 check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s%s", base, hint)
265
266 }
267 }
268
269 case *Array:
270 n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
271
272
273
274
275
276
277
278
279 if utyp.len < 0 {
280 utyp.len = n
281
282
283
284
285 if e.Type != nil {
286 check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
287 }
288 }
289
290 case *Slice:
291 check.indexedElts(e.Elts, utyp.elem, -1)
292
293 case *Map:
294
295
296
297 keyIsInterface := isNonTypeParamInterface(utyp.key)
298 visited := make(map[any][]Type, len(e.Elts))
299 for _, e := range e.Elts {
300 kv, _ := e.(*ast.KeyValueExpr)
301 if kv == nil {
302 check.error(e, MissingLitKey, "missing key in map literal")
303 continue
304 }
305 check.genericExpr(utyp.key, x, kv.Key, utyp.key)
306 check.assignment(x, utyp.key, "map literal")
307 if !x.isValid() {
308 continue
309 }
310 if x.mode() == constant_ {
311 duplicate := false
312 xkey := keyVal(x.val)
313 if keyIsInterface {
314 for _, vtyp := range visited[xkey] {
315 if Identical(vtyp, x.typ()) {
316 duplicate = true
317 break
318 }
319 }
320 visited[xkey] = append(visited[xkey], x.typ())
321 } else {
322 _, duplicate = visited[xkey]
323 visited[xkey] = nil
324 }
325 if duplicate {
326 check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
327 continue
328 }
329 }
330 check.genericExpr(utyp.elem, x, kv.Value, utyp.elem)
331 check.assignment(x, utyp.elem, "map literal")
332 }
333
334 default:
335
336
337 for _, e := range e.Elts {
338 if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
339
340
341
342 e = kv.Value
343 }
344 check.use(e)
345 }
346
347 if isValid(utyp) {
348 var qualifier string
349 if isElem {
350 qualifier = " element"
351 }
352 var cause string
353 if utyp == nil {
354 cause = " (no common underlying type)"
355 }
356 check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
357 x.invalidate()
358 return
359 }
360 }
361
362 x.mode_ = value
363 x.typ_ = typ
364 }
365
366
367
368
369
370 func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
371 visited := make(map[int64]bool, len(elts))
372 var index, max int64
373 for _, e := range elts {
374
375 validIndex := false
376 eval := e
377 if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
378 if typ, i := check.index(kv.Key, length); isValid(typ) {
379 if i >= 0 {
380 index = i
381 validIndex = true
382 } else {
383 check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
384 }
385 }
386 eval = kv.Value
387 } else if length >= 0 && index >= length {
388 check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
389 } else {
390 validIndex = true
391 }
392
393
394 if validIndex {
395 if visited[index] {
396 check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
397 }
398 visited[index] = true
399 }
400 index++
401 if index > max {
402 max = index
403 }
404
405
406 var x operand
407 check.genericExpr(typ, &x, eval, typ)
408 check.assignment(&x, typ, "array or slice literal")
409 }
410 return max
411 }
412
View as plain text