aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Freeman <mark@golang.org>2026-02-02 14:00:43 -0500
committerGopher Robot <gobot@golang.org>2026-02-05 14:24:12 -0800
commitcfe0f5557163ae64c19bccf51e2c98fa0fc76430 (patch)
treec762ae9a2bf3b10ba36db090446e5bc02cd49a57 /src
parentfd146ff3b315c54e271a886d7451d0abd89f2cad (diff)
downloadgo-cfe0f5557163ae64c19bccf51e2c98fa0fc76430.tar.xz
go/types, types2: mechanically replace read accesses to operand.typ_
This provides a hook to enforce that operand.typ is only observed where operand.mode is not invalid. For #76110 Change-Id: I915f3ac09dc10bfe3f9f688d6190ad58e195ddcb Reviewed-on: https://go-review.googlesource.com/c/go/+/741220 Auto-Submit: Mark Freeman <markfreeman@google.com> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/types2/assignments.go26
-rw-r--r--src/cmd/compile/internal/types2/builtins.go122
-rw-r--r--src/cmd/compile/internal/types2/call.go50
-rw-r--r--src/cmd/compile/internal/types2/const.go10
-rw-r--r--src/cmd/compile/internal/types2/conversions.go22
-rw-r--r--src/cmd/compile/internal/types2/expr.go140
-rw-r--r--src/cmd/compile/internal/types2/index.go34
-rw-r--r--src/cmd/compile/internal/types2/infer.go14
-rw-r--r--src/cmd/compile/internal/types2/literals.go4
-rw-r--r--src/cmd/compile/internal/types2/operand.go42
-rw-r--r--src/cmd/compile/internal/types2/range.go10
-rw-r--r--src/cmd/compile/internal/types2/recording.go6
-rw-r--r--src/cmd/compile/internal/types2/stmt.go26
-rw-r--r--src/cmd/compile/internal/types2/typexpr.go8
-rw-r--r--src/go/types/assignments.go26
-rw-r--r--src/go/types/builtins.go122
-rw-r--r--src/go/types/call.go50
-rw-r--r--src/go/types/const.go10
-rw-r--r--src/go/types/conversions.go22
-rw-r--r--src/go/types/expr.go138
-rw-r--r--src/go/types/index.go34
-rw-r--r--src/go/types/infer.go14
-rw-r--r--src/go/types/literals.go4
-rw-r--r--src/go/types/operand.go42
-rw-r--r--src/go/types/range.go10
-rw-r--r--src/go/types/recording.go6
-rw-r--r--src/go/types/stmt.go26
-rw-r--r--src/go/types/typexpr.go8
28 files changed, 521 insertions, 505 deletions
diff --git a/src/cmd/compile/internal/types2/assignments.go b/src/cmd/compile/internal/types2/assignments.go
index cbe30b0201..1e00dade6a 100644
--- a/src/cmd/compile/internal/types2/assignments.go
+++ b/src/cmd/compile/internal/types2/assignments.go
@@ -37,7 +37,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
return
}
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
target := T
// spec: "If an untyped constant is assigned to a variable of interface
// type or the blank identifier, the constant is first converted to type
@@ -52,16 +52,16 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
return
}
} else if T == nil || isNonTypeParamInterface(T) {
- target = Default(x.typ_)
+ target = Default(x.typ())
}
} else { // go/types
if T == nil || isNonTypeParamInterface(T) {
- if T == nil && x.typ_ == Typ[UntypedNil] {
+ if T == nil && x.typ() == Typ[UntypedNil] {
check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
x.mode_ = invalid
return
}
- target = Default(x.typ_)
+ target = Default(x.typ())
}
}
newType, val, code := check.implicitTypeAndValue(x, target)
@@ -83,7 +83,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
x.val = val
check.updateExprVal(x.expr, val)
}
- if newType != x.typ_ {
+ if newType != x.typ() {
x.typ_ = newType
check.updateExprType(x.expr, newType, false)
}
@@ -116,7 +116,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
}
func (check *Checker) initConst(lhs *Const, x *operand) {
- if x.mode_ == invalid || !isValid(x.typ_) || !isValid(lhs.typ) {
+ if x.mode_ == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
@@ -131,11 +131,11 @@ func (check *Checker) initConst(lhs *Const, x *operand) {
}
return
}
- assert(isConstType(x.typ_))
+ assert(isConstType(x.typ()))
// If the lhs doesn't have a type yet, use the type of x.
if lhs.typ == nil {
- lhs.typ = x.typ_
+ lhs.typ = x.typ()
}
check.assignment(x, lhs.typ, "constant declaration")
@@ -151,7 +151,7 @@ func (check *Checker) initConst(lhs *Const, x *operand) {
// 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.mode_ == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
@@ -161,7 +161,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) {
// If lhs doesn't have a type yet, use the type of x.
if lhs.typ == nil {
- typ := x.typ_
+ typ := x.typ()
if isUntyped(typ) {
// convert untyped types to default types
if typ == Typ[UntypedNil] {
@@ -216,7 +216,7 @@ func (check *Checker) lhsVar(lhs syntax.Expr) Type {
check.usedVars[v] = v_used // restore v.used
}
- if x.mode_ == invalid || !isValid(x.typ_) {
+ if x.mode_ == invalid || !isValid(x.typ()) {
return Typ[Invalid]
}
@@ -240,7 +240,7 @@ func (check *Checker) lhsVar(lhs syntax.Expr) Type {
return Typ[Invalid]
}
- return x.typ_
+ return x.typ()
}
// assignVar checks the assignment lhs = rhs (if x == nil), or lhs = x (if x != nil).
@@ -278,7 +278,7 @@ func (check *Checker) assignVar(lhs, rhs syntax.Expr, x *operand, context string
// operandTypes returns the list of types for the given operands.
func operandTypes(list []*operand) (res []Type) {
for _, x := range list {
- res = append(res, x.typ_)
+ res = append(res, x.typ())
}
return res
}
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index 6cc0993c50..f64758a92b 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -109,7 +109,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
y := args[1]
hasString := false
- for _, u := range typeset(y.typ_) {
+ for _, u := range typeset(y.typ()) {
if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
// typeset ⊇ {[]byte}
} else if isString(u) {
@@ -122,7 +122,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if y != nil && hasString {
// setting the signature also signals that we're done
- sig = makeSig(x.typ_, x.typ_, y.typ_)
+ sig = makeSig(x.typ(), x.typ(), y.typ())
sig.variadic = true
}
}
@@ -131,7 +131,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// general case
if sig == nil {
// check arguments by creating custom signature
- sig = makeSig(x.typ_, x.typ_, NewSlice(E)) // []E required for variadic signature
+ sig = makeSig(x.typ(), x.typ(), NewSlice(E)) // []E required for variadic signature
sig.variadic = true
check.arguments(call, sig, nil, nil, args, nil) // discard result (we know the result type)
// ok to continue even if check.arguments reported errors
@@ -148,7 +148,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// len(x)
mode := invalid
var val constant.Value
- switch t := arrayPtrDeref(x.typ_.Underlying()).(type) {
+ switch t := arrayPtrDeref(x.typ().Underlying()).(type) {
case *Basic:
if isString(t) && id == _Len {
if x.mode_ == constant_ {
@@ -183,10 +183,10 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
case *Interface:
- if !isTypeParam(x.typ_) {
+ if !isTypeParam(x.typ()) {
break
}
- if underIs(x.typ_, func(u Type) bool {
+ if underIs(x.typ(), func(u Type) bool {
switch t := arrayPtrDeref(u).(type) {
case *Basic:
if isString(t) && id == _Len {
@@ -207,7 +207,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if mode == invalid {
// avoid error if underlying type is invalid
- if isValid(x.typ_.Underlying()) {
+ if isValid(x.typ().Underlying()) {
code := InvalidCap
if id == _Len {
code = InvalidLen
@@ -219,7 +219,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// record the signature before changing x.typ
if check.recordTypes() && mode != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ()))
}
x.mode_ = mode
@@ -230,7 +230,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// clear(m)
check.verifyVersionf(call.Fun, go1_21, "clear")
- if !underIs(x.typ_, func(u Type) bool {
+ if !underIs(x.typ(), func(u Type) bool {
switch u.(type) {
case *Map, *Slice:
return true
@@ -243,12 +243,12 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = novalue
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(nil, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(nil, x.typ()))
}
case _Close:
// close(c)
- if !underIs(x.typ_, func(u Type) bool {
+ if !underIs(x.typ(), func(u Type) bool {
uch, _ := u.(*Chan)
if uch == nil {
check.errorf(x, InvalidClose, invalidOp+"cannot close non-channel %s", x)
@@ -264,7 +264,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
x.mode_ = novalue
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(nil, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(nil, x.typ()))
}
case _Complex:
@@ -273,10 +273,10 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// convert or check untyped arguments
d := 0
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
d |= 1
}
- if isUntyped(y.typ_) {
+ if isUntyped(y.typ()) {
d |= 2
}
switch d {
@@ -284,10 +284,10 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// x and y are typed => nothing to do
case 1:
// only x is untyped => convert to type of y
- check.convertUntyped(x, y.typ_)
+ check.convertUntyped(x, y.typ())
case 2:
// only y is untyped => convert to type of x
- check.convertUntyped(y, x.typ_)
+ check.convertUntyped(y, x.typ())
case 3:
// x and y are untyped =>
// 1) if both are constants, convert them to untyped
@@ -299,7 +299,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// because shifts of floats are not permitted)
if x.mode_ == constant_ && y.mode_ == constant_ {
toFloat := func(x *operand) {
- if isNumeric(x.typ_) && constant.Sign(constant.Imag(x.val)) == 0 {
+ if isNumeric(x.typ()) && constant.Sign(constant.Imag(x.val)) == 0 {
x.typ_ = Typ[UntypedFloat]
}
}
@@ -317,8 +317,8 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
// both argument types must be identical
- if !Identical(x.typ_, y.typ_) {
- check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ_, y.typ_)
+ if !Identical(x.typ(), y.typ()) {
+ check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ(), y.typ())
return
}
@@ -340,7 +340,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
resTyp := check.applyTypeFunc(f, x, id)
if resTyp == nil {
- check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ_)
+ check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ())
return
}
@@ -352,7 +352,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if check.recordTypes() && x.mode_ != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ_, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ(), x.typ()))
}
x.typ_ = resTyp
@@ -372,7 +372,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
var special bool
if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
special = true
- for _, u := range typeset(y.typ_) {
+ for _, u := range typeset(y.typ()) {
if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
// typeset ⊇ {[]byte}
} else if isString(u) {
@@ -396,7 +396,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
srcE, err := sliceElem(y)
if err != nil {
// If we have a string, for a better error message proceed with byte element type.
- if !allString(y.typ_) {
+ if !allString(y.typ()) {
check.errorf(y, InvalidCopy, "invalid copy: %s", err.format(check))
return
}
@@ -409,7 +409,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ_, y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ(), y.typ()))
}
x.mode_ = value
x.typ_ = Typ[Int]
@@ -418,7 +418,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// delete(map_, key)
// map_ must be a map type or a type parameter describing map types.
// The key cannot be a type parameter for now.
- map_ := x.typ_
+ map_ := x.typ()
var key Type
if !underIs(map_, func(u Type) bool {
map_, _ := u.(*Map)
@@ -452,11 +452,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// real(complexT) floatT
// convert or check untyped argument
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
if x.mode_ == constant_ {
// an untyped constant number can always be considered
// as a complex constant
- if isNumeric(x.typ_) {
+ if isNumeric(x.typ()) {
x.typ_ = Typ[UntypedComplex]
}
} else {
@@ -494,7 +494,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if id == _Real {
code = InvalidReal
}
- check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ_)
+ check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ())
return
}
@@ -510,7 +510,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
if check.recordTypes() && x.mode_ != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ()))
}
x.typ_ = resTyp
@@ -571,7 +571,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = value
x.typ_ = T
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, types...))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), types...))
}
case _Max, _Min:
@@ -589,7 +589,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
return
}
- if !allOrdered(a.typ_) {
+ if !allOrdered(a.typ()) {
check.errorf(a, InvalidMinMaxOperand, invalidArg+"%s cannot be ordered", a)
return
}
@@ -601,8 +601,8 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
return
}
- if !Identical(x.typ_, a.typ_) {
- check.errorf(a, MismatchedTypes, invalidArg+"mismatched types %s (previous argument) and %s (type of %s)", x.typ_, a.typ_, a.expr)
+ if !Identical(x.typ(), a.typ()) {
+ check.errorf(a, MismatchedTypes, invalidArg+"mismatched types %s (previous argument) and %s (type of %s)", x.typ(), a.typ(), a.expr)
return
}
@@ -628,15 +628,15 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// Use the final type computed above for all arguments.
for _, a := range args {
- check.updateExprType(a.expr, x.typ_, true)
+ check.updateExprType(a.expr, x.typ(), true)
}
if check.recordTypes() && x.mode_ != constant_ {
types := make([]Type, nargs)
for i := range types {
- types[i] = x.typ_
+ types[i] = x.typ()
}
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, types...))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), types...))
}
case _New:
@@ -650,26 +650,26 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
return
case typexpr:
// new(T)
- check.validVarType(arg, x.typ_)
+ check.validVarType(arg, x.typ())
default:
// new(expr)
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
// check for overflow and untyped nil
check.assignment(x, nil, "argument to new")
if x.mode_ == invalid {
return
}
- assert(isTyped(x.typ_))
+ assert(isTyped(x.typ()))
}
// report version error only if there are no other errors
check.verifyVersionf(call.Fun, go1_26, "new(%s)", arg)
}
- T := x.typ_
+ T := x.typ()
x.mode_ = value
x.typ_ = NewPointer(T)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, T))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), T))
}
case _Panic:
@@ -708,7 +708,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
if a.mode_ == invalid {
return
}
- params[i] = a.typ_
+ params[i] = a.typ()
}
}
@@ -722,7 +722,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = value
x.typ_ = &emptyInterface
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ()))
}
case _Add:
@@ -742,7 +742,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = value
x.typ_ = Typ[UnsafePointer]
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, x.typ_, y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), x.typ(), y.typ()))
}
case _Alignof:
@@ -752,14 +752,14 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
return
}
- if check.hasVarSize(x.typ_) {
+ if check.hasVarSize(x.typ()) {
x.mode_ = value
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ()))
}
} else {
x.mode_ = constant_
- x.val = constant.MakeInt64(check.conf.alignof(x.typ_))
+ x.val = constant.MakeInt64(check.conf.alignof(x.typ()))
// result is constant - no need to record signature
}
x.typ_ = Typ[Uintptr]
@@ -780,7 +780,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
return
}
- base := derefStructPtr(x.typ_)
+ base := derefStructPtr(x.typ())
sel := selx.Sel.Value
obj, index, indirect := lookupFieldOrMethod(base, false, check.pkg, sel, false)
switch obj.(type) {
@@ -840,13 +840,13 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
return
}
- if check.hasVarSize(x.typ_) {
+ if check.hasVarSize(x.typ()) {
x.mode_ = value
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ()))
}
} else {
- size := check.conf.sizeof(x.typ_)
+ size := check.conf.sizeof(x.typ())
if size < 0 {
check.errorf(x, TypeTooLarge, "%s is too large", x)
return
@@ -861,7 +861,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// unsafe.Slice(ptr *T, len IntegerType) []T
check.verifyVersionf(call.Fun, go1_17, "unsafe.Slice")
- u, _ := commonUnder(x.typ_, nil)
+ u, _ := commonUnder(x.typ(), nil)
ptr, _ := u.(*Pointer)
if ptr == nil {
check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
@@ -876,14 +876,14 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = value
x.typ_ = NewSlice(ptr.base)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, ptr, y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), ptr, y.typ()))
}
case _SliceData:
// unsafe.SliceData(slice []T) *T
check.verifyVersionf(call.Fun, go1_20, "unsafe.SliceData")
- u, _ := commonUnder(x.typ_, nil)
+ u, _ := commonUnder(x.typ(), nil)
slice, _ := u.(*Slice)
if slice == nil {
check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
@@ -893,7 +893,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = value
x.typ_ = NewPointer(slice.elem)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, slice))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), slice))
}
case _String:
@@ -913,7 +913,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = value
x.typ_ = Typ[String]
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, NewPointer(universeByte), y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), NewPointer(universeByte), y.typ()))
}
case _StringData:
@@ -928,14 +928,14 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
x.mode_ = value
x.typ_ = NewPointer(universeByte)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, Typ[String]))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), Typ[String]))
}
case _Assert:
// 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.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
return
}
@@ -984,7 +984,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
// or a type error if x is not a slice (or a type set of slices).
func sliceElem(x *operand) (Type, *typeError) {
var E Type
- for _, u := range typeset(x.typ_) {
+ for _, u := range typeset(x.typ()) {
s, _ := u.(*Slice)
if s == nil {
if x.isNil() {
@@ -1070,7 +1070,7 @@ func (check *Checker) hasVarSize(t Type) bool {
// applyTypeFunc returns nil.
// If x is not a type parameter, the result is f(x).
func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
- if tp, _ := Unalias(x.typ_).(*TypeParam); tp != nil {
+ if tp, _ := Unalias(x.typ()).(*TypeParam); tp != nil {
// Test if t satisfies the requirements for the argument
// type and collect possible result types at the same time.
var terms []*Term
@@ -1114,7 +1114,7 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId)
return ptyp
}
- return f(x.typ_)
+ return f(x.typ())
}
// makeSig makes a signature for the given argument and result types.
diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go
index 8671b13649..0de514f4f4 100644
--- a/src/cmd/compile/internal/types2/call.go
+++ b/src/cmd/compile/internal/types2/call.go
@@ -58,7 +58,7 @@ func (check *Checker) funcInst(T *target, pos syntax.Pos, x *operand, inst *synt
// Check the number of type arguments (got) vs number of type parameters (want).
// Note that x is a function value, not a type expression, so we don't need to
// call Underlying below.
- sig := x.typ_.(*Signature)
+ sig := x.typ().(*Signature)
got, want := len(targs), sig.TypeParams().Len()
if got > want {
// Providing too many type arguments is always an error.
@@ -197,7 +197,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
if x.mode_ == invalid {
return conversion
}
- T := x.typ_
+ T := x.typ()
x.mode_ = invalid
// We cannot convert a value to an incomplete type; make sure it's complete.
if !check.isComplete(T) {
@@ -249,7 +249,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
// If the operand type is a type parameter, all types in its type set
// must have a common underlying type, which must be a signature.
- u, err := commonUnder(x.typ_, func(t, u Type) *typeError {
+ u, err := commonUnder(x.typ(), func(t, u Type) *typeError {
if _, ok := u.(*Signature); u != nil && !ok {
return typeErrorf("%s is not a function", t)
}
@@ -341,7 +341,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_) {
+ if x.mode_ == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ()) {
x.mode_ = invalid
}
@@ -380,7 +380,7 @@ func (check *Checker) genericExprList(elist []syntax.Expr) (resList []*operand,
if i < len(targsList) {
if n := len(targsList[i]); n > 0 {
// x must be a partially instantiated function
- assert(n < x.typ_.(*Signature).TypeParams().Len())
+ assert(n < x.typ().(*Signature).TypeParams().Len())
}
}
}
@@ -417,7 +417,7 @@ func (check *Checker) genericExprList(elist []syntax.Expr) (resList []*operand,
// 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.mode_ != invalid {
// x is a function call returning multiple values; it cannot be generic.
resList = make([]*operand, t.Len())
for i, v := range t.vars {
@@ -580,7 +580,7 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
if enableReverseTypeInference {
for i, arg := range args {
// generic arguments cannot have a defined (*Named) type - no need for underlying type below
- if asig, _ := arg.typ_.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
+ if asig, _ := arg.typ().(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
// The argument type is a generic function signature. This type is
// pointer-identical with (it's copied from) the type of the generic
// function argument and thus the function object.
@@ -650,7 +650,7 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
j := n
for _, i := range genericArgs {
arg := args[i]
- asig := arg.typ_.(*Signature)
+ asig := arg.typ().(*Signature)
k := j + asig.TypeParams().Len()
// targs[j:k] are the inferred type arguments for asig
arg.typ_ = check.instantiateSignature(call.Pos(), arg.expr, asig, targs[j:k], nil) // TODO(gri) provide xlist if possible (partial instantiations)
@@ -765,14 +765,14 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
x.mode_ = variable
x.typ_ = exp.typ
if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
- x.typ_ = x.typ_.(*Pointer).base
+ x.typ_ = x.typ().(*Pointer).base
}
case *Func:
x.mode_ = funcMode
x.typ_ = exp.typ
if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
x.mode_ = value
- x.typ_ = x.typ_.(*Signature).results.vars[0].typ
+ x.typ_ = x.typ().(*Signature).results.vars[0].typ
}
case *Builtin:
x.mode_ = builtin
@@ -797,7 +797,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
}
// We cannot select on an incomplete type; make sure it's complete.
- if !check.isComplete(x.typ_) {
+ if !check.isComplete(x.typ()) {
goto Error
}
@@ -818,14 +818,14 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
// Additionally, if x.typ is a pointer type, selecting implicitly dereferences the value, meaning
// its base type must also be complete.
- if p, ok := x.typ_.Underlying().(*Pointer); ok && !check.isComplete(p.base) {
+ if p, ok := x.typ().Underlying().(*Pointer); ok && !check.isComplete(p.base) {
goto Error
}
- obj, index, indirect = lookupFieldOrMethod(x.typ_, x.mode_ == variable, check.pkg, sel, false)
+ obj, index, indirect = lookupFieldOrMethod(x.typ(), x.mode_ == variable, check.pkg, sel, false)
if obj == nil {
// Don't report another error if the underlying type was invalid (go.dev/issue/49541).
- if !isValid(x.typ_.Underlying()) {
+ if !isValid(x.typ().Underlying()) {
goto Error
}
@@ -837,19 +837,19 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
if indirect {
if x.mode_ == typexpr {
- check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ_, sel, x.typ_, sel)
+ check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ(), sel, x.typ(), sel)
} else {
- check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ_)
+ check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ())
}
goto Error
}
var why string
- if isInterfacePtr(x.typ_) {
- why = check.interfacePtrError(x.typ_)
+ if isInterfacePtr(x.typ()) {
+ why = check.interfacePtrError(x.typ())
} else {
- alt, _, _ := lookupFieldOrMethod(x.typ_, x.mode_ == variable, check.pkg, sel, true)
- why = check.lookupError(x.typ_, sel, alt, false)
+ alt, _, _ := lookupFieldOrMethod(x.typ(), x.mode_ == variable, check.pkg, sel, true)
+ why = check.lookupError(x.typ(), sel, alt, false)
}
check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
goto Error
@@ -859,12 +859,12 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
switch obj := obj.(type) {
case *Var:
if x.mode_ == typexpr {
- check.errorf(e.X, MissingFieldOrMethod, "operand for field selector %s must be value of type %s", sel, x.typ_)
+ check.errorf(e.X, MissingFieldOrMethod, "operand for field selector %s must be value of type %s", sel, x.typ())
goto Error
}
// field value
- check.recordSelection(e, FieldVal, x.typ_, obj, index, indirect)
+ check.recordSelection(e, FieldVal, x.typ(), obj, index, indirect)
if x.mode_ == variable || indirect {
x.mode_ = variable
} else {
@@ -878,7 +878,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
if x.mode_ == typexpr {
// method expression
- check.recordSelection(e, MethodExpr, x.typ_, obj, index, indirect)
+ check.recordSelection(e, MethodExpr, x.typ(), obj, index, indirect)
sig := obj.typ.(*Signature)
if sig.recv == nil {
@@ -906,7 +906,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
name = "_"
}
}
- params = append([]*Var{NewParam(sig.recv.pos, sig.recv.pkg, name, x.typ_)}, params...)
+ params = append([]*Var{NewParam(sig.recv.pos, sig.recv.pkg, name, x.typ())}, params...)
x.mode_ = value
x.typ_ = &Signature{
tparams: sig.tparams,
@@ -919,7 +919,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
// TODO(gri) If we needed to take into account the receiver's
// addressability, should we report the type &(x.typ) instead?
- check.recordSelection(e, MethodVal, x.typ_, obj, index, indirect)
+ check.recordSelection(e, MethodVal, x.typ(), obj, index, indirect)
x.mode_ = value
diff --git a/src/cmd/compile/internal/types2/const.go b/src/cmd/compile/internal/types2/const.go
index d5e4f8429b..271c659c0c 100644
--- a/src/cmd/compile/internal/types2/const.go
+++ b/src/cmd/compile/internal/types2/const.go
@@ -32,8 +32,8 @@ func (check *Checker) overflow(x *operand, opPos syntax.Pos) {
// their type after each constant operation.
// x.typ cannot be a type parameter (type
// parameters cannot be constant types).
- if isTyped(x.typ_) {
- check.representable(x, x.typ_.Underlying().(*Basic))
+ if isTyped(x.typ()) {
+ check.representable(x, x.typ().Underlying().(*Basic))
return
}
@@ -253,7 +253,7 @@ func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Co
assert(x.mode_ == constant_)
v := x.val
if !representableConst(x.val, check, typ, &v) {
- if isNumeric(x.typ_) && isNumeric(typ) {
+ if isNumeric(x.typ()) && isNumeric(typ) {
// numeric conversion : error msg
//
// integer -> integer : overflows
@@ -261,7 +261,7 @@ func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Co
// float -> integer : truncated
// float -> float : overflows
//
- if !isInteger(x.typ_) && isInteger(typ) {
+ if !isInteger(x.typ()) && isInteger(typ) {
return nil, TruncatedFloat
} else {
return nil, NumericOverflow
@@ -299,7 +299,7 @@ func (check *Checker) convertUntyped(x *operand, target Type) {
x.val = val
check.updateExprVal(x.expr, val)
}
- if newType != x.typ_ {
+ if newType != x.typ() {
x.typ_ = newType
check.updateExprType(x.expr, newType, false)
}
diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go
index 3544dfc07b..329878be5a 100644
--- a/src/cmd/compile/internal/types2/conversions.go
+++ b/src/cmd/compile/internal/types2/conversions.go
@@ -23,7 +23,7 @@ func (check *Checker) conversion(x *operand, T Type) {
// nothing to do
case representableConst(x.val, check, t, val):
return true
- case isInteger(x.typ_) && isString(t):
+ case isInteger(x.typ()) && isString(t):
codepoint := unicode.ReplacementChar
if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune {
codepoint = rune(i)
@@ -45,7 +45,7 @@ func (check *Checker) conversion(x *operand, T Type) {
// A conversion from an integer constant to an integer type
// can only fail if there's overflow. Give a concise error.
// (go.dev/issue/63563)
- if !ok && isInteger(x.typ_) && isInteger(T) {
+ if !ok && isInteger(x.typ()) && isInteger(T) {
check.errorf(x, InvalidConversion, "constant %s overflows %s", x.val, T)
x.mode_ = invalid
return
@@ -62,11 +62,11 @@ func (check *Checker) conversion(x *operand, T Type) {
cause = check.sprintf("%s does not contain specific types", T)
return false
}
- if isString(x.typ_) && isBytesOrRunes(u) {
+ if isString(x.typ()) && isBytesOrRunes(u) {
return true
}
if !constConvertibleTo(u, nil) {
- if isInteger(x.typ_) && isInteger(u) {
+ if isInteger(x.typ()) && isInteger(u) {
// see comment above on constant conversion
cause = check.sprintf("constant %s overflows %s (in %s)", x.val, u, T)
} else {
@@ -96,7 +96,7 @@ func (check *Checker) conversion(x *operand, T Type) {
// The conversion argument types are final. For untyped values the
// conversion provides the type, per the spec: "A constant may be
// given a type explicitly by a constant declaration or conversion,...".
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
final := T
// - For conversions to interfaces, except for untyped nil arguments
// and isTypes2, use the argument's default type.
@@ -106,12 +106,12 @@ func (check *Checker) conversion(x *operand, T Type) {
// - If !isTypes2, keep untyped nil for untyped nil arguments.
// - For constant integer to string conversions, keep the argument type.
// (See also the TODO below.)
- if isTypes2 && x.typ_ == Typ[UntypedNil] {
+ if isTypes2 && x.typ() == Typ[UntypedNil] {
// ok
} else if isNonTypeParamInterface(T) || constArg && !isConstType(T) || !isTypes2 && x.isNil() {
- final = Default(x.typ_) // default type of untyped nil is untyped nil
- } else if x.mode_ == constant_ && isInteger(x.typ_) && allString(T) {
- final = x.typ_
+ final = Default(x.typ()) // default type of untyped nil is untyped nil
+ } else if x.mode_ == constant_ && isInteger(x.typ()) && allString(T) {
+ final = x.typ()
}
check.updateExprType(x.expr, final, true)
}
@@ -140,7 +140,7 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
}
origT := T
- V := Unalias(x.typ_)
+ V := Unalias(x.typ())
T = Unalias(T)
Vu := V.Underlying()
Tu := T.Underlying()
@@ -281,7 +281,7 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
return false // no specific types
}
if !x.convertibleTo(check, T.typ, cause) {
- errorf("cannot convert %s to type %s (in %s)", x.typ_, T.typ, Tp)
+ errorf("cannot convert %s to type %s (in %s)", x.typ(), T.typ, Tp)
return false
}
return true
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index dad04dbb0b..d35d108b5a 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -23,7 +23,7 @@ are generally of the form:
func f(x *operand, e *syntax.Expr, ...)
where e is the expression to be checked, and x is the result of the check.
-The check performed by f may fail in which case x.mode == invalid, and
+The check performed by f may fail in which case x.mode_ == invalid, and
related error messages will have been issued by f.
If a hint argument is present, it is the composite literal element type
@@ -72,7 +72,7 @@ func init() {
func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool {
if pred := m[op]; pred != nil {
- if !pred(x.typ_) {
+ if !pred(x.typ()) {
check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
return false
}
@@ -144,7 +144,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
return
}
x.mode_ = value
- x.typ_ = &Pointer{base: x.typ_}
+ x.typ_ = &Pointer{base: x.typ()}
return
case syntax.Recv:
@@ -160,7 +160,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
case syntax.Tilde:
// Provide a better error position and message than what check.op below would do.
- if !allInteger(x.typ_) {
+ if !allInteger(x.typ()) {
check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
x.mode_ = invalid
return
@@ -180,8 +180,8 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
return
}
var prec uint
- if isUnsigned(x.typ_) {
- prec = uint(check.conf.sizeof(x.typ_) * 8)
+ if isUnsigned(x.typ()) {
+ prec = uint(check.conf.sizeof(x.typ()) * 8)
}
x.val = constant.UnaryOp(op2tok[op], x.val, prec)
x.expr = e
@@ -197,7 +197,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
// or send to x (recv == false) operation. If the operation is not valid, chanElem
// reports an error and returns nil.
func (check *Checker) chanElem(pos poser, x *operand, recv bool) Type {
- u, err := commonUnder(x.typ_, func(t, u Type) *typeError {
+ u, err := commonUnder(x.typ(), func(t, u Type) *typeError {
if u == nil {
return typeErrorf("no specific channel type")
}
@@ -220,14 +220,14 @@ func (check *Checker) chanElem(pos poser, x *operand, recv bool) Type {
cause := err.format(check)
if recv {
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s: %s", x, cause)
} else {
// In this case, only the non-channel and send-only channel error are possible.
check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s %s", cause, x)
}
} else {
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(pos, InvalidSend, invalidOp+"cannot send to %s: %s", x, cause)
} else {
// In this case, only the non-channel and receive-only channel error are possible.
@@ -411,21 +411,21 @@ func (check *Checker) updateExprVal(x syntax.Expr, val constant.Value) {
// 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) {
- return x.typ_, nil, 0
+ if x.mode_ == invalid || isTyped(x.typ()) || !isValid(target) {
+ return x.typ(), nil, 0
}
// x is untyped
if isUntyped(target) {
// both x and target are untyped
- if m := maxType(x.typ_, target); m != nil {
+ if m := maxType(x.typ(), target); m != nil {
return m, nil, 0
}
return nil, nil, InvalidUntypedConversion
}
if x.isNil() {
- assert(isUntyped(x.typ_))
+ assert(isUntyped(x.typ()))
if hasNil(target) {
return target, nil, 0
}
@@ -445,7 +445,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
// result of comparisons (untyped bool), intermediate
// (delayed-checked) rhs operands of shifts, and as
// the value nil.
- switch x.typ_.(*Basic).kind {
+ switch x.typ().(*Basic).kind {
case UntypedBool:
if !isBoolean(target) {
return nil, nil, InvalidUntypedConversion
@@ -483,7 +483,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
if !u.Empty() {
return nil, nil, InvalidUntypedConversion // cannot assign untyped values to non-empty interfaces
}
- return Default(x.typ_), nil, 0 // default type for nil is nil
+ return Default(x.typ()), nil, 0 // default type for nil is nil
default:
return nil, nil, InvalidUntypedConversion
}
@@ -493,7 +493,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
// If switchCase is true, the operator op is ignored.
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_) {
+ if !isValid(x.typ()) || !isValid(y.typ()) {
x.mode_ = invalid
return
}
@@ -508,16 +508,16 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase b
// spec: "In any comparison, the first operand must be assignable
// to the type of the second operand, or vice versa."
code := MismatchedTypes
- ok, _ := x.assignableTo(check, y.typ_, nil)
+ ok, _ := x.assignableTo(check, y.typ(), nil)
if !ok {
- ok, _ = y.assignableTo(check, x.typ_, nil)
+ ok, _ = y.assignableTo(check, x.typ(), nil)
}
if !ok {
// Report the error on the 2nd operand since we only
// know after seeing the 2nd operand whether we have
// a type mismatch.
errOp = y
- cause = check.sprintf("mismatched types %s and %s", x.typ_, y.typ_)
+ cause = check.sprintf("mismatched types %s and %s", x.typ(), y.typ())
goto Error
}
@@ -529,9 +529,9 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase b
switch {
case x.isNil() || y.isNil():
// Comparison against nil requires that the other operand type has nil.
- typ := x.typ_
+ typ := x.typ()
if x.isNil() {
- typ = y.typ_
+ typ = y.typ()
}
if !hasNil(typ) {
// This case should only be possible for "nil == nil".
@@ -542,24 +542,24 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase b
goto Error
}
- case !Comparable(x.typ_):
+ case !Comparable(x.typ()):
errOp = x
- cause = check.incomparableCause(x.typ_)
+ cause = check.incomparableCause(x.typ())
goto Error
- case !Comparable(y.typ_):
+ case !Comparable(y.typ()):
errOp = y
- cause = check.incomparableCause(y.typ_)
+ cause = check.incomparableCause(y.typ())
goto Error
}
case syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
// spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
switch {
- case !allOrdered(x.typ_):
+ case !allOrdered(x.typ()):
errOp = x
goto Error
- case !allOrdered(y.typ_):
+ case !allOrdered(y.typ()):
errOp = y
goto Error
}
@@ -579,8 +579,8 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase b
// time will be materialized. Update the expression trees.
// If the current types are untyped, the materialized type
// is the respective default type.
- check.updateExprType(x.expr, Default(x.typ_), true)
- check.updateExprType(y.expr, Default(y.typ_), true)
+ check.updateExprType(x.expr, Default(x.typ()), true)
+ check.updateExprType(y.expr, Default(y.typ()), true)
}
// spec: "Comparison operators compare two operands and yield
@@ -591,17 +591,17 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase b
Error:
// We have an offending operand errOp and possibly an error cause.
if cause == "" {
- if isTypeParam(x.typ_) || isTypeParam(y.typ_) {
+ if isTypeParam(x.typ()) || isTypeParam(y.typ()) {
// TODO(gri) should report the specific type causing the problem, if any
- if !isTypeParam(x.typ_) {
+ if !isTypeParam(x.typ()) {
errOp = y
}
- cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ_, op)
+ cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ(), op)
} else {
// catch-all: neither x nor y is a type parameter
- what := compositeKind(errOp.typ_)
+ what := compositeKind(errOp.typ())
if what == "" {
- what = check.sprintf("%s", errOp.typ_)
+ what = check.sprintf("%s", errOp.typ())
}
cause = check.sprintf("operator %s not defined on %s", op, what)
}
@@ -634,7 +634,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
xval = constant.ToInt(x.val)
}
- if allInteger(x.typ_) || isUntyped(x.typ_) && xval != nil && xval.Kind() == constant.Int {
+ if allInteger(x.typ()) || isUntyped(x.typ()) && xval != nil && xval.Kind() == constant.Int {
// The lhs is of integer type or an untyped constant representable
// as an integer. Nothing to do.
} else {
@@ -659,7 +659,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
return
}
- if isUntyped(y.typ_) {
+ if isUntyped(y.typ()) {
// 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])
@@ -671,12 +671,12 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
} else {
// Check that RHS is otherwise at least of integer type.
switch {
- case allInteger(y.typ_):
- if !allUnsigned(y.typ_) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
+ case allInteger(y.typ()):
+ if !allUnsigned(y.typ()) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
x.mode_ = invalid
return
}
- case isUntyped(y.typ_):
+ case isUntyped(y.typ()):
// This is incorrect, but preserves pre-existing behavior.
// See also go.dev/issue/47410.
check.convertUntyped(y, Typ[Uint])
@@ -697,7 +697,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
x.val = constant.MakeUnknown()
// ensure the correct type - see comment below
- if !isInteger(x.typ_) {
+ if !isInteger(x.typ()) {
x.typ_ = Typ[UntypedInt]
}
return
@@ -714,7 +714,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
// (e.g., 2.0, an untyped float) - this can only happen for untyped
// non-integer numeric constants. Correct the type so that the shift
// result is of integer type.
- if !isInteger(x.typ_) {
+ if !isInteger(x.typ()) {
x.typ_ = Typ[UntypedInt]
}
// x is a constant so xval != nil and it must be of Int kind.
@@ -725,7 +725,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
}
// non-constant shift with constant lhs
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
// spec: "If the left operand of a non-constant shift
// expression is an untyped constant, the type of the
// constant is what it would be if the shift expression
@@ -756,7 +756,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_) {
+ if !allInteger(x.typ()) {
check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
x.mode_ = invalid
return
@@ -818,14 +818,14 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
return
}
- if !Identical(x.typ_, y.typ_) {
+ if !Identical(x.typ(), y.typ()) {
// only report an error if we have valid types
// (otherwise we had an error reported elsewhere already)
- if isValid(x.typ_) && isValid(y.typ_) {
+ if isValid(x.typ()) && isValid(y.typ()) {
if e != nil {
- check.errorf(x, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ_, y.typ_)
+ check.errorf(x, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ(), y.typ())
} else {
- check.errorf(x, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ_, y.typ_)
+ check.errorf(x, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ(), y.typ())
}
}
x.mode_ = invalid
@@ -839,14 +839,14 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
if op == syntax.Div || op == syntax.Rem {
// check for zero divisor
- if (x.mode_ == constant_ || allInteger(x.typ_)) && y.mode_ == constant_ && constant.Sign(y.val) == 0 {
+ 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
return
}
// check for divisor underflow in complex division (see go.dev/issue/20227)
- if x.mode_ == constant_ && y.mode_ == constant_ && isComplex(x.typ_) {
+ if x.mode_ == constant_ && y.mode_ == constant_ && isComplex(x.typ()) {
re, im := constant.Real(y.val), constant.Imag(y.val)
re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
@@ -866,7 +866,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
}
// force integer division for integer operands
tok := op2tok[op]
- if op == syntax.Div && isInteger(x.typ_) {
+ if op == syntax.Div && isInteger(x.typ()) {
tok = token.QUO_ASSIGN
}
x.val = constant.BinaryOp(x.val, tok, y.val)
@@ -893,49 +893,49 @@ func (check *Checker) matchTypes(x, y *operand) {
// not compatible, we report a type mismatch error.
mayConvert := func(x, y *operand) bool {
// If both operands are typed, there's no need for an implicit conversion.
- if isTyped(x.typ_) && isTyped(y.typ_) {
+ if isTyped(x.typ()) && isTyped(y.typ()) {
return false
}
// A numeric type can only convert to another numeric type.
- if allNumeric(x.typ_) != allNumeric(y.typ_) {
+ if allNumeric(x.typ()) != allNumeric(y.typ()) {
return false
}
// An untyped operand may convert to its default type when paired with an empty interface
// TODO(gri) This should only matter for comparisons (the only binary operation that is
// valid with interfaces), but in that case the assignability check should take
// care of the conversion. Verify and possibly eliminate this extra test.
- if isNonTypeParamInterface(x.typ_) || isNonTypeParamInterface(y.typ_) {
+ if isNonTypeParamInterface(x.typ()) || isNonTypeParamInterface(y.typ()) {
return true
}
// A boolean type can only convert to another boolean type.
- if allBoolean(x.typ_) != allBoolean(y.typ_) {
+ if allBoolean(x.typ()) != allBoolean(y.typ()) {
return false
}
// A string type can only convert to another string type.
- if allString(x.typ_) != allString(y.typ_) {
+ if allString(x.typ()) != allString(y.typ()) {
return false
}
// Untyped nil can only convert to a type that has a nil.
if x.isNil() {
- return hasNil(y.typ_)
+ return hasNil(y.typ())
}
if y.isNil() {
- return hasNil(x.typ_)
+ return hasNil(x.typ())
}
// An untyped operand cannot convert to a pointer.
// TODO(gri) generalize to type parameters
- if isPointer(x.typ_) || isPointer(y.typ_) {
+ if isPointer(x.typ()) || isPointer(y.typ()) {
return false
}
return true
}
if mayConvert(x, y) {
- check.convertUntyped(x, y.typ_)
+ check.convertUntyped(x, y.typ())
if x.mode_ == invalid {
return
}
- check.convertUntyped(y, x.typ_)
+ check.convertUntyped(y, x.typ())
if y.mode_ == invalid {
x.mode_ = invalid
return
@@ -1007,7 +1007,7 @@ func (check *Checker) nonGeneric(T *target, x *operand) {
return
}
var what string
- switch t := x.typ_.(type) {
+ switch t := x.typ().(type) {
case *Alias, *Named:
if isGeneric(t) {
what = "type"
@@ -1109,11 +1109,11 @@ func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Ty
check.error(e, InvalidSyntaxTree, "invalid use of AssertExpr")
goto Error
}
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
goto Error
}
- if _, ok := x.typ_.Underlying().(*Interface); !ok {
+ if _, ok := x.typ().Underlying().(*Interface); !ok {
check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
goto Error
}
@@ -1173,11 +1173,11 @@ func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Ty
case invalid:
goto Error
case typexpr:
- check.validVarType(e.X, x.typ_)
- x.typ_ = &Pointer{base: x.typ_}
+ check.validVarType(e.X, x.typ())
+ x.typ_ = &Pointer{base: x.typ()}
default:
var base Type
- if !underIs(x.typ_, func(u Type) bool {
+ if !underIs(x.typ(), func(u Type) bool {
p, _ := u.(*Pointer)
if p == nil {
check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
@@ -1293,7 +1293,7 @@ func keyVal(x constant.Value) any {
// typeAssertion checks x.(T). The type of x must be an interface.
func (check *Checker) typeAssertion(e syntax.Expr, x *operand, T Type, typeSwitch bool) {
var cause string
- if check.assertableTo(x.typ_, T, &cause) {
+ if check.assertableTo(x.typ(), T, &cause) {
return // success
}
@@ -1302,7 +1302,7 @@ func (check *Checker) typeAssertion(e syntax.Expr, x *operand, T Type, typeSwitc
return
}
- check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ_, cause)
+ check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ(), cause)
}
// expr typechecks expression e and initializes x with the expression value.
@@ -1333,7 +1333,7 @@ func (check *Checker) multiExpr(e syntax.Expr, allowCommaOk bool) (list []*opera
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.mode_ != invalid {
// multiple values
list = make([]*operand, t.Len())
for i, v := range t.vars {
@@ -1408,7 +1408,7 @@ func (check *Checker) exclude(x *operand, modeset uint) {
func (check *Checker) singleValue(x *operand) {
if x.mode_ == value {
// tuple types are never named - no need for underlying type below
- if t, ok := x.typ_.(*Tuple); ok {
+ 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
diff --git a/src/cmd/compile/internal/types2/index.go b/src/cmd/compile/internal/types2/index.go
index 2a98ef8815..12d89e9cae 100644
--- a/src/cmd/compile/internal/types2/index.go
+++ b/src/cmd/compile/internal/types2/index.go
@@ -29,13 +29,13 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
x.mode_ = invalid
// TODO(gri) here we re-evaluate e.X - try to avoid this
x.typ_ = check.varType(e)
- if isValid(x.typ_) {
+ if isValid(x.typ()) {
x.mode_ = typexpr
}
return false
case value:
- if sig, _ := x.typ_.Underlying().(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
+ if sig, _ := x.typ().Underlying().(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
// function instantiation
return true
}
@@ -48,11 +48,11 @@ 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_) {
+ if !check.isComplete(x.typ()) {
x.mode_ = invalid
return false
}
- switch typ := x.typ_.Underlying().(type) {
+ switch typ := x.typ().Underlying().(type) {
case *Pointer:
// Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
// its base type must also be complete.
@@ -72,7 +72,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
// ordinary index expression
valid := false
length := int64(-1) // valid if >= 0
- switch typ := x.typ_.Underlying().(type) {
+ switch typ := x.typ().Underlying().(type) {
case *Basic:
if isString(typ) {
valid = true
@@ -123,14 +123,14 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
return false
case *Interface:
- if !isTypeParam(x.typ_) {
+ if !isTypeParam(x.typ()) {
break
}
// TODO(gri) report detailed failure cause for better error messages
var key, elem Type // key != nil: we must have all maps
mode := variable // non-maps result mode
// TODO(gri) factor out closure and use it for non-typeparam cases as well
- if underIs(x.typ_, func(u Type) bool {
+ if underIs(x.typ(), func(u Type) bool {
l := int64(-1) // valid if >= 0
var k, e Type // k is only set for maps
switch t := u.(type) {
@@ -220,7 +220,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
// In pathological (invalid) cases (e.g.: type T1 [][[]T1{}[0][0]]T0)
// the element type may be accessed before it's set. Make sure we have
// a valid type.
- if x.typ_ == nil {
+ if x.typ() == nil {
x.typ_ = Typ[Invalid]
}
@@ -238,9 +238,9 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
// determine common underlying type cu
var ct, cu Type // type and respective common underlying type
var hasString bool
- for t, u := range typeset(x.typ_) {
+ for t, u := range typeset(x.typ()) {
if u == nil {
- check.errorf(x, NonSliceableOperand, "cannot slice %s: no specific type in %s", x, x.typ_)
+ check.errorf(x, NonSliceableOperand, "cannot slice %s: no specific type in %s", x, x.typ())
cu = nil
break
}
@@ -268,15 +268,15 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
// If we saw a string, proceed with string type,
// but don't go from untyped string to string.
cu = Typ[String]
- if !isTypeParam(x.typ_) {
- cu = x.typ_.Underlying() // untyped string remains untyped
+ if !isTypeParam(x.typ()) {
+ cu = x.typ().Underlying() // untyped string remains untyped
}
}
// Note that we don't permit slice expressions where x is a type expression, so we don't check for that here.
// 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) {
+ if p, ok := x.typ().Underlying().(*Pointer); ok && !check.isComplete(p.base) {
x.mode_ = invalid
return
}
@@ -306,7 +306,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
}
// spec: "For untyped string operands the result
// is a non-constant value of type string."
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
x.typ_ = Typ[String]
}
}
@@ -428,7 +428,7 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64)
}
if x.mode_ != constant_ {
- return x.typ_, -1
+ return x.typ(), -1
}
if x.val.Kind() == constant.Unknown {
@@ -443,7 +443,7 @@ func (check *Checker) index(index syntax.Expr, max int64) (typ Type, val int64)
}
// 0 <= v [ && v < max ]
- return x.typ_, v
+ return x.typ(), v
}
// isValidIndex checks whether operand x satisfies the criteria for integer
@@ -462,7 +462,7 @@ func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNega
}
// spec: "the index x must be of integer type or an untyped constant"
- if !allInteger(x.typ_) {
+ if !allInteger(x.typ()) {
check.errorf(x, code, invalidArg+"%s %s must be integer", what, x)
return false
}
diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go
index 7a0acd2e31..0cd6aaf999 100644
--- a/src/cmd/compile/internal/types2/infer.go
+++ b/src/cmd/compile/internal/types2/infer.go
@@ -170,12 +170,12 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
continue
}
par := params.At(i)
- if isParameterized(tparams, par.typ) || isParameterized(tparams, arg.typ_) {
+ if isParameterized(tparams, par.typ) || isParameterized(tparams, arg.typ()) {
// Function parameters are always typed. Arguments may be untyped.
// Collect the indices of untyped arguments and handle them later.
- if isTyped(arg.typ_) {
- if !u.unify(par.typ, arg.typ_, assign) {
- errorf(par.typ, arg.typ_, arg)
+ if isTyped(arg.typ()) {
+ if !u.unify(par.typ, arg.typ(), assign) {
+ errorf(par.typ, arg.typ(), arg)
return nil
}
} else if _, ok := par.typ.(*TypeParam); ok && !arg.isNil() {
@@ -337,11 +337,11 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
}
max := maxUntyped[tpar]
if max == nil {
- max = arg.typ_
+ max = arg.typ()
} else {
- m := maxType(max, arg.typ_)
+ m := maxType(max, arg.typ())
if m == nil {
- err.addf(arg, "mismatched types %s and %s (cannot infer %s)", max, arg.typ_, tpar)
+ err.addf(arg, "mismatched types %s and %s (cannot infer %s)", max, arg.typ(), tpar)
return nil
}
max = m
diff --git a/src/cmd/compile/internal/types2/literals.go b/src/cmd/compile/internal/types2/literals.go
index 8da6345bc1..5459d7f5c1 100644
--- a/src/cmd/compile/internal/types2/literals.go
+++ b/src/cmd/compile/internal/types2/literals.go
@@ -269,12 +269,12 @@ func (check *Checker) compositeLit(x *operand, e *syntax.CompositeLit, hint Type
xkey := keyVal(x.val)
if keyIsInterface {
for _, vtyp := range visited[xkey] {
- if Identical(vtyp, x.typ_) {
+ if Identical(vtyp, x.typ()) {
duplicate = true
break
}
}
- visited[xkey] = append(visited[xkey], x.typ_)
+ visited[xkey] = append(visited[xkey], x.typ())
} else {
_, duplicate = visited[xkey]
visited[xkey] = nil
diff --git a/src/cmd/compile/internal/types2/operand.go b/src/cmd/compile/internal/types2/operand.go
index be10c0a609..1d29810a72 100644
--- a/src/cmd/compile/internal/types2/operand.go
+++ b/src/cmd/compile/internal/types2/operand.go
@@ -60,6 +60,14 @@ type operand struct {
id builtinId
}
+func (x *operand) typ() Type {
+ return x.typ_
+}
+
+func (x *operand) isValid() bool {
+ return 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 {
@@ -110,17 +118,17 @@ func operandString(x *operand, qf Qualifier) string {
// special-case nil
if isTypes2 {
if x.mode_ == nilvalue {
- switch x.typ_ {
+ switch x.typ() {
case nil, Typ[Invalid]:
return "nil (with invalid type)"
case Typ[UntypedNil]:
return "nil"
default:
- return fmt.Sprintf("nil (of type %s)", TypeString(x.typ_, qf))
+ return fmt.Sprintf("nil (of type %s)", TypeString(x.typ(), qf))
}
}
} else { // go/types
- if x.mode_ == value && x.typ_ == Typ[UntypedNil] {
+ if x.mode_ == value && x.typ() == Typ[UntypedNil] {
return "nil"
}
}
@@ -135,7 +143,7 @@ func operandString(x *operand, qf Qualifier) string {
case builtin:
expr = predeclaredFuncs[x.id].name
case typexpr:
- expr = TypeString(x.typ_, qf)
+ expr = TypeString(x.typ(), qf)
case constant_:
expr = x.val.String()
}
@@ -154,9 +162,9 @@ func operandString(x *operand, qf Qualifier) string {
// no type
default:
// should have a type, but be cautious (don't crash during printing)
- if x.typ_ != nil {
- if isUntyped(x.typ_) {
- buf.WriteString(x.typ_.(*Basic).name)
+ if x.typ() != nil {
+ if isUntyped(x.typ()) {
+ buf.WriteString(x.typ().(*Basic).name)
buf.WriteByte(' ')
break
}
@@ -177,9 +185,9 @@ func operandString(x *operand, qf Qualifier) string {
// <typ>
if hasType {
- if isValid(x.typ_) {
+ if isValid(x.typ()) {
var desc string
- if isGeneric(x.typ_) {
+ if isGeneric(x.typ()) {
desc = "generic "
}
@@ -187,14 +195,14 @@ func operandString(x *operand, qf Qualifier) string {
// If the type is a renamed basic type, describe the basic type,
// as in "int32 type MyInt" for a *Named type MyInt.
// If it is a type parameter, describe the constraint instead.
- tpar, _ := Unalias(x.typ_).(*TypeParam)
+ tpar, _ := Unalias(x.typ()).(*TypeParam)
if tpar == nil {
- switch x.typ_.(type) {
+ switch x.typ().(type) {
case *Alias, *Named:
- what := compositeKind(x.typ_)
+ what := compositeKind(x.typ())
if what == "" {
// x.typ must be basic type
- what = x.typ_.Underlying().(*Basic).name
+ what = x.typ().Underlying().(*Basic).name
}
desc += what + " "
}
@@ -202,7 +210,7 @@ func operandString(x *operand, qf Qualifier) string {
// desc is "" or has a trailing space at the end
buf.WriteString(" of " + desc + "type ")
- WriteType(&buf, x.typ_, qf)
+ WriteType(&buf, x.typ(), qf)
if tpar != nil {
buf.WriteString(" constrained by ")
@@ -295,7 +303,7 @@ func (x *operand) isNil() bool {
if isTypes2 {
return x.mode_ == nilvalue
} else { // go/types
- return x.mode_ == value && x.typ_ == Typ[UntypedNil]
+ return x.mode_ == value && x.typ() == Typ[UntypedNil]
}
}
@@ -311,7 +319,7 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
}
origT := T
- V := Unalias(x.typ_)
+ V := Unalias(x.typ())
T = Unalias(T)
// x's type is identical to T
@@ -416,7 +424,7 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
}
ok, code = x.assignableTo(check, T.typ, cause)
if !ok {
- errorf("cannot assign %s to %s (in %s)", x.typ_, T.typ, Tp)
+ errorf("cannot assign %s to %s (in %s)", x.typ(), T.typ, Tp)
return false
}
return true
diff --git a/src/cmd/compile/internal/types2/range.go b/src/cmd/compile/internal/types2/range.go
index 189aca64ce..c6f7be3319 100644
--- a/src/cmd/compile/internal/types2/range.go
+++ b/src/cmd/compile/internal/types2/range.go
@@ -35,7 +35,7 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *syntax.ForStmt, no
check.expr(nil, &x, rangeVar)
if isTypes2 && x.mode_ != invalid && sValue == nil && !check.hasCallOrRecv {
- if t, ok := arrayPtrDeref(x.typ_.Underlying()).(*Array); ok {
+ if t, ok := arrayPtrDeref(x.typ().Underlying()).(*Array); ok {
for {
// Put constant info on the thing inside parentheses.
// That's where (*../noder/writer).expr expects it.
@@ -62,7 +62,7 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *syntax.ForStmt, no
// determine key/value types
var key, val Type
if x.mode_ != invalid {
- k, v, cause, ok := rangeKeyVal(check, x.typ_, func(v goVersion) bool {
+ k, v, cause, ok := rangeKeyVal(check, x.typ(), func(v goVersion) bool {
return check.allowVersion(v)
})
switch {
@@ -92,7 +92,7 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *syntax.ForStmt, no
lhs := [2]syntax.Expr{sKey, sValue} // sKey, sValue may be nil
rhs := [2]Type{key, val} // key, val may be nil
- rangeOverInt := isInteger(x.typ_)
+ rangeOverInt := isInteger(x.typ())
if isDef {
// short variable declaration
@@ -169,8 +169,8 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *syntax.ForStmt, no
// 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_) {
- check.softErrorf(lhs, InvalidRangeExpr, "cannot use iteration variable of type %s", x.typ_)
+ if x.mode_ != invalid && !isInteger(x.typ()) {
+ check.softErrorf(lhs, InvalidRangeExpr, "cannot use iteration variable of type %s", x.typ())
}
} else {
var y operand
diff --git a/src/cmd/compile/internal/types2/recording.go b/src/cmd/compile/internal/types2/recording.go
index 76e6752e57..c6eaed9077 100644
--- a/src/cmd/compile/internal/types2/recording.go
+++ b/src/cmd/compile/internal/types2/recording.go
@@ -23,10 +23,10 @@ func (check *Checker) record(x *operand) {
case novalue:
typ = (*Tuple)(nil)
case constant_:
- typ = x.typ_
+ typ = x.typ()
val = x.val
default:
- typ = x.typ_
+ typ = x.typ()
}
assert(x.expr != nil && typ != nil)
@@ -97,7 +97,7 @@ func (check *Checker) recordCommaOkTypes(x syntax.Expr, a []*operand) {
if a[0].mode_ == invalid {
return
}
- t0, t1 := a[0].typ_, a[1].typ_
+ t0, t1 := a[0].typ(), a[1].typ()
assert(isTyped(t0) && isTyped(t1) && (allBoolean(t1) || t1 == universeError))
if m := check.Types; m != nil {
for {
diff --git a/src/cmd/compile/internal/types2/stmt.go b/src/cmd/compile/internal/types2/stmt.go
index 05941f29c5..1c18a6278b 100644
--- a/src/cmd/compile/internal/types2/stmt.go
+++ b/src/cmd/compile/internal/types2/stmt.go
@@ -241,7 +241,7 @@ L:
if x.mode_ == invalid || v.mode_ == invalid {
continue L
}
- check.convertUntyped(&v, x.typ_)
+ check.convertUntyped(&v, x.typ())
if v.mode_ == invalid {
continue L
}
@@ -259,7 +259,7 @@ L:
// look for duplicate types for a given value
// (quadratic algorithm, but these lists tend to be very short)
for _, vt := range seen[val] {
- if Identical(v.typ_, vt.typ) {
+ if Identical(v.typ(), vt.typ) {
err := check.newError(DuplicateCase)
err.addf(&v, "duplicate case %s in expression switch", &v)
err.addf(vt.pos, "previous case")
@@ -267,7 +267,7 @@ L:
continue L
}
}
- seen[val] = append(seen[val], valueType{v.Pos(), v.typ_})
+ seen[val] = append(seen[val], valueType{v.Pos(), v.typ()})
}
}
}
@@ -345,7 +345,7 @@ L:
if len(types) != 1 || T == nil {
T = Typ[Invalid]
if x != nil {
- T = x.typ_
+ T = x.typ()
}
}
@@ -398,7 +398,7 @@ L:
if len(types) != 1 || T == nil {
T = Typ[Invalid]
if x != nil {
- T = x.typ_
+ T = x.typ()
}
}
@@ -480,8 +480,8 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
if x.mode_ == invalid {
return
}
- if !allNumeric(x.typ_) {
- check.errorf(s.Lhs, NonNumericIncDec, invalidOp+"%s%s%s (non-numeric type %s)", s.Lhs, s.Op, s.Op, x.typ_)
+ if !allNumeric(x.typ()) {
+ check.errorf(s.Lhs, NonNumericIncDec, invalidOp+"%s%s%s (non-numeric type %s)", s.Lhs, s.Op, s.Op, x.typ())
return
}
check.assignVar(s.Lhs, nil, &x, "assignment")
@@ -592,7 +592,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
check.simpleStmt(s.Init)
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode_ != invalid && !allBoolean(x.typ_) {
+ if x.mode_ != invalid && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
}
check.stmt(inner, s.Then)
@@ -694,7 +694,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
if s.Cond != nil {
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode_ != invalid && !allBoolean(x.typ_) {
+ if x.mode_ != invalid && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
}
}
@@ -721,8 +721,8 @@ func (check *Checker) switchStmt(inner stmtContext, s *syntax.SwitchStmt) {
// 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_) {
- check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ_)
+ 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
}
} else {
@@ -786,9 +786,9 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
var x operand
check.expr(nil, &x, guard.X)
if x.mode_ != invalid {
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
- } else if IsInterface(x.typ_) {
+ } else if IsInterface(x.typ()) {
sx = &x
} else {
check.errorf(&x, InvalidTypeSwitch, "%s is not an interface", &x)
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index a7ea0f611d..69d1d76174 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -250,7 +250,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *TypeName) (T Type) {
switch x.mode_ {
case typexpr:
- return x.typ_
+ return x.typ()
case invalid:
// ignore - error reported before
case novalue:
@@ -265,7 +265,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *TypeName) (T Type) {
switch x.mode_ {
case typexpr:
- return x.typ_
+ return x.typ()
case invalid:
// ignore - error reported before
case novalue:
@@ -489,7 +489,7 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
return -1
}
- if isUntyped(x.typ_) || isInteger(x.typ_) {
+ if isUntyped(x.typ()) || isInteger(x.typ()) {
if val := constant.ToInt(x.val); val.Kind() == constant.Int {
if representableConst(val, check, Typ[Int], nil) {
if n, ok := constant.Int64Val(val); ok && n >= 0 {
@@ -500,7 +500,7 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
}
var msg string
- if isInteger(x.typ_) {
+ if isInteger(x.typ()) {
msg = "invalid array length %s"
} else {
msg = "array length %s must be integer"
diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go
index 2955ac2b73..2b9c2d5065 100644
--- a/src/go/types/assignments.go
+++ b/src/go/types/assignments.go
@@ -40,7 +40,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
return
}
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
target := T
// spec: "If an untyped constant is assigned to a variable of interface
// type or the blank identifier, the constant is first converted to type
@@ -55,16 +55,16 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
return
}
} else if T == nil || isNonTypeParamInterface(T) {
- target = Default(x.typ_)
+ target = Default(x.typ())
}
} else { // go/types
if T == nil || isNonTypeParamInterface(T) {
- if T == nil && x.typ_ == Typ[UntypedNil] {
+ if T == nil && x.typ() == Typ[UntypedNil] {
check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
x.mode_ = invalid
return
}
- target = Default(x.typ_)
+ target = Default(x.typ())
}
}
newType, val, code := check.implicitTypeAndValue(x, target)
@@ -86,7 +86,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
x.val = val
check.updateExprVal(x.expr, val)
}
- if newType != x.typ_ {
+ if newType != x.typ() {
x.typ_ = newType
check.updateExprType(x.expr, newType, false)
}
@@ -119,7 +119,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
}
func (check *Checker) initConst(lhs *Const, x *operand) {
- if x.mode_ == invalid || !isValid(x.typ_) || !isValid(lhs.typ) {
+ if x.mode_ == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
@@ -134,11 +134,11 @@ func (check *Checker) initConst(lhs *Const, x *operand) {
}
return
}
- assert(isConstType(x.typ_))
+ assert(isConstType(x.typ()))
// If the lhs doesn't have a type yet, use the type of x.
if lhs.typ == nil {
- lhs.typ = x.typ_
+ lhs.typ = x.typ()
}
check.assignment(x, lhs.typ, "constant declaration")
@@ -154,7 +154,7 @@ func (check *Checker) initConst(lhs *Const, x *operand) {
// 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.mode_ == invalid || !isValid(x.typ()) || !isValid(lhs.typ) {
if lhs.typ == nil {
lhs.typ = Typ[Invalid]
}
@@ -164,7 +164,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) {
// If lhs doesn't have a type yet, use the type of x.
if lhs.typ == nil {
- typ := x.typ_
+ typ := x.typ()
if isUntyped(typ) {
// convert untyped types to default types
if typ == Typ[UntypedNil] {
@@ -219,7 +219,7 @@ func (check *Checker) lhsVar(lhs ast.Expr) Type {
check.usedVars[v] = v_used // restore v.used
}
- if x.mode_ == invalid || !isValid(x.typ_) {
+ if x.mode_ == invalid || !isValid(x.typ()) {
return Typ[Invalid]
}
@@ -243,7 +243,7 @@ func (check *Checker) lhsVar(lhs ast.Expr) Type {
return Typ[Invalid]
}
- return x.typ_
+ return x.typ()
}
// assignVar checks the assignment lhs = rhs (if x == nil), or lhs = x (if x != nil).
@@ -281,7 +281,7 @@ func (check *Checker) assignVar(lhs, rhs ast.Expr, x *operand, context string) {
// operandTypes returns the list of types for the given operands.
func operandTypes(list []*operand) (res []Type) {
for _, x := range list {
- res = append(res, x.typ_)
+ res = append(res, x.typ())
}
return res
}
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index 1d4f4a7b43..146e8d6574 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -112,7 +112,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
y := args[1]
hasString := false
- for _, u := range typeset(y.typ_) {
+ for _, u := range typeset(y.typ()) {
if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
// typeset ⊇ {[]byte}
} else if isString(u) {
@@ -125,7 +125,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
if y != nil && hasString {
// setting the signature also signals that we're done
- sig = makeSig(x.typ_, x.typ_, y.typ_)
+ sig = makeSig(x.typ(), x.typ(), y.typ())
sig.variadic = true
}
}
@@ -134,7 +134,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// general case
if sig == nil {
// check arguments by creating custom signature
- sig = makeSig(x.typ_, x.typ_, NewSlice(E)) // []E required for variadic signature
+ sig = makeSig(x.typ(), x.typ(), NewSlice(E)) // []E required for variadic signature
sig.variadic = true
check.arguments(call, sig, nil, nil, args, nil) // discard result (we know the result type)
// ok to continue even if check.arguments reported errors
@@ -151,7 +151,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// len(x)
mode := invalid
var val constant.Value
- switch t := arrayPtrDeref(x.typ_.Underlying()).(type) {
+ switch t := arrayPtrDeref(x.typ().Underlying()).(type) {
case *Basic:
if isString(t) && id == _Len {
if x.mode_ == constant_ {
@@ -186,10 +186,10 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
case *Interface:
- if !isTypeParam(x.typ_) {
+ if !isTypeParam(x.typ()) {
break
}
- if underIs(x.typ_, func(u Type) bool {
+ if underIs(x.typ(), func(u Type) bool {
switch t := arrayPtrDeref(u).(type) {
case *Basic:
if isString(t) && id == _Len {
@@ -210,7 +210,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
if mode == invalid {
// avoid error if underlying type is invalid
- if isValid(x.typ_.Underlying()) {
+ if isValid(x.typ().Underlying()) {
code := InvalidCap
if id == _Len {
code = InvalidLen
@@ -222,7 +222,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// record the signature before changing x.typ
if check.recordTypes() && mode != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ()))
}
x.mode_ = mode
@@ -233,7 +233,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// clear(m)
check.verifyVersionf(call.Fun, go1_21, "clear")
- if !underIs(x.typ_, func(u Type) bool {
+ if !underIs(x.typ(), func(u Type) bool {
switch u.(type) {
case *Map, *Slice:
return true
@@ -246,12 +246,12 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = novalue
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(nil, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(nil, x.typ()))
}
case _Close:
// close(c)
- if !underIs(x.typ_, func(u Type) bool {
+ if !underIs(x.typ(), func(u Type) bool {
uch, _ := u.(*Chan)
if uch == nil {
check.errorf(x, InvalidClose, invalidOp+"cannot close non-channel %s", x)
@@ -267,7 +267,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
x.mode_ = novalue
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(nil, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(nil, x.typ()))
}
case _Complex:
@@ -276,10 +276,10 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// convert or check untyped arguments
d := 0
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
d |= 1
}
- if isUntyped(y.typ_) {
+ if isUntyped(y.typ()) {
d |= 2
}
switch d {
@@ -287,10 +287,10 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// x and y are typed => nothing to do
case 1:
// only x is untyped => convert to type of y
- check.convertUntyped(x, y.typ_)
+ check.convertUntyped(x, y.typ())
case 2:
// only y is untyped => convert to type of x
- check.convertUntyped(y, x.typ_)
+ check.convertUntyped(y, x.typ())
case 3:
// x and y are untyped =>
// 1) if both are constants, convert them to untyped
@@ -302,7 +302,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// because shifts of floats are not permitted)
if x.mode_ == constant_ && y.mode_ == constant_ {
toFloat := func(x *operand) {
- if isNumeric(x.typ_) && constant.Sign(constant.Imag(x.val)) == 0 {
+ if isNumeric(x.typ()) && constant.Sign(constant.Imag(x.val)) == 0 {
x.typ_ = Typ[UntypedFloat]
}
}
@@ -320,8 +320,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
// both argument types must be identical
- if !Identical(x.typ_, y.typ_) {
- check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ_, y.typ_)
+ if !Identical(x.typ(), y.typ()) {
+ check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ(), y.typ())
return
}
@@ -343,7 +343,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
resTyp := check.applyTypeFunc(f, x, id)
if resTyp == nil {
- check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ_)
+ check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ())
return
}
@@ -355,7 +355,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
if check.recordTypes() && x.mode_ != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ_, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ(), x.typ()))
}
x.typ_ = resTyp
@@ -375,7 +375,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
var special bool
if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
special = true
- for _, u := range typeset(y.typ_) {
+ for _, u := range typeset(y.typ()) {
if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
// typeset ⊇ {[]byte}
} else if isString(u) {
@@ -399,7 +399,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
srcE, err := sliceElem(y)
if err != nil {
// If we have a string, for a better error message proceed with byte element type.
- if !allString(y.typ_) {
+ if !allString(y.typ()) {
check.errorf(y, InvalidCopy, "invalid copy: %s", err.format(check))
return
}
@@ -412,7 +412,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ_, y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ(), y.typ()))
}
x.mode_ = value
x.typ_ = Typ[Int]
@@ -421,7 +421,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// delete(map_, key)
// map_ must be a map type or a type parameter describing map types.
// The key cannot be a type parameter for now.
- map_ := x.typ_
+ map_ := x.typ()
var key Type
if !underIs(map_, func(u Type) bool {
map_, _ := u.(*Map)
@@ -455,11 +455,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// real(complexT) floatT
// convert or check untyped argument
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
if x.mode_ == constant_ {
// an untyped constant number can always be considered
// as a complex constant
- if isNumeric(x.typ_) {
+ if isNumeric(x.typ()) {
x.typ_ = Typ[UntypedComplex]
}
} else {
@@ -497,7 +497,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
if id == _Real {
code = InvalidReal
}
- check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ_)
+ check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ())
return
}
@@ -513,7 +513,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
if check.recordTypes() && x.mode_ != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ()))
}
x.typ_ = resTyp
@@ -574,7 +574,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = value
x.typ_ = T
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, types...))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), types...))
}
case _Max, _Min:
@@ -592,7 +592,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
return
}
- if !allOrdered(a.typ_) {
+ if !allOrdered(a.typ()) {
check.errorf(a, InvalidMinMaxOperand, invalidArg+"%s cannot be ordered", a)
return
}
@@ -604,8 +604,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
return
}
- if !Identical(x.typ_, a.typ_) {
- check.errorf(a, MismatchedTypes, invalidArg+"mismatched types %s (previous argument) and %s (type of %s)", x.typ_, a.typ_, a.expr)
+ if !Identical(x.typ(), a.typ()) {
+ check.errorf(a, MismatchedTypes, invalidArg+"mismatched types %s (previous argument) and %s (type of %s)", x.typ(), a.typ(), a.expr)
return
}
@@ -631,15 +631,15 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// Use the final type computed above for all arguments.
for _, a := range args {
- check.updateExprType(a.expr, x.typ_, true)
+ check.updateExprType(a.expr, x.typ(), true)
}
if check.recordTypes() && x.mode_ != constant_ {
types := make([]Type, nargs)
for i := range types {
- types[i] = x.typ_
+ types[i] = x.typ()
}
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, types...))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), types...))
}
case _New:
@@ -653,26 +653,26 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
return
case typexpr:
// new(T)
- check.validVarType(arg, x.typ_)
+ check.validVarType(arg, x.typ())
default:
// new(expr)
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
// check for overflow and untyped nil
check.assignment(x, nil, "argument to new")
if x.mode_ == invalid {
return
}
- assert(isTyped(x.typ_))
+ assert(isTyped(x.typ()))
}
// report version error only if there are no other errors
check.verifyVersionf(call.Fun, go1_26, "new(%s)", arg)
}
- T := x.typ_
+ T := x.typ()
x.mode_ = value
x.typ_ = NewPointer(T)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, T))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), T))
}
case _Panic:
@@ -711,7 +711,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
if a.mode_ == invalid {
return
}
- params[i] = a.typ_
+ params[i] = a.typ()
}
}
@@ -725,7 +725,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = value
x.typ_ = &emptyInterface
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ()))
}
case _Add:
@@ -745,7 +745,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = value
x.typ_ = Typ[UnsafePointer]
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, x.typ_, y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), x.typ(), y.typ()))
}
case _Alignof:
@@ -755,14 +755,14 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
return
}
- if check.hasVarSize(x.typ_) {
+ if check.hasVarSize(x.typ()) {
x.mode_ = value
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ()))
}
} else {
x.mode_ = constant_
- x.val = constant.MakeInt64(check.conf.alignof(x.typ_))
+ x.val = constant.MakeInt64(check.conf.alignof(x.typ()))
// result is constant - no need to record signature
}
x.typ_ = Typ[Uintptr]
@@ -783,7 +783,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
return
}
- base := derefStructPtr(x.typ_)
+ base := derefStructPtr(x.typ())
sel := selx.Sel.Name
obj, index, indirect := lookupFieldOrMethod(base, false, check.pkg, sel, false)
switch obj.(type) {
@@ -843,13 +843,13 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
return
}
- if check.hasVarSize(x.typ_) {
+ if check.hasVarSize(x.typ()) {
x.mode_ = value
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ()))
}
} else {
- size := check.conf.sizeof(x.typ_)
+ size := check.conf.sizeof(x.typ())
if size < 0 {
check.errorf(x, TypeTooLarge, "%s is too large", x)
return
@@ -864,7 +864,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// unsafe.Slice(ptr *T, len IntegerType) []T
check.verifyVersionf(call.Fun, go1_17, "unsafe.Slice")
- u, _ := commonUnder(x.typ_, nil)
+ u, _ := commonUnder(x.typ(), nil)
ptr, _ := u.(*Pointer)
if ptr == nil {
check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
@@ -879,14 +879,14 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = value
x.typ_ = NewSlice(ptr.base)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, ptr, y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), ptr, y.typ()))
}
case _SliceData:
// unsafe.SliceData(slice []T) *T
check.verifyVersionf(call.Fun, go1_20, "unsafe.SliceData")
- u, _ := commonUnder(x.typ_, nil)
+ u, _ := commonUnder(x.typ(), nil)
slice, _ := u.(*Slice)
if slice == nil {
check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
@@ -896,7 +896,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = value
x.typ_ = NewPointer(slice.elem)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, slice))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), slice))
}
case _String:
@@ -916,7 +916,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = value
x.typ_ = Typ[String]
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, NewPointer(universeByte), y.typ_))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), NewPointer(universeByte), y.typ()))
}
case _StringData:
@@ -931,14 +931,14 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
x.mode_ = value
x.typ_ = NewPointer(universeByte)
if check.recordTypes() {
- check.recordBuiltinType(call.Fun, makeSig(x.typ_, Typ[String]))
+ check.recordBuiltinType(call.Fun, makeSig(x.typ(), Typ[String]))
}
case _Assert:
// 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.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
return
}
@@ -987,7 +987,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
// or a type error if x is not a slice (or a type set of slices).
func sliceElem(x *operand) (Type, *typeError) {
var E Type
- for _, u := range typeset(x.typ_) {
+ for _, u := range typeset(x.typ()) {
s, _ := u.(*Slice)
if s == nil {
if x.isNil() {
@@ -1073,7 +1073,7 @@ func (check *Checker) hasVarSize(t Type) bool {
// applyTypeFunc returns nil.
// If x is not a type parameter, the result is f(x).
func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
- if tp, _ := Unalias(x.typ_).(*TypeParam); tp != nil {
+ if tp, _ := Unalias(x.typ()).(*TypeParam); tp != nil {
// Test if t satisfies the requirements for the argument
// type and collect possible result types at the same time.
var terms []*Term
@@ -1117,7 +1117,7 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId)
return ptyp
}
- return f(x.typ_)
+ return f(x.typ())
}
// makeSig makes a signature for the given argument and result types.
diff --git a/src/go/types/call.go b/src/go/types/call.go
index 3d85e164c8..c19aebb1f0 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -59,7 +59,7 @@ func (check *Checker) funcInst(T *target, pos token.Pos, x *operand, ix *indexed
// Check the number of type arguments (got) vs number of type parameters (want).
// Note that x is a function value, not a type expression, so we don't need to
// call Underlying below.
- sig := x.typ_.(*Signature)
+ sig := x.typ().(*Signature)
got, want := len(targs), sig.TypeParams().Len()
if got > want {
// Providing too many type arguments is always an error.
@@ -199,7 +199,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
if x.mode_ == invalid {
return conversion
}
- T := x.typ_
+ T := x.typ()
x.mode_ = invalid
// We cannot convert a value to an incomplete type; make sure it's complete.
if !check.isComplete(T) {
@@ -251,7 +251,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
// If the operand type is a type parameter, all types in its type set
// must have a common underlying type, which must be a signature.
- u, err := commonUnder(x.typ_, func(t, u Type) *typeError {
+ u, err := commonUnder(x.typ(), func(t, u Type) *typeError {
if _, ok := u.(*Signature); u != nil && !ok {
return typeErrorf("%s is not a function", t)
}
@@ -343,7 +343,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_) {
+ if x.mode_ == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ()) {
x.mode_ = invalid
}
@@ -382,7 +382,7 @@ func (check *Checker) genericExprList(elist []ast.Expr) (resList []*operand, tar
if i < len(targsList) {
if n := len(targsList[i]); n > 0 {
// x must be a partially instantiated function
- assert(n < x.typ_.(*Signature).TypeParams().Len())
+ assert(n < x.typ().(*Signature).TypeParams().Len())
}
}
}
@@ -419,7 +419,7 @@ func (check *Checker) genericExprList(elist []ast.Expr) (resList []*operand, tar
// 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.mode_ != invalid {
// x is a function call returning multiple values; it cannot be generic.
resList = make([]*operand, t.Len())
for i, v := range t.vars {
@@ -582,7 +582,7 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
if enableReverseTypeInference {
for i, arg := range args {
// generic arguments cannot have a defined (*Named) type - no need for underlying type below
- if asig, _ := arg.typ_.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
+ if asig, _ := arg.typ().(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
// The argument type is a generic function signature. This type is
// pointer-identical with (it's copied from) the type of the generic
// function argument and thus the function object.
@@ -652,7 +652,7 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
j := n
for _, i := range genericArgs {
arg := args[i]
- asig := arg.typ_.(*Signature)
+ asig := arg.typ().(*Signature)
k := j + asig.TypeParams().Len()
// targs[j:k] are the inferred type arguments for asig
arg.typ_ = check.instantiateSignature(call.Pos(), arg.expr, asig, targs[j:k], nil) // TODO(gri) provide xlist if possible (partial instantiations)
@@ -767,14 +767,14 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
x.mode_ = variable
x.typ_ = exp.typ
if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
- x.typ_ = x.typ_.(*Pointer).base
+ x.typ_ = x.typ().(*Pointer).base
}
case *Func:
x.mode_ = funcMode
x.typ_ = exp.typ
if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
x.mode_ = value
- x.typ_ = x.typ_.(*Signature).results.vars[0].typ
+ x.typ_ = x.typ().(*Signature).results.vars[0].typ
}
case *Builtin:
x.mode_ = builtin
@@ -800,7 +800,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
}
// We cannot select on an incomplete type; make sure it's complete.
- if !check.isComplete(x.typ_) {
+ if !check.isComplete(x.typ()) {
goto Error
}
@@ -821,14 +821,14 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
// Additionally, if x.typ is a pointer type, selecting implicitly dereferences the value, meaning
// its base type must also be complete.
- if p, ok := x.typ_.Underlying().(*Pointer); ok && !check.isComplete(p.base) {
+ if p, ok := x.typ().Underlying().(*Pointer); ok && !check.isComplete(p.base) {
goto Error
}
- obj, index, indirect = lookupFieldOrMethod(x.typ_, x.mode_ == variable, check.pkg, sel, false)
+ obj, index, indirect = lookupFieldOrMethod(x.typ(), x.mode_ == variable, check.pkg, sel, false)
if obj == nil {
// Don't report another error if the underlying type was invalid (go.dev/issue/49541).
- if !isValid(x.typ_.Underlying()) {
+ if !isValid(x.typ().Underlying()) {
goto Error
}
@@ -840,19 +840,19 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
if indirect {
if x.mode_ == typexpr {
- check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ_, sel, x.typ_, sel)
+ check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ(), sel, x.typ(), sel)
} else {
- check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ_)
+ check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ())
}
goto Error
}
var why string
- if isInterfacePtr(x.typ_) {
- why = check.interfacePtrError(x.typ_)
+ if isInterfacePtr(x.typ()) {
+ why = check.interfacePtrError(x.typ())
} else {
- alt, _, _ := lookupFieldOrMethod(x.typ_, x.mode_ == variable, check.pkg, sel, true)
- why = check.lookupError(x.typ_, sel, alt, false)
+ alt, _, _ := lookupFieldOrMethod(x.typ(), x.mode_ == variable, check.pkg, sel, true)
+ why = check.lookupError(x.typ(), sel, alt, false)
}
check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
goto Error
@@ -862,12 +862,12 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
switch obj := obj.(type) {
case *Var:
if x.mode_ == typexpr {
- check.errorf(e.X, MissingFieldOrMethod, "operand for field selector %s must be value of type %s", sel, x.typ_)
+ check.errorf(e.X, MissingFieldOrMethod, "operand for field selector %s must be value of type %s", sel, x.typ())
goto Error
}
// field value
- check.recordSelection(e, FieldVal, x.typ_, obj, index, indirect)
+ check.recordSelection(e, FieldVal, x.typ(), obj, index, indirect)
if x.mode_ == variable || indirect {
x.mode_ = variable
} else {
@@ -881,7 +881,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
if x.mode_ == typexpr {
// method expression
- check.recordSelection(e, MethodExpr, x.typ_, obj, index, indirect)
+ check.recordSelection(e, MethodExpr, x.typ(), obj, index, indirect)
sig := obj.typ.(*Signature)
if sig.recv == nil {
@@ -909,7 +909,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
name = "_"
}
}
- params = append([]*Var{NewParam(sig.recv.pos, sig.recv.pkg, name, x.typ_)}, params...)
+ params = append([]*Var{NewParam(sig.recv.pos, sig.recv.pkg, name, x.typ())}, params...)
x.mode_ = value
x.typ_ = &Signature{
tparams: sig.tparams,
@@ -922,7 +922,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
// TODO(gri) If we needed to take into account the receiver's
// addressability, should we report the type &(x.typ) instead?
- check.recordSelection(e, MethodVal, x.typ_, obj, index, indirect)
+ check.recordSelection(e, MethodVal, x.typ(), obj, index, indirect)
// TODO(gri) The verification pass below is disabled for now because
// method sets don't match method lookup in some cases.
diff --git a/src/go/types/const.go b/src/go/types/const.go
index c8e24428fc..285f286a9d 100644
--- a/src/go/types/const.go
+++ b/src/go/types/const.go
@@ -34,8 +34,8 @@ func (check *Checker) overflow(x *operand, opPos token.Pos) {
// their type after each constant operation.
// x.typ cannot be a type parameter (type
// parameters cannot be constant types).
- if isTyped(x.typ_) {
- check.representable(x, x.typ_.Underlying().(*Basic))
+ if isTyped(x.typ()) {
+ check.representable(x, x.typ().Underlying().(*Basic))
return
}
@@ -255,7 +255,7 @@ func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Co
assert(x.mode_ == constant_)
v := x.val
if !representableConst(x.val, check, typ, &v) {
- if isNumeric(x.typ_) && isNumeric(typ) {
+ if isNumeric(x.typ()) && isNumeric(typ) {
// numeric conversion : error msg
//
// integer -> integer : overflows
@@ -263,7 +263,7 @@ func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Co
// float -> integer : truncated
// float -> float : overflows
//
- if !isInteger(x.typ_) && isInteger(typ) {
+ if !isInteger(x.typ()) && isInteger(typ) {
return nil, TruncatedFloat
} else {
return nil, NumericOverflow
@@ -301,7 +301,7 @@ func (check *Checker) convertUntyped(x *operand, target Type) {
x.val = val
check.updateExprVal(x.expr, val)
}
- if newType != x.typ_ {
+ if newType != x.typ() {
x.typ_ = newType
check.updateExprType(x.expr, newType, false)
}
diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go
index e64a46ff7c..905f722545 100644
--- a/src/go/types/conversions.go
+++ b/src/go/types/conversions.go
@@ -26,7 +26,7 @@ func (check *Checker) conversion(x *operand, T Type) {
// nothing to do
case representableConst(x.val, check, t, val):
return true
- case isInteger(x.typ_) && isString(t):
+ case isInteger(x.typ()) && isString(t):
codepoint := unicode.ReplacementChar
if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune {
codepoint = rune(i)
@@ -48,7 +48,7 @@ func (check *Checker) conversion(x *operand, T Type) {
// A conversion from an integer constant to an integer type
// can only fail if there's overflow. Give a concise error.
// (go.dev/issue/63563)
- if !ok && isInteger(x.typ_) && isInteger(T) {
+ if !ok && isInteger(x.typ()) && isInteger(T) {
check.errorf(x, InvalidConversion, "constant %s overflows %s", x.val, T)
x.mode_ = invalid
return
@@ -65,11 +65,11 @@ func (check *Checker) conversion(x *operand, T Type) {
cause = check.sprintf("%s does not contain specific types", T)
return false
}
- if isString(x.typ_) && isBytesOrRunes(u) {
+ if isString(x.typ()) && isBytesOrRunes(u) {
return true
}
if !constConvertibleTo(u, nil) {
- if isInteger(x.typ_) && isInteger(u) {
+ if isInteger(x.typ()) && isInteger(u) {
// see comment above on constant conversion
cause = check.sprintf("constant %s overflows %s (in %s)", x.val, u, T)
} else {
@@ -99,7 +99,7 @@ func (check *Checker) conversion(x *operand, T Type) {
// The conversion argument types are final. For untyped values the
// conversion provides the type, per the spec: "A constant may be
// given a type explicitly by a constant declaration or conversion,...".
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
final := T
// - For conversions to interfaces, except for untyped nil arguments
// and isTypes2, use the argument's default type.
@@ -109,12 +109,12 @@ func (check *Checker) conversion(x *operand, T Type) {
// - If !isTypes2, keep untyped nil for untyped nil arguments.
// - For constant integer to string conversions, keep the argument type.
// (See also the TODO below.)
- if isTypes2 && x.typ_ == Typ[UntypedNil] {
+ if isTypes2 && x.typ() == Typ[UntypedNil] {
// ok
} else if isNonTypeParamInterface(T) || constArg && !isConstType(T) || !isTypes2 && x.isNil() {
- final = Default(x.typ_) // default type of untyped nil is untyped nil
- } else if x.mode_ == constant_ && isInteger(x.typ_) && allString(T) {
- final = x.typ_
+ final = Default(x.typ()) // default type of untyped nil is untyped nil
+ } else if x.mode_ == constant_ && isInteger(x.typ()) && allString(T) {
+ final = x.typ()
}
check.updateExprType(x.expr, final, true)
}
@@ -143,7 +143,7 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
}
origT := T
- V := Unalias(x.typ_)
+ V := Unalias(x.typ())
T = Unalias(T)
Vu := V.Underlying()
Tu := T.Underlying()
@@ -284,7 +284,7 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
return false // no specific types
}
if !x.convertibleTo(check, T.typ, cause) {
- errorf("cannot convert %s to type %s (in %s)", x.typ_, T.typ, Tp)
+ errorf("cannot convert %s to type %s (in %s)", x.typ(), T.typ, Tp)
return false
}
return true
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index cc6f0ad309..72ecefc7e9 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -23,7 +23,7 @@ are generally of the form:
func f(x *operand, e *ast.Expr, ...)
where e is the expression to be checked, and x is the result of the check.
-The check performed by f may fail in which case x.mode == invalid, and
+The check performed by f may fail in which case x.mode_ == invalid, and
related error messages will have been issued by f.
If a hint argument is present, it is the composite literal element type
@@ -72,7 +72,7 @@ func init() {
func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
if pred := m[op]; pred != nil {
- if !pred(x.typ_) {
+ if !pred(x.typ()) {
check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
return false
}
@@ -143,7 +143,7 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
return
}
x.mode_ = value
- x.typ_ = &Pointer{base: x.typ_}
+ x.typ_ = &Pointer{base: x.typ()}
return
case token.ARROW:
@@ -159,7 +159,7 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
case token.TILDE:
// Provide a better error position and message than what check.op below would do.
- if !allInteger(x.typ_) {
+ if !allInteger(x.typ()) {
check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
x.mode_ = invalid
return
@@ -179,8 +179,8 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
return
}
var prec uint
- if isUnsigned(x.typ_) {
- prec = uint(check.conf.sizeof(x.typ_) * 8)
+ if isUnsigned(x.typ()) {
+ prec = uint(check.conf.sizeof(x.typ()) * 8)
}
x.val = constant.UnaryOp(op, x.val, prec)
x.expr = e
@@ -196,7 +196,7 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
// or send to x (recv == false) operation. If the operation is not valid, chanElem
// reports an error and returns nil.
func (check *Checker) chanElem(pos positioner, x *operand, recv bool) Type {
- u, err := commonUnder(x.typ_, func(t, u Type) *typeError {
+ u, err := commonUnder(x.typ(), func(t, u Type) *typeError {
if u == nil {
return typeErrorf("no specific channel type")
}
@@ -219,14 +219,14 @@ func (check *Checker) chanElem(pos positioner, x *operand, recv bool) Type {
cause := err.format(check)
if recv {
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s: %s", x, cause)
} else {
// In this case, only the non-channel and send-only channel error are possible.
check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s %s", cause, x)
}
} else {
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(pos, InvalidSend, invalidOp+"cannot send to %s: %s", x, cause)
} else {
// In this case, only the non-channel and receive-only channel error are possible.
@@ -386,14 +386,14 @@ func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) {
// 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) {
- return x.typ_, nil, 0
+ if x.mode_ == invalid || isTyped(x.typ()) || !isValid(target) {
+ return x.typ(), nil, 0
}
// x is untyped
if isUntyped(target) {
// both x and target are untyped
- if m := maxType(x.typ_, target); m != nil {
+ if m := maxType(x.typ(), target); m != nil {
return m, nil, 0
}
return nil, nil, InvalidUntypedConversion
@@ -412,7 +412,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
// result of comparisons (untyped bool), intermediate
// (delayed-checked) rhs operands of shifts, and as
// the value nil.
- switch x.typ_.(*Basic).kind {
+ switch x.typ().(*Basic).kind {
case UntypedBool:
if !isBoolean(target) {
return nil, nil, InvalidUntypedConversion
@@ -466,7 +466,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
if !u.Empty() {
return nil, nil, InvalidUntypedConversion
}
- return Default(x.typ_), nil, 0
+ return Default(x.typ()), nil, 0
case *Pointer, *Signature, *Slice, *Map, *Chan:
if !x.isNil() {
return nil, nil, InvalidUntypedConversion
@@ -482,7 +482,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
// If switchCase is true, the operator op is ignored.
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_) {
+ if !isValid(x.typ()) || !isValid(y.typ()) {
x.mode_ = invalid
return
}
@@ -497,16 +497,16 @@ func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool)
// spec: "In any comparison, the first operand must be assignable
// to the type of the second operand, or vice versa."
code := MismatchedTypes
- ok, _ := x.assignableTo(check, y.typ_, nil)
+ ok, _ := x.assignableTo(check, y.typ(), nil)
if !ok {
- ok, _ = y.assignableTo(check, x.typ_, nil)
+ ok, _ = y.assignableTo(check, x.typ(), nil)
}
if !ok {
// Report the error on the 2nd operand since we only
// know after seeing the 2nd operand whether we have
// a type mismatch.
errOp = y
- cause = check.sprintf("mismatched types %s and %s", x.typ_, y.typ_)
+ cause = check.sprintf("mismatched types %s and %s", x.typ(), y.typ())
goto Error
}
@@ -518,9 +518,9 @@ func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool)
switch {
case x.isNil() || y.isNil():
// Comparison against nil requires that the other operand type has nil.
- typ := x.typ_
+ typ := x.typ()
if x.isNil() {
- typ = y.typ_
+ typ = y.typ()
}
if !hasNil(typ) {
// This case should only be possible for "nil == nil".
@@ -531,24 +531,24 @@ func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool)
goto Error
}
- case !Comparable(x.typ_):
+ case !Comparable(x.typ()):
errOp = x
- cause = check.incomparableCause(x.typ_)
+ cause = check.incomparableCause(x.typ())
goto Error
- case !Comparable(y.typ_):
+ case !Comparable(y.typ()):
errOp = y
- cause = check.incomparableCause(y.typ_)
+ cause = check.incomparableCause(y.typ())
goto Error
}
case token.LSS, token.LEQ, token.GTR, token.GEQ:
// spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
switch {
- case !allOrdered(x.typ_):
+ case !allOrdered(x.typ()):
errOp = x
goto Error
- case !allOrdered(y.typ_):
+ case !allOrdered(y.typ()):
errOp = y
goto Error
}
@@ -568,8 +568,8 @@ func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool)
// time will be materialized. Update the expression trees.
// If the current types are untyped, the materialized type
// is the respective default type.
- check.updateExprType(x.expr, Default(x.typ_), true)
- check.updateExprType(y.expr, Default(y.typ_), true)
+ check.updateExprType(x.expr, Default(x.typ()), true)
+ check.updateExprType(y.expr, Default(y.typ()), true)
}
// spec: "Comparison operators compare two operands and yield
@@ -580,17 +580,17 @@ func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool)
Error:
// We have an offending operand errOp and possibly an error cause.
if cause == "" {
- if isTypeParam(x.typ_) || isTypeParam(y.typ_) {
+ if isTypeParam(x.typ()) || isTypeParam(y.typ()) {
// TODO(gri) should report the specific type causing the problem, if any
- if !isTypeParam(x.typ_) {
+ if !isTypeParam(x.typ()) {
errOp = y
}
- cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ_, op)
+ cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ(), op)
} else {
// catch-all neither x nor y is a type parameter
- what := compositeKind(errOp.typ_)
+ what := compositeKind(errOp.typ())
if what == "" {
- what = check.sprintf("%s", errOp.typ_)
+ what = check.sprintf("%s", errOp.typ())
}
cause = check.sprintf("operator %s not defined on %s", op, what)
}
@@ -623,7 +623,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
xval = constant.ToInt(x.val)
}
- if allInteger(x.typ_) || isUntyped(x.typ_) && xval != nil && xval.Kind() == constant.Int {
+ if allInteger(x.typ()) || isUntyped(x.typ()) && xval != nil && xval.Kind() == constant.Int {
// The lhs is of integer type or an untyped constant representable
// as an integer. Nothing to do.
} else {
@@ -648,7 +648,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
return
}
- if isUntyped(y.typ_) {
+ if isUntyped(y.typ()) {
// 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])
@@ -660,12 +660,12 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
} else {
// Check that RHS is otherwise at least of integer type.
switch {
- case allInteger(y.typ_):
- if !allUnsigned(y.typ_) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
+ case allInteger(y.typ()):
+ if !allUnsigned(y.typ()) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
x.mode_ = invalid
return
}
- case isUntyped(y.typ_):
+ case isUntyped(y.typ()):
// This is incorrect, but preserves pre-existing behavior.
// See also go.dev/issue/47410.
check.convertUntyped(y, Typ[Uint])
@@ -686,7 +686,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
x.val = constant.MakeUnknown()
// ensure the correct type - see comment below
- if !isInteger(x.typ_) {
+ if !isInteger(x.typ()) {
x.typ_ = Typ[UntypedInt]
}
return
@@ -703,7 +703,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
// (e.g., 2.0, an untyped float) - this can only happen for untyped
// non-integer numeric constants. Correct the type so that the shift
// result is of integer type.
- if !isInteger(x.typ_) {
+ if !isInteger(x.typ()) {
x.typ_ = Typ[UntypedInt]
}
// x is a constant so xval != nil and it must be of Int kind.
@@ -714,7 +714,7 @@ func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
}
// non-constant shift with constant lhs
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
// spec: "If the left operand of a non-constant shift
// expression is an untyped constant, the type of the
// constant is what it would be if the shift expression
@@ -745,7 +745,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_) {
+ if !allInteger(x.typ()) {
check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
x.mode_ = invalid
return
@@ -807,18 +807,18 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
return
}
- if !Identical(x.typ_, y.typ_) {
+ if !Identical(x.typ(), y.typ()) {
// only report an error if we have valid types
// (otherwise we had an error reported elsewhere already)
- if isValid(x.typ_) && isValid(y.typ_) {
+ if isValid(x.typ()) && isValid(y.typ()) {
var posn positioner = x
if e != nil {
posn = e
}
if e != nil {
- check.errorf(posn, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ_, y.typ_)
+ check.errorf(posn, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ(), y.typ())
} else {
- check.errorf(posn, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ_, y.typ_)
+ check.errorf(posn, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ(), y.typ())
}
}
x.mode_ = invalid
@@ -832,14 +832,14 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
if op == token.QUO || op == token.REM {
// check for zero divisor
- if (x.mode_ == constant_ || allInteger(x.typ_)) && y.mode_ == constant_ && constant.Sign(y.val) == 0 {
+ 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
return
}
// check for divisor underflow in complex division (see go.dev/issue/20227)
- if x.mode_ == constant_ && y.mode_ == constant_ && isComplex(x.typ_) {
+ if x.mode_ == constant_ && y.mode_ == constant_ && isComplex(x.typ()) {
re, im := constant.Real(y.val), constant.Imag(y.val)
re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
@@ -858,7 +858,7 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token
return
}
// force integer division of integer operands
- if op == token.QUO && isInteger(x.typ_) {
+ if op == token.QUO && isInteger(x.typ()) {
op = token.QUO_ASSIGN
}
x.val = constant.BinaryOp(x.val, op, y.val)
@@ -885,49 +885,49 @@ func (check *Checker) matchTypes(x, y *operand) {
// not compatible, we report a type mismatch error.
mayConvert := func(x, y *operand) bool {
// If both operands are typed, there's no need for an implicit conversion.
- if isTyped(x.typ_) && isTyped(y.typ_) {
+ if isTyped(x.typ()) && isTyped(y.typ()) {
return false
}
// A numeric type can only convert to another numeric type.
- if allNumeric(x.typ_) != allNumeric(y.typ_) {
+ if allNumeric(x.typ()) != allNumeric(y.typ()) {
return false
}
// An untyped operand may convert to its default type when paired with an empty interface
// TODO(gri) This should only matter for comparisons (the only binary operation that is
// valid with interfaces), but in that case the assignability check should take
// care of the conversion. Verify and possibly eliminate this extra test.
- if isNonTypeParamInterface(x.typ_) || isNonTypeParamInterface(y.typ_) {
+ if isNonTypeParamInterface(x.typ()) || isNonTypeParamInterface(y.typ()) {
return true
}
// A boolean type can only convert to another boolean type.
- if allBoolean(x.typ_) != allBoolean(y.typ_) {
+ if allBoolean(x.typ()) != allBoolean(y.typ()) {
return false
}
// A string type can only convert to another string type.
- if allString(x.typ_) != allString(y.typ_) {
+ if allString(x.typ()) != allString(y.typ()) {
return false
}
// Untyped nil can only convert to a type that has a nil.
if x.isNil() {
- return hasNil(y.typ_)
+ return hasNil(y.typ())
}
if y.isNil() {
- return hasNil(x.typ_)
+ return hasNil(x.typ())
}
// An untyped operand cannot convert to a pointer.
// TODO(gri) generalize to type parameters
- if isPointer(x.typ_) || isPointer(y.typ_) {
+ if isPointer(x.typ()) || isPointer(y.typ()) {
return false
}
return true
}
if mayConvert(x, y) {
- check.convertUntyped(x, y.typ_)
+ check.convertUntyped(x, y.typ())
if x.mode_ == invalid {
return
}
- check.convertUntyped(y, x.typ_)
+ check.convertUntyped(y, x.typ())
if y.mode_ == invalid {
x.mode_ = invalid
return
@@ -999,7 +999,7 @@ func (check *Checker) nonGeneric(T *target, x *operand) {
return
}
var what string
- switch t := x.typ_.(type) {
+ switch t := x.typ().(type) {
case *Alias, *Named:
if isGeneric(t) {
what = "type"
@@ -1098,11 +1098,11 @@ func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type)
check.error(e, BadTypeKeyword, "use of .(type) outside type switch")
goto Error
}
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
goto Error
}
- if _, ok := x.typ_.Underlying().(*Interface); !ok {
+ if _, ok := x.typ().Underlying().(*Interface); !ok {
check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
goto Error
}
@@ -1127,11 +1127,11 @@ func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type)
case invalid:
goto Error
case typexpr:
- check.validVarType(e.X, x.typ_)
- x.typ_ = &Pointer{base: x.typ_}
+ check.validVarType(e.X, x.typ())
+ x.typ_ = &Pointer{base: x.typ()}
default:
var base Type
- if !underIs(x.typ_, func(u Type) bool {
+ if !underIs(x.typ(), func(u Type) bool {
p, _ := u.(*Pointer)
if p == nil {
check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
@@ -1244,7 +1244,7 @@ func keyVal(x constant.Value) any {
// typeAssertion checks x.(T). The type of x must be an interface.
func (check *Checker) typeAssertion(e ast.Expr, x *operand, T Type, typeSwitch bool) {
var cause string
- if check.assertableTo(x.typ_, T, &cause) {
+ if check.assertableTo(x.typ(), T, &cause) {
return // success
}
@@ -1253,7 +1253,7 @@ func (check *Checker) typeAssertion(e ast.Expr, x *operand, T Type, typeSwitch b
return
}
- check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ_, cause)
+ check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ(), cause)
}
// expr typechecks expression e and initializes x with the expression value.
@@ -1284,7 +1284,7 @@ func (check *Checker) multiExpr(e ast.Expr, allowCommaOk bool) (list []*operand,
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.mode_ != invalid {
// multiple values
list = make([]*operand, t.Len())
for i, v := range t.vars {
@@ -1359,7 +1359,7 @@ func (check *Checker) exclude(x *operand, modeset uint) {
func (check *Checker) singleValue(x *operand) {
if x.mode_ == value {
// tuple types are never named - no need for underlying type below
- if t, ok := x.typ_.(*Tuple); ok {
+ 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
diff --git a/src/go/types/index.go b/src/go/types/index.go
index 711c88a540..064d162653 100644
--- a/src/go/types/index.go
+++ b/src/go/types/index.go
@@ -30,13 +30,13 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
x.mode_ = invalid
// TODO(gri) here we re-evaluate e.X - try to avoid this
x.typ_ = check.varType(e.orig)
- if isValid(x.typ_) {
+ if isValid(x.typ()) {
x.mode_ = typexpr
}
return false
case value:
- if sig, _ := x.typ_.Underlying().(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
+ if sig, _ := x.typ().Underlying().(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
// function instantiation
return true
}
@@ -49,11 +49,11 @@ 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_) {
+ if !check.isComplete(x.typ()) {
x.mode_ = invalid
return false
}
- switch typ := x.typ_.Underlying().(type) {
+ switch typ := x.typ().Underlying().(type) {
case *Pointer:
// Additionally, if x.typ is a pointer to an array type, indexing implicitly dereferences the value, meaning
// its base type must also be complete.
@@ -73,7 +73,7 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
// ordinary index expression
valid := false
length := int64(-1) // valid if >= 0
- switch typ := x.typ_.Underlying().(type) {
+ switch typ := x.typ().Underlying().(type) {
case *Basic:
if isString(typ) {
valid = true
@@ -124,14 +124,14 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
return false
case *Interface:
- if !isTypeParam(x.typ_) {
+ if !isTypeParam(x.typ()) {
break
}
// TODO(gri) report detailed failure cause for better error messages
var key, elem Type // key != nil: we must have all maps
mode := variable // non-maps result mode
// TODO(gri) factor out closure and use it for non-typeparam cases as well
- if underIs(x.typ_, func(u Type) bool {
+ if underIs(x.typ(), func(u Type) bool {
l := int64(-1) // valid if >= 0
var k, e Type // k is only set for maps
switch t := u.(type) {
@@ -222,7 +222,7 @@ func (check *Checker) indexExpr(x *operand, e *indexedExpr) (isFuncInst bool) {
// In pathological (invalid) cases (e.g.: type T1 [][[]T1{}[0][0]]T0)
// the element type may be accessed before it's set. Make sure we have
// a valid type.
- if x.typ_ == nil {
+ if x.typ() == nil {
x.typ_ = Typ[Invalid]
}
@@ -241,9 +241,9 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
var ct, cu Type // type and respective common underlying type
var hasString bool
// TODO(adonovan): use go1.23 "range typeset()".
- typeset(x.typ_)(func(t, u Type) bool {
+ typeset(x.typ())(func(t, u Type) bool {
if u == nil {
- check.errorf(x, NonSliceableOperand, "cannot slice %s: no specific type in %s", x, x.typ_)
+ check.errorf(x, NonSliceableOperand, "cannot slice %s: no specific type in %s", x, x.typ())
cu = nil
return false
}
@@ -273,15 +273,15 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
// If we saw a string, proceed with string type,
// but don't go from untyped string to string.
cu = Typ[String]
- if !isTypeParam(x.typ_) {
- cu = x.typ_.Underlying() // untyped string remains untyped
+ if !isTypeParam(x.typ()) {
+ cu = x.typ().Underlying() // untyped string remains untyped
}
}
// Note that we don't permit slice expressions where x is a type expression, so we don't check for that here.
// 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) {
+ if p, ok := x.typ().Underlying().(*Pointer); ok && !check.isComplete(p.base) {
x.mode_ = invalid
return
}
@@ -311,7 +311,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
}
// spec: "For untyped string operands the result
// is a non-constant value of type string."
- if isUntyped(x.typ_) {
+ if isUntyped(x.typ()) {
x.typ_ = Typ[String]
}
}
@@ -428,7 +428,7 @@ func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) {
}
if x.mode_ != constant_ {
- return x.typ_, -1
+ return x.typ(), -1
}
if x.val.Kind() == constant.Unknown {
@@ -443,7 +443,7 @@ func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) {
}
// 0 <= v [ && v < max ]
- return x.typ_, v
+ return x.typ(), v
}
func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNegative bool) bool {
@@ -458,7 +458,7 @@ func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNega
}
// spec: "the index x must be of integer type or an untyped constant"
- if !allInteger(x.typ_) {
+ if !allInteger(x.typ()) {
check.errorf(x, code, invalidArg+"%s %s must be integer", what, x)
return false
}
diff --git a/src/go/types/infer.go b/src/go/types/infer.go
index 2570ea8cab..db960723ca 100644
--- a/src/go/types/infer.go
+++ b/src/go/types/infer.go
@@ -173,12 +173,12 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
continue
}
par := params.At(i)
- if isParameterized(tparams, par.typ) || isParameterized(tparams, arg.typ_) {
+ if isParameterized(tparams, par.typ) || isParameterized(tparams, arg.typ()) {
// Function parameters are always typed. Arguments may be untyped.
// Collect the indices of untyped arguments and handle them later.
- if isTyped(arg.typ_) {
- if !u.unify(par.typ, arg.typ_, assign) {
- errorf(par.typ, arg.typ_, arg)
+ if isTyped(arg.typ()) {
+ if !u.unify(par.typ, arg.typ(), assign) {
+ errorf(par.typ, arg.typ(), arg)
return nil
}
} else if _, ok := par.typ.(*TypeParam); ok && !arg.isNil() {
@@ -340,11 +340,11 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
}
max := maxUntyped[tpar]
if max == nil {
- max = arg.typ_
+ max = arg.typ()
} else {
- m := maxType(max, arg.typ_)
+ m := maxType(max, arg.typ())
if m == nil {
- err.addf(arg, "mismatched types %s and %s (cannot infer %s)", max, arg.typ_, tpar)
+ err.addf(arg, "mismatched types %s and %s (cannot infer %s)", max, arg.typ(), tpar)
return nil
}
max = m
diff --git a/src/go/types/literals.go b/src/go/types/literals.go
index f6d79c299b..2bcd229358 100644
--- a/src/go/types/literals.go
+++ b/src/go/types/literals.go
@@ -273,12 +273,12 @@ func (check *Checker) compositeLit(x *operand, e *ast.CompositeLit, hint Type) {
xkey := keyVal(x.val)
if keyIsInterface {
for _, vtyp := range visited[xkey] {
- if Identical(vtyp, x.typ_) {
+ if Identical(vtyp, x.typ()) {
duplicate = true
break
}
}
- visited[xkey] = append(visited[xkey], x.typ_)
+ visited[xkey] = append(visited[xkey], x.typ())
} else {
_, duplicate = visited[xkey]
visited[xkey] = nil
diff --git a/src/go/types/operand.go b/src/go/types/operand.go
index db525ff10e..3de2455899 100644
--- a/src/go/types/operand.go
+++ b/src/go/types/operand.go
@@ -64,6 +64,14 @@ type operand struct {
id builtinId
}
+func (x *operand) typ() Type {
+ return x.typ_
+}
+
+func (x *operand) isValid() bool {
+ return 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 {
@@ -114,17 +122,17 @@ func operandString(x *operand, qf Qualifier) string {
// special-case nil
if isTypes2 {
if x.mode_ == nilvalue {
- switch x.typ_ {
+ switch x.typ() {
case nil, Typ[Invalid]:
return "nil (with invalid type)"
case Typ[UntypedNil]:
return "nil"
default:
- return fmt.Sprintf("nil (of type %s)", TypeString(x.typ_, qf))
+ return fmt.Sprintf("nil (of type %s)", TypeString(x.typ(), qf))
}
}
} else { // go/types
- if x.mode_ == value && x.typ_ == Typ[UntypedNil] {
+ if x.mode_ == value && x.typ() == Typ[UntypedNil] {
return "nil"
}
}
@@ -139,7 +147,7 @@ func operandString(x *operand, qf Qualifier) string {
case builtin:
expr = predeclaredFuncs[x.id].name
case typexpr:
- expr = TypeString(x.typ_, qf)
+ expr = TypeString(x.typ(), qf)
case constant_:
expr = x.val.String()
}
@@ -158,9 +166,9 @@ func operandString(x *operand, qf Qualifier) string {
// no type
default:
// should have a type, but be cautious (don't crash during printing)
- if x.typ_ != nil {
- if isUntyped(x.typ_) {
- buf.WriteString(x.typ_.(*Basic).name)
+ if x.typ() != nil {
+ if isUntyped(x.typ()) {
+ buf.WriteString(x.typ().(*Basic).name)
buf.WriteByte(' ')
break
}
@@ -181,9 +189,9 @@ func operandString(x *operand, qf Qualifier) string {
// <typ>
if hasType {
- if isValid(x.typ_) {
+ if isValid(x.typ()) {
var desc string
- if isGeneric(x.typ_) {
+ if isGeneric(x.typ()) {
desc = "generic "
}
@@ -191,14 +199,14 @@ func operandString(x *operand, qf Qualifier) string {
// If the type is a renamed basic type, describe the basic type,
// as in "int32 type MyInt" for a *Named type MyInt.
// If it is a type parameter, describe the constraint instead.
- tpar, _ := Unalias(x.typ_).(*TypeParam)
+ tpar, _ := Unalias(x.typ()).(*TypeParam)
if tpar == nil {
- switch x.typ_.(type) {
+ switch x.typ().(type) {
case *Alias, *Named:
- what := compositeKind(x.typ_)
+ what := compositeKind(x.typ())
if what == "" {
// x.typ must be basic type
- what = x.typ_.Underlying().(*Basic).name
+ what = x.typ().Underlying().(*Basic).name
}
desc += what + " "
}
@@ -206,7 +214,7 @@ func operandString(x *operand, qf Qualifier) string {
// desc is "" or has a trailing space at the end
buf.WriteString(" of " + desc + "type ")
- WriteType(&buf, x.typ_, qf)
+ WriteType(&buf, x.typ(), qf)
if tpar != nil {
buf.WriteString(" constrained by ")
@@ -299,7 +307,7 @@ func (x *operand) isNil() bool {
if isTypes2 {
return x.mode_ == nilvalue
} else { // go/types
- return x.mode_ == value && x.typ_ == Typ[UntypedNil]
+ return x.mode_ == value && x.typ() == Typ[UntypedNil]
}
}
@@ -315,7 +323,7 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
}
origT := T
- V := Unalias(x.typ_)
+ V := Unalias(x.typ())
T = Unalias(T)
// x's type is identical to T
@@ -420,7 +428,7 @@ func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Cod
}
ok, code = x.assignableTo(check, T.typ, cause)
if !ok {
- errorf("cannot assign %s to %s (in %s)", x.typ_, T.typ, Tp)
+ errorf("cannot assign %s to %s (in %s)", x.typ(), T.typ, Tp)
return false
}
return true
diff --git a/src/go/types/range.go b/src/go/types/range.go
index 59a529a65a..cbe2c37535 100644
--- a/src/go/types/range.go
+++ b/src/go/types/range.go
@@ -38,7 +38,7 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *ast.RangeStmt, noN
check.expr(nil, &x, rangeVar)
if isTypes2 && x.mode_ != invalid && sValue == nil && !check.hasCallOrRecv {
- if t, ok := arrayPtrDeref(x.typ_.Underlying()).(*Array); ok {
+ if t, ok := arrayPtrDeref(x.typ().Underlying()).(*Array); ok {
for {
// Put constant info on the thing inside parentheses.
// That's where (*../noder/writer).expr expects it.
@@ -65,7 +65,7 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *ast.RangeStmt, noN
// determine key/value types
var key, val Type
if x.mode_ != invalid {
- k, v, cause, ok := rangeKeyVal(check, x.typ_, func(v goVersion) bool {
+ k, v, cause, ok := rangeKeyVal(check, x.typ(), func(v goVersion) bool {
return check.allowVersion(v)
})
switch {
@@ -95,7 +95,7 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *ast.RangeStmt, noN
lhs := [2]ast.Expr{sKey, sValue} // sKey, sValue may be nil
rhs := [2]Type{key, val} // key, val may be nil
- rangeOverInt := isInteger(x.typ_)
+ rangeOverInt := isInteger(x.typ())
if isDef {
// short variable declaration
@@ -172,8 +172,8 @@ func (check *Checker) rangeStmt(inner stmtContext, rangeStmt *ast.RangeStmt, noN
// 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_) {
- check.softErrorf(lhs, InvalidRangeExpr, "cannot use iteration variable of type %s", x.typ_)
+ if x.mode_ != invalid && !isInteger(x.typ()) {
+ check.softErrorf(lhs, InvalidRangeExpr, "cannot use iteration variable of type %s", x.typ())
}
} else {
var y operand
diff --git a/src/go/types/recording.go b/src/go/types/recording.go
index 570839ac8a..d440259c28 100644
--- a/src/go/types/recording.go
+++ b/src/go/types/recording.go
@@ -26,10 +26,10 @@ func (check *Checker) record(x *operand) {
case novalue:
typ = (*Tuple)(nil)
case constant_:
- typ = x.typ_
+ typ = x.typ()
val = x.val
default:
- typ = x.typ_
+ typ = x.typ()
}
assert(x.expr != nil && typ != nil)
@@ -100,7 +100,7 @@ func (check *Checker) recordCommaOkTypes(x ast.Expr, a []*operand) {
if a[0].mode_ == invalid {
return
}
- t0, t1 := a[0].typ_, a[1].typ_
+ t0, t1 := a[0].typ(), a[1].typ()
assert(isTyped(t0) && isTyped(t1) && (allBoolean(t1) || t1 == universeError))
if m := check.Types; m != nil {
for {
diff --git a/src/go/types/stmt.go b/src/go/types/stmt.go
index 6db1e70dad..a449feb220 100644
--- a/src/go/types/stmt.go
+++ b/src/go/types/stmt.go
@@ -242,7 +242,7 @@ L:
if x.mode_ == invalid || v.mode_ == invalid {
continue L
}
- check.convertUntyped(&v, x.typ_)
+ check.convertUntyped(&v, x.typ())
if v.mode_ == invalid {
continue L
}
@@ -260,7 +260,7 @@ L:
// look for duplicate types for a given value
// (quadratic algorithm, but these lists tend to be very short)
for _, vt := range seen[val] {
- if Identical(v.typ_, vt.typ) {
+ if Identical(v.typ(), vt.typ) {
err := check.newError(DuplicateCase)
err.addf(&v, "duplicate case %s in expression switch", &v)
err.addf(atPos(vt.pos), "previous case")
@@ -268,7 +268,7 @@ L:
continue L
}
}
- seen[val] = append(seen[val], valueType{v.Pos(), v.typ_})
+ seen[val] = append(seen[val], valueType{v.Pos(), v.typ()})
}
}
}
@@ -346,7 +346,7 @@ L:
if len(types) != 1 || T == nil {
T = Typ[Invalid]
if x != nil {
- T = x.typ_
+ T = x.typ()
}
}
@@ -399,7 +399,7 @@ L:
if len(types) != 1 || T == nil {
T = Typ[Invalid]
if x != nil {
- T = x.typ_
+ T = x.typ()
}
}
@@ -489,8 +489,8 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
if x.mode_ == invalid {
return
}
- if !allNumeric(x.typ_) {
- check.errorf(s.X, NonNumericIncDec, invalidOp+"%s%s (non-numeric type %s)", s.X, s.Tok, x.typ_)
+ if !allNumeric(x.typ()) {
+ check.errorf(s.X, NonNumericIncDec, invalidOp+"%s%s (non-numeric type %s)", s.X, s.Tok, x.typ())
return
}
@@ -609,7 +609,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
check.simpleStmt(s.Init)
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode_ != invalid && !allBoolean(x.typ_) {
+ if x.mode_ != invalid && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
}
check.stmt(inner, s.Body)
@@ -636,8 +636,8 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
// 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_) {
- check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ_)
+ 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
}
} else {
@@ -729,9 +729,9 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
var x operand
check.expr(nil, &x, expr.X)
if x.mode_ != invalid {
- if isTypeParam(x.typ_) {
+ if isTypeParam(x.typ()) {
check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
- } else if IsInterface(x.typ_) {
+ } else if IsInterface(x.typ()) {
sx = &x
} else {
check.errorf(&x, InvalidTypeSwitch, "%s is not an interface", &x)
@@ -837,7 +837,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
if s.Cond != nil {
var x operand
check.expr(nil, &x, s.Cond)
- if x.mode_ != invalid && !allBoolean(x.typ_) {
+ if x.mode_ != invalid && !allBoolean(x.typ()) {
check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
}
}
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index 654a731493..848d662f10 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -248,7 +248,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *TypeName) (T Type) {
switch x.mode_ {
case typexpr:
- return x.typ_
+ return x.typ()
case invalid:
// ignore - error reported before
case novalue:
@@ -263,7 +263,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *TypeName) (T Type) {
switch x.mode_ {
case typexpr:
- return x.typ_
+ return x.typ()
case invalid:
// ignore - error reported before
case novalue:
@@ -485,7 +485,7 @@ func (check *Checker) arrayLength(e ast.Expr) int64 {
return -1
}
- if isUntyped(x.typ_) || isInteger(x.typ_) {
+ if isUntyped(x.typ()) || isInteger(x.typ()) {
if val := constant.ToInt(x.val); val.Kind() == constant.Int {
if representableConst(val, check, Typ[Int], nil) {
if n, ok := constant.Int64Val(val); ok && n >= 0 {
@@ -496,7 +496,7 @@ func (check *Checker) arrayLength(e ast.Expr) int64 {
}
var msg string
- if isInteger(x.typ_) {
+ if isInteger(x.typ()) {
msg = "invalid array length %s"
} else {
msg = "array length %s must be integer"