diff options
author | Dan Scales <danscales@google.com> | 2021-03-29 08:28:01 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-03-30 03:05:45 +0000 |
commit | eeadfa2d3810c252f86a88ddd282b48be5abc6df (patch) | |
tree | cbc38592e0a2dbad05d343271124278d028bcf95 /src/cmd/compile/internal/noder/helpers.go | |
parent | a95454b6f31a982f064d262987199fba19f085e9 (diff) | |
download | go-git-eeadfa2d3810c252f86a88ddd282b48be5abc6df.tar.gz |
cmd/compile: fix various small bugs related to type lists
Fix various small bugs related to delaying transformations due to type
params. Most of these relate to the need to delay a transformation when
an argument of an expression or statement has a type parameter that has
a structural constraint. The structural constraint implies the operation
should work, but the transformation can't happen until the actual value
of the type parameter is known.
- delay transformations for send statements and return statements if
any args/values have type params.
- similarly, delay transformation of a call where the function arg has
type parameters. This is mainly important for the case where the
function arg is a pure type parameter, but has a structural
constraint that requires it to be a function. Move the setting of
n.Use to transformCall(), since we may not know how many return
values there are until then, if the function arg is a type parameter.
- set the type of unary expressions from the type2 type (as we do with
most other expressions), since that works better with expressions
with type params.
- deal with these delayed transformations in subster.node() and convert
the CALL checks to a switch statement.
- make sure ir.CurFunc is set properly during stenciling, including
closures (needed for transforming return statements during
stenciling).
New test file typelist.go with tests for these cases.
Change-Id: I1b82f949d8cec47d906429209e846f4ebc8ec85e
Reviewed-on: https://go-review.googlesource.com/c/go/+/305729
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/helpers.go')
-rw-r--r-- | src/cmd/compile/internal/noder/helpers.go | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go index cb8052c0cb..e5a6dbcb01 100644 --- a/src/cmd/compile/internal/noder/helpers.go +++ b/src/cmd/compile/internal/noder/helpers.go @@ -149,9 +149,13 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool) } } - n.Use = ir.CallUseExpr - if fun.Type().NumResults() == 0 { - n.Use = ir.CallUseStmt + if fun.Type().HasTParam() { + // If the fun arg is or has a type param, don't do any extra + // transformations, since we may not have needed properties yet + // (e.g. number of return values, etc). The type param is probably + // described by a structural constraint that requires it to be a + // certain function type, etc., but we don't want to analyze that. + return typed(typ, n) } if fun.Op() == ir.OXDOT { @@ -191,9 +195,9 @@ func Compare(pos src.XPos, typ *types.Type, op ir.Op, x, y ir.Node) ir.Node { return n } -func Deref(pos src.XPos, x ir.Node) *ir.StarExpr { +func Deref(pos src.XPos, typ *types.Type, x ir.Node) *ir.StarExpr { n := ir.NewStarExpr(pos, x) - typed(x.Type().Elem(), n) + typed(typ, n) return n } @@ -288,17 +292,22 @@ func Slice(pos src.XPos, typ *types.Type, x, low, high, max ir.Node) ir.Node { return n } -func Unary(pos src.XPos, op ir.Op, x ir.Node) ir.Node { +func Unary(pos src.XPos, typ *types.Type, op ir.Op, x ir.Node) ir.Node { switch op { case ir.OADDR: return Addr(pos, x) case ir.ODEREF: - return Deref(pos, x) + return Deref(pos, typ, x) } - typ := x.Type() if op == ir.ORECV { - typ = typ.Elem() + if typ.IsFuncArgStruct() && typ.NumFields() == 2 { + // Remove the second boolean type (if provided by type2), + // since that works better with the rest of the compiler + // (which will add it back in later). + assert(typ.Field(1).Type.Kind() == types.TBOOL) + typ = typ.Field(0).Type + } } return typed(typ, ir.NewUnaryExpr(pos, op, x)) } |