aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/operand.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-01-15 18:19:00 -0800
committerRobert Griesemer <gri@golang.org>2021-01-20 05:50:46 +0000
commitd8796b5670d46a4197fc5e81a32d127c45ab6557 (patch)
treeec7789dbc126130c2f0b3d30b1b12695acd6d18f /src/cmd/compile/internal/types2/operand.go
parent48a3cb399da872554f6ea13e1e92b3c8c73fec95 (diff)
downloadgo-d8796b5670d46a4197fc5e81a32d127c45ab6557.tar.gz
go-d8796b5670d46a4197fc5e81a32d127c45ab6557.zip
[dev.typeparams] cmd/compile/internal/types2: report type of nil based on context
With this CL, the type reported for uses of the predeclared identifier nil changes from untyped nil to the type of the context within which nil is used, matching the behaviour of types2 for other untyped types. If an untyped nil value is assigned or converted to an interface, the nil expression is given the interface type. The predicate TypeAndValue.IsNil doesn't change in behavior, it still reports whether the relevant expression is a (typed or untyped) nil value. Change-Id: Id766468f3f3f2a53e4c55e1e6cd521e459c4a94f Reviewed-on: https://go-review.googlesource.com/c/go/+/284218 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/operand.go')
-rw-r--r--src/cmd/compile/internal/types2/operand.go23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/types2/operand.go b/src/cmd/compile/internal/types2/operand.go
index d5a10b2c29..a14120c2c9 100644
--- a/src/cmd/compile/internal/types2/operand.go
+++ b/src/cmd/compile/internal/types2/operand.go
@@ -27,6 +27,7 @@ const (
variable // operand is an addressable variable
mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
value // operand is a computed value
+ nilvalue // operand is the nil value
commaok // like value, but operand may be used in a comma,ok expression
commaerr // like commaok, but second value is error, not boolean
cgofunc // operand is a cgo function
@@ -41,6 +42,7 @@ var operandModeString = [...]string{
variable: "variable",
mapindex: "map index expression",
value: "value",
+ nilvalue: "nil",
commaok: "comma, ok expression",
commaerr: "comma, error expression",
cgofunc: "cgo function",
@@ -96,6 +98,9 @@ func (x *operand) Pos() syntax.Pos {
// value <expr> (<untyped kind> <mode> )
// value <expr> ( <mode> of type <typ>)
//
+// nilvalue untyped nil
+// nilvalue nil ( of type <typ>)
+//
// commaok <expr> (<untyped kind> <mode> )
// commaok <expr> ( <mode> of type <typ>)
//
@@ -106,6 +111,18 @@ func (x *operand) Pos() syntax.Pos {
// cgofunc <expr> ( <mode> of type <typ>)
//
func operandString(x *operand, qf Qualifier) string {
+ // special-case nil
+ if x.mode == nilvalue {
+ switch x.typ {
+ case nil, Typ[Invalid]:
+ return "nil (with invalid type)"
+ case Typ[UntypedNil]:
+ return "untyped nil"
+ default:
+ return fmt.Sprintf("nil (of type %s)", TypeString(x.typ, qf))
+ }
+ }
+
var buf bytes.Buffer
var expr string
@@ -222,10 +239,8 @@ func (x *operand) setConst(k syntax.LitKind, lit string) {
x.val = val
}
-// isNil reports whether x is the nil value.
-func (x *operand) isNil() bool {
- return x.mode == value && x.typ == Typ[UntypedNil]
-}
+// isNil reports whether x is a typed or the untyped nil value.
+func (x *operand) isNil() bool { return x.mode == nilvalue }
// TODO(gri) The functions operand.assignableTo, checker.convertUntyped,
// checker.representable, and checker.assignment are