Scott Murphy Heiberg created GROOVY-12659:
---------------------------------------------
Summary: Closure packing packs a closure literal that escapes
through a ternary, an elvis or a curry/asWritable/clone call
Key: GROOVY-12659
URL: https://issues.apache.org/jira/browse/GROOVY-12659
Project: Groovy
Issue Type: Bug
Affects Versions: 6.0.0, 7.0.0-alpha-1
Reporter: Scott Murphy Heiberg
{code:groovy}
class Holder { Closure handler }
@groovy.transform.PackedClosures
class C {
void install(Holder h, boolean b) { h.handler = b ? { Integer x -> x + 1 }
: null }
Closure make() { return { Integer x, Integer y -> x + y }.curry(1) }
}
def h = new Holder()
new C().install(h, true)
h.handler.delegate = 'd'
new C().make().delegate = 'd'
{code}
*Actual:* both delegate assignments throw {{UnsupportedOperationException:
Cannot set a delegate on a @PackedClosures closure}}. The same happens for an
elvis and for a literal behind rcurry, ncurry, asWritable, clone, dehydrate or
rehydrate, when the result is stored to a field, property or index, appended
with {{<<}}, returned, or placed in a list or map literal.
*Expected:* the literal is declined from packing, as it is when it is itself
the stored or returned value, and the delegate can be set.
Cause: the escape walk in {{ClosureWriter.collectEscapingClosures}} marks a
literal only when it is the escaping expression itself. It does not follow the
value through ternary and elvis branches, through casts, or into the curried or
wrapped closure. CurriedClosure and the asWritable wrapper pass setDelegate on
to the packed closure, and clone, dehydrate and rehydrate return a packed copy.
Verified on 6.0.0 and master.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)