"bytes"
"fmt"
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
)
type TypeAndValue struct {
mode operandMode
Type Type
- Value exact.Value // == constant.Value
+ Value constant.Value
}
// TODO(gri) Consider eliminating the IsVoid predicate. Instead, report
// nil Value.
func (tv TypeAndValue) IsValue() bool {
switch tv.mode {
- case constant, variable, mapindex, value, commaok:
+ case constant_, variable, mapindex, value, commaok:
return true
}
return false
switch x.mode {
case invalid:
return true // error reported before
- case constant, variable, mapindex, value, commaok:
+ case constant_, variable, mapindex, value, commaok:
// ok
default:
unreachable()
}
// rhs must be a constant
- if x.mode != constant {
+ if x.mode != constant_ {
check.errorf(x.pos(), "%s is not constant", x)
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
import (
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
)
// len(x)
mode := invalid
var typ Type
- var val exact.Value
+ var val constant.Value
switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) {
case *Basic:
if isString(t) && id == _Len {
- if x.mode == constant {
- mode = constant
- val = exact.MakeInt64(int64(len(exact.StringVal(x.val))))
+ if x.mode == constant_ {
+ mode = constant_
+ val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
} else {
mode = value
}
// the expression s does not contain channel receives or
// function calls; in this case s is not evaluated."
if !check.hasCallOrRecv {
- mode = constant
- val = exact.MakeInt64(t.len)
+ mode = constant_
+ val = constant.MakeInt64(t.len)
}
case *Slice, *Chan:
x.mode = mode
x.typ = Typ[Int]
x.val = val
- if check.Types != nil && mode != constant {
+ if check.Types != nil && mode != constant_ {
check.recordBuiltinType(call.Fun, makeSig(x.typ, typ))
}
return
}
- if x.mode == constant && y.mode == constant {
- x.val = exact.BinaryOp(x.val, token.ADD, exact.MakeImag(y.val))
+ if x.mode == constant_ && y.mode == constant_ {
+ x.val = constant.BinaryOp(x.val, token.ADD, constant.MakeImag(y.val))
} else {
x.mode = value
}
case Float64:
complexT = Typ[Complex128]
case UntypedInt, UntypedRune, UntypedFloat:
- if x.mode == constant {
+ if x.mode == constant_ {
realT = defaultType(realT).(*Basic)
complexT = Typ[UntypedComplex]
} else {
}
x.typ = complexT
- if check.Types != nil && x.mode != constant {
+ if check.Types != nil && x.mode != constant_ {
check.recordBuiltinType(call.Fun, makeSig(complexT, realT, realT))
}
- if x.mode != constant {
+ if x.mode != constant_ {
// The arguments have now their final types, which at run-
// time will be materialized. Update the expression trees.
// If the current types are untyped, the materialized type
check.invalidArg(x.pos(), "%s must be a complex number", x)
return
}
- if x.mode == constant {
+ if x.mode == constant_ {
if id == _Real {
- x.val = exact.Real(x.val)
+ x.val = constant.Real(x.val)
} else {
- x.val = exact.Imag(x.val)
+ x.val = constant.Imag(x.val)
}
} else {
x.mode = value
unreachable()
}
- if check.Types != nil && x.mode != constant {
+ if check.Types != nil && x.mode != constant_ {
check.recordBuiltinType(call.Fun, makeSig(Typ[k], x.typ))
}
x.typ = Typ[k]
return
}
- x.mode = constant
- x.val = exact.MakeInt64(check.conf.alignof(x.typ))
+ x.mode = constant_
+ x.val = constant.MakeInt64(check.conf.alignof(x.typ))
x.typ = Typ[Uintptr]
// result is constant - no need to record signature
check.recordSelection(selx, FieldVal, base, obj, index, false)
offs := check.conf.offsetof(base, index)
- x.mode = constant
- x.val = exact.MakeInt64(offs)
+ x.mode = constant_
+ x.val = constant.MakeInt64(offs)
x.typ = Typ[Uintptr]
// result is constant - no need to record signature
return
}
- x.mode = constant
- x.val = exact.MakeInt64(check.conf.sizeof(x.typ))
+ x.mode = constant_
+ x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
x.typ = Typ[Uintptr]
// result is constant - no need to record signature
// assert(pred) causes a typechecker error if pred is false.
// The result of assert is the value of pred if there is no error.
// Note: assert is only available in self-test mode.
- if x.mode != constant || !isBoolean(x.typ) {
+ if x.mode != constant_ || !isBoolean(x.typ) {
check.invalidArg(x.pos(), "%s is not a boolean constant", x)
return
}
- if x.val.Kind() != exact.Bool {
+ if x.val.Kind() != constant.Bool {
check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x)
return
}
- if !exact.BoolVal(x.val) {
+ if !constant.BoolVal(x.val) {
check.errorf(call.Pos(), "%s failed", call)
// compile-time assertion failure - safe to continue
}
}
x.expr = e
// a non-constant result implies a function call
- if x.mode != invalid && x.mode != constant {
+ if x.mode != invalid && x.mode != constant_ {
check.hasCallOrRecv = true
}
return predeclaredFuncs[id].kind
switch exp := exp.(type) {
case *Const:
assert(exp.Val() != nil)
- x.mode = constant
+ x.mode = constant_
x.typ = exp.typ
x.val = exp.val
case *TypeName:
import (
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
)
isLhs bool // expression is lhs operand of a shift with delayed type-check
mode operandMode
typ *Basic
- val exact.Value // constant value; or nil (if not a constant)
+ val constant.Value // constant value; or nil (if not a constant)
}
// funcInfo stores the information required for type-checking a function.
// A context represents the context within which an object is type-checked.
type context struct {
- decl *declInfo // package-level declaration whose init expression/function body is checked
- scope *Scope // top-most scope for lookups
- iota exact.Value // value of iota in a constant declaration; nil otherwise
- sig *Signature // function signature if inside a function; nil otherwise
- hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions
- hasCallOrRecv bool // set if an expression contains a function call or channel receive operation
+ decl *declInfo // package-level declaration whose init expression/function body is checked
+ scope *Scope // top-most scope for lookups
+ iota constant.Value // value of iota in a constant declaration; nil otherwise
+ sig *Signature // function signature if inside a function; nil otherwise
+ hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions
+ hasCallOrRecv bool // set if an expression contains a function call or channel receive operation
}
// A Checker maintains the state of the type checker.
m[tname] = append(m[tname], meth)
}
-func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val exact.Value) {
+func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) {
m := check.untyped
if m == nil {
m = make(map[ast.Expr]exprInfo)
}
}
-func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val exact.Value) {
+func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
assert(x != nil)
assert(typ != nil)
if mode == invalid {
return // omit
}
assert(typ != nil)
- if mode == constant {
+ if mode == constant_ {
assert(val != nil)
assert(typ == Typ[Invalid] || isConstType(typ))
}
package types
-import exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+import "go/constant"
// Conversion type-checks the conversion T(x).
// The result is in x.
func (check *Checker) conversion(x *operand, T Type) {
- constArg := x.mode == constant
+ constArg := x.mode == constant_
var ok bool
switch {
ok = true
case isInteger(x.typ) && isString(t):
codepoint := int64(-1)
- if i, ok := exact.Int64Val(x.val); ok {
+ if i, ok := constant.Int64Val(x.val); ok {
codepoint = i
}
// If codepoint < 0 the absolute value is too large (or unknown) for
// conversion. This is the same as converting any other out-of-range
// value - let string(codepoint) do the work.
- x.val = exact.MakeString(string(codepoint))
+ x.val = constant.MakeString(string(codepoint))
ok = true
}
case x.convertibleTo(check.conf, T):
import (
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
)
defer func() { check.iota = nil }()
// provide valid constant value under all circumstances
- obj.val = exact.MakeUnknown()
+ obj.val = constant.MakeUnknown()
// determine type, if any
if typ != nil {
// declare all constants
lhs := make([]*Const, len(s.Names))
for i, name := range s.Names {
- obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
+ obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota)))
lhs[i] = obj
var init ast.Expr
import (
"fmt"
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
"math"
)
return
}
- if x.mode == constant {
+ if x.mode == constant_ {
typ := x.typ.Underlying().(*Basic)
var prec uint
if isUnsigned(typ) {
prec = uint(check.conf.sizeof(typ) * 8)
}
- x.val = exact.UnaryOp(op, x.val, prec)
+ x.val = constant.UnaryOp(op, x.val, prec)
// Typed constants must be representable in
// their type after each constant operation.
if isTyped(typ) {
return false
}
-func fitsFloat32(x exact.Value) bool {
- f32, _ := exact.Float32Val(x)
+func fitsFloat32(x constant.Value) bool {
+ f32, _ := constant.Float32Val(x)
f := float64(f32)
return !math.IsInf(f, 0)
}
-func roundFloat32(x exact.Value) exact.Value {
- f32, _ := exact.Float32Val(x)
+func roundFloat32(x constant.Value) constant.Value {
+ f32, _ := constant.Float32Val(x)
f := float64(f32)
if !math.IsInf(f, 0) {
- return exact.MakeFloat64(f)
+ return constant.MakeFloat64(f)
}
return nil
}
-func fitsFloat64(x exact.Value) bool {
- f, _ := exact.Float64Val(x)
+func fitsFloat64(x constant.Value) bool {
+ f, _ := constant.Float64Val(x)
return !math.IsInf(f, 0)
}
-func roundFloat64(x exact.Value) exact.Value {
- f, _ := exact.Float64Val(x)
+func roundFloat64(x constant.Value) constant.Value {
+ f, _ := constant.Float64Val(x)
if !math.IsInf(f, 0) {
- return exact.MakeFloat64(f)
+ return constant.MakeFloat64(f)
}
return nil
}
// If rounded != nil, *rounded is set to the rounded value of x for
// representable floating-point values; it is left alone otherwise.
// It is ok to provide the addressof the first argument for rounded.
-func representableConst(x exact.Value, conf *Config, as BasicKind, rounded *exact.Value) bool {
+func representableConst(x constant.Value, conf *Config, as BasicKind, rounded *constant.Value) bool {
switch x.Kind() {
- case exact.Unknown:
+ case constant.Unknown:
return true
- case exact.Bool:
+ case constant.Bool:
return as == Bool || as == UntypedBool
- case exact.Int:
- if x, ok := exact.Int64Val(x); ok {
+ case constant.Int:
+ if x, ok := constant.Int64Val(x); ok {
switch as {
case Int:
var s = uint(conf.sizeof(Typ[as])) * 8
}
}
- n := exact.BitLen(x)
+ n := constant.BitLen(x)
switch as {
case Uint, Uintptr:
var s = uint(conf.sizeof(Typ[as])) * 8
- return exact.Sign(x) >= 0 && n <= int(s)
+ return constant.Sign(x) >= 0 && n <= int(s)
case Uint64:
- return exact.Sign(x) >= 0 && n <= 64
+ return constant.Sign(x) >= 0 && n <= 64
case Float32, Complex64:
if rounded == nil {
return fitsFloat32(x)
return true
}
- case exact.Float:
+ case constant.Float:
switch as {
case Float32, Complex64:
if rounded == nil {
return true
}
- case exact.Complex:
+ case constant.Complex:
switch as {
case Complex64:
if rounded == nil {
- return fitsFloat32(exact.Real(x)) && fitsFloat32(exact.Imag(x))
+ return fitsFloat32(constant.Real(x)) && fitsFloat32(constant.Imag(x))
}
- re := roundFloat32(exact.Real(x))
- im := roundFloat32(exact.Imag(x))
+ re := roundFloat32(constant.Real(x))
+ im := roundFloat32(constant.Imag(x))
if re != nil && im != nil {
- *rounded = exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
+ *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
return true
}
case Complex128:
if rounded == nil {
- return fitsFloat64(exact.Real(x)) && fitsFloat64(exact.Imag(x))
+ return fitsFloat64(constant.Real(x)) && fitsFloat64(constant.Imag(x))
}
- re := roundFloat64(exact.Real(x))
- im := roundFloat64(exact.Imag(x))
+ re := roundFloat64(constant.Real(x))
+ im := roundFloat64(constant.Imag(x))
if re != nil && im != nil {
- *rounded = exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
+ *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
return true
}
case UntypedComplex:
return true
}
- case exact.String:
+ case constant.String:
return as == String || as == UntypedString
default:
// representable checks that a constant operand is representable in the given basic type.
func (check *Checker) representable(x *operand, typ *Basic) {
- assert(x.mode == constant)
+ assert(x.mode == constant_)
if !representableConst(x.val, check.conf, typ.kind, &x.val) {
var msg string
if isNumeric(x.typ) && isNumeric(typ) {
}
// updateExprVal updates the value of x to val.
-func (check *Checker) updateExprVal(x ast.Expr, val exact.Value) {
+func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) {
if info, ok := check.untyped[x]; ok {
info.val = val
check.untyped[x] = info
// typed target
switch t := target.Underlying().(type) {
case *Basic:
- if x.mode == constant {
+ if x.mode == constant_ {
check.representable(x, t)
if x.mode == invalid {
return
return
}
- if x.mode == constant && y.mode == constant {
- x.val = exact.MakeBool(exact.Compare(x.val, op, y.val))
+ if x.mode == constant_ && y.mode == constant_ {
+ x.val = constant.MakeBool(constant.Compare(x.val, op, y.val))
// The operands are never materialized; no need to update
// their types.
} else {
return
}
- if x.mode == constant {
- if y.mode == constant {
+ if x.mode == constant_ {
+ if y.mode == constant_ {
// rhs must be an integer value
if !y.isInteger() {
check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y)
}
// rhs must be within reasonable bounds
const stupidShift = 1023 - 1 + 52 // so we can express smallestFloat64
- s, ok := exact.Uint64Val(y.val)
+ s, ok := constant.Uint64Val(y.val)
if !ok || s > stupidShift {
check.invalidOp(y.pos(), "stupid shift count %s", y)
x.mode = invalid
if !isInteger(x.typ) {
x.typ = Typ[UntypedInt]
}
- x.val = exact.Shift(x.val, op, uint(s))
+ x.val = constant.Shift(x.val, op, uint(s))
return
}
}
// constant rhs must be >= 0
- if y.mode == constant && exact.Sign(y.val) < 0 {
+ if y.mode == constant_ && constant.Sign(y.val) < 0 {
check.invalidOp(y.pos(), "shift count %s must not be negative", y)
}
return
}
- if (op == token.QUO || op == token.REM) && (x.mode == constant || isInteger(x.typ)) && y.mode == constant && exact.Sign(y.val) == 0 {
+ if (op == token.QUO || op == token.REM) && (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
check.invalidOp(y.pos(), "division by zero")
x.mode = invalid
return
}
- if x.mode == constant && y.mode == constant {
+ if x.mode == constant_ && y.mode == constant_ {
typ := x.typ.Underlying().(*Basic)
// force integer division of integer operands
if op == token.QUO && isInteger(typ) {
op = token.QUO_ASSIGN
}
- x.val = exact.BinaryOp(x.val, op, y.val)
+ x.val = constant.BinaryOp(x.val, op, y.val)
// Typed constants must be representable in
// their type after each constant operation.
if isTyped(typ) {
}
// a constant index i must be in bounds
- if x.mode == constant {
- if exact.Sign(x.val) < 0 {
+ if x.mode == constant_ {
+ if constant.Sign(x.val) < 0 {
check.invalidArg(x.pos(), "index %s must not be negative", &x)
return
}
- i, valid = exact.Int64Val(x.val)
+ i, valid = constant.Int64Val(x.val)
if !valid || max >= 0 && i >= max {
check.errorf(x.pos(), "index %s is out of bounds", &x)
return i, false
// convert x into a user-friendly set of values
// TODO(gri) this code can be simplified
var typ Type
- var val exact.Value
+ var val constant.Value
switch x.mode {
case invalid:
typ = Typ[Invalid]
case novalue:
typ = (*Tuple)(nil)
- case constant:
+ case constant_:
typ = x.typ
val = x.val
default:
}
continue
}
- if x.mode == constant {
+ if x.mode == constant_ {
duplicate := false
// if the key is of interface type, the type is also significant when checking for duplicates
if _, ok := utyp.key.Underlying().(*Interface); ok {
case *Basic:
if isString(typ) {
valid = true
- if x.mode == constant {
- length = int64(len(exact.StringVal(x.val)))
+ if x.mode == constant_ {
+ length = int64(len(constant.StringVal(x.val)))
}
// an indexed string always yields a byte value
// (not a constant) even if the string and the
goto Error
}
valid = true
- if x.mode == constant {
- length = int64(len(exact.StringVal(x.val)))
+ if x.mode == constant_ {
+ length = int64(len(constant.StringVal(x.val)))
}
// spec: "For untyped string operands the result
// is a non-constant value of type string."
"bytes"
"fmt"
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
)
// A Const represents a declared constant.
type Const struct {
object
- val exact.Value
+ val constant.Value
visited bool // for initialization cycle detection
}
-func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val exact.Value) *Const {
+func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
return &Const{object{nil, pos, pkg, name, typ, 0, token.NoPos}, val, false}
}
-func (obj *Const) Val() exact.Value { return obj.val }
+func (obj *Const) Val() constant.Value { return obj.val }
// A TypeName represents a declared type.
type TypeName struct {
import (
"bytes"
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
)
type operandMode byte
const (
- invalid operandMode = iota // operand is invalid
- novalue // operand represents no value (result of a function call w/o result)
- builtin // operand is a built-in function
- typexpr // operand is a type
- constant // operand is a constant; the operand's typ is a Basic type
- variable // operand is an addressable variable
- mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
- value // operand is a computed value
- commaok // like value, but operand may be used in a comma,ok expression
+ invalid operandMode = iota // operand is invalid
+ novalue // operand represents no value (result of a function call w/o result)
+ builtin // operand is a built-in function
+ typexpr // operand is a type
+ constant_ // operand is a constant; the operand's typ is a Basic type
+ variable // operand is an addressable variable
+ mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
+ value // operand is a computed value
+ commaok // like value, but operand may be used in a comma,ok expression
)
var operandModeString = [...]string{
- invalid: "invalid operand",
- novalue: "no value",
- builtin: "built-in",
- typexpr: "type",
- constant: "constant",
- variable: "variable",
- mapindex: "map index expression",
- value: "value",
- commaok: "comma, ok expression",
+ invalid: "invalid operand",
+ novalue: "no value",
+ builtin: "built-in",
+ typexpr: "type",
+ constant_: "constant",
+ variable: "variable",
+ mapindex: "map index expression",
+ value: "value",
+ commaok: "comma, ok expression",
}
// An operand represents an intermediate value during type checking.
mode operandMode
expr ast.Expr
typ Type
- val exact.Value
+ val constant.Value
id builtinId
}
expr = predeclaredFuncs[x.id].name
case typexpr:
expr = TypeString(x.typ, qf)
- case constant:
+ case constant_:
expr = x.val.String()
}
}
buf.WriteString(operandModeString[x.mode])
// <val>
- if x.mode == constant {
+ if x.mode == constant_ {
if s := x.val.String(); s != expr {
buf.WriteByte(' ')
buf.WriteString(s)
// setConst sets x to the untyped constant for literal lit.
func (x *operand) setConst(tok token.Token, lit string) {
- val := exact.MakeFromLiteral(lit, tok, 0)
+ val := constant.MakeFromLiteral(lit, tok, 0)
if val == nil {
// TODO(gri) Should we make it an unknown constant instead?
x.mode = invalid
kind = UntypedString
}
- x.mode = constant
+ x.mode = constant_
x.typ = Typ[kind]
x.val = val
}
if isUntyped(Vu) {
switch t := Tu.(type) {
case *Basic:
- if x.mode == constant {
+ if x.mode == constant_ {
return representableConst(x.val, conf, t.kind, nil)
}
// The result of a comparison is an untyped boolean,
func (x *operand) isInteger() bool {
return x.mode == invalid ||
isInteger(x.typ) ||
- isUntyped(x.typ) && x.mode == constant && representableConst(x.val, nil, UntypedInt, nil) // no *Config required for UntypedInt
+ isUntyped(x.typ) && x.mode == constant_ && representableConst(x.val, nil, UntypedInt, nil) // no *Config required for UntypedInt
}
import (
"fmt"
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
pathLib "path"
"strconv"
// declare all constants
for i, name := range s.Names {
- obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
+ obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota)))
var init ast.Expr
if i < len(last.Values) {
// We're not using testing's benchmarking mechanism directly
// because we want custom output.
- for _, p := range []string{"types", "exact", "gcimporter"} {
+ for _, p := range []string{"types", "constant", filepath.Join("internal", "gcimporter")} {
path := filepath.Join("..", p)
runbench(t, path, false)
runbench(t, path, true)
import (
"fmt"
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
)
} else {
// spec: "A missing switch expression is
// equivalent to the boolean value true."
- x.mode = constant
+ x.mode = constant_
x.typ = Typ[Bool]
- x.val = exact.MakeBool(true)
+ x.val = constant.MakeBool(true)
x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"}
}
import (
"go/ast"
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
"sort"
"strconv"
x.val = obj.val
}
assert(x.val != nil)
- x.mode = constant
+ x.mode = constant_
case *TypeName:
x.mode = typexpr
func (check *Checker) arrayLength(e ast.Expr) int64 {
var x operand
check.expr(&x, e)
- if x.mode != constant {
+ if x.mode != constant_ {
if x.mode != invalid {
check.errorf(x.pos(), "array length %s must be constant", &x)
}
check.errorf(x.pos(), "array length %s must be integer", &x)
return 0
}
- n, ok := exact.Int64Val(x.val)
+ n, ok := constant.Int64Val(x.val)
if !ok || n < 0 {
check.errorf(x.pos(), "invalid array length %s", &x)
return 0
package types
import (
- exact "go/constant" // Renamed to reduce diffs from x/tools. TODO: remove
+ "go/constant"
"go/token"
"strings"
)
var predeclaredConsts = [...]struct {
name string
kind BasicKind
- val exact.Value
+ val constant.Value
}{
- {"true", UntypedBool, exact.MakeBool(true)},
- {"false", UntypedBool, exact.MakeBool(false)},
- {"iota", UntypedInt, exact.MakeInt64(0)},
+ {"true", UntypedBool, constant.MakeBool(true)},
+ {"false", UntypedBool, constant.MakeBool(false)},
+ {"iota", UntypedInt, constant.MakeInt64(0)},
}
func defPredeclaredConsts() {