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.mode = invalid
65 return
66 }
67 }
68 x.setConst(e.Kind, e.Value)
69 if x.mode == invalid {
70
71
72
73
74 check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
75 x.mode = invalid
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.mode = invalid
108 }
109 }
110
111 func (check *Checker) compositeLit(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 case hint != nil:
132
133 typ = hint
134 base = typ
135
136 if b, ok := deref(coreType(base)); ok {
137 base = b
138 }
139 isElem = true
140
141 default:
142
143 check.error(e, UntypedLit, "missing type in composite literal")
144
145 typ = Typ[Invalid]
146 base = typ
147 }
148
149 switch utyp := coreType(base).(type) {
150 case *Struct:
151
152
153 if utyp.fields == nil {
154 check.error(e, InvalidTypeCycle, "invalid recursive type")
155 x.mode = invalid
156 return
157 }
158 if len(e.Elts) == 0 {
159 break
160 }
161
162
163
164 fields := utyp.fields
165 if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
166
167 visited := make([]bool, len(fields))
168 for _, e := range e.Elts {
169 kv, _ := e.(*ast.KeyValueExpr)
170 if kv == nil {
171 check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
172 continue
173 }
174 key, _ := kv.Key.(*ast.Ident)
175
176
177 check.expr(nil, x, kv.Value)
178 if key == nil {
179 check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
180 continue
181 }
182 i := fieldIndex(fields, check.pkg, key.Name, false)
183 if i < 0 {
184 var alt Object
185 if j := fieldIndex(fields, check.pkg, key.Name, true); j >= 0 {
186 alt = fields[j]
187 }
188 msg := check.lookupError(base, key.Name, alt, true)
189 check.error(kv.Key, MissingLitField, msg)
190 continue
191 }
192 fld := fields[i]
193 check.recordUse(key, fld)
194 etyp := fld.typ
195 check.assignment(x, etyp, "struct literal")
196
197 if visited[i] {
198 check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Name)
199 continue
200 }
201 visited[i] = true
202 }
203 } else {
204
205 for i, e := range e.Elts {
206 if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
207 check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
208 continue
209 }
210 check.expr(nil, x, e)
211 if i >= len(fields) {
212 check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
213 break
214 }
215
216 fld := fields[i]
217 if !fld.Exported() && fld.pkg != check.pkg {
218 check.errorf(x, UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
219 continue
220 }
221 etyp := fld.typ
222 check.assignment(x, etyp, "struct literal")
223 }
224 if len(e.Elts) < len(fields) {
225 check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
226
227 }
228 }
229
230 case *Array:
231
232
233
234 if utyp.elem == nil {
235 check.error(e, InvalidTypeCycle, "invalid recursive type")
236 x.mode = invalid
237 return
238 }
239 n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
240
241
242
243
244
245
246
247
248 if utyp.len < 0 {
249 utyp.len = n
250
251
252
253
254 if e.Type != nil {
255 check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
256 }
257 }
258
259 case *Slice:
260
261
262 if utyp.elem == nil {
263 check.error(e, InvalidTypeCycle, "invalid recursive type")
264 x.mode = invalid
265 return
266 }
267 check.indexedElts(e.Elts, utyp.elem, -1)
268
269 case *Map:
270
271
272 if utyp.key == nil || utyp.elem == nil {
273 check.error(e, InvalidTypeCycle, "invalid recursive type")
274 x.mode = invalid
275 return
276 }
277
278
279
280 keyIsInterface := isNonTypeParamInterface(utyp.key)
281 visited := make(map[any][]Type, len(e.Elts))
282 for _, e := range e.Elts {
283 kv, _ := e.(*ast.KeyValueExpr)
284 if kv == nil {
285 check.error(e, MissingLitKey, "missing key in map literal")
286 continue
287 }
288 check.exprWithHint(x, kv.Key, utyp.key)
289 check.assignment(x, utyp.key, "map literal")
290 if x.mode == invalid {
291 continue
292 }
293 if x.mode == constant_ {
294 duplicate := false
295 xkey := keyVal(x.val)
296 if keyIsInterface {
297 for _, vtyp := range visited[xkey] {
298 if Identical(vtyp, x.typ) {
299 duplicate = true
300 break
301 }
302 }
303 visited[xkey] = append(visited[xkey], x.typ)
304 } else {
305 _, duplicate = visited[xkey]
306 visited[xkey] = nil
307 }
308 if duplicate {
309 check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
310 continue
311 }
312 }
313 check.exprWithHint(x, kv.Value, utyp.elem)
314 check.assignment(x, utyp.elem, "map literal")
315 }
316
317 default:
318
319
320 for _, e := range e.Elts {
321 if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
322
323
324
325 e = kv.Value
326 }
327 check.use(e)
328 }
329
330 if isValid(utyp) {
331 var qualifier string
332 if isElem {
333 qualifier = " element"
334 }
335 var cause string
336 if utyp == nil {
337 cause = " (no core type)"
338 }
339 check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
340 x.mode = invalid
341 return
342 }
343 }
344
345 x.mode = value
346 x.typ = typ
347 }
348
349
350
351
352
353 func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
354 visited := make(map[int64]bool, len(elts))
355 var index, max int64
356 for _, e := range elts {
357
358 validIndex := false
359 eval := e
360 if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
361 if typ, i := check.index(kv.Key, length); isValid(typ) {
362 if i >= 0 {
363 index = i
364 validIndex = true
365 } else {
366 check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
367 }
368 }
369 eval = kv.Value
370 } else if length >= 0 && index >= length {
371 check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
372 } else {
373 validIndex = true
374 }
375
376
377 if validIndex {
378 if visited[index] {
379 check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
380 }
381 visited[index] = true
382 }
383 index++
384 if index > max {
385 max = index
386 }
387
388
389 var x operand
390 check.exprWithHint(&x, eval, typ)
391 check.assignment(&x, typ, "array or slice literal")
392 }
393 return max
394 }
395
View as plain text