1
0
mirror of https://github.com/golang/go synced 2024-11-11 19:31:37 -07:00

cmd/compile: fix case where we didn't delay transformAssign in varDecl

We delay all transformations on generic functions, and only do them on
instantiated functions, for several reasons, of which one is that
otherwise the compiler won't understand the relationship between
constrained type parameters. In an instantiation with shape arguments,
the underlying relationship between the type arguments are clear and
don't lead to compiler errors.

This issue is because I missed delaying assignment transformations for
variable declarations. So, we were trying to transform an assignment,
and the compiler doesn't understand the relationship between the T and U
type parameters.

The fix is to delay assignment transformations for variable declarations
of generic functions, just as we do already for normal assignment
statements.

A work-around for this issue would be to just separate the assignment
from the variable declaration in the generic function (for this case of
an assignment involving both of the constrained type parameters).

Fixes #50147

Change-Id: Icdbcda147e5c4b386e4715811761cbe73d0d837e
Reviewed-on: https://go-review.googlesource.com/c/go/+/371534
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Dan Scales 2021-12-13 16:15:52 -08:00
parent 5b9207ff67
commit 006d4e6278
2 changed files with 25 additions and 10 deletions

View File

@ -286,22 +286,26 @@ func (g *irgen) varDecl(out *ir.Nodes, decl *syntax.VarDecl) {
} else if ir.CurFunc == nil {
name.Defn = as
}
lhs := []ir.Node{as.X}
rhs := []ir.Node{}
if as.Y != nil {
rhs = []ir.Node{as.Y}
}
transformAssign(as, lhs, rhs)
as.X = lhs[0]
if as.Y != nil {
as.Y = rhs[0]
if !g.delayTransform() {
lhs := []ir.Node{as.X}
rhs := []ir.Node{}
if as.Y != nil {
rhs = []ir.Node{as.Y}
}
transformAssign(as, lhs, rhs)
as.X = lhs[0]
if as.Y != nil {
as.Y = rhs[0]
}
}
as.SetTypecheck(1)
out.Append(as)
}
}
if as2 != nil {
transformAssign(as2, as2.Lhs, as2.Rhs)
if !g.delayTransform() {
transformAssign(as2, as2.Lhs, as2.Rhs)
}
as2.SetTypecheck(1)
out.Append(as2)
}

View File

@ -0,0 +1,11 @@
// compile -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 p
func Foo[T any, U interface{ *T }](x T) {
var _ U = &x
}