b29a6e48fb
- Introduce new language feature 'ReadDeserializedContracts', which allows to deserialize contracts from metadata. - Introduce new language feature 'AllowContractsForCustomFunctions', which allows reading contracts from sources. - Use new features instead of combination 'CallsInPlaceEffect || ReturnsEffect' - Rename 'CallsInPlaceEffect' -> 'UseCallsInPlaceEffect', 'ReturnsEffect' -> 'UseReturnsEffect'. As names suggest, they control if it is allowed to use corresponding effect in analysis. We have to introduce separate 'ReadDeserializedContracts' to enable contracts only in some modules of the project, because libraries are read with project-wide settings (see KT-20692).
45 lines
1.3 KiB
Kotlin
Vendored
45 lines
1.3 KiB
Kotlin
Vendored
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
|
|
|
import kotlin.internal.contracts.*
|
|
|
|
inline fun <T> myRun(block: () -> T): T {
|
|
contract {
|
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
|
}
|
|
return block()
|
|
}
|
|
|
|
fun innerComputation(): Int = 42
|
|
fun outerComputation(): Int = 52
|
|
|
|
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()
|
|
} |