Source file src/go/types/literals.go

     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.invalidate()
    65  			return
    66  		}
    67  	}
    68  	x.setConst(e.Kind, e.Value)
    69  	if !x.isValid() {
    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.invalidate()
    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.invalidate()
   108  	}
   109  }
   110  
   111  func (check *Checker) compositeLit(T *target, x *operand, e *ast.CompositeLit) {
   112  	var typ, base Type
   113  	var isElem bool // true if composite literal is an untyped 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  		} else {
   126  			typ = check.typ(e.Type)
   127  		}
   128  		base = typ
   129  
   130  	case T != nil:
   131  		// no composite literal type present - use assignment context
   132  		assert(T.typ != nil)
   133  		// report a version error only if we have an inferred type that is not a hint
   134  		_ = T.hint || check.verifyVersionf(e, go1_28, "missing type in composite literal")
   135  		typ = T.typ
   136  		base = typ
   137  		// *T implies &T{}
   138  		u, _ := commonUnder(base, nil)
   139  		if b, ok := deref(u); ok {
   140  			base = b
   141  		}
   142  		isElem = T.hint
   143  
   144  	default:
   145  		// no composite literal type present
   146  		// TODO(gri) provide better error messages depending on context
   147  		check.error(e, UntypedLit, "missing type in composite literal")
   148  		// continue with invalid type so that elements are "used" (go.dev/issue/69092)
   149  		typ = Typ[Invalid]
   150  		base = typ
   151  	}
   152  
   153  	// We cannot create a literal of an incomplete type; make sure it's complete.
   154  	if !check.isComplete(base) {
   155  		x.invalidate()
   156  		return
   157  	}
   158  
   159  	switch u, _ := commonUnder(base, nil); utyp := u.(type) {
   160  	case *Struct:
   161  		if len(e.Elts) == 0 {
   162  			break
   163  		}
   164  		// Convention for error messages on invalid struct literals:
   165  		// we mention the struct type only if it clarifies the error
   166  		// (e.g., a duplicate field error doesn't need the struct type).
   167  		fields := utyp.fields
   168  		if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
   169  			// all elements must have keys
   170  			visited := make(trie[*Var])
   171  			for _, e := range e.Elts {
   172  				kv, _ := e.(*ast.KeyValueExpr)
   173  				if kv == nil {
   174  					check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
   175  					continue
   176  				}
   177  				key, _ := kv.Key.(*ast.Ident)
   178  				// do all possible checks early (before exiting due to errors)
   179  				// so we don't drop information on the floor
   180  				if key == nil {
   181  					check.genericExpr(nil, x, kv.Value)
   182  					check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
   183  					continue
   184  				}
   185  				obj, index, indirect := lookupFieldOrMethod(utyp, false, check.pkg, key.Name, false)
   186  				if obj == nil {
   187  					check.genericExpr(nil, x, kv.Value)
   188  					alt, _, _ := lookupFieldOrMethod(utyp, false, check.pkg, key.Name, true)
   189  					msg := check.lookupError(base, key.Name, alt, true)
   190  					check.error(kv.Key, MissingLitField, msg)
   191  					continue
   192  				}
   193  				fld, _ := obj.(*Var)
   194  				if fld == nil {
   195  					check.genericExpr(nil, x, kv.Value)
   196  					check.errorf(kv.Key, MissingLitField, "%s is not a field", kv.Key)
   197  					continue
   198  				}
   199  				// we can now check the value using the field target type
   200  				etyp := fld.typ
   201  				check.genericExpr(newTarget(etyp, "struct field"), x, kv.Value)
   202  				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) {
   203  					continue
   204  				}
   205  				if indirect {
   206  					check.errorf(kv.Key, InvalidLitField, "invalid implicit pointer indirection to reach %s", kv.Key)
   207  					continue
   208  				}
   209  				check.recordUse(key, fld)
   210  				check.assignment(x, etyp, "struct literal")
   211  				if alt, n := visited.insert(index, fld); n != 0 {
   212  					if fld == alt {
   213  						check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", fld.name)
   214  					} else if n < len(index) {
   215  						check.errorf(kv, DuplicateLitField, "cannot specify promoted field %s and enclosing embedded field %s", fld.name, alt.name)
   216  					} else { // n > len(index)
   217  						check.errorf(kv, DuplicateLitField, "cannot specify embedded field %s and enclosed promoted field %s", fld.name, alt.name)
   218  					}
   219  				}
   220  			}
   221  		} else {
   222  			// no element must have a key
   223  			for i, e := range e.Elts {
   224  				if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
   225  					check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
   226  					continue
   227  				}
   228  				if i >= len(fields) {
   229  					check.genericExpr(nil, x, e)
   230  					check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
   231  					break // cannot continue
   232  				}
   233  				// i < len(fields)
   234  				fld := fields[i]
   235  				etyp := fld.typ
   236  				check.genericExpr(newTarget(etyp, "struct field"), x, e)
   237  				if !fld.Exported() && fld.pkg != check.pkg {
   238  					check.errorf(x, UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
   239  					continue
   240  				}
   241  				check.assignment(x, etyp, "struct literal")
   242  			}
   243  			if len(e.Elts) < len(fields) {
   244  				var hint string
   245  				for _, fld := range fields {
   246  					if !fld.Exported() && fld.pkg != check.pkg {
   247  						hint = " (type has unexported fields - use key:value pairs)"
   248  						break
   249  					}
   250  				}
   251  				check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s%s", base, hint)
   252  				// ok to continue
   253  			}
   254  		}
   255  
   256  	case *Array:
   257  		n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
   258  		// If we have an array of unknown length (usually [...]T arrays, but also
   259  		// arrays [n]T where n is invalid) set the length now that we know it and
   260  		// record the type for the array (usually done by check.typ which is not
   261  		// called for [...]T). We handle [...]T arrays and arrays with invalid
   262  		// length the same here because it makes sense to "guess" the length for
   263  		// the latter if we have a composite literal; e.g. for [n]int{1, 2, 3}
   264  		// where n is invalid for some reason, it seems fair to assume it should
   265  		// be 3 (see also Checked.arrayLength and go.dev/issue/27346).
   266  		if utyp.len < 0 {
   267  			utyp.len = n
   268  			// e.Type is missing if we have a composite literal element
   269  			// that is itself a composite literal with omitted type. In
   270  			// that case there is nothing to record (there is no type in
   271  			// the source at that point).
   272  			if e.Type != nil {
   273  				check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
   274  			}
   275  		}
   276  
   277  	case *Slice:
   278  		check.indexedElts(e.Elts, utyp.elem, -1)
   279  
   280  	case *Map:
   281  		// If the map key type is an interface (but not a type parameter),
   282  		// the type of a constant key must be considered when checking for
   283  		// duplicates.
   284  		keyIsInterface := isNonTypeParamInterface(utyp.key)
   285  		visited := make(map[any][]Type, len(e.Elts))
   286  		for _, e := range e.Elts {
   287  			kv, _ := e.(*ast.KeyValueExpr)
   288  			if kv == nil {
   289  				check.error(e, MissingLitKey, "missing key in map literal")
   290  				continue
   291  			}
   292  			check.genericExpr(newHint(utyp.key, "map key"), x, kv.Key)
   293  			check.assignment(x, utyp.key, "map literal")
   294  			if !x.isValid() {
   295  				continue
   296  			}
   297  			if x.mode() == constant_ {
   298  				duplicate := false
   299  				xkey := keyVal(x.val)
   300  				if keyIsInterface {
   301  					for _, vtyp := range visited[xkey] {
   302  						if Identical(vtyp, x.typ()) {
   303  							duplicate = true
   304  							break
   305  						}
   306  					}
   307  					visited[xkey] = append(visited[xkey], x.typ())
   308  				} else {
   309  					_, duplicate = visited[xkey]
   310  					visited[xkey] = nil
   311  				}
   312  				if duplicate {
   313  					check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
   314  					continue
   315  				}
   316  			}
   317  			check.genericExpr(newHint(utyp.elem, "map value"), x, kv.Value)
   318  			check.assignment(x, utyp.elem, "map literal")
   319  		}
   320  
   321  	default:
   322  		// when "using" all elements unpack KeyValueExpr
   323  		// explicitly because check.use doesn't accept them
   324  		for _, e := range e.Elts {
   325  			if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
   326  				// Ideally, we should also "use" kv.Key but we can't know
   327  				// if it's an externally defined struct key or not. Going
   328  				// forward anyway can lead to other errors. Give up instead.
   329  				e = kv.Value
   330  			}
   331  			check.use(e)
   332  		}
   333  		// if utyp is invalid, an error was reported before
   334  		if isValid(utyp) {
   335  			var qualifier string
   336  			if isElem {
   337  				qualifier = " element"
   338  			}
   339  			var cause string
   340  			if utyp == nil {
   341  				cause = " (no common underlying type)"
   342  			}
   343  			check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
   344  			x.invalidate()
   345  			return
   346  		}
   347  	}
   348  
   349  	x.mode_ = value
   350  	x.typ_ = typ
   351  }
   352  
   353  // indexedElts checks the elements (elts) of an array or slice composite literal
   354  // against the literal's element type (typ), and the element indices against
   355  // the literal length if known (length >= 0). It returns the length of the
   356  // literal (maximum index value + 1).
   357  func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
   358  	visited := make(map[int64]bool, len(elts))
   359  	var index, max int64
   360  	for _, e := range elts {
   361  		// determine and check index
   362  		validIndex := false
   363  		eval := e
   364  		if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
   365  			if typ, i := check.index(kv.Key, length); isValid(typ) {
   366  				if i >= 0 {
   367  					index = i
   368  					validIndex = true
   369  				} else {
   370  					check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
   371  				}
   372  			}
   373  			eval = kv.Value
   374  		} else if length >= 0 && index >= length {
   375  			check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
   376  		} else {
   377  			validIndex = true
   378  		}
   379  
   380  		// if we have a valid index, check for duplicate entries
   381  		if validIndex {
   382  			if visited[index] {
   383  				check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
   384  			}
   385  			visited[index] = true
   386  		}
   387  		index++
   388  		if index > max {
   389  			max = index
   390  		}
   391  
   392  		// check element against composite literal element type
   393  		var x operand
   394  		check.genericExpr(newHint(typ, "array or slice element"), &x, eval)
   395  		check.assignment(&x, typ, "array or slice literal")
   396  	}
   397  	return max
   398  }
   399  

View as plain text