From 006d4e627812816123a5bb86ebf5a2fa57af8b4a Mon Sep 17 00:00:00 2001 From: Dan Scales Date: Mon, 13 Dec 2021 16:15:52 -0800 Subject: 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 Reviewed-by: Keith Randall --- src/cmd/compile/internal/noder/decl.go | 24 ++++++++++++++---------- test/typeparam/issue50147.go | 11 +++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 test/typeparam/issue50147.go diff --git a/src/cmd/compile/internal/noder/decl.go b/src/cmd/compile/internal/noder/decl.go index b7fd95e2e8..df1ca1c505 100644 --- a/src/cmd/compile/internal/noder/decl.go +++ b/src/cmd/compile/internal/noder/decl.go @@ -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) } diff --git a/test/typeparam/issue50147.go b/test/typeparam/issue50147.go new file mode 100644 index 0000000000..2bdce6c504 --- /dev/null +++ b/test/typeparam/issue50147.go @@ -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 +} -- cgit v1.2.3-54-g00ecf