mirror of
https://github.com/golang/go
synced 2024-11-17 14:04:48 -07:00
cmd/compile: fix implement for closure in a global assignment
If closure in a global assignment and has a method receiver. We should assign receiver as a global variable, not a local variable. Fixes #48225 Change-Id: I8f65dd6e8baf66a5eff24028d28ad0a594091add Reviewed-on: https://go-review.googlesource.com/c/go/+/348512 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com> Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com>
This commit is contained in:
parent
2c4f389c02
commit
c981874a5a
@ -396,13 +396,19 @@ func (g *irgen) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
|
|||||||
if rcvrValue != nil {
|
if rcvrValue != nil {
|
||||||
rcvrVar = ir.NewNameAt(pos, typecheck.LookupNum(".rcvr", g.dnum))
|
rcvrVar = ir.NewNameAt(pos, typecheck.LookupNum(".rcvr", g.dnum))
|
||||||
g.dnum++
|
g.dnum++
|
||||||
rcvrVar.Class = ir.PAUTO
|
|
||||||
typed(rcvrValue.Type(), rcvrVar)
|
typed(rcvrValue.Type(), rcvrVar)
|
||||||
rcvrVar.Curfn = outer
|
|
||||||
rcvrAssign = ir.NewAssignStmt(pos, rcvrVar, rcvrValue)
|
rcvrAssign = ir.NewAssignStmt(pos, rcvrVar, rcvrValue)
|
||||||
rcvrAssign.SetTypecheck(1)
|
rcvrAssign.SetTypecheck(1)
|
||||||
rcvrVar.Defn = rcvrAssign
|
rcvrVar.Defn = rcvrAssign
|
||||||
outer.Dcl = append(outer.Dcl, rcvrVar)
|
if outer == nil {
|
||||||
|
rcvrVar.Class = ir.PEXTERN
|
||||||
|
g.target.Decls = append(g.target.Decls, rcvrAssign)
|
||||||
|
g.target.Externs = append(g.target.Externs, rcvrVar)
|
||||||
|
} else {
|
||||||
|
rcvrVar.Class = ir.PAUTO
|
||||||
|
rcvrVar.Curfn = outer
|
||||||
|
outer.Dcl = append(outer.Dcl, rcvrVar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build body of closure. This involves just calling the wrapped function directly
|
// Build body of closure. This involves just calling the wrapped function directly
|
||||||
|
37
test/typeparam/issue48225.go
Normal file
37
test/typeparam/issue48225.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// run -gcflags="-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
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
type Foo[T any] struct {
|
||||||
|
val int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (foo Foo[T]) Get() *T {
|
||||||
|
if foo.val != 1 {
|
||||||
|
panic("bad val field in Foo receiver")
|
||||||
|
}
|
||||||
|
return new(T)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
newInt = Foo[int]{val: 1}.Get
|
||||||
|
newString = Foo[string]{val: 1}.Get
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
i := newInt()
|
||||||
|
s := newString()
|
||||||
|
|
||||||
|
if t := reflect.TypeOf(i).String(); t != "*int" {
|
||||||
|
panic(t)
|
||||||
|
}
|
||||||
|
if t := reflect.TypeOf(s).String(); t != "*string" {
|
||||||
|
panic(t)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user