cmd/compile: fix nongeneric closures in generic functions

Ensure that formal parameter Names are correctly copied and marked
with the correct Curfn. We need to ensure this even when the underlying
closure has no type parameters.

(Aside: it is strange that the types of things contain formal
parameter names that need to be copied. Maybe that's an underlying
larger problem that needs to be fixed.)

Fixes #45738

Change-Id: Ia13d69eea992ff7080bd44065115bc52eb624e73
Reviewed-on: https://go-review.googlesource.com/c/go/+/313652
Trust: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
Keith Randall 2021-04-26 14:13:19 -07:00
parent 8ab7064e33
commit f432d3fc41
3 changed files with 26 additions and 2 deletions

View file

@ -1295,7 +1295,7 @@ func (e *escape) newLoc(n ir.Node, transient bool) *location {
if n.Op() == ir.ONAME {
n := n.(*ir.Name)
if n.Curfn != e.curfn {
base.Fatalf("curfn mismatch: %v != %v", n.Curfn, e.curfn)
base.Fatalf("curfn mismatch: %v != %v for %v", n.Curfn, e.curfn, n)
}
if n.Opt != nil {
@ -1308,6 +1308,9 @@ func (e *escape) newLoc(n ir.Node, transient bool) *location {
}
func (b *batch) oldLoc(n *ir.Name) *location {
if n.Canonical().Opt == nil {
base.Fatalf("%v has no location", n)
}
return n.Canonical().Opt.(*location)
}

View file

@ -667,7 +667,10 @@ func instTypeName(name string, targs []*types.Type) string {
// result is t; otherwise the result is a new type. It deals with recursive types
// by using TFORW types and finding partially or fully created types via sym.Def.
func (subst *subster) typ(t *types.Type) *types.Type {
if !t.HasTParam() {
if !t.HasTParam() && t.Kind() != types.TFUNC {
// Note: function types need to be copied regardless, as the
// types of closures may contain declarations that need
// to be copied. See #45738.
return t
}

View file

@ -0,0 +1,18 @@
// 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 main
//go:noinline
func f[T any]() {
x := 5
g := func() int { return x }
g()
}
func main() {
f[int]()
}