}
func (check *Checker) initConst(lhs *Const, x *operand) {
- if x.mode() == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
+ if !x.isValid() || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
}
check.assignment(x, lhs.typ, "constant declaration")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// or Typ[Invalid] in case of an error.
// If the initialization check fails, x.mode is set to invalid.
func (check *Checker) initVar(lhs *Var, x *operand, context string) {
- if x.mode() == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
+ if !x.isValid() || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
check.usedVars[v] = v_used // restore v.used
}
- if x.mode() == invalid || !isValid(x.typ()) {
+ if !x.isValid() || !isValid(x.typ()) {
return Typ[Invalid]
}
args = check.exprList(argList)
nargs = len(args)
for _, a := range args {
- if a.mode() == invalid {
+ if !a.isValid() {
return
}
}
// and check below
}
}
- if x.mode() == invalid || y.mode() == invalid {
+ if !x.isValid() || !y.isValid() {
return
}
*x = *args[1] // key
check.assignment(x, key, "argument to delete")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// result in an error (shift of complex value)
check.convertUntyped(x, Typ[Complex128])
// x should be invalid now, but be conservative and check
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
}
}
for i, a := range args {
- if a.mode() == invalid {
+ if !a.isValid() {
return
}
// The first argument is already in x and there's nothing left to do.
if i > 0 {
check.matchTypes(x, a)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
x.mode_ = value
// A value must not be untyped.
check.assignment(x, &emptyInterface, "argument to built-in "+bin.name)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
}
if isUntyped(x.typ()) {
// check for overflow and untyped nil
check.assignment(x, nil, "argument to new")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
assert(isTyped(x.typ()))
}
check.assignment(x, &emptyInterface, "argument to panic")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
params = make([]Type, nargs)
for i, a := range args {
check.assignment(a, nil, "argument to built-in "+predeclaredFuncs[id].name)
- if a.mode() == invalid {
+ if !a.isValid() {
return
}
params[i] = a.typ()
check.verifyVersionf(call.Fun, go1_17, "unsafe.Add")
check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
case _Alignof:
// unsafe.Alignof(x T) uintptr
check.assignment(x, nil, "argument to unsafe.Alignof")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
}
check.expr(nil, x, selx.X)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
case _Sizeof:
// unsafe.Sizeof(x T) uintptr
check.assignment(x, nil, "argument to unsafe.Sizeof")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.verifyVersionf(call.Fun, go1_20, "unsafe.String")
check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.verifyVersionf(call.Fun, go1_20, "unsafe.StringData")
check.assignment(x, Typ[String], "argument to unsafe.StringData")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.dump("%v: %s", atPos(x1), x1)
x1 = &t // use incoming x only for first argument
}
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// trace is only available in test mode - no need to record signature
panic("unreachable")
}
- assert(x.mode() != invalid)
+ assert(x.isValid())
return true
}
case typexpr:
// conversion
check.nonGeneric(nil, x)
- if x.mode() == invalid {
+ if !x.isValid() {
return conversion
}
T := x.typ()
check.errorf(call, WrongArgCount, "missing argument in conversion to %s", T)
case 1:
check.expr(nil, x, call.ArgList[0])
- if x.mode() != invalid {
+ if x.isValid() {
if t, _ := T.Underlying().(*Interface); t != nil && !isTypeParam(T) {
if !t.IsMethodSet() {
check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
}
x.expr = call
// a non-constant result implies a function call
- if x.mode() != invalid && x.mode() != constant_ {
+ if x.isValid() && x.mode() != constant_ {
check.hasCallOrRecv = true
}
return predeclaredFuncs[id].kind
// x is not a function instantiation (it may still be a generic function).
check.rawExpr(nil, &x, e, nil, true)
check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
- if t, ok := x.typ().(*Tuple); ok && x.mode() != invalid {
+ if t, ok := x.typ().(*Tuple); ok && x.isValid() {
// x is a function call returning multiple values; it cannot be generic.
resList = make([]*operand, t.Len())
for i, v := range t.vars {
default:
check.rawExpr(nil, &x, e, nil, true)
}
- return x.mode() != invalid
+ return x.isValid()
}
func (check *Checker) unary(x *operand, e *syntax.Operation) {
check.expr(nil, x, e.X)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// If x is a constant, it must be representable as a value of typ.
c := operand{old.mode, x, old.typ, old.val, 0}
check.convertUntyped(&c, typ)
- if c.mode() == invalid {
+ if !c.isValid() {
return
}
}
// If x is a constant operand, the returned constant.Value will be the
// representation of x in this context.
func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
- if x.mode() == invalid || isTyped(x.typ()) || !isValid(target) {
+ if !x.isValid() || isTyped(x.typ()) || !isValid(target) {
return x.typ(), nil, 0
}
// x is untyped
// Caution: Check for representability here, rather than in the switch
// below, because isInteger includes untyped integers (was bug go.dev/issue/43697).
check.representable(y, Typ[Uint])
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
return
}
// This is incorrect, but preserves pre-existing behavior.
// See also go.dev/issue/47410.
check.convertUntyped(y, Typ[Uint])
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
return
}
check.expr(nil, x, lhs)
check.expr(nil, &y, rhs)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
x.expr = y.expr
return
}
check.matchTypes(x, &y)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
if mayConvert(x, y) {
check.convertUntyped(x, y.typ())
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.convertUntyped(y, x.typ())
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
return
}
// from a non-nil target T, nonGeneric reports an error and invalidates x.mode and x.typ.
// Otherwise it leaves x alone.
func (check *Checker) nonGeneric(T *target, x *operand) {
- if x.mode() == invalid || x.mode() == novalue {
+ if !x.isValid() || x.mode() == novalue {
return
}
var what string
goto Error // error reported during parsing
}
check.basicLit(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *syntax.FuncLit:
check.funcLit(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *syntax.CompositeLit:
check.compositeLit(x, e, hint)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
}
check.funcInst(T, e.Pos(), x, e, true)
}
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *syntax.SliceExpr:
check.sliceExpr(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *syntax.AssertExpr:
check.expr(nil, x, e.X)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
// x.(type) expressions are encoded via TypeSwitchGuards
}
check.unary(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
if e.Op == syntax.Recv {
// binary expression
check.binary(x, e, e.X, e.Y, e.Op)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
check.rawExpr(nil, &x, e, nil, false)
check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
- if t, ok := x.typ().(*Tuple); ok && x.mode() != invalid {
+ if t, ok := x.typ().(*Tuple); ok && x.isValid() {
// multiple values
list = make([]*operand, t.Len())
for i, v := range t.vars {
// x should not be generic at this point, but be safe and check
check.nonGeneric(nil, x)
- if x.mode() == invalid {
+ if !x.isValid() {
return false
}
func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
check.expr(nil, x, e.X)
- if x.mode() == invalid {
+ if !x.isValid() {
check.use(e.Index[:]...)
return
}
// If the operand is not valid, an error is reported (using what as context)
// and the result is false.
func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNegative bool) bool {
- if x.mode() == invalid {
+ if !x.isValid() {
return false
}
// spec: "a constant index that is untyped is given type int"
check.convertUntyped(x, Typ[Int])
- if x.mode() == invalid {
+ if !x.isValid() {
return false
}
// If we have invalid (ordinary) arguments, an error was reported before.
// Avoid additional inference errors and exit early (go.dev/issue/60434).
for _, arg := range args {
- if arg.mode() == invalid {
+ if !arg.isValid() {
return nil
}
}
}
for i, arg := range args {
- if arg.mode() == invalid {
+ if !arg.isValid() {
// An error was reported earlier. Ignore this arg
// and continue, we may still be able to infer all
// targs resulting in fewer follow-on errors.
}
}
x.setConst(e.Kind, e.Value)
- if x.mode() == invalid {
+ if !x.isValid() {
// The parser already establishes syntactic correctness.
// If we reach here it's because of number under-/overflow.
// TODO(gri) setConst (and in turn the go/constant package)
}
check.exprWithHint(x, kv.Key, utyp.key)
check.assignment(x, utyp.key, "map literal")
- if x.mode() == invalid {
+ if !x.isValid() {
continue
}
if x.mode() == constant_ {
// if assignableTo is invoked through an exported API call, i.e., when all
// methods have been type-checked.
func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
- if x.mode() == invalid || !isValid(T) {
+ if !x.isValid() || !isValid(T) {
return true, 0 // avoid spurious errors
}
check.hasCallOrRecv = false
check.expr(nil, &x, rangeVar)
- if isTypes2 && x.mode() != invalid && sValue == nil && !check.hasCallOrRecv {
+ if isTypes2 && x.isValid() && sValue == nil && !check.hasCallOrRecv {
if t, ok := arrayPtrDeref(x.typ().Underlying()).(*Array); ok {
for {
// Put constant info on the thing inside parentheses.
// determine key/value types
var key, val Type
- if x.mode() != invalid {
+ if x.isValid() {
k, v, cause, ok := rangeKeyVal(check, x.typ(), func(v goVersion) bool {
return check.allowVersion(v)
})
// If the assignment succeeded, if x was untyped before, it now
// has a type inferred via the assignment. It must be an integer.
// (go.dev/issues/67027)
- if x.mode() != invalid && !isInteger(x.typ()) {
+ if x.isValid() && !isInteger(x.typ()) {
check.softErrorf(lhs, InvalidRangeExpr, "cannot use iteration variable of type %s", x.typ())
}
} else {
for _, e := range values {
var v operand
check.expr(nil, &v, e)
- if x.mode() == invalid || v.mode() == invalid {
+ if !x.isValid() || !v.isValid() {
continue L
}
check.convertUntyped(&v, x.typ())
- if v.mode() == invalid {
+ if !v.isValid() {
continue L
}
// Order matters: By comparing v against x, error positions are at the case values.
res := v // keep original v unchanged
check.comparison(&res, x, syntax.Eql, true)
- if res.mode() == invalid {
+ if !res.isValid() {
continue L
}
if v.mode() != constant_ {
var ch, val operand
check.expr(nil, &ch, s.Chan)
check.expr(nil, &val, s.Value)
- if ch.mode() == invalid || val.mode() == invalid {
+ if !ch.isValid() || !val.isValid() {
return
}
if elem := check.chanElem(s, &ch, false); elem != nil {
// (no need to call unpackExpr as s.Lhs must be single-valued)
var x operand
check.expr(nil, &x, s.Lhs)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
if !allNumeric(x.typ()) {
check.simpleStmt(s.Init)
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode() != invalid && !allBoolean(x.typ()) {
+ if x.isValid() && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
}
check.stmt(inner, s.Then)
if s.Cond != nil {
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode() != invalid && !allBoolean(x.typ()) {
+ if x.isValid() && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
}
}
// By checking assignment of x to an invisible temporary
// (as a compiler would), we get all the relevant checks.
check.assignment(&x, nil, "switch expression")
- if x.mode() != invalid && !Comparable(x.typ()) && !hasNil(x.typ()) {
+ if x.isValid() && !Comparable(x.typ()) && !hasNil(x.typ()) {
check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ())
x.invalidate()
}
{
var x operand
check.expr(nil, &x, guard.X)
- if x.mode() != invalid {
+ if x.isValid() {
if isTypeParam(x.typ()) {
check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
} else if IsInterface(x.typ()) {
var x operand
check.expr(nil, &x, e)
if x.mode() != constant_ {
- if x.mode() != invalid {
+ if x.isValid() {
check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
}
return -1
}
func (check *Checker) initConst(lhs *Const, x *operand) {
- if x.mode() == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
+ if !x.isValid() || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
}
check.assignment(x, lhs.typ, "constant declaration")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// or Typ[Invalid] in case of an error.
// If the initialization check fails, x.mode is set to invalid.
func (check *Checker) initVar(lhs *Var, x *operand, context string) {
- if x.mode() == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
+ if !x.isValid() || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
check.usedVars[v] = v_used // restore v.used
}
- if x.mode() == invalid || !isValid(x.typ()) {
+ if !x.isValid() || !isValid(x.typ()) {
return Typ[Invalid]
}
args = check.exprList(argList)
nargs = len(args)
for _, a := range args {
- if a.mode() == invalid {
+ if !a.isValid() {
return
}
}
// and check below
}
}
- if x.mode() == invalid || y.mode() == invalid {
+ if !x.isValid() || !y.isValid() {
return
}
*x = *args[1] // key
check.assignment(x, key, "argument to delete")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// result in an error (shift of complex value)
check.convertUntyped(x, Typ[Complex128])
// x should be invalid now, but be conservative and check
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
}
}
for i, a := range args {
- if a.mode() == invalid {
+ if !a.isValid() {
return
}
// The first argument is already in x and there's nothing left to do.
if i > 0 {
check.matchTypes(x, a)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
x.mode_ = value
// A value must not be untyped.
check.assignment(x, &emptyInterface, "argument to built-in "+bin.name)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
}
if isUntyped(x.typ()) {
// check for overflow and untyped nil
check.assignment(x, nil, "argument to new")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
assert(isTyped(x.typ()))
}
check.assignment(x, &emptyInterface, "argument to panic")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
params = make([]Type, nargs)
for i, a := range args {
check.assignment(a, nil, "argument to built-in "+predeclaredFuncs[id].name)
- if a.mode() == invalid {
+ if !a.isValid() {
return
}
params[i] = a.typ()
check.verifyVersionf(call.Fun, go1_17, "unsafe.Add")
check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
case _Alignof:
// unsafe.Alignof(x T) uintptr
check.assignment(x, nil, "argument to unsafe.Alignof")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
}
check.expr(nil, x, selx.X)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
case _Sizeof:
// unsafe.Sizeof(x T) uintptr
check.assignment(x, nil, "argument to unsafe.Sizeof")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.verifyVersionf(call.Fun, go1_20, "unsafe.String")
check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.verifyVersionf(call.Fun, go1_20, "unsafe.StringData")
check.assignment(x, Typ[String], "argument to unsafe.StringData")
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.dump("%v: %s", x1.Pos(), x1)
x1 = &t // use incoming x only for first argument
}
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// trace is only available in test mode - no need to record signature
panic("unreachable")
}
- assert(x.mode() != invalid)
+ assert(x.isValid())
return true
}
case typexpr:
// conversion
check.nonGeneric(nil, x)
- if x.mode() == invalid {
+ if !x.isValid() {
return conversion
}
T := x.typ()
check.errorf(inNode(call, call.Rparen), WrongArgCount, "missing argument in conversion to %s", T)
case 1:
check.expr(nil, x, call.Args[0])
- if x.mode() != invalid {
+ if x.isValid() {
if hasDots(call) {
check.errorf(call.Args[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
break
}
x.expr = call
// a non-constant result implies a function call
- if x.mode() != invalid && x.mode() != constant_ {
+ if x.isValid() && x.mode() != constant_ {
check.hasCallOrRecv = true
}
return predeclaredFuncs[id].kind
// x is not a function instantiation (it may still be a generic function).
check.rawExpr(nil, &x, e, nil, true)
check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
- if t, ok := x.typ().(*Tuple); ok && x.mode() != invalid {
+ if t, ok := x.typ().(*Tuple); ok && x.isValid() {
// x is a function call returning multiple values; it cannot be generic.
resList = make([]*operand, t.Len())
for i, v := range t.vars {
default:
check.rawExpr(nil, &x, e, nil, true)
}
- return x.mode() != invalid
+ return x.isValid()
}
// The unary expression e may be nil. It's passed in for better error messages only.
func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
check.expr(nil, x, e.X)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
// If x is a constant, it must be representable as a value of typ.
c := operand{old.mode, x, old.typ, old.val, 0}
check.convertUntyped(&c, typ)
- if c.mode() == invalid {
+ if !c.isValid() {
return
}
}
// If x is a constant operand, the returned constant.Value will be the
// representation of x in this context.
func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
- if x.mode() == invalid || isTyped(x.typ()) || !isValid(target) {
+ if !x.isValid() || isTyped(x.typ()) || !isValid(target) {
return x.typ(), nil, 0
}
// x is untyped
// Caution: Check for representability here, rather than in the switch
// below, because isInteger includes untyped integers (was bug go.dev/issue/43697).
check.representable(y, Typ[Uint])
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
return
}
// This is incorrect, but preserves pre-existing behavior.
// See also go.dev/issue/47410.
check.convertUntyped(y, Typ[Uint])
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
return
}
check.expr(nil, x, lhs)
check.expr(nil, &y, rhs)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
x.expr = y.expr
return
}
check.matchTypes(x, &y)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
if mayConvert(x, y) {
check.convertUntyped(x, y.typ())
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.convertUntyped(y, x.typ())
- if y.mode() == invalid {
+ if !y.isValid() {
x.invalidate()
return
}
// from a non-nil target T, nonGeneric reports an error and invalidates x.mode and x.typ.
// Otherwise it leaves x alone.
func (check *Checker) nonGeneric(T *target, x *operand) {
- if x.mode() == invalid || x.mode() == novalue {
+ if !x.isValid() || x.mode() == novalue {
return
}
var what string
case *ast.BasicLit:
check.basicLit(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *ast.FuncLit:
check.funcLit(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *ast.CompositeLit:
check.compositeLit(x, e, hint)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
}
check.funcInst(T, e.Pos(), x, ix, true)
}
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *ast.SliceExpr:
check.sliceExpr(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
case *ast.TypeAssertExpr:
check.expr(nil, x, e.X)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
// x.(type) expressions are handled explicitly in type switches
case *ast.UnaryExpr:
check.unary(x, e)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
if e.Op == token.ARROW {
case *ast.BinaryExpr:
check.binary(x, e, e.X, e.Y, e.Op, e.OpPos)
- if x.mode() == invalid {
+ if !x.isValid() {
goto Error
}
check.rawExpr(nil, &x, e, nil, false)
check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
- if t, ok := x.typ().(*Tuple); ok && x.mode() != invalid {
+ if t, ok := x.typ().(*Tuple); ok && x.isValid() {
// multiple values
list = make([]*operand, t.Len())
for i, v := range t.vars {
// x should not be generic at this point, but be safe and check
check.nonGeneric(nil, x)
- if x.mode() == invalid {
+ if !x.isValid() {
return false
}
func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
check.expr(nil, x, e.X)
- if x.mode() == invalid {
+ if !x.isValid() {
check.use(e.Low, e.High, e.Max)
return
}
}
func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNegative bool) bool {
- if x.mode() == invalid {
+ if !x.isValid() {
return false
}
// spec: "a constant index that is untyped is given type int"
check.convertUntyped(x, Typ[Int])
- if x.mode() == invalid {
+ if !x.isValid() {
return false
}
// If we have invalid (ordinary) arguments, an error was reported before.
// Avoid additional inference errors and exit early (go.dev/issue/60434).
for _, arg := range args {
- if arg.mode() == invalid {
+ if !arg.isValid() {
return nil
}
}
}
for i, arg := range args {
- if arg.mode() == invalid {
+ if !arg.isValid() {
// An error was reported earlier. Ignore this arg
// and continue, we may still be able to infer all
// targs resulting in fewer follow-on errors.
}
}
x.setConst(e.Kind, e.Value)
- if x.mode() == invalid {
+ if !x.isValid() {
// The parser already establishes syntactic correctness.
// If we reach here it's because of number under-/overflow.
// TODO(gri) setConst (and in turn the go/constant package)
}
check.exprWithHint(x, kv.Key, utyp.key)
check.assignment(x, utyp.key, "map literal")
- if x.mode() == invalid {
+ if !x.isValid() {
continue
}
if x.mode() == constant_ {
// if assignableTo is invoked through an exported API call, i.e., when all
// methods have been type-checked.
func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
- if x.mode() == invalid || !isValid(T) {
+ if !x.isValid() || !isValid(T) {
return true, 0 // avoid spurious errors
}
check.hasCallOrRecv = false
check.expr(nil, &x, rangeVar)
- if isTypes2 && x.mode() != invalid && sValue == nil && !check.hasCallOrRecv {
+ if isTypes2 && x.isValid() && sValue == nil && !check.hasCallOrRecv {
if t, ok := arrayPtrDeref(x.typ().Underlying()).(*Array); ok {
for {
// Put constant info on the thing inside parentheses.
// determine key/value types
var key, val Type
- if x.mode() != invalid {
+ if x.isValid() {
k, v, cause, ok := rangeKeyVal(check, x.typ(), func(v goVersion) bool {
return check.allowVersion(v)
})
// If the assignment succeeded, if x was untyped before, it now
// has a type inferred via the assignment. It must be an integer.
// (go.dev/issues/67027)
- if x.mode() != invalid && !isInteger(x.typ()) {
+ if x.isValid() && !isInteger(x.typ()) {
check.softErrorf(lhs, InvalidRangeExpr, "cannot use iteration variable of type %s", x.typ())
}
} else {
for _, e := range values {
var v operand
check.expr(nil, &v, e)
- if x.mode() == invalid || v.mode() == invalid {
+ if !x.isValid() || !v.isValid() {
continue L
}
check.convertUntyped(&v, x.typ())
- if v.mode() == invalid {
+ if !v.isValid() {
continue L
}
// Order matters: By comparing v against x, error positions are at the case values.
res := v // keep original v unchanged
check.comparison(&res, x, token.EQL, true)
- if res.mode() == invalid {
+ if !res.isValid() {
continue L
}
if v.mode() != constant_ {
var ch, val operand
check.expr(nil, &ch, s.Chan)
check.expr(nil, &val, s.Value)
- if ch.mode() == invalid || val.mode() == invalid {
+ if !ch.isValid() || !val.isValid() {
return
}
if elem := check.chanElem(inNode(s, s.Arrow), &ch, false); elem != nil {
var x operand
check.expr(nil, &x, s.X)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
if !allNumeric(x.typ()) {
Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
check.binary(&x, nil, s.X, Y, op, s.TokPos)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.assignVar(s.X, nil, &x, "assignment")
}
var x operand
check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op, s.TokPos)
- if x.mode() == invalid {
+ if !x.isValid() {
return
}
check.assignVar(s.Lhs[0], nil, &x, "assignment")
check.simpleStmt(s.Init)
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode() != invalid && !allBoolean(x.typ()) {
+ if x.isValid() && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
}
check.stmt(inner, s.Body)
// By checking assignment of x to an invisible temporary
// (as a compiler would), we get all the relevant checks.
check.assignment(&x, nil, "switch expression")
- if x.mode() != invalid && !Comparable(x.typ()) && !hasNil(x.typ()) {
+ if x.isValid() && !Comparable(x.typ()) && !hasNil(x.typ()) {
check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ())
x.invalidate()
}
{
var x operand
check.expr(nil, &x, expr.X)
- if x.mode() != invalid {
+ if x.isValid() {
if isTypeParam(x.typ()) {
check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
} else if IsInterface(x.typ()) {
if s.Cond != nil {
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode() != invalid && !allBoolean(x.typ()) {
+ if x.isValid() && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
}
}
var x operand
check.expr(nil, &x, e)
if x.mode() != constant_ {
- if x.mode() != invalid {
+ if x.isValid() {
check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
}
return -1