== 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) -> ===================== == log == fun log() = Unit --------------------- Unit : Unit NEW: r(Unit) -> ===================== == outerFinallyInitializes == fun outerFinallyInitializes() { val x: Int try { myRun { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } // Definite reassignment here, cause can get here only if myRun finished x = outerComputation() } catch (e: java.lang.Exception) { // can catch exception thrown by the inner, so x can be not initialized log() } finally { // Possible reassignment (e.g. if everything finished) x = 42 } // Properly initialized x.inc() } --------------------- : {<: Exception} NEW: magic[FAKE_INITIALIZER](e: java.lang.Exception) -> { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } : {<: () -> Unit} NEW: r({ try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 }) -> myRun { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } : * NEW: call(myRun { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 }, myRun|) -> outerComputation() : Int NEW: call(outerComputation(), outerComputation) -> x = outerComputation() !: * { myRun { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } // Definite reassignment here, cause can get here only if myRun finished x = outerComputation() } !: * COPY log() : * NEW: call(log(), log) -> { // can catch exception thrown by the inner, so x can be not initialized log() } : * COPY 42 : Int NEW: r(42) -> x = 42 !: * { // Possible reassignment (e.g. if everything finished) x = 42 } !: * COPY try { myRun { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } // Definite reassignment here, cause can get here only if myRun finished x = outerComputation() } catch (e: java.lang.Exception) { // can catch exception thrown by the inner, so x can be not initialized log() } finally { // Possible reassignment (e.g. if everything finished) x = 42 } : * NEW: merge(try { myRun { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } // Definite reassignment here, cause can get here only if myRun finished x = outerComputation() } catch (e: java.lang.Exception) { // can catch exception thrown by the inner, so x can be not initialized log() } finally { // Possible reassignment (e.g. if everything finished) x = 42 }|!, ) -> x : Int NEW: r(x) -> inc() : * NEW: call(inc(), inc|) -> x.inc() : * COPY { val x: Int try { myRun { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } // Definite reassignment here, cause can get here only if myRun finished x = outerComputation() } catch (e: java.lang.Exception) { // can catch exception thrown by the inner, so x can be not initialized log() } finally { // Possible reassignment (e.g. if everything finished) x = 42 } // Properly initialized x.inc() } : * COPY ===================== == inlined anonymous_1 == { try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 } --------------------- : {<: Exception} NEW: magic[FAKE_INITIALIZER](e: java.lang.Exception) -> innerComputation() : Int NEW: call(innerComputation(), innerComputation) -> x = innerComputation() !: * { x = innerComputation() } !: * COPY log() : * NEW: call(log(), log) -> { log() } : * COPY try { x = innerComputation() } catch (e: java.lang.Exception) { log() } : * NEW: merge(try { x = innerComputation() } catch (e: java.lang.Exception) { log() }|!, ) -> 42 : Int NEW: r(42) -> x = 42 !: * try { x = innerComputation() } catch (e: java.lang.Exception) { log() } // possible reassignment if innerComputation finished x = 42 !: * COPY ===================== == innerFinalltInitializes == fun innerFinalltInitializes() { val x: Int try { myRun { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } // Properly initialized x.inc() } catch (e: java.lang.Exception) { log() } // Still can be non-initialized (e.g. if x.inc() threw an exception) x.inc() } --------------------- : {<: Exception} NEW: magic[FAKE_INITIALIZER](e: java.lang.Exception) -> { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } : {<: () -> Any} NEW: r({ try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } }) -> myRun { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } : * NEW: call(myRun { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } }, myRun|) -> x : Int NEW: r(x) -> inc() : * NEW: call(inc(), inc|) -> x.inc() : * COPY { myRun { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } // Properly initialized x.inc() } : * COPY log() : * NEW: call(log(), log) -> { log() } : * COPY try { myRun { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } // Properly initialized x.inc() } catch (e: java.lang.Exception) { log() } : * NEW: merge(try { myRun { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } // Properly initialized x.inc() } catch (e: java.lang.Exception) { log() }|, ) -> x : Int NEW: r(x) -> inc() : * NEW: call(inc(), inc|) -> x.inc() : * COPY { val x: Int try { myRun { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } // Properly initialized x.inc() } catch (e: java.lang.Exception) { log() } // Still can be non-initialized (e.g. if x.inc() threw an exception) x.inc() } : * COPY ===================== == inlined anonymous_2 == { try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } } --------------------- : {<: Exception} NEW: magic[FAKE_INITIALIZER](e: java.lang.Exception) -> innerComputation() : {<: Any} NEW: call(innerComputation(), innerComputation) -> { innerComputation() } : {<: Any} COPY log() : {<: Any} NEW: call(log(), log) -> { log() } : {<: Any} COPY 42 : Int NEW: r(42) -> x = 42 !: * { x = 42 } !: * COPY try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } : {<: Any} NEW: merge(try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 }|, ) -> try { innerComputation() } catch (e: java.lang.Exception) { log() } finally { x = 42 } : {<: Any} COPY =====================