diff options
author | Robert Griesemer <gri@golang.org> | 2021-01-15 18:19:00 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-01-20 05:50:46 +0000 |
commit | d8796b5670d46a4197fc5e81a32d127c45ab6557 (patch) | |
tree | ec7789dbc126130c2f0b3d30b1b12695acd6d18f /src/cmd/compile/internal/types2/operand.go | |
parent | 48a3cb399da872554f6ea13e1e92b3c8c73fec95 (diff) | |
download | go-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.go | 23 |
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 |