mirror of
https://github.com/golang/go
synced 2024-11-22 20:50:05 -07:00
[dev.typeparams] Get dictionaryCapture.go working.
METHVALUE in a generic function (that is not called) was not causing buildClosure() to be called and therefore not using dictionaries. Also, had to add an extra check to make sure that if we have a FUNCINST node above a METHVALUE, we only call buildClosure once. Change-Id: I49756152fc343e5ac1c449e697960fc2a0f482ae Reviewed-on: https://go-review.googlesource.com/c/go/+/336429 Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
4e6836e82c
commit
ee20dff27d
@ -92,8 +92,8 @@ func (g *irgen) stencil() {
|
|||||||
// generic F, not immediately called
|
// generic F, not immediately called
|
||||||
closureRequired = true
|
closureRequired = true
|
||||||
}
|
}
|
||||||
if n.Op() == ir.OMETHEXPR && len(deref(n.(*ir.SelectorExpr).X.Type()).RParams()) > 0 && !types.IsInterfaceMethod(n.(*ir.SelectorExpr).Selection.Type) {
|
if (n.Op() == ir.OMETHEXPR || n.Op() == ir.OMETHVALUE) && len(deref(n.(*ir.SelectorExpr).X.Type()).RParams()) > 0 && !types.IsInterfaceMethod(n.(*ir.SelectorExpr).Selection.Type) {
|
||||||
// T.M, T a type which is generic, not immediately
|
// T.M or x.M, where T or x is generic, but not immediately
|
||||||
// called. Not necessary if the method selected is
|
// called. Not necessary if the method selected is
|
||||||
// actually for an embedded interface field.
|
// actually for an embedded interface field.
|
||||||
closureRequired = true
|
closureRequired = true
|
||||||
@ -180,18 +180,31 @@ func (g *irgen) stencil() {
|
|||||||
// in the infrequent case of an OFUNCINST without a corresponding
|
// in the infrequent case of an OFUNCINST without a corresponding
|
||||||
// call.
|
// call.
|
||||||
if closureRequired {
|
if closureRequired {
|
||||||
|
modified = true
|
||||||
var edit func(ir.Node) ir.Node
|
var edit func(ir.Node) ir.Node
|
||||||
var outer *ir.Func
|
var outer *ir.Func
|
||||||
if f, ok := decl.(*ir.Func); ok {
|
if f, ok := decl.(*ir.Func); ok {
|
||||||
outer = f
|
outer = f
|
||||||
}
|
}
|
||||||
edit = func(x ir.Node) ir.Node {
|
edit = func(x ir.Node) ir.Node {
|
||||||
|
if x.Op() == ir.OFUNCINST {
|
||||||
|
child := x.(*ir.InstExpr).X
|
||||||
|
if child.Op() == ir.OMETHEXPR || child.Op() == ir.OMETHVALUE {
|
||||||
|
// Call EditChildren on child (x.X),
|
||||||
|
// not x, so that we don't do
|
||||||
|
// buildClosure() on the
|
||||||
|
// METHEXPR/METHVALUE nodes as well.
|
||||||
|
ir.EditChildren(child, edit)
|
||||||
|
return g.buildClosure(outer, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
ir.EditChildren(x, edit)
|
ir.EditChildren(x, edit)
|
||||||
switch {
|
switch {
|
||||||
case x.Op() == ir.OFUNCINST:
|
case x.Op() == ir.OFUNCINST:
|
||||||
return g.buildClosure(outer, x)
|
return g.buildClosure(outer, x)
|
||||||
case x.Op() == ir.OMETHEXPR && len(deref(x.(*ir.SelectorExpr).X.Type()).RParams()) > 0 &&
|
case (x.Op() == ir.OMETHEXPR || x.Op() == ir.OMETHVALUE) &&
|
||||||
!types.IsInterfaceMethod(x.(*ir.SelectorExpr).Selection.Type): // TODO: test for ptr-to-method case
|
len(deref(x.(*ir.SelectorExpr).X.Type()).RParams()) > 0 &&
|
||||||
|
!types.IsInterfaceMethod(x.(*ir.SelectorExpr).Selection.Type):
|
||||||
return g.buildClosure(outer, x)
|
return g.buildClosure(outer, x)
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
@ -264,13 +277,16 @@ func (g *irgen) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
|
|||||||
fmt.Printf("%s in %v for generic method value %v\n", dictkind, outer, inst.X)
|
fmt.Printf("%s in %v for generic method value %v\n", dictkind, outer, inst.X)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // ir.OMETHEXPR
|
} else { // ir.OMETHEXPR or ir.METHVALUE
|
||||||
// Method expression T.M where T is a generic type.
|
// Method expression T.M where T is a generic type.
|
||||||
se := x.(*ir.SelectorExpr)
|
se := x.(*ir.SelectorExpr)
|
||||||
targs := deref(se.X.Type()).RParams()
|
targs := deref(se.X.Type()).RParams()
|
||||||
if len(targs) == 0 {
|
if len(targs) == 0 {
|
||||||
panic("bad")
|
panic("bad")
|
||||||
}
|
}
|
||||||
|
if x.Op() == ir.OMETHVALUE {
|
||||||
|
rcvrValue = se.X
|
||||||
|
}
|
||||||
|
|
||||||
// se.X.Type() is the top-level type of the method expression. To
|
// se.X.Type() is the top-level type of the method expression. To
|
||||||
// correctly handle method expressions involving embedded fields,
|
// correctly handle method expressions involving embedded fields,
|
||||||
|
@ -2174,10 +2174,9 @@ var g3Failures = setOf(
|
|||||||
|
|
||||||
"typeparam/mdempsky/4.go", // -G=3 can't export functions with labeled breaks in loops
|
"typeparam/mdempsky/4.go", // -G=3 can't export functions with labeled breaks in loops
|
||||||
|
|
||||||
"typeparam/cons.go", // causes an unreachable method
|
"typeparam/cons.go", // causes an unreachable method
|
||||||
"typeparam/dictionaryCapture.go", // segv, dictionary access failure?
|
"typeparam/issue44688.go", // interface conversion fails due to missing method
|
||||||
"typeparam/issue44688.go", // interface conversion fails due to missing method
|
"typeparam/mdempsky/14.go", // interface comparison failure
|
||||||
"typeparam/mdempsky/14.go", // interface comparison failure
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var unifiedFailures = setOf(
|
var unifiedFailures = setOf(
|
||||||
|
Loading…
Reference in New Issue
Block a user