diff options
author | Dan Scales <danscales@google.com> | 2021-03-18 14:36:39 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-03-23 04:23:52 +0000 |
commit | 0265b6475f08f2c23a742132db87c357fcbfa458 (patch) | |
tree | e436cb1c782b16ab3270c2d11f77765afdd9aa97 /src/cmd/compile/internal/typecheck/expr.go | |
parent | b8371d495bb291f61e4fa3ac1b84116c70ac1223 (diff) | |
download | go-0265b6475f08f2c23a742132db87c357fcbfa458.tar.gz go-0265b6475f08f2c23a742132db87c357fcbfa458.zip |
cmd/compile: replace calls to typecheck with transform functions
For additions, compares, and slices, create transform functions that do
just the transformations for those nodes by the typecheck package (given
that the code has been fully typechecked by types2). For nodes that have
no args with typeparams, we call these transform functions directly in
noder2. But for nodes that have args with typeparams, we have to delay
and call the tranform functions during stenciling, since we don't know
the specific types involved.
We indicate that a node still needs transformation by setting Typecheck
to a new value 3. This value means the current type of the node has been
set (via types2), but the node may still need transformation.
Had to export typcheck.IsCmp and typecheck.Assignop from the typecheck
package.
Added new tests list2.go (required delaying compare typecheck/transform
because of != compare in checkList) and adder.go (requires delaying add
typecheck/transform, since it can do addition for numbers or strings).
There are several more transformation functions needed for expressions
(indexing, calls, etc.) and several more complicated ones needed for
statements (mainly various kinds of assignments).
Change-Id: I7d89d13a4108308ea0304a4b815ab60b40c59b0a
Reviewed-on: https://go-review.googlesource.com/c/go/+/303091
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/typecheck/expr.go')
-rw-r--r-- | src/cmd/compile/internal/typecheck/expr.go | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go index 10a4c1b1dc..fb39709686 100644 --- a/src/cmd/compile/internal/typecheck/expr.go +++ b/src/cmd/compile/internal/typecheck/expr.go @@ -77,6 +77,10 @@ func tcShift(n, l, r ir.Node) (ir.Node, ir.Node, *types.Type) { return l, r, t } +func IsCmp(op ir.Op) bool { + return iscmp[op] +} + // tcArith typechecks operands of a binary arithmetic expression. // The result of tcArith MUST be assigned back to original operands, // t is the type of the expression, and should be set by the caller. e.g: @@ -102,7 +106,7 @@ func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type) // The conversion allocates, so only do it if the concrete type is huge. converted := false if r.Type().Kind() != types.TBLANK { - aop, _ = assignop(l.Type(), r.Type()) + aop, _ = Assignop(l.Type(), r.Type()) if aop != ir.OXXX { if r.Type().IsInterface() && !l.Type().IsInterface() && !types.IsComparable(l.Type()) { base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type())) @@ -121,7 +125,7 @@ func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type) } if !converted && l.Type().Kind() != types.TBLANK { - aop, _ = assignop(r.Type(), l.Type()) + aop, _ = Assignop(r.Type(), l.Type()) if aop != ir.OXXX { if l.Type().IsInterface() && !r.Type().IsInterface() && !types.IsComparable(r.Type()) { base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type())) |