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>
This commit is contained in:
Dan Scales 2021-09-02 08:47:40 -07:00
parent c10b980220
commit 07b30a4f77
3 changed files with 44 additions and 4 deletions

View 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))
}
}

View 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)

View file

@ -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]()
}