]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: mechanically swap x.mode_ = invalid for x.invalidate()
authorMark Freeman <mark@golang.org>
Thu, 5 Feb 2026 20:58:52 +0000 (15:58 -0500)
committerGopher Robot <gobot@golang.org>
Thu, 5 Feb 2026 22:24:24 +0000 (14:24 -0800)
Change-Id: I7802b10f63a52e5f864d550a7ad7678d4581a796
Reviewed-on: https://go-review.googlesource.com/c/go/+/742500
Auto-Submit: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
20 files changed:
src/cmd/compile/internal/types2/assignments.go
src/cmd/compile/internal/types2/call.go
src/cmd/compile/internal/types2/const.go
src/cmd/compile/internal/types2/conversions.go
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/index.go
src/cmd/compile/internal/types2/literals.go
src/cmd/compile/internal/types2/operand.go
src/cmd/compile/internal/types2/stmt.go
src/cmd/compile/internal/types2/typexpr.go
src/go/types/assignments.go
src/go/types/call.go
src/go/types/const.go
src/go/types/conversions.go
src/go/types/expr.go
src/go/types/index.go
src/go/types/literals.go
src/go/types/operand.go
src/go/types/stmt.go
src/go/types/typexpr.go

index 5903a5a310940ca45441c2c54f54d2d93e29ae71..bd188d51da6c92683850603a0e9403e92a0e804c 100644 (file)
@@ -33,7 +33,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                // we may get here because of other problems (go.dev/issue/39634, crash 12)
                // TODO(gri) do we need a new "generic" error code here?
                check.errorf(x, IncompatibleAssign, "cannot assign %s to %s in %s", x, T, context)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -48,7 +48,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                        if x.isNil() {
                                if T == nil {
                                        check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
-                                       x.mode_ = invalid
+                                       x.invalidate()
                                        return
                                }
                        } else if T == nil || isNonTypeParamInterface(T) {
@@ -58,7 +58,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                        if T == nil || isNonTypeParamInterface(T) {
                                if T == nil && x.typ() == Typ[UntypedNil] {
                                        check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
-                                       x.mode_ = invalid
+                                       x.invalidate()
                                        return
                                }
                                target = Default(x.typ())
@@ -76,7 +76,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                                code = IncompatibleAssign
                        }
                        check.error(x, code, msg)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                if val != nil {
@@ -111,7 +111,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                } else {
                        check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
                }
-               x.mode_ = invalid
+               x.invalidate()
        }
 }
 
