diff options
author | Robert Griesemer <gri@golang.org> | 2021-03-17 16:59:47 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-03-18 00:23:25 +0000 |
commit | 51e4bb236cb8feb8118ed6dd768ddac834dad2ef (patch) | |
tree | 8613515630a4ea6a37dc803d38d8dd33dcd38c2d /src/cmd/compile/internal/types2/expr.go | |
parent | 2583c1b4df979eae16fab6527275030a630da42b (diff) | |
download | go-51e4bb236cb8feb8118ed6dd768ddac834dad2ef.tar.gz go-51e4bb236cb8feb8118ed6dd768ddac834dad2ef.zip |
cmd/compile/internal/types2: delay recording types of untyped operands when checking against type parameters
Don't eagerly record the target type for an untyped operand if the
target type is just one of possibly many types in the type list of
a type parameter. Instead, record expression type only after we
checked that all types in the type list are ok.
Also, update assertion in Checker.recordTypeAndValue since (currently),
a type parameter is not considered a const type. We may change that,
eventually.
This is a temporary (but working) solution. Eventually we should
copy the approach taken in go/types.
Fixes #45096.
Change-Id: Icf61ee893aca6ead32bfc45ee5831572e672357b
Reviewed-on: https://go-review.googlesource.com/c/go/+/302755
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/types2/expr.go')
-rw-r--r-- | src/cmd/compile/internal/types2/expr.go | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index b89eb199eb..4cdec84604 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -628,7 +628,7 @@ func (check *Checker) convertUntyped(x *operand, target Type) { for _, t := range unpack(types) { x := *x // make a copy; convertUntypedInternal modifies x - check.convertUntypedInternal(&x, t) + check.convertUntypedInternal(&x, t, false) if x.mode == invalid { goto Error } @@ -639,7 +639,7 @@ func (check *Checker) convertUntyped(x *operand, target Type) { return } - check.convertUntypedInternal(x, target) + check.convertUntypedInternal(x, target, true) return Error: @@ -649,7 +649,7 @@ Error: } // convertUntypedInternal should only be called by convertUntyped. -func (check *Checker) convertUntypedInternal(x *operand, target Type) { +func (check *Checker) convertUntypedInternal(x *operand, target Type, update bool) { assert(isTyped(target)) if x.isNil() { @@ -669,7 +669,9 @@ func (check *Checker) convertUntypedInternal(x *operand, target Type) { return } // expression value may have been rounded - update if needed - check.updateExprVal(x.expr, x.val) + if update { + check.updateExprVal(x.expr, x.val) + } } else { // Non-constant untyped values may appear as the // result of comparisons (untyped bool), intermediate @@ -694,7 +696,7 @@ func (check *Checker) convertUntypedInternal(x *operand, target Type) { } case *Sum: t.is(func(t Type) bool { - check.convertUntypedInternal(x, t) + check.convertUntypedInternal(x, t, false) return x.mode != invalid }) case *Interface: @@ -712,7 +714,9 @@ func (check *Checker) convertUntypedInternal(x *operand, target Type) { OK: x.typ = target - check.updateExprType(x.expr, target, true) + if update { + check.updateExprType(x.expr, target, true) + } return Error: |