diff options
author | Dan Scales <danscales@google.com> | 2021-07-21 16:23:17 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-07-23 20:57:41 +0000 |
commit | 12866bd8ea13e43bc5995f58cdeb67ffd64a1c8c (patch) | |
tree | d57f6807409e9814c6020f1628487adf6fc8b516 /src/cmd/compile/internal/noder/transform.go | |
parent | 4cdc65d32a3f0378cc508e8eb395063b83683fd4 (diff) | |
download | go-git-12866bd8ea13e43bc5995f58cdeb67ffd64a1c8c.tar.gz |
[dev.typeparams] Add CONVIFACE nodes in noder2, where possible
Changes to add CONVIFACE nodes where possible in noder2, even when the
args are typeparams. The transformation to insert a CONVIFACE node can
usually happen when there an obvious assignment/conversion to an
interface type from a non-interface type. So, we now do this
tranformation for:
- direct conversions to an interface type
- function arguments that are implicitly converted to an interface
based on the parameter types.
- EQ/NE comparison of an interface and a non-interface
With this change, we can remove some special case checks for CONVIFACE
nodes after transformation in node(), and instead just have the one
check in the CONVIFACE check.
Change-Id: I7cf2ef920aebf9e5553210aeaf19f344e128ca62
Reviewed-on: https://go-review.googlesource.com/c/go/+/336992
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/transform.go')
-rw-r--r-- | src/cmd/compile/internal/noder/transform.go | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go index 86bdb91395..f89ae13237 100644 --- a/src/cmd/compile/internal/noder/transform.go +++ b/src/cmd/compile/internal/noder/transform.go @@ -156,7 +156,7 @@ func transformCall(n *ir.CallExpr) { n.SetOp(ir.OCALLFUNC) } - typecheckaste(ir.OCALL, n.X, n.IsDDD, t.Params(), n.Args) + typecheckaste(ir.OCALL, n.X, n.IsDDD, t.Params(), n.Args, false) if l.Op() == ir.ODOTMETH && len(deref(n.X.Type().Recv().Type).RParams()) == 0 { typecheck.FixMethodCall(n) } @@ -194,7 +194,7 @@ func transformCompare(n *ir.BinaryExpr) { aop, _ := typecheck.Assignop(lt, rt) if aop != ir.OXXX { types.CalcSize(lt) - if rt.IsInterface() == lt.IsInterface() || lt.Width >= 1<<16 { + if lt.HasTParam() || rt.IsInterface() == lt.IsInterface() || lt.Width >= 1<<16 { l = ir.NewConvExpr(base.Pos, aop, rt, l) l.SetTypecheck(1) } @@ -207,7 +207,7 @@ func transformCompare(n *ir.BinaryExpr) { aop, _ := typecheck.Assignop(rt, lt) if aop != ir.OXXX { types.CalcSize(rt) - if rt.IsInterface() == lt.IsInterface() || rt.Width >= 1<<16 { + if rt.HasTParam() || rt.IsInterface() == lt.IsInterface() || rt.Width >= 1<<16 { r = ir.NewConvExpr(base.Pos, aop, lt, r) r.SetTypecheck(1) } @@ -468,8 +468,11 @@ func assignconvfn(n ir.Node, t *types.Type) ir.Node { return r } -// Corresponds to typecheck.typecheckaste. -func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl ir.Nodes) { +// Corresponds to typecheck.typecheckaste, but we add an extra flag convifaceOnly +// only. If convifaceOnly is true, we only do interface conversion. We use this to do +// early insertion of CONVIFACE nodes during noder2, when the function or args may +// have typeparams. +func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl ir.Nodes, convifaceOnly bool) { var t *types.Type var i int @@ -488,7 +491,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i if isddd { n = nl[i] ir.SetPos(n) - if n.Type() != nil { + if n.Type() != nil && (!convifaceOnly || t.IsInterface()) { nl[i] = assignconvfn(n, t) } return @@ -498,7 +501,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i for ; i < len(nl); i++ { n = nl[i] ir.SetPos(n) - if n.Type() != nil { + if n.Type() != nil && (!convifaceOnly || t.IsInterface()) { nl[i] = assignconvfn(n, t.Elem()) } } @@ -507,7 +510,7 @@ func typecheckaste(op ir.Op, call ir.Node, isddd bool, tstruct *types.Type, nl i n = nl[i] ir.SetPos(n) - if n.Type() != nil { + if n.Type() != nil && (!convifaceOnly || t.IsInterface()) { nl[i] = assignconvfn(n, t) } i++ @@ -529,7 +532,7 @@ func transformReturn(rs *ir.ReturnStmt) { return } - typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), nl) + typecheckaste(ir.ORETURN, nil, false, ir.CurFunc.Type().Results(), nl, false) } // transformSelect transforms a select node, creating an assignment list as needed |