cmd/compile: allow importing and exporting of ODYNAMICTYPE
Change-Id: I2fca7a801c85ed93c002c23bfcb0cf9593f1bdf4
Reviewed-on: https://go-review.googlesource.com/c/go/+/356571
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>
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go
index e3dd10a..46865ba 100644
--- a/src/cmd/compile/internal/typecheck/iexport.go
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -1763,6 +1763,19 @@
w.op(ir.OTYPE)
w.typ(n.Type())
+ case ir.ODYNAMICTYPE:
+ n := n.(*ir.DynamicType)
+ w.op(ir.ODYNAMICTYPE)
+ w.pos(n.Pos())
+ w.expr(n.X)
+ if n.ITab != nil {
+ w.bool(true)
+ w.expr(n.ITab)
+ } else {
+ w.bool(false)
+ }
+ w.typ(n.Type())
+
case ir.OTYPESW:
n := n.(*ir.TypeSwitchGuard)
w.op(ir.OTYPESW)
diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go
index 6351fc3..cb1e56b 100644
--- a/src/cmd/compile/internal/typecheck/iimport.go
+++ b/src/cmd/compile/internal/typecheck/iimport.go
@@ -1312,6 +1312,14 @@
case ir.OTYPE:
return ir.TypeNode(r.typ())
+ case ir.ODYNAMICTYPE:
+ n := ir.NewDynamicType(r.pos(), r.expr())
+ if r.bool() {
+ n.ITab = r.expr()
+ }
+ n.SetType(r.typ())
+ return n
+
case ir.OTYPESW:
pos := r.pos()
var tag *ir.Ident
diff --git a/test/typeparam/issue49027.dir/a.go b/test/typeparam/issue49027.dir/a.go
index d3ec27d..da88297 100644
--- a/test/typeparam/issue49027.dir/a.go
+++ b/test/typeparam/issue49027.dir/a.go
@@ -15,7 +15,41 @@
func Conv2(v interface{}) (string, bool) {
return conv2[string](v)
}
+
func conv2[T any](v interface{}) (T, bool) {
x, ok := v.(T)
return x, ok
}
+
+func Conv3(v interface{}) string {
+ return conv3[string](v)
+}
+
+func conv3[T any](v interface{}) T {
+ switch v := v.(type) {
+ case T:
+ return v
+ default:
+ var z T
+ return z
+ }
+}
+
+type Mystring string
+
+func (Mystring) Foo() {
+}
+
+func Conv4(v interface{Foo()}) Mystring {
+ return conv4[Mystring](v)
+}
+
+func conv4[T interface{Foo()}](v interface{Foo()}) T {
+ switch v := v.(type) {
+ case T:
+ return v
+ default:
+ var z T
+ return z
+ }
+}
diff --git a/test/typeparam/issue49027.dir/main.go b/test/typeparam/issue49027.dir/main.go
index d0dc33d..aa20a2f 100644
--- a/test/typeparam/issue49027.dir/main.go
+++ b/test/typeparam/issue49027.dir/main.go
@@ -22,4 +22,12 @@
if y != s {
panic(fmt.Sprintf("got %s wanted %s", y, s))
}
+ z := a.Conv3(s)
+ if z != s {
+ panic(fmt.Sprintf("got %s wanted %s", z, s))
+ }
+ w := a.Conv4(a.Mystring(s))
+ if w != a.Mystring(s) {
+ panic(fmt.Sprintf("got %s wanted %s", w, s))
+ }
}