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)