1
0
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:
Dan Scales 2021-07-18 11:09:12 -07:00
parent 4e6836e82c
commit ee20dff27d
2 changed files with 24 additions and 9 deletions

View File

@ -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,

View File

@ -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(