From 0742e6dbc08f1ac5e7de966dcdf43cea03117c0c Mon Sep 17 00:00:00 2001 From: Robert Findley Date: Thu, 13 Apr 2023 13:55:42 +0000 Subject: [PATCH] Revert "go/types, types2: remove unnecessary tests for x.typ == Typ[Invalid]" This reverts commit 4c49d52439805c248f4a01d529b90b22e821b7d6. Reason for revert: it is trickier than expected to enforce an invariant that x.typ == Typ[Invalid] => x.mode == invalid. For example, builtins have invalid type until their call is evaluated. I think it is better to keep this defensive code for now. My bad for suggesting this strictness. I will send a follow-up CL with a test that exercises the panic discovered inside Google, and a bit more commentary about what 'invalid' means in both contexts. Fixes #59603 Change-Id: If291f7268e7ef7ae6cd9bb861bb9af349a729cb2 Reviewed-on: https://go-review.googlesource.com/c/go/+/484375 TryBot-Result: Gopher Robot Reviewed-by: Robert Griesemer Run-TryBot: Robert Findley --- src/cmd/compile/internal/types2/assignments.go | 8 ++++++-- src/go/types/assignments.go | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/cmd/compile/internal/types2/assignments.go b/src/cmd/compile/internal/types2/assignments.go index 5a51b3de1e2..02823fed2c6 100644 --- a/src/cmd/compile/internal/types2/assignments.go +++ b/src/cmd/compile/internal/types2/assignments.go @@ -99,7 +99,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) { } func (check *Checker) initConst(lhs *Const, x *operand) { - if x.mode == invalid || lhs.typ == Typ[Invalid] { + if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { if lhs.typ == nil { lhs.typ = Typ[Invalid] } @@ -133,7 +133,7 @@ func (check *Checker) initConst(lhs *Const, x *operand) { // If lhs doesn't have a type yet, it is given the type of x, // or Typ[Invalid] in case of an error. func (check *Checker) initVar(lhs *Var, x *operand, context string) { - if x.mode == invalid || lhs.typ == Typ[Invalid] { + if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { if lhs.typ == nil { lhs.typ = Typ[Invalid] } @@ -195,6 +195,10 @@ func (check *Checker) lhsVar(lhs syntax.Expr) Type { v.used = v_used // restore v.used } + if x.mode == invalid || x.typ == Typ[Invalid] { + return Typ[Invalid] + } + // spec: "Each left-hand side operand must be addressable, a map index // expression, or the blank identifier. Operands may be parenthesized." switch x.mode { diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go index 5eca569b568..68b07a71722 100644 --- a/src/go/types/assignments.go +++ b/src/go/types/assignments.go @@ -97,7 +97,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) { } func (check *Checker) initConst(lhs *Const, x *operand) { - if x.mode == invalid || lhs.typ == Typ[Invalid] { + if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { if lhs.typ == nil { lhs.typ = Typ[Invalid] } @@ -131,7 +131,7 @@ func (check *Checker) initConst(lhs *Const, x *operand) { // If lhs doesn't have a type yet, it is given the type of x, // or Typ[Invalid] in case of an error. func (check *Checker) initVar(lhs *Var, x *operand, context string) { - if x.mode == invalid || lhs.typ == Typ[Invalid] { + if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { if lhs.typ == nil { lhs.typ = Typ[Invalid] } @@ -193,6 +193,10 @@ func (check *Checker) lhsVar(lhs ast.Expr) Type { v.used = v_used // restore v.used } + if x.mode == invalid || x.typ == Typ[Invalid] { + return Typ[Invalid] + } + // spec: "Each left-hand side operand must be addressable, a map index // expression, or the blank identifier. Operands may be parenthesized." switch x.mode {