== myRun == inline fun myRun(block: () -> T): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() } --------------------- : {<: () -> T} NEW: magic[FAKE_INITIALIZER](block: () -> T) -> { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } : {<: ContractBuilder.() -> Unit} NEW: r({ callsInPlace(block, InvocationKind.EXACTLY_ONCE) }) -> contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } : * NEW: call(contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }, contract|) -> block : {<: () -> T} NEW: r(block) -> block() : {<: T} NEW: call(block(), invoke|) -> return block() !: * { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() } !: * COPY ===================== == anonymous_0 == { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } --------------------- : {<: ContractBuilder} NEW: magic[IMPLICIT_RECEIVER](callsInPlace(block, InvocationKind.EXACTLY_ONCE)) -> block : {<: Function} NEW: r(block) -> EXACTLY_ONCE : {<: InvocationKind} NEW: r(EXACTLY_ONCE) -> InvocationKind.EXACTLY_ONCE : {<: InvocationKind} COPY callsInPlace(block, InvocationKind.EXACTLY_ONCE) : * NEW: call(callsInPlace(block, InvocationKind.EXACTLY_ONCE), callsInPlace|, , ) -> callsInPlace(block, InvocationKind.EXACTLY_ONCE) : * COPY ===================== == innerComputation == fun innerComputation(): Int = 42 --------------------- 42 : Int NEW: r(42) -> ===================== == outerComputation == fun outerComputation(): Int = 52 --------------------- 52 : Int NEW: r(52) -> ===================== == innerTryCatchInitializes == fun innerTryCatchInitializes() { val x: Int try { myRun { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } // Can get here only when inlined lambda exited properly, i.e. x is initialized x.inc() outerComputation() } catch (e: java.lang.Exception) { // Can get here if innerComputation() threw an exception that wasn't catched by the inner catch (x is not initialized) // OR if outerComputation() threw an exception (x is initialized because we reach outer computation only when inner finished ok) // So, x=I? here x.inc() // Potential reasignment x = 42 } // Here x=I because outer try-catch either exited normally (x=I) or catched exception (x=I, with reassingment, though) x.inc() } --------------------- : {<: Exception} NEW: magic[FAKE_INITIALIZER](e: java.lang.Exception) -> { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } : {<: () -> Int} NEW: r({ try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } }) -> myRun { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } : * NEW: call(myRun { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } }, myRun|) -> x : Int NEW: r(x) -> inc() : * NEW: call(inc(), inc|) -> x.inc() : * COPY outerComputation() : * NEW: call(outerComputation(), outerComputation) -> { myRun { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } // Can get here only when inlined lambda exited properly, i.e. x is initialized x.inc() outerComputation() } : * COPY x : Int NEW: r(x) -> inc() : * NEW: call(inc(), inc|) -> x.inc() : * COPY 42 : Int NEW: r(42) -> x = 42 !: * { // Can get here if innerComputation() threw an exception that wasn't catched by the inner catch (x is not initialized) // OR if outerComputation() threw an exception (x is initialized because we reach outer computation only when inner finished ok) // So, x=I? here x.inc() // Potential reasignment x = 42 } !: * COPY try { myRun { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } // Can get here only when inlined lambda exited properly, i.e. x is initialized x.inc() outerComputation() } catch (e: java.lang.Exception) { // Can get here if innerComputation() threw an exception that wasn't catched by the inner catch (x is not initialized) // OR if outerComputation() threw an exception (x is initialized because we reach outer computation only when inner finished ok) // So, x=I? here x.inc() // Potential reasignment x = 42 } : * NEW: merge(try { myRun { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } // Can get here only when inlined lambda exited properly, i.e. x is initialized x.inc() outerComputation() } catch (e: java.lang.Exception) { // Can get here if innerComputation() threw an exception that wasn't catched by the inner catch (x is not initialized) // OR if outerComputation() threw an exception (x is initialized because we reach outer computation only when inner finished ok) // So, x=I? here x.inc() // Potential reasignment x = 42 }|, !) -> x : Int NEW: r(x) -> inc() : * NEW: call(inc(), inc|) -> x.inc() : * COPY { val x: Int try { myRun { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } // Can get here only when inlined lambda exited properly, i.e. x is initialized x.inc() outerComputation() } catch (e: java.lang.Exception) { // Can get here if innerComputation() threw an exception that wasn't catched by the inner catch (x is not initialized) // OR if outerComputation() threw an exception (x is initialized because we reach outer computation only when inner finished ok) // So, x=I? here x.inc() // Potential reasignment x = 42 } // Here x=I because outer try-catch either exited normally (x=I) or catched exception (x=I, with reassingment, though) x.inc() } : * COPY ===================== == inlined anonymous_1 == { try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } } --------------------- : {<: Exception} NEW: magic[FAKE_INITIALIZER](e: java.lang.Exception) -> innerComputation() : Int NEW: call(innerComputation(), innerComputation) -> x : Int NEW: r(x) -> inc() : Int NEW: call(inc(), inc|) -> x.inc() : Int COPY { x = innerComputation() x.inc() } : Int COPY 42 : Int NEW: r(42) -> x : Int NEW: r(x) -> inc() : Int NEW: call(inc(), inc|) -> x.inc() : Int COPY { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } : Int COPY try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } : Int NEW: merge(try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() }|, ) -> try { x = innerComputation() x.inc() } catch (e: java.lang.Exception) { /** Potential reassignment because x.inc() could threw */ x = 42 x.inc() } : Int COPY =====================