mirror of
https://github.com/golang/go
synced 2024-11-26 21:01:31 -07:00
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:
parent
8ab7064e33
commit
f432d3fc41
@ -1295,7 +1295,7 @@ func (e *escape) newLoc(n ir.Node, transient bool) *location {
|
|||||||
if n.Op() == ir.ONAME {
|
if n.Op() == ir.ONAME {
|
||||||
n := n.(*ir.Name)
|
n := n.(*ir.Name)
|
||||||
if n.Curfn != e.curfn {
|
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 {
|
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 {
|
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)
|
return n.Canonical().Opt.(*location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
// 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.
|
// by using TFORW types and finding partially or fully created types via sym.Def.
|
||||||
func (subst *subster) typ(t *types.Type) *types.Type {
|
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
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
test/typeparam/issue45738.go
Normal file
18
test/typeparam/issue45738.go
Normal 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]()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user