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)

Reply via email to