Skip to content

Commit cfd0868

Browse files
committed
cmd/compile: fix delayTransform condition
The delayTransform only checks whether ir.CurFunc is generic function or not. but when compiling a non-generic closure inside a generic function, we also want to delay the transformation, which delayTransform fails to detect, since when ir.CurFunc is the closure, not the top level function. Instead, we must rely on irgen.topFuncIsGeneric field to decide whether to delay the transformation, the same logic with what is being done for not adding closure inside a generic function to g.target.Decls list. Fixes #48609 Change-Id: I5bf5592027d112fe8b19c92eb906add424c46507 Reviewed-on: https://go-review.googlesource.com/c/go/+/351855 Trust: Cuong Manh Le <[email protected]> Trust: Dan Scales <[email protected]> Run-TryBot: Cuong Manh Le <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Dan Scales <[email protected]>
1 parent c94543b commit cfd0868

File tree

5 files changed

+34
-16
lines changed

5 files changed

+34
-16
lines changed

src/cmd/compile/internal/noder/expr.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
168168
if index.Op() != ir.OTYPE {
169169
// This is just a normal index expression
170170
n := Index(pos, g.typ(typ), g.expr(expr.X), index)
171-
if !delayTransform() {
171+
if !g.delayTransform() {
172172
// transformIndex will modify n.Type() for OINDEXMAP.
173173
transformIndex(n)
174174
}
@@ -206,7 +206,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
206206

207207
case *syntax.SliceExpr:
208208
n := Slice(pos, g.typ(typ), g.expr(expr.X), g.expr(expr.Index[0]), g.expr(expr.Index[1]), g.expr(expr.Index[2]))
209-
if !delayTransform() {
209+
if !g.delayTransform() {
210210
transformSlice(n)
211211
}
212212
return n
@@ -218,7 +218,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
218218
switch op := g.op(expr.Op, binOps[:]); op {
219219
case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
220220
n := Compare(pos, g.typ(typ), op, g.expr(expr.X), g.expr(expr.Y))
221-
if !delayTransform() {
221+
if !g.delayTransform() {
222222
transformCompare(n)
223223
}
224224
return n
@@ -228,7 +228,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
228228
return typed(x.Type(), ir.NewLogicalExpr(pos, op, x, y))
229229
default:
230230
n := Binary(pos, op, g.typ(typ), g.expr(expr.X), g.expr(expr.Y))
231-
if op == ir.OADD && !delayTransform() {
231+
if op == ir.OADD && !g.delayTransform() {
232232
return transformAdd(n)
233233
}
234234
return n

src/cmd/compile/internal/noder/helpers.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,3 @@ func IncDec(pos src.XPos, op ir.Op, x ir.Node) *ir.AssignOpStmt {
317317
}
318318
return ir.NewAssignOpStmt(pos, op, x, bl)
319319
}
320-
321-
// delayTransform returns true if we should delay all transforms, because we are
322-
// creating the nodes for a generic function/method.
323-
func delayTransform() bool {
324-
return ir.CurFunc != nil && ir.CurFunc.Type().HasTParam()
325-
}

src/cmd/compile/internal/noder/irgen.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,9 @@ func (g *irgen) unhandled(what string, p poser) {
319319
base.FatalfAt(g.pos(p), "unhandled %s: %T", what, p)
320320
panic("unreachable")
321321
}
322+
323+
// delayTransform returns true if we should delay all transforms, because we are
324+
// creating the nodes for a generic function/method.
325+
func (g *irgen) delayTransform() bool {
326+
return g.topFuncIsGeneric
327+
}

src/cmd/compile/internal/noder/stmt.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
4040
return wrapname(g.pos(stmt.X), g.expr(stmt.X))
4141
case *syntax.SendStmt:
4242
n := ir.NewSendStmt(g.pos(stmt), g.expr(stmt.Chan), g.expr(stmt.Value))
43-
if !delayTransform() {
43+
if !g.delayTransform() {
4444
transformSend(n)
4545
}
4646
n.SetTypecheck(1)
@@ -62,7 +62,7 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
6262
lhs := g.expr(stmt.Lhs)
6363
n = ir.NewAssignOpStmt(g.pos(stmt), op, lhs, rhs)
6464
}
65-
if !delayTransform() {
65+
if !g.delayTransform() {
6666
transformAsOp(n)
6767
}
6868
n.SetTypecheck(1)
@@ -77,7 +77,7 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
7777
n := ir.NewAssignStmt(g.pos(stmt), lhs[0], rhs[0])
7878
n.Def = initDefn(n, names)
7979

80-
if !delayTransform() {
80+
if !g.delayTransform() {
8181
lhs, rhs := []ir.Node{n.X}, []ir.Node{n.Y}
8282
transformAssign(n, lhs, rhs)
8383
n.X, n.Y = lhs[0], rhs[0]
@@ -88,7 +88,7 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
8888

8989
n := ir.NewAssignListStmt(g.pos(stmt), ir.OAS2, lhs, rhs)
9090
n.Def = initDefn(n, names)
91-
if !delayTransform() {
91+
if !g.delayTransform() {
9292
transformAssign(n, n.Lhs, n.Rhs)
9393
}
9494
n.SetTypecheck(1)
@@ -100,7 +100,7 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
100100
return ir.NewGoDeferStmt(g.pos(stmt), g.tokOp(int(stmt.Tok), callOps[:]), g.expr(stmt.Call))
101101
case *syntax.ReturnStmt:
102102
n := ir.NewReturnStmt(g.pos(stmt), g.exprList(stmt.Results))
103-
if !delayTransform() {
103+
if !g.delayTransform() {
104104
transformReturn(n)
105105
}
106106
n.SetTypecheck(1)
@@ -112,7 +112,7 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
112112
case *syntax.SelectStmt:
113113
n := g.selectStmt(stmt)
114114

115-
if !delayTransform() {
115+
if !g.delayTransform() {
116116
transformSelect(n.(*ir.SelectStmt))
117117
}
118118
n.SetTypecheck(1)

test/typeparam/issue48609.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// compile -G=3
2+
3+
// Copyright 2021 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package p
8+
9+
import "constraints"
10+
11+
func f[T constraints.Chan[E], E any](e E) T {
12+
ch := make(T)
13+
go func() {
14+
defer close(ch)
15+
ch <- e
16+
}()
17+
return ch
18+
}

0 commit comments

Comments
 (0)