aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/walk
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2021-07-23 18:10:58 -0700
committerKeith Randall <khr@golang.org>2021-07-24 15:57:01 +0000
commit77e0bf294cc431d5608c183d56b6aadbb95b09b0 (patch)
tree0acfce3c498e01a17f73ce5edab40c08fdd9616f /src/cmd/compile/internal/walk
parent9f928f9318efb9e6a9d45e7ed959afaaee4b7315 (diff)
downloadgo-77e0bf294cc431d5608c183d56b6aadbb95b09b0.tar.gz
go-77e0bf294cc431d5608c183d56b6aadbb95b09b0.zip
[dev.typeparams] cmd/compile: introduce OCONVIDATA op
This operation computes just the data field needed to put its argument into an interface. Used by generics because we produce the type field of an interface using dictionaries (instead of statically). With this operation defined, we can now assert that shape types are never marked as used in interfaces (the only previous use was IDATA(CONVIFACE(t))). Change-Id: Idb1eb5f3b238285cb99413d382599c0621b7681a Reviewed-on: https://go-review.googlesource.com/c/go/+/337109 Trust: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/walk')
-rw-r--r--src/cmd/compile/internal/walk/assign.go1
-rw-r--r--src/cmd/compile/internal/walk/convert.go14
-rw-r--r--src/cmd/compile/internal/walk/expr.go7
-rw-r--r--src/cmd/compile/internal/walk/order.go10
4 files changed, 26 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/walk/assign.go b/src/cmd/compile/internal/walk/assign.go
index 6d697a53ae..d4c1aafdc1 100644
--- a/src/cmd/compile/internal/walk/assign.go
+++ b/src/cmd/compile/internal/walk/assign.go
@@ -429,6 +429,7 @@ func readsMemory(n ir.Node) bool {
ir.OBITNOT,
ir.OCONV,
ir.OCONVIFACE,
+ ir.OCONVIDATA,
ir.OCONVNOP,
ir.ODIV,
ir.ODOT,
diff --git a/src/cmd/compile/internal/walk/convert.go b/src/cmd/compile/internal/walk/convert.go
index e659ee59f1..d15575f643 100644
--- a/src/cmd/compile/internal/walk/convert.go
+++ b/src/cmd/compile/internal/walk/convert.go
@@ -39,14 +39,22 @@ func walkConv(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
return typecheck.Conv(mkcall(fn, types.Types[result], init, typecheck.Conv(n.X, types.Types[param])), n.Type())
}
-// walkConvInterface walks an OCONVIFACE node.
+// walkConvInterface walks an OCONVIFACE or OCONVIDATA node.
func walkConvInterface(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+
n.X = walkExpr(n.X, init)
fromType := n.X.Type()
toType := n.Type()
-
- if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) { // skip unnamed functions (func _())
+ if n.Op() == ir.OCONVIDATA {
+ // Just convert to empty interface, to make it easy.
+ // The caller throws away the type word.
+ toType = types.NewInterface(types.LocalPkg, nil)
+ // Note: don't pass fromType to MarkTypeUsedInInterface because it is likely
+ // a shape type. The appropriate call to MarkTypeUsedInInterface will come
+ // when building the dictionary (from which the matching type word will come).
+ } else if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) {
+ // skip unnamed functions (func _())
reflectdata.MarkTypeUsedInInterface(fromType, ir.CurFunc.LSym)
}
diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go
index eed6ef86c2..f0d37198d3 100644
--- a/src/cmd/compile/internal/walk/expr.go
+++ b/src/cmd/compile/internal/walk/expr.go
@@ -206,6 +206,13 @@ func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
n := n.(*ir.ConvExpr)
return walkConvInterface(n, init)
+ case ir.OCONVIDATA:
+ n := n.(*ir.ConvExpr)
+ r := ir.NewUnaryExpr(n.Pos(), ir.OIDATA, walkConvInterface(n, init))
+ r.SetType(types.Types[types.TUNSAFEPTR])
+ r.SetTypecheck(1)
+ return r
+
case ir.OCONV, ir.OCONVNOP:
n := n.(*ir.ConvExpr)
return walkConv(n, init)
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go
index cd2bbcb73b..fe6ae3fda0 100644
--- a/src/cmd/compile/internal/walk/order.go
+++ b/src/cmd/compile/internal/walk/order.go
@@ -1156,16 +1156,20 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
// concrete type (not interface) argument might need an addressable
// temporary to pass to the runtime conversion routine.
- case ir.OCONVIFACE:
+ case ir.OCONVIFACE, ir.OCONVIDATA:
n := n.(*ir.ConvExpr)
n.X = o.expr(n.X, nil)
if n.X.Type().IsInterface() {
return n
}
- if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
+ to := n.Type()
+ if n.Op() == ir.OCONVIDATA {
+ to = types.NewInterface(types.LocalPkg, nil)
+ }
+ if _, _, needsaddr := convFuncName(n.X.Type(), to); needsaddr || isStaticCompositeLiteral(n.X) {
// Need a temp if we need to pass the address to the conversion function.
// We also process static composite literal node here, making a named static global
- // whose address we can put directly in an interface (see OCONVIFACE case in walk).
+ // whose address we can put directly in an interface (see OCONVIFACE/OCONVIDATA case in walk).
n.X = o.addrTemp(n.X)
}
return n