aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-09-02 08:47:40 -0700
committerDan Scales <danscales@google.com>2021-09-17 23:04:15 +0000
commit07b30a4f77cf89a283c45c338f0cfcb68e15aab1 (patch)
treea155c135609b9931d3507b46646ea5ffe4a89402
parentc10b98022027ce584b0571359439fae41a721dd3 (diff)
downloadgo-07b30a4f77cf89a283c45c338f0cfcb68e15aab1.tar.gz
go-07b30a4f77cf89a283c45c338f0cfcb68e15aab1.zip
cmd/compile: delay transformAssign if lhs/rhs have typeparam
This also requires that we sometimes delay transformSelect(), if the assignments in the Comm part of the select have not been transformed. Fixes #48137 Change-Id: I163aa1f999d1e63616280dca807561b12b2aa779 Reviewed-on: https://go-review.googlesource.com/c/go/+/347915 Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-rw-r--r--src/cmd/compile/internal/noder/stencil.go3
-rw-r--r--src/cmd/compile/internal/noder/stmt.go20
-rw-r--r--test/typeparam/issue48137.go25
3 files changed, 44 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
index e60383f4e0..e2525a8f7e 100644
--- a/src/cmd/compile/internal/noder/stencil.go
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -995,6 +995,9 @@ func (subst *subster) node(n ir.Node) ir.Node {
case ir.OSEND:
transformSend(m.(*ir.SendStmt))
+ case ir.OSELECT:
+ transformSelect(m.(*ir.SelectStmt))
+
}
}
diff --git a/src/cmd/compile/internal/noder/stmt.go b/src/cmd/compile/internal/noder/stmt.go
index 7f608bb91f..aefd9fcdaa 100644
--- a/src/cmd/compile/internal/noder/stmt.go
+++ b/src/cmd/compile/internal/noder/stmt.go
@@ -84,13 +84,13 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
// to know the types of the left and right sides in various cases.
delay := false
for _, e := range lhs {
- if e.Typecheck() == 3 {
+ if e.Type().HasTParam() || e.Typecheck() == 3 {
delay = true
break
}
}
for _, e := range rhs {
- if e.Typecheck() == 3 {
+ if e.Type().HasTParam() || e.Typecheck() == 3 {
delay = true
break
}
@@ -145,8 +145,20 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
return g.forStmt(stmt)
case *syntax.SelectStmt:
n := g.selectStmt(stmt)
- transformSelect(n.(*ir.SelectStmt))
- n.SetTypecheck(1)
+
+ delay := false
+ for _, ncase := range n.(*ir.SelectStmt).Cases {
+ if ncase.Comm != nil && ncase.Comm.Typecheck() == 3 {
+ delay = true
+ break
+ }
+ }
+ if delay {
+ n.SetTypecheck(3)
+ } else {
+ transformSelect(n.(*ir.SelectStmt))
+ n.SetTypecheck(1)
+ }
return n
case *syntax.SwitchStmt:
return g.switchStmt(stmt)
diff --git a/test/typeparam/issue48137.go b/test/typeparam/issue48137.go
new file mode 100644
index 0000000000..3dd7810482
--- /dev/null
+++ b/test/typeparam/issue48137.go
@@ -0,0 +1,25 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type Constraint[T any] interface {
+ ~func() T
+}
+
+func Foo[T Constraint[T]]() T {
+ var t T
+
+ t = func() T {
+ return t
+ }
+ return t
+}
+
+func main() {
+ type Bar func() Bar
+ Foo[Bar]()
+}