// generic F, not immediately called
closureRequired = true
}
- if n.Op() == ir.OMETHEXPR && 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
+ 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 or x.M, where T or x is generic, but not immediately
// called. Not necessary if the method selected is
// actually for an embedded interface field.
closureRequired = true
// in the infrequent case of an OFUNCINST without a corresponding
// call.
if closureRequired {
+ modified = true
var edit func(ir.Node) ir.Node
var outer *ir.Func
if f, ok := decl.(*ir.Func); ok {
outer = f
}
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)
switch {
case x.Op() == ir.OFUNCINST:
return g.buildClosure(outer, x)
- case x.Op() == ir.OMETHEXPR && len(deref(x.(*ir.SelectorExpr).X.Type()).RParams()) > 0 &&
- !types.IsInterfaceMethod(x.(*ir.SelectorExpr).Selection.Type): // TODO: test for ptr-to-method case
+ case (x.Op() == ir.OMETHEXPR || x.Op() == ir.OMETHVALUE) &&
+ len(deref(x.(*ir.SelectorExpr).X.Type()).RParams()) > 0 &&
+ !types.IsInterfaceMethod(x.(*ir.SelectorExpr).Selection.Type):
return g.buildClosure(outer, x)
}
return 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.
se := x.(*ir.SelectorExpr)
targs := deref(se.X.Type()).RParams()
if len(targs) == 0 {
panic("bad")
}
+ if x.Op() == ir.OMETHVALUE {
+ rcvrValue = se.X
+ }
// se.X.Type() is the top-level type of the method expression. To
// correctly handle method expressions involving embedded fields,
"typeparam/mdempsky/4.go", // -G=3 can't export functions with labeled breaks in loops
- "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/mdempsky/14.go", // interface comparison failure
+ "typeparam/cons.go", // causes an unreachable method
+ "typeparam/issue44688.go", // interface conversion fails due to missing method
+ "typeparam/mdempsky/14.go", // interface comparison failure
)
var unifiedFailures = setOf(