@@ -155,7 +155,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) {
                if lhs.typ == nil {
                        lhs.typ = Typ[Invalid]
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -167,7 +167,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) {
                        if typ == Typ[UntypedNil] {
                                check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
                                lhs.typ = Typ[Invalid]
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                        typ = Default(typ)
@@ -250,7 +250,7 @@ func (check *Checker) assignVar(lhs, rhs syntax.Expr, x *operand, context string
        T := check.lhsVar(lhs) // nil if lhs is _
        if !isValid(T) {
                if x != nil {
-                       x.mode_ = invalid
+                       x.invalidate()
                } else {
                        check.use(rhs)
                }
index 0e73c25f25d6afe052a5884db683ae02ae54bc25..467dc376094f591b5e2ac31caf469ac53aa58c99 100644 (file)
@@ -49,7 +49,7 @@ func (check *Checker) funcInst(T *target, pos syntax.Pos, x *operand, inst *synt
                xlist = syntax.UnpackListExpr(inst.Index)
                targs = check.typeList(xlist)
                if targs == nil {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return nil
                }
                assert(len(targs) == len(xlist))
@@ -63,7 +63,7 @@ func (check *Checker) funcInst(T *target, pos syntax.Pos, x *operand, inst *synt
        if got > want {
                // Providing too many type arguments is always an error.
                check.errorf(xlist[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
-               x.mode_ = invalid
+               x.invalidate()
                return nil
        }
 
@@ -113,7 +113,7 @@ func (check *Checker) funcInst(T *target, pos syntax.Pos, x *operand, inst *synt
                        if !err.empty() {
                                err.report()
                        }
-                       x.mode_ = invalid
+                       x.invalidate()
                        return nil
                }
                got = len(targs)
@@ -198,7 +198,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
                        return conversion
                }
                T := x.typ()
-               x.mode_ = invalid
+               x.invalidate()
                // We cannot convert a value to an incomplete type; make sure it's complete.
                if !check.isComplete(T) {
                        x.expr = call
@@ -233,7 +233,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
                // no need to check for non-genericity here
                id := x.id
                if !check.builtin(x, call, id) {
-                       x.mode_ = invalid
+                       x.invalidate()
                }
                x.expr = call
                // a non-constant result implies a function call
@@ -257,7 +257,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
        })
        if err != nil {
                check.errorf(x, InvalidCall, invalidOp+"cannot call %s: %s", x, err.format(check))
-               x.mode_ = invalid
+               x.invalidate()
                x.expr = call
                return statement
        }
@@ -274,7 +274,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
                targs = check.typeList(xlist)
                if targs == nil {
                        check.use(call.ArgList...)
-                       x.mode_ = invalid
+                       x.invalidate()
                        x.expr = call
                        return statement
                }
@@ -285,7 +285,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
                if got > want {
                        check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
                        check.use(call.ArgList...)
-                       x.mode_ = invalid
+                       x.invalidate()
                        x.expr = call
                        return statement
                }
@@ -327,7 +327,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
                typ := sig.results.vars[0].typ // unpack tuple
                // We cannot return a value of an incomplete type; make sure it's complete.
                if !check.isComplete(typ) {
-                       x.mode_ = invalid
+                       x.invalidate()
                        x.expr = call
                        return statement
                }
@@ -342,7 +342,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
        // if type inference failed, a parameterized result must be invalidated
        // (operands cannot have a parameterized type)
        if x.mode() == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ()) {
-               x.mode_ = invalid
+               x.invalidate()
        }
 
        return statement
@@ -938,7 +938,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
        return
 
 Error:
-       x.mode_ = invalid
+       x.invalidate()
        x.typ_ = Typ[Invalid]
        x.expr = e
 }
index 875386d6ba56a1dde58206d8de1ffe4ed02d9879..74f45a6e8badf3348790eddbdcff291d1ae6f5b4 100644 (file)
@@ -238,7 +238,7 @@ func (check *Checker) representable(x *operand, typ *Basic) {
        v, code := check.representation(x, typ)
        if code != 0 {
                check.invalidConversion(code, x, typ)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
        assert(v != nil)
@@ -292,7 +292,7 @@ func (check *Checker) convertUntyped(x *operand, target Type) {
                        t = safeUnderlying(target)
                }
                check.invalidConversion(code, x, t)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
        if val != nil {
index 40f982c332ef3ec28d277b7a1b9bf1a99d0a3e4a..693ccd4b609454cc1ef652b51198c385b84cd887 100644 (file)
@@ -47,7 +47,7 @@ func (check *Checker) conversion(x *operand, T Type) {
                // (go.dev/issue/63563)
                if !ok && isInteger(x.typ()) && isInteger(T) {
                        check.errorf(x, InvalidConversion, "constant %s overflows %s", x.val, T)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        case constArg && isTypeParam(T):
@@ -89,7 +89,7 @@ func (check *Checker) conversion(x *operand, T Type) {
                } else {
                        check.errorf(x, InvalidConversion, "cannot convert %s to type %s", x, T)
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
index 7925dbfb05dffd09f45379b81c0918a64776b99c..b092e74b0fb6e102803909dc27ec4e81cd21622c 100644 (file)
@@ -140,7 +140,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
                // requirement x may also be a composite literal."
                if _, ok := syntax.Unparen(e.X).(*syntax.CompositeLit); !ok && x.mode() != variable {
                        check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                x.mode_ = value
@@ -155,14 +155,14 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
                        check.hasCallOrRecv = true
                        return
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
 
        case syntax.Tilde:
                // Provide a better error position and message than what check.op below would do.
                if !allInteger(x.typ()) {
                        check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint (use ^ for bitwise complement)")
@@ -170,7 +170,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
        }
 
        if !check.op(unaryOpPredicates, x, op) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -494,7 +494,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
 func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase bool) {
        // Avoid spurious errors if any of the operands has an invalid type (go.dev/issue/54405).
        if !isValid(x.typ()) || !isValid(y.typ()) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -611,7 +611,7 @@ Error:
        } else {
                check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
        }
-       x.mode_ = invalid
+       x.invalidate()
 }
 
 // incomparableCause returns a more specific cause why typ is not comparable.
@@ -640,7 +640,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
        } else {
                // shift has no chance
                check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -655,7 +655,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
                if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
                        check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
 
@@ -664,7 +664,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                        // below, because isInteger includes untyped integers (was bug go.dev/issue/43697).
                        check.representable(y, Typ[Uint])
                        if y.mode() == invalid {
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                }
@@ -673,7 +673,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                switch {
                case allInteger(y.typ()):
                        if !allUnsigned(y.typ()) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                case isUntyped(y.typ()):
@@ -681,12 +681,12 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                        // See also go.dev/issue/47410.
                        check.convertUntyped(y, Typ[Uint])
                        if y.mode() == invalid {
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                default:
                        check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
@@ -707,7 +707,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                        s, ok := constant.Uint64Val(yval)
                        if !ok || s > shiftBound {
                                check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                        // The lhs is representable as an integer but may not be an integer
@@ -758,7 +758,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
        // non-constant shift - lhs must be an integer
        if !allInteger(x.typ()) {
                check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -798,7 +798,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
                return
        }
        if y.mode() == invalid {
-               x.mode_ = invalid
+               x.invalidate()
                x.expr = y.expr
                return
        }
@@ -828,12 +828,12 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
                                check.errorf(x, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ(), y.typ())
                        }
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
        if !check.op(binaryOpPredicates, x, op) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -841,7 +841,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
                // check for zero divisor
                if (x.mode() == constant_ || allInteger(x.typ())) && y.mode() == constant_ && constant.Sign(y.val) == 0 {
                        check.error(&y, DivByZero, invalidOp+"division by zero")
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
 
@@ -851,7 +851,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
                        re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
                        if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
                                check.error(&y, DivByZero, invalidOp+"division by zero")
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                }
@@ -937,7 +937,7 @@ func (check *Checker) matchTypes(x, y *operand) {
                }
                check.convertUntyped(y, x.typ())
                if y.mode() == invalid {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
@@ -1023,7 +1023,7 @@ func (check *Checker) nonGeneric(T *target, x *operand) {
        }
        if what != "" {
                check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
-               x.mode_ = invalid
+               x.invalidate()
                x.typ_ = Typ[Invalid]
        }
 }
@@ -1034,7 +1034,7 @@ func (check *Checker) nonGeneric(T *target, x *operand) {
 func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Type) exprKind {
        // make sure x has a valid state in case of bailout
        // (was go.dev/issue/5770)
-       x.mode_ = invalid
+       x.invalidate()
        x.typ_ = Typ[Invalid]
 
        switch e := e.(type) {
@@ -1243,7 +1243,7 @@ func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Ty
        return expression
 
 Error:
-       x.mode_ = invalid
+       x.invalidate()
        x.expr = e
        return statement // avoid follow-up errors
 }
@@ -1400,7 +1400,7 @@ func (check *Checker) exclude(x *operand, modeset uint) {
                        panic("unreachable")
                }
                check.errorf(x, code, msg, x)
-               x.mode_ = invalid
+               x.invalidate()
        }
 }
 
@@ -1411,7 +1411,7 @@ func (check *Checker) singleValue(x *operand) {
                if t, ok := x.typ().(*Tuple); ok {
                        assert(t.Len() != 1)
                        check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
-                       x.mode_ = invalid
+                       x.invalidate()
                }
        }
 }
index 68a7e620758d52039ca4ce930d3f7dee444a5983..054def5402a4e2bca8c8ac292c2ea38ead9ba16d 100644 (file)
@@ -26,7 +26,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
 
        case typexpr:
                // type instantiation
-               x.mode_ = invalid
+               x.invalidate()
                // TODO(gri) here we re-evaluate e.X - try to avoid this
                x.typ_ = check.varType(e)
                if isValid(x.typ()) {
@@ -49,7 +49,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
 
        // We cannot index on an incomplete type; make sure it's complete.
        if !check.isComplete(x.typ()) {
-               x.mode_ = invalid
+               x.invalidate()
                return false
        }
        switch typ := x.typ().Underlying().(type) {
@@ -57,14 +57,14 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
                // Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
                // its base type must also be complete.
                if !check.isComplete(typ.base) {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return false
                }
        case *Map:
                // Lastly, if x.typ is a map type, indexing must produce a value of a complete type, meaning
                // its element type must also be complete.
                if !check.isComplete(typ.elem) {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return false
                }
        }
@@ -110,7 +110,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
        case *Map:
                index := check.singleIndex(e)
                if index == nil {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return false
                }
                var key operand
@@ -184,7 +184,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
                        if key != nil {
                                index := check.singleIndex(e)
                                if index == nil {
-                                       x.mode_ = invalid
+                                       x.invalidate()
                                        return false
                                }
                                var k operand
@@ -207,13 +207,13 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
        if !valid {
                check.errorf(e.Pos(), NonSliceableOperand, "cannot index %s", x)
                check.use(e.Index)
-               x.mode_ = invalid
+               x.invalidate()
                return false
        }
 
        index := check.singleIndex(e)
        if index == nil {
-               x.mode_ = invalid
+               x.invalidate()
                return false
        }
 
@@ -277,7 +277,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
        // However, if x.typ is a pointer to an array type, slicing implicitly dereferences the value, meaning
        // its base type must also be complete.
        if p, ok := x.typ().Underlying().(*Pointer); ok && !check.isComplete(p.base) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -286,7 +286,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
        switch u := cu.(type) {
        case nil:
                // error reported above
-               x.mode_ = invalid
+               x.invalidate()
                return
 
        case *Basic:
@@ -297,7 +297,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
                                        at = e // e.Index[2] should be present but be careful
                                }
                                check.error(at, InvalidSliceExpr, invalidOp+"3-index slice of string")
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                        valid = true
@@ -316,7 +316,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
                length = u.len
                if x.mode() != variable {
                        check.errorf(x, NonSliceableOperand, "cannot slice unaddressable value %s", x)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                x.typ_ = &Slice{elem: u.elem}
@@ -335,7 +335,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
 
        if !valid {
                check.errorf(x, NonSliceableOperand, "cannot slice %s", x)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -344,7 +344,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
        // spec: "Only the first index may be omitted; it defaults to 0."
        if e.Full && (e.Index[1] == nil || e.Index[2] == nil) {
                check.error(e, InvalidSyntaxTree, "2nd and 3rd index required in 3-index slice")
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
index c52e070e44d93e4b6d0ed9c4eeb8f887bac9487b..e33efd93eae88d9022df61355eb3cbb295d9fcda 100644 (file)
@@ -57,7 +57,7 @@ func (check *Checker) basicLit(x *operand, e *syntax.BasicLit) {
                const limit = 10000
                if len(e.Value) > limit {
                        check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
@@ -68,7 +68,7 @@ func (check *Checker) basicLit(x *operand, e *syntax.BasicLit) {
                // TODO(gri) setConst (and in turn the go/constant package)
                // should return an error describing the issue.
                check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
        // Ensure that integer values don't overflow (go.dev/issue/54280).
@@ -100,7 +100,7 @@ func (check *Checker) funcLit(x *operand, e *syntax.FuncLit) {
                x.typ_ = sig
        } else {
                check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e)
-               x.mode_ = invalid
+               x.invalidate()
        }
 }
 
@@ -145,7 +145,7 @@ func (check *Checker) compositeLit(x *operand, e *syntax.CompositeLit, hint Type
 
        // We cannot create a literal of an incomplete type; make sure it's complete.
        if !check.isComplete(base) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -311,7 +311,7 @@ func (check *Checker) compositeLit(x *operand, e *syntax.CompositeLit, hint Type
                                cause = " (no common underlying type)"
                        }
                        check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
index fe06fc78613c2cadcc3bb875fd2143fc5d727111..83066c0e3011ab99eacfce064008a993c96dfa01 100644 (file)
@@ -72,6 +72,10 @@ func (x *operand) isValid() bool {
        return x.mode() != invalid
 }
 
+func (x *operand) invalidate() {
+       x.mode_ = invalid
+}
+
 // Pos returns the position of the expression corresponding to x.
 // If x is invalid the position is nopos.
 func (x *operand) Pos() syntax.Pos {
@@ -293,7 +297,7 @@ func (x *operand) setConst(k syntax.LitKind, lit string) {
 
        val := makeFromLiteral(lit, k)
        if val.Kind() == constant.Unknown {
-               x.mode_ = invalid
+               x.invalidate()
                x.typ_ = Typ[Invalid]
                return
        }
index ecc202ddade1ac8a6790c19f43ee095a7afcc1d3..1da8afb23895ec0b4319f6912bc39fa4bb0db8da 100644 (file)
@@ -723,7 +723,7 @@ func (check *Checker) switchStmt(inner stmtContext, s *syntax.SwitchStmt) {
                check.assignment(&x, nil, "switch expression")
                if x.mode() != invalid && !Comparable(x.typ()) && !hasNil(x.typ()) {
                        check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ())
-                       x.mode_ = invalid
+                       x.invalidate()
                }
        } else {
                // spec: "A missing switch expression is
index a9575230cffc592db69d7477a3126bfa44707e78..8453e2d5eb93ae29fc3b78c6432c469f1e491b82 100644 (file)
@@ -18,7 +18,7 @@ import (
 // If an error occurred, x.mode is set to invalid.
 // If wantType is set, the identifier e is expected to denote a type.
 func (check *Checker) ident(x *operand, e *syntax.Name, wantType bool) {
-       x.mode_ = invalid
+       x.invalidate()
        x.expr = e
 
        scope, obj := check.lookupScope(e.Value)
index 36413ff3125a1b21e31f30d82ab75862ea7cb8af..5655ea0b10ea10ef10917eb1ef8d92aad52d8c14 100644 (file)
@@ -36,7 +36,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                // we may get here because of other problems (go.dev/issue/39634, crash 12)
                // TODO(gri) do we need a new "generic" error code here?
                check.errorf(x, IncompatibleAssign, "cannot assign %s to %s in %s", x, T, context)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -51,7 +51,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                        if x.isNil() {
                                if T == nil {
                                        check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
-                                       x.mode_ = invalid
+                                       x.invalidate()
                                        return
                                }
                        } else if T == nil || isNonTypeParamInterface(T) {
@@ -61,7 +61,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                        if T == nil || isNonTypeParamInterface(T) {
                                if T == nil && x.typ() == Typ[UntypedNil] {
                                        check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
-                                       x.mode_ = invalid
+                                       x.invalidate()
                                        return
                                }
                                target = Default(x.typ())
@@ -79,7 +79,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                                code = IncompatibleAssign
                        }
                        check.error(x, code, msg)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                if val != nil {
@@ -114,7 +114,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
                } else {
                        check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
                }
-               x.mode_ = invalid
+               x.invalidate()
        }
 }
 
@@ -158,7 +158,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) {
                if lhs.typ == nil {
                        lhs.typ = Typ[Invalid]
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -170,7 +170,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) {
                        if typ == Typ[UntypedNil] {
                                check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
                                lhs.typ = Typ[Invalid]
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                        typ = Default(typ)
@@ -253,7 +253,7 @@ func (check *Checker) assignVar(lhs, rhs ast.Expr, x *operand, context string) {
        T := check.lhsVar(lhs) // nil if lhs is _
        if !isValid(T) {
                if x != nil {
-                       x.mode_ = invalid
+                       x.invalidate()
                } else {
                        check.use(rhs)
                }
index d9368c618da59b5889a801da7c88a6ed6c75fc0e..0b8ef351db94c48197990e8c483c5153f15a1f88 100644 (file)
@@ -50,7 +50,7 @@ func (check *Checker) funcInst(T *target, pos token.Pos, x *operand, ix *indexed
                xlist = ix.indices
                targs = check.typeList(xlist)
                if targs == nil {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return nil
                }
                assert(len(targs) == len(xlist))
@@ -64,7 +64,7 @@ func (check *Checker) funcInst(T *target, pos token.Pos, x *operand, ix *indexed
        if got > want {
                // Providing too many type arguments is always an error.
                check.errorf(ix.indices[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
-               x.mode_ = invalid
+               x.invalidate()
                return nil
        }
 
@@ -115,7 +115,7 @@ func (check *Checker) funcInst(T *target, pos token.Pos, x *operand, ix *indexed
                        if !err.empty() {
                                err.report()
                        }
-                       x.mode_ = invalid
+                       x.invalidate()
                        return nil
                }
                got = len(targs)
@@ -200,7 +200,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
                        return conversion
                }
                T := x.typ()
-               x.mode_ = invalid
+               x.invalidate()
                // We cannot convert a value to an incomplete type; make sure it's complete.
                if !check.isComplete(T) {
                        x.expr = call
@@ -235,7 +235,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
                // no need to check for non-genericity here
                id := x.id
                if !check.builtin(x, call, id) {
-                       x.mode_ = invalid
+                       x.invalidate()
                }
                x.expr = call
                // a non-constant result implies a function call
@@ -259,7 +259,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
        })
        if err != nil {
                check.errorf(x, InvalidCall, invalidOp+"cannot call %s: %s", x, err.format(check))
-               x.mode_ = invalid
+               x.invalidate()
                x.expr = call
                return statement
        }
@@ -276,7 +276,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
                targs = check.typeList(xlist)
                if targs == nil {
                        check.use(call.Args...)
-                       x.mode_ = invalid
+                       x.invalidate()
                        x.expr = call
                        return statement
                }
@@ -287,7 +287,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
                if got > want {
                        check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
                        check.use(call.Args...)
-                       x.mode_ = invalid
+                       x.invalidate()
                        x.expr = call
                        return statement
                }
@@ -329,7 +329,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
                typ := sig.results.vars[0].typ // unpack tuple
                // We cannot return a value of an incomplete type; make sure it's complete.
                if !check.isComplete(typ) {
-                       x.mode_ = invalid
+                       x.invalidate()
                        x.expr = call
                        return statement
                }
@@ -344,7 +344,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
        // if type inference failed, a parameterized result must be invalidated
        // (operands cannot have a parameterized type)
        if x.mode() == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ()) {
-               x.mode_ = invalid
+               x.invalidate()
        }
 
        return statement
@@ -986,7 +986,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
        return
 
 Error:
-       x.mode_ = invalid
+       x.invalidate()
        x.typ_ = Typ[Invalid]
        x.expr = e
 }
index 5162aac22cb0280f13ad587287e7aa7c88a55b7b..f897df63a7c16d818623e57761ac673ce4fa62ae 100644 (file)
@@ -240,7 +240,7 @@ func (check *Checker) representable(x *operand, typ *Basic) {
        v, code := check.representation(x, typ)
        if code != 0 {
                check.invalidConversion(code, x, typ)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
        assert(v != nil)
@@ -294,7 +294,7 @@ func (check *Checker) convertUntyped(x *operand, target Type) {
                        t = safeUnderlying(target)
                }
                check.invalidConversion(code, x, t)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
        if val != nil {
index 7f0bc8efb2b31925eef1b90dcf435fa8bf24eadf..2794b55bf54ccd3dfc6038f6c24e7b9521d68dbd 100644 (file)
@@ -50,7 +50,7 @@ func (check *Checker) conversion(x *operand, T Type) {
                // (go.dev/issue/63563)
                if !ok && isInteger(x.typ()) && isInteger(T) {
                        check.errorf(x, InvalidConversion, "constant %s overflows %s", x.val, T)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        case constArg && isTypeParam(T):
@@ -92,7 +92,7 @@ func (check *Checker) conversion(x *operand, T Type) {
                } else {
                        check.errorf(x, InvalidConversion, "cannot convert %s to type %s", x, T)
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
index 840452dcc056ff26f45deaf89d9aa0f300ce3e13..344246e74130e91fe6585c7203b2d844c29e5f0a 100644 (file)
@@ -139,7 +139,7 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
                // requirement x may also be a composite literal."
                if _, ok := ast.Unparen(e.X).(*ast.CompositeLit); !ok && x.mode() != variable {
                        check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                x.mode_ = value
@@ -154,14 +154,14 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
                        check.hasCallOrRecv = true
                        return
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
 
        case token.TILDE:
                // Provide a better error position and message than what check.op below would do.
                if !allInteger(x.typ()) {
                        check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint (use ^ for bitwise complement)")
@@ -169,7 +169,7 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
        }
 
        if !check.op(unaryOpPredicates, x, op) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -483,7 +483,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
 func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool) {
        // Avoid spurious errors if any of the operands has an invalid type (go.dev/issue/54405).
        if !isValid(x.typ()) || !isValid(y.typ()) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -600,7 +600,7 @@ Error:
        } else {
                check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
        }
-       x.mode_ = invalid
+       x.invalidate()
 }
 
 // incomparableCause returns a more specific cause why typ is not comparable.
@@ -629,7 +629,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
        } else {
                // shift has no chance
                check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -644,7 +644,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
                yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
                if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
                        check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
 
@@ -653,7 +653,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
                        // below, because isInteger includes untyped integers (was bug go.dev/issue/43697).
                        check.representable(y, Typ[Uint])
                        if y.mode() == invalid {
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                }
@@ -662,7 +662,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
                switch {
                case allInteger(y.typ()):
                        if !allUnsigned(y.typ()) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                case isUntyped(y.typ()):
@@ -670,12 +670,12 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
                        // See also go.dev/issue/47410.
                        check.convertUntyped(y, Typ[Uint])
                        if y.mode() == invalid {
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                default:
                        check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
@@ -696,7 +696,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
                        s, ok := constant.Uint64Val(yval)
                        if !ok || s > shiftBound {
                                check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                        // The lhs is representable as an integer but may not be an integer
@@ -747,7 +747,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
        // non-constant shift - lhs must be an integer
        if !allInteger(x.typ()) {
                check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -787,7 +787,7 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
                return
        }
        if y.mode() == invalid {
-               x.mode_ = invalid
+               x.invalidate()
                x.expr = y.expr
                return
        }
@@ -821,12 +821,12 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
                                check.errorf(posn, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ(), y.typ())
                        }
                }
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
        if !check.op(binaryOpPredicates, x, op) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -834,7 +834,7 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
                // check for zero divisor
                if (x.mode() == constant_ || allInteger(x.typ())) && y.mode() == constant_ && constant.Sign(y.val) == 0 {
                        check.error(&y, DivByZero, invalidOp+"division by zero")
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
 
@@ -844,7 +844,7 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
                        re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
                        if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
                                check.error(&y, DivByZero, invalidOp+"division by zero")
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                }
@@ -929,7 +929,7 @@ func (check *Checker) matchTypes(x, y *operand) {
                }
                check.convertUntyped(y, x.typ())
                if y.mode() == invalid {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
@@ -1015,7 +1015,7 @@ func (check *Checker) nonGeneric(T *target, x *operand) {
        }
        if what != "" {
                check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
-               x.mode_ = invalid
+               x.invalidate()
                x.typ_ = Typ[Invalid]
        }
 }
@@ -1026,7 +1026,7 @@ func (check *Checker) nonGeneric(T *target, x *operand) {
 func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type) exprKind {
        // make sure x has a valid state in case of bailout
        // (was go.dev/issue/5770)
-       x.mode_ = invalid
+       x.invalidate()
        x.typ_ = Typ[Invalid]
 
        switch e := e.(type) {
@@ -1194,7 +1194,7 @@ func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type)
        return expression
 
 Error:
-       x.mode_ = invalid
+       x.invalidate()
        x.expr = e
        return statement // avoid follow-up errors
 }
@@ -1351,7 +1351,7 @@ func (check *Checker) exclude(x *operand, modeset uint) {
                        panic("unreachable")
                }
                check.errorf(x, code, msg, x)
-               x.mode_ = invalid
+               x.invalidate()
        }
 }
 
@@ -1362,7 +1362,7 @@ func (check *Checker) singleValue(x *operand) {
                if t, ok := x.typ().(*Tuple); ok {
                        assert(t.Len() != 1)
                        check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
-                       x.mode_ = invalid
+                       x.invalidate()
                }
        }
 }
index 8dc46f0783682d6aa75bd4ce9810d8bdbbe6699a..8a540151cb7aaf8ab19d4c5e4ddc91bc8f9e7bff 100644 (file)
@@ -27,7 +27,7 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
 
        case typexpr:
                // type instantiation
-               x.mode_ = invalid
+               x.invalidate()
                // TODO(gri) here we re-evaluate e.X - try to avoid this
                x.typ_ = check.varType(e.orig)
                if isValid(x.typ()) {
@@ -50,7 +50,7 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
 
        // We cannot index on an incomplete type; make sure it's complete.
        if !check.isComplete(x.typ()) {
-               x.mode_ = invalid
+               x.invalidate()
                return false
        }
        switch typ := x.typ().Underlying().(type) {
@@ -58,14 +58,14 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
                // Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
                // its base type must also be complete.
                if !check.isComplete(typ.base) {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return false
                }
        case *Map:
                // Lastly, if x.typ is a map type, indexing must produce a value of a complete type, meaning
                // its element type must also be complete.
                if !check.isComplete(typ.elem) {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return false
                }
        }
@@ -111,7 +111,7 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
        case *Map:
                index := check.singleIndex(e)
                if index == nil {
-                       x.mode_ = invalid
+                       x.invalidate()
                        return false
                }
                var key operand
@@ -185,7 +185,7 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
                        if key != nil {
                                index := check.singleIndex(e)
                                if index == nil {
-                                       x.mode_ = invalid
+                                       x.invalidate()
                                        return false
                                }
                                var k operand
@@ -209,13 +209,13 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
                // types2 uses the position of '[' for the error
                check.errorf(x, NonIndexableOperand, "cannot index %s", x)
                check.use(e.indices...)
-               x.mode_ = invalid
+               x.invalidate()
                return false
        }
 
        index := check.singleIndex(e)
        if index == nil {
-               x.mode_ = invalid
+               x.invalidate()
                return false
        }
 
@@ -282,7 +282,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
        // However, if x.typ is a pointer to an array type, slicing implicitly dereferences the value, meaning
        // its base type must also be complete.
        if p, ok := x.typ().Underlying().(*Pointer); ok && !check.isComplete(p.base) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -291,7 +291,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
        switch u := cu.(type) {
        case nil:
                // error reported above
-               x.mode_ = invalid
+               x.invalidate()
                return
 
        case *Basic:
@@ -302,7 +302,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
                                        at = e // e.Index[2] should be present but be careful
                                }
                                check.error(at, InvalidSliceExpr, invalidOp+"3-index slice of string")
-                               x.mode_ = invalid
+                               x.invalidate()
                                return
                        }
                        valid = true
@@ -321,7 +321,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
                length = u.len
                if x.mode() != variable {
                        check.errorf(x, NonSliceableOperand, "cannot slice unaddressable value %s", x)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
                x.typ_ = &Slice{elem: u.elem}
@@ -340,7 +340,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
 
        if !valid {
                check.errorf(x, NonSliceableOperand, "cannot slice %s", x)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -349,7 +349,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
        // spec: "Only the first index may be omitted; it defaults to 0."
        if e.Slice3 && (e.High == nil || e.Max == nil) {
                check.error(inNode(e, e.Rbrack), InvalidSyntaxTree, "2nd and 3rd index required in 3-index slice")
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
index 11366f1d45151b547d81efabbd4d166eabc9033d..bc98ae8db0e47c037609162f97c04701c2c70856 100644 (file)
@@ -61,7 +61,7 @@ func (check *Checker) basicLit(x *operand, e *ast.BasicLit) {
                const limit = 10000
                if len(e.Value) > limit {
                        check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
@@ -72,7 +72,7 @@ func (check *Checker) basicLit(x *operand, e *ast.BasicLit) {
                // TODO(gri) setConst (and in turn the go/constant package)
                // should return an error describing the issue.
                check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
        // Ensure that integer values don't overflow (go.dev/issue/54280).
@@ -104,7 +104,7 @@ func (check *Checker) funcLit(x *operand, e *ast.FuncLit) {
                x.typ_ = sig
        } else {
                check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e)
-               x.mode_ = invalid
+               x.invalidate()
        }
 }
 
@@ -149,7 +149,7 @@ func (check *Checker) compositeLit(x *operand, e *ast.CompositeLit, hint Type) {
 
        // We cannot create a literal of an incomplete type; make sure it's complete.
        if !check.isComplete(base) {
-               x.mode_ = invalid
+               x.invalidate()
                return
        }
 
@@ -315,7 +315,7 @@ func (check *Checker) compositeLit(x *operand, e *ast.CompositeLit, hint Type) {
                                cause = " (no common underlying type)"
                        }
                        check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
-                       x.mode_ = invalid
+                       x.invalidate()
                        return
                }
        }
index b5c24a802ccb1f13bdb07e2f0ab13903b69162de..66850d67d6c6b5cdf674725747048f046cf36986 100644 (file)
@@ -76,6 +76,10 @@ func (x *operand) isValid() bool {
        return x.mode() != invalid
 }
 
+func (x *operand) invalidate() {
+       x.mode_ = invalid
+}
+
 // Pos returns the position of the expression corresponding to x.
 // If x is invalid the position is nopos.
 func (x *operand) Pos() token.Pos {
@@ -297,7 +301,7 @@ func (x *operand) setConst(k token.Token, lit string) {
 
        val := makeFromLiteral(lit, k)
        if val.Kind() == constant.Unknown {
-               x.mode_ = invalid
+               x.invalidate()
                x.typ_ = Typ[Invalid]
                return
        }
index ee2f872577fd75975e0beedd854b833228b7432d..773c2fd590e80900d87deed3fac259e1de5dbd0c 100644 (file)
@@ -638,7 +638,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
                        check.assignment(&x, nil, "switch expression")
                        if x.mode() != invalid && !Comparable(x.typ()) && !hasNil(x.typ()) {
                                check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ())
-                               x.mode_ = invalid
+                               x.invalidate()
                        }
                } else {
                        // spec: "A missing switch expression is
index 79b7f6b5ca7b67e743ea3ee0addc71e11f602515..c718922572fd47a517e087dfda4658b2686068d4 100644 (file)
@@ -18,7 +18,7 @@ import (
 // If an error occurred, x.mode is set to invalid.
 // If wantType is set, the identifier e is expected to denote a type.
 func (check *Checker) ident(x *operand, e *ast.Ident, wantType bool) {
-       x.mode_ = invalid
+       x.invalidate()
        x.expr = e
 
        scope, obj := check.lookupScope(e.Name)