]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: delay transformAssign if lhs/rhs have typeparam
authorDan Scales <danscales@google.com>
Thu, 2 Sep 2021 15:47:40 +0000 (08:47 -0700)
committerDan Scales <danscales@google.com>
Fri, 17 Sep 2021 23:04:15 +0000 (23:04 +0000)
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>
src/cmd/compile/internal/noder/stencil.go
src/cmd/compile/internal/noder/stmt.go
test/typeparam/issue48137.go [new file with mode: 0644]

index e60383f4e01abb8fee1d465570a16a0d43dfcb25..e2525a8f7edfea671013251286050a87c8617b50 100644 (file)
@@ -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))
+
                        }
                }
 
index 7f608bb91f85438c8f1017a162e399dac15e3d2c..aefd9fcdaae9cd68fd3959a1f8dac963694cfd5a 100644 (file)
@@ -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 (file)
index 0000000..3dd7810
--- /dev/null
@@ -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]()
+}