Scott Murphy Heiberg created GROOVY-12656:
---------------------------------------------

             Summary: Closure packing packs a closure literal composed with >> 
or << whose composition escapes
                 Key: GROOVY-12656
                 URL: https://issues.apache.org/jira/browse/GROOVY-12656
             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, Closure c) { h.handler = c >> { x -> x + 1 } }
    Closure make(Closure c) { return { x -> x + 1 } << c }
}

def h = new Holder()
new C().install(h, { x -> x * 2 })
h.handler.delegate = 'd'
def r = new C().make({ x -> x * 2 })
r.delegate = 'd'
{code}

*Actual:* both delegate assignments throw 
{{java.lang.UnsupportedOperationException: Cannot set a delegate on a 
@PackedClosures closure (hoisted method '$packed$closure$0') ...}}. The same 
happens with {{-Dgroovy.target.closure.pack=true}} and under {{@TypeChecked}} 
and {{@CompileStatic}}.

*Expected:* the closure literal is declined from packing, as it is when stored 
or returned directly, and setting a delegate works as it does without packing.

Cause: the compile-time escape walk in 
{{ClosureWriter.collectEscapingClosures}} marks only a literal that is itself 
the stored, appended or returned value. Composition builds a ComposedClosure 
that keeps a clone of the literal (the clone of a packed closure is still 
packed) and passes setDelegate on to it, so the literal escapes along with the 
composition.

Verified on 6.0.0 and master.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to