literals.go raw

   1  // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
   2  // Source: ../../cmd/compile/internal/types2/literals.go
   3  
   4  // Copyright 2024 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 implements typechecking of literals.
   9  
  10  package types
  11  
  12  import (
  13  	"go/ast"
  14  	"go/token"
  15  	. "internal/types/errors"
  16  	"strings"
  17  )
  18  
  19  // langCompat reports an error if the representation of a numeric
  20  // literal is not compatible with the current language version.
  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  	// len(s) > 2
  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  		// The max. mantissa precision for untyped numeric values
  53  		// is 512 bits, or 4048 bits for each of the two integer
  54  		// parts of a fraction for floating-point numbers that are
  55  		// represented accurately in the go/constant package.
  56  		// Constant literals that are longer than this many bits
  57  		// are not meaningful; and excessively long constants may
  58  		// consume a lot of space and time for a useless conversion.
  59  		// Cap constant length with a generous upper limit that also
  60  		// allows for separators between all digits.
  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  		// The parser already establishes syntactic correctness.
  71  		// If we reach here it's because of number under-/overflow.
  72  		// TODO(gri) setConst (and in turn the go/constant package)
  73  		// should return an error describing the issue.
  74  		check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
  75  		x.mode = invalid
  76  		return
  77  	}
  78  	// Ensure that integer values don't overflow (go.dev/issue/54280).
  79  	x.expr = e // make sure that check.overflow below has an error position
  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  		// Set the Scope's extent to the complete "func (...) {...}"
  86  		// so that Scope.Innermost works correctly.
  87  		sig.scope.pos = e.Pos()
  88  		sig.scope.end = endPos(e)
  89  		if !check.conf.IgnoreFuncBodies && e.Body != nil {
  90  			// Anonymous functions are considered part of the
  91  			// init expression/func declaration which contains
  92  			// them: use existing package-level declaration info.
  93  			decl := check.decl // capture for use in closure below
  94  			iota := check.iota // capture for use in closure below (go.dev/issue/22345)
  95  			// Don't type-check right away because the function may
  96  			// be part of a type definition to which the function
  97  			// body refers. Instead, type-check as soon as possible,
  98  			// but before the enclosing scope contents changes (go.dev/issue/22992).
  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 // true if composite literal is an element of an enclosing composite literal
 114  
 115  	switch {
 116  	case e.Type != nil:
 117  		// composite literal type present - use it
 118  		// [...]T array types may only appear with composite literals.
 119  		// Check for them here so we don't have to handle ... in general.
 120  		if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && isdddArray(atyp) {
 121  			// We have an "open" [...]T array type.
 122  			// Create a new ArrayType with unknown length (-1)
 123  			// and finish setting it up after analyzing the literal.
 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  		// no composite literal type present - use hint (element type of enclosing type)
 133  		typ = hint
 134  		base = typ
 135  		// *T implies &T{}
 136  		u, _ := commonUnder(base, nil)
 137  		if b, ok := deref(u); ok {
 138  			base = b
 139  		}
 140  		isElem = true
 141  
 142  	default:
 143  		// TODO(gri) provide better error messages depending on context
 144  		check.error(e, UntypedLit, "missing type in composite literal")
 145  		// continue with invalid type so that elements are "used" (go.dev/issue/69092)
 146  		typ = Typ[Invalid]
 147  		base = typ
 148  	}
 149  
 150  	switch u, _ := commonUnder(base, nil); utyp := u.(type) {
 151  	case *Struct:
 152  		// Prevent crash if the struct referred to is not yet set up.
 153  		// See analogous comment for *Array.
 154  		if utyp.fields == nil {
 155  			check.error(e, InvalidTypeCycle, "invalid recursive type")
 156  			x.mode = invalid
 157  			return
 158  		}
 159  		if len(e.Elts) == 0 {
 160  			break
 161  		}
 162  		// Convention for error messages on invalid struct literals:
 163  		// we mention the struct type only if it clarifies the error
 164  		// (e.g., a duplicate field error doesn't need the struct type).
 165  		fields := utyp.fields
 166  		if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
 167  			// all elements must have keys
 168  			visited := make([]bool, len(fields))
 169  			for _, e := range e.Elts {
 170  				kv, _ := e.(*ast.KeyValueExpr)
 171  				if kv == nil {
 172  					check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
 173  					continue
 174  				}
 175  				key, _ := kv.Key.(*ast.Ident)
 176  				// do all possible checks early (before exiting due to errors)
 177  				// so we don't drop information on the floor
 178  				check.expr(nil, x, kv.Value)
 179  				if key == nil {
 180  					check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
 181  					continue
 182  				}
 183  				i := fieldIndex(fields, check.pkg, key.Name, false)
 184  				if i < 0 {
 185  					var alt Object
 186  					if j := fieldIndex(fields, check.pkg, key.Name, true); j >= 0 {
 187  						alt = fields[j]
 188  					}
 189  					msg := check.lookupError(base, key.Name, alt, true)
 190  					check.error(kv.Key, MissingLitField, msg)
 191  					continue
 192  				}
 193  				fld := fields[i]
 194  				check.recordUse(key, fld)
 195  				etyp := fld.typ
 196  				check.assignment(x, etyp, "struct literal")
 197  				// 0 <= i < len(fields)
 198  				if visited[i] {
 199  					check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Name)
 200  					continue
 201  				}
 202  				visited[i] = true
 203  			}
 204  		} else {
 205  			// no element must have a key
 206  			for i, e := range e.Elts {
 207  				if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
 208  					check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
 209  					continue
 210  				}
 211  				check.expr(nil, x, e)
 212  				if i >= len(fields) {
 213  					check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
 214  					break // cannot continue
 215  				}
 216  				// i < len(fields)
 217  				fld := fields[i]
 218  				if !fld.Exported() && fld.pkg != check.pkg {
 219  					check.errorf(x, UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
 220  					continue
 221  				}
 222  				etyp := fld.typ
 223  				check.assignment(x, etyp, "struct literal")
 224  			}
 225  			if len(e.Elts) < len(fields) {
 226  				check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
 227  				// ok to continue
 228  			}
 229  		}
 230  
 231  	case *Array:
 232  		// Prevent crash if the array referred to is not yet set up. Was go.dev/issue/18643.
 233  		// This is a stop-gap solution. Should use Checker.objPath to report entire
 234  		// path starting with earliest declaration in the source. TODO(gri) fix this.
 235  		if utyp.elem == nil {
 236  			check.error(e, InvalidTypeCycle, "invalid recursive type")
 237  			x.mode = invalid
 238  			return
 239  		}
 240  		n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
 241  		// If we have an array of unknown length (usually [...]T arrays, but also
 242  		// arrays [n]T where n is invalid) set the length now that we know it and
 243  		// record the type for the array (usually done by check.typ which is not
 244  		// called for [...]T). We handle [...]T arrays and arrays with invalid
 245  		// length the same here because it makes sense to "guess" the length for
 246  		// the latter if we have a composite literal; e.g. for [n]int{1, 2, 3}
 247  		// where n is invalid for some reason, it seems fair to assume it should
 248  		// be 3 (see also Checked.arrayLength and go.dev/issue/27346).
 249  		if utyp.len < 0 {
 250  			utyp.len = n
 251  			// e.Type is missing if we have a composite literal element
 252  			// that is itself a composite literal with omitted type. In
 253  			// that case there is nothing to record (there is no type in
 254  			// the source at that point).
 255  			if e.Type != nil {
 256  				check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
 257  			}
 258  		}
 259  
 260  	case *Slice:
 261  		// Prevent crash if the slice referred to is not yet set up.
 262  		// See analogous comment for *Array.
 263  		if utyp.elem == nil {
 264  			check.error(e, InvalidTypeCycle, "invalid recursive type")
 265  			x.mode = invalid
 266  			return
 267  		}
 268  		check.indexedElts(e.Elts, utyp.elem, -1)
 269  
 270  	case *Map:
 271  		// Prevent crash if the map referred to is not yet set up.
 272  		// See analogous comment for *Array.
 273  		if utyp.key == nil || utyp.elem == nil {
 274  			check.error(e, InvalidTypeCycle, "invalid recursive type")
 275  			x.mode = invalid
 276  			return
 277  		}
 278  		// If the map key type is an interface (but not a type parameter),
 279  		// the type of a constant key must be considered when checking for
 280  		// duplicates.
 281  		keyIsInterface := isNonTypeParamInterface(utyp.key)
 282  		visited := make(map[any][]Type, len(e.Elts))
 283  		for _, e := range e.Elts {
 284  			kv, _ := e.(*ast.KeyValueExpr)
 285  			if kv == nil {
 286  				check.error(e, MissingLitKey, "missing key in map literal")
 287  				continue
 288  			}
 289  			check.exprWithHint(x, kv.Key, utyp.key)
 290  			check.assignment(x, utyp.key, "map literal")
 291  			if x.mode == invalid {
 292  				continue
 293  			}
 294  			if x.mode == constant_ {
 295  				duplicate := false
 296  				xkey := keyVal(x.val)
 297  				if keyIsInterface {
 298  					for _, vtyp := range visited[xkey] {
 299  						if Identical(vtyp, x.typ) {
 300  							duplicate = true
 301  							break
 302  						}
 303  					}
 304  					visited[xkey] = append(visited[xkey], x.typ)
 305  				} else {
 306  					_, duplicate = visited[xkey]
 307  					visited[xkey] = nil
 308  				}
 309  				if duplicate {
 310  					check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
 311  					continue
 312  				}
 313  			}
 314  			check.exprWithHint(x, kv.Value, utyp.elem)
 315  			check.assignment(x, utyp.elem, "map literal")
 316  		}
 317  
 318  	default:
 319  		// when "using" all elements unpack KeyValueExpr
 320  		// explicitly because check.use doesn't accept them
 321  		for _, e := range e.Elts {
 322  			if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
 323  				// Ideally, we should also "use" kv.Key but we can't know
 324  				// if it's an externally defined struct key or not. Going
 325  				// forward anyway can lead to other errors. Give up instead.
 326  				e = kv.Value
 327  			}
 328  			check.use(e)
 329  		}
 330  		// if utyp is invalid, an error was reported before
 331  		if isValid(utyp) {
 332  			var qualifier string
 333  			if isElem {
 334  				qualifier = " element"
 335  			}
 336  			var cause string
 337  			if utyp == nil {
 338  				cause = " (no common underlying type)"
 339  			}
 340  			check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
 341  			x.mode = invalid
 342  			return
 343  		}
 344  	}
 345  
 346  	x.mode = value
 347  	x.typ = typ
 348  }
 349  
 350  // indexedElts checks the elements (elts) of an array or slice composite literal
 351  // against the literal's element type (typ), and the element indices against
 352  // the literal length if known (length >= 0). It returns the length of the
 353  // literal (maximum index value + 1).
 354  func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
 355  	visited := make(map[int64]bool, len(elts))
 356  	var index, max int64
 357  	for _, e := range elts {
 358  		// determine and check index
 359  		validIndex := false
 360  		eval := e
 361  		if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
 362  			if typ, i := check.index(kv.Key, length); isValid(typ) {
 363  				if i >= 0 {
 364  					index = i
 365  					validIndex = true
 366  				} else {
 367  					check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
 368  				}
 369  			}
 370  			eval = kv.Value
 371  		} else if length >= 0 && index >= length {
 372  			check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
 373  		} else {
 374  			validIndex = true
 375  		}
 376  
 377  		// if we have a valid index, check for duplicate entries
 378  		if validIndex {
 379  			if visited[index] {
 380  				check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
 381  			}
 382  			visited[index] = true
 383  		}
 384  		index++
 385  		if index > max {
 386  			max = index
 387  		}
 388  
 389  		// check element against composite literal element type
 390  		var x operand
 391  		check.exprWithHint(&x, eval, typ)
 392  		check.assignment(&x, typ, "array or slice literal")
 393  	}
 394  	return max
 395  }
 396