Effects: add diagnostic tests on contracts
- Make AbstractDiagnosticsTest dump function contracts - Add diagnostics tests on parsing contracts - Add diagnostics tests on smartcats in presence of functions with contracts - Add diagnostics tests on initialization and flow in presence of in-place called lambdas ========== Introduction of EffectSystem: 16/18
This commit is contained in:
+50
@@ -0,0 +1,50 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBoolean(): Boolean = false
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
if (getBoolean())
|
||||||
|
myRun {
|
||||||
|
while (getBoolean()) {
|
||||||
|
do {
|
||||||
|
myRun {
|
||||||
|
if (getBoolean()) {
|
||||||
|
x = 42 // No reassignment because of break
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = 43 // No reassignment because of break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
} while (<!UNREACHABLE_CODE!>getBoolean()<!>)
|
||||||
|
// Loop executed exectly once, initializing x
|
||||||
|
myRun { x.inc() }
|
||||||
|
|
||||||
|
myRun { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// x is I?D here because loop could've been execited
|
||||||
|
// VAL_REASSIGNMENT isn't reported because of repeating diagnostic
|
||||||
|
x = 42
|
||||||
|
// x is ID now
|
||||||
|
}
|
||||||
|
else
|
||||||
|
myRun {
|
||||||
|
x = 42
|
||||||
|
}
|
||||||
|
// x is ID because both branches are ID
|
||||||
|
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun getBoolean(): kotlin.Boolean
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
== myRun ==
|
||||||
|
fun <T> myRun(@CalledInPlace block: () -> T): T = block()
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(@CalledInPlace block: () -> T) INIT: in: {} out: {block=D}
|
||||||
|
magic[FAKE_INITIALIZER](@CalledInPlace block: () -> T) -> <v0> INIT: in: {block=D} out: {block=D}
|
||||||
|
w(block|<v0>) INIT: in: {block=D} out: {block=ID} USE: in: {block=READ} out: {block=READ}
|
||||||
|
r(block) -> <v1> INIT: in: {block=ID} out: {block=ID} USE: in: {} out: {block=READ}
|
||||||
|
mark(block())
|
||||||
|
call(block(), invoke|<v1>) -> <v2>
|
||||||
|
ret(*|<v2>) L1
|
||||||
|
L1:
|
||||||
|
<END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {block=I?} out: {block=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== functionWithExpressionBody ==
|
||||||
|
fun functionWithExpressionBody(x: Int) = myRun {
|
||||||
|
if (x == 0) return true
|
||||||
|
if (x == 1) return false
|
||||||
|
return functionWithExpressionBody(x - 2)
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L0:
|
||||||
|
1 <START> INIT: in: {} out: {}
|
||||||
|
v(x: Int) INIT: in: {} out: {x=D}
|
||||||
|
magic[FAKE_INITIALIZER](x: Int) -> <v0> INIT: in: {x=D} out: {x=D}
|
||||||
|
w(x|<v0>) INIT: in: {x=D} out: {x=ID}
|
||||||
|
mark({ if (x == 0) return true if (x == 1) return false return functionWithExpressionBody(x - 2) }) INIT: in: {x=ID} out: {x=ID}
|
||||||
|
jmp?(L2)
|
||||||
|
d({ if (x == 0) return true if (x == 1) return false return functionWithExpressionBody(x - 2) }) INIT: in: {} out: {} USE: in: {x=READ} out: {x=READ}
|
||||||
|
L2 [after local declaration]:
|
||||||
|
r({ if (x == 0) return true if (x == 1) return false return functionWithExpressionBody(x - 2) }) -> <v1> INIT: in: {x=ID} out: {x=ID}
|
||||||
|
mark(myRun { if (x == 0) return true if (x == 1) return false return functionWithExpressionBody(x - 2) })
|
||||||
|
call(myRun { if (x == 0) return true if (x == 1) return false return functionWithExpressionBody(x - 2) }, myRun|<v1>) -> <v2>
|
||||||
|
ret(*|<v2>) L1
|
||||||
|
L1:
|
||||||
|
<END>
|
||||||
|
error:
|
||||||
|
<ERROR> INIT: in: {} out: {}
|
||||||
|
sink:
|
||||||
|
<SINK> INIT: in: {x=I?} out: {x=I?} USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
|
== anonymous_0 ==
|
||||||
|
{
|
||||||
|
if (x == 0) return true
|
||||||
|
if (x == 1) return false
|
||||||
|
return functionWithExpressionBody(x - 2)
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
L3:
|
||||||
|
2 <START> INIT: in: {x=ID} out: {x=ID}
|
||||||
|
3 mark(if (x == 0) return true if (x == 1) return false return functionWithExpressionBody(x - 2))
|
||||||
|
mark(if (x == 0) return true)
|
||||||
|
r(x) -> <v0>
|
||||||
|
r(0) -> <v1>
|
||||||
|
mark(x == 0)
|
||||||
|
call(x == 0, equals|<v0>, <v1>) -> <v2>
|
||||||
|
jf(L5|<v2>) USE: in: {x=READ} out: {x=READ}
|
||||||
|
r(true) -> <v3>
|
||||||
|
ret(*|<v3>) L1 USE: in: {} out: {}
|
||||||
|
- jmp(L6)
|
||||||
|
L5 [else branch]:
|
||||||
|
read (Unit) INIT: in: {x=ID} out: {x=ID}
|
||||||
|
L6 ['if' expression result]:
|
||||||
|
merge(if (x == 0) return true|!<v4>) -> <v5>
|
||||||
|
mark(if (x == 1) return false)
|
||||||
|
r(x) -> <v6>
|
||||||
|
r(1) -> <v7>
|
||||||
|
mark(x == 1)
|
||||||
|
call(x == 1, equals|<v6>, <v7>) -> <v8>
|
||||||
|
jf(L7|<v8>) USE: in: {x=READ} out: {x=READ}
|
||||||
|
r(false) -> <v9>
|
||||||
|
ret(*|<v9>) L1 USE: in: {} out: {}
|
||||||
|
- jmp(L8)
|
||||||
|
L7 [else branch]:
|
||||||
|
read (Unit) INIT: in: {x=ID} out: {x=ID}
|
||||||
|
L8 ['if' expression result]:
|
||||||
|
merge(if (x == 1) return false|!<v10>) -> <v11> USE: in: {x=READ} out: {x=READ}
|
||||||
|
r(x) -> <v12> USE: in: {} out: {x=READ}
|
||||||
|
r(2) -> <v13>
|
||||||
|
mark(x - 2)
|
||||||
|
call(x - 2, minus|<v12>, <v13>) -> <v14>
|
||||||
|
mark(functionWithExpressionBody(x - 2))
|
||||||
|
call(functionWithExpressionBody(x - 2), functionWithExpressionBody|<v14>) -> <v15>
|
||||||
|
ret(*|<v15>) L1 USE: in: {} out: {}
|
||||||
|
- 2 ret(*|!<v16>) L4
|
||||||
|
L4:
|
||||||
|
<END> INIT: in: {} out: {}
|
||||||
|
error:
|
||||||
|
<ERROR>
|
||||||
|
sink:
|
||||||
|
<SINK> USE: in: {} out: {}
|
||||||
|
=====================
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun functionWithExpressionBody(x: Int): Boolean = myRun {
|
||||||
|
if (x == 0) return true
|
||||||
|
if (x == 1) return false
|
||||||
|
return functionWithExpressionBody(x - 2)
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun functionWithExpressionBody(/*0*/ x: kotlin.Int): kotlin.Boolean
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun functionWithSideEffects(x: Int): Int = x + 1 // ...and some other useful side-effects
|
||||||
|
|
||||||
|
fun log(<!UNUSED_PARAMETER!>s<!>: String) = Unit // some logging or println or whatever returning Unit
|
||||||
|
|
||||||
|
fun implicitCastWithIf(s: String) {
|
||||||
|
myRun { if (s == "") functionWithSideEffects(42) else log(s) }
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun functionWithSideEffects(/*0*/ x: kotlin.Int): kotlin.Int
|
||||||
|
public fun implicitCastWithIf(/*0*/ s: kotlin.String): kotlin.Unit
|
||||||
|
public fun log(/*0*/ s: kotlin.String): kotlin.Unit
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun myRun(block: () -> Unit): Unit {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
myRun { throw java.lang.IllegalArgumentException() }
|
||||||
|
<!UNREACHABLE_CODE!>val x: Int = 42<!>
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public inline fun myRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun myRun(block: () -> Unit): Unit {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun unknownRun(block: () -> Unit) { block() }
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
val x: Int
|
||||||
|
myRun {
|
||||||
|
unknownRun { println("shouldn't change anything") }
|
||||||
|
x = 42
|
||||||
|
}
|
||||||
|
println(x)
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(): kotlin.Unit
|
||||||
|
public inline fun myRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public inline fun unknownRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
Vendored
+85
@@ -0,0 +1,85 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T, R> T.myLet(block: (T) -> R): R {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun unknownRun(block: () -> Unit) = block()
|
||||||
|
|
||||||
|
fun getBool(): Boolean = false
|
||||||
|
|
||||||
|
fun threeLevelsReturnNoInitialization(x: Int?): Int? {
|
||||||
|
// Inner always jumps to outer
|
||||||
|
// And middle always calls inner
|
||||||
|
// So, in fact, middle never finished normally
|
||||||
|
// Hence 'y = 54' in middle is unreachable, and middle doesn't performs definite initalization
|
||||||
|
// Hence, outer doesn't performs definite initialization
|
||||||
|
val y: Int
|
||||||
|
myRun outer@ {
|
||||||
|
myRun middle@ {
|
||||||
|
x.myLet inner@ {
|
||||||
|
if (it == null) {
|
||||||
|
y = 42
|
||||||
|
return@outer Unit
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return@outer Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Possible to report unreachable here
|
||||||
|
<!UNREACHABLE_CODE!>y = 54<!>
|
||||||
|
}
|
||||||
|
return <!UNINITIALIZED_VARIABLE!>y<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun threeLevelsReturnWithInitialization(x: Int?): Int? {
|
||||||
|
val y: Int
|
||||||
|
myRun outer@ {
|
||||||
|
myRun middle@ {
|
||||||
|
x.myLet inner@ {
|
||||||
|
if (it == null) {
|
||||||
|
y = 42
|
||||||
|
return@outer Unit
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
y = 34
|
||||||
|
return@outer Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return y.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun threeLevelsReturnWithUnknown(x: Int?): Int? {
|
||||||
|
val y: Int
|
||||||
|
myRun outer@ {
|
||||||
|
unknownRun middle@ {
|
||||||
|
x.myLet inner@ {
|
||||||
|
if (it == null) {
|
||||||
|
<!CAPTURED_VAL_INITIALIZATION!>y<!> = 42
|
||||||
|
return@outer Unit
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
y = 34
|
||||||
|
return@outer Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return <!UNINITIALIZED_VARIABLE!>y<!>.inc()
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun getBool(): kotlin.Boolean
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun threeLevelsReturnNoInitialization(/*0*/ x: kotlin.Int?): kotlin.Int?
|
||||||
|
public fun threeLevelsReturnWithInitialization(/*0*/ x: kotlin.Int?): kotlin.Int?
|
||||||
|
public fun threeLevelsReturnWithUnknown(/*0*/ x: kotlin.Int?): kotlin.Int?
|
||||||
|
public inline fun unknownRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public inline fun </*0*/ T, /*1*/ R> T.myLet(/*0*/ block: (T) -> R): R
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -INVISIBLE_MEMBER -INVISIBLE_REFERENCE
|
||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
|
||||||
|
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 log() = Unit
|
||||||
|
|
||||||
|
fun outerFinallyInitializes() {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
try {
|
||||||
|
myRun {
|
||||||
|
try {
|
||||||
|
x = innerComputation()
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
log()
|
||||||
|
}
|
||||||
|
// possible reassignment if innerComputation finished
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = 42
|
||||||
|
// x is ID here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Definite reassignment here, cause can get here only if myRun finished
|
||||||
|
// Not reported because of repeating diagnostic
|
||||||
|
x = outerComputation()
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
// can catch exception thrown by the inner, so x can be not initalized
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
log()
|
||||||
|
} finally {
|
||||||
|
// Possible reassignment (e.g. if everything finished)
|
||||||
|
// Not reported because of repeating diagnostic
|
||||||
|
x = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
// Properly initialized
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun innerFinallyInitializes() {
|
||||||
|
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 unitialized because we don't know what can happen in try-block
|
||||||
|
// (e.g., OutOfMemory exception could've happened even before myRun was executed)
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun innerFinallyInitializesOuterRethrows() {
|
||||||
|
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()
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guaranteed to be initialized because all catch-clauses are rethrowing
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun innerComputation(): kotlin.Int
|
||||||
|
public fun innerFinallyInitializes(): kotlin.Unit
|
||||||
|
public fun innerFinallyInitializesOuterRethrows(): kotlin.Unit
|
||||||
|
public fun log(): kotlin.Unit
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun outerComputation(): kotlin.Int
|
||||||
|
public fun outerFinallyInitializes(): kotlin.Unit
|
||||||
Vendored
+46
@@ -0,0 +1,46 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
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
|
||||||
|
<!VAL_REASSIGNMENT!>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
|
||||||
|
<!UNINITIALIZED_VARIABLE!>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()
|
||||||
|
}
|
||||||
compiler/testData/diagnostics/testsWithStdLib/contracts/controlflow/flowInlining/nestedTryCatchs.txt
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun innerComputation(): kotlin.Int
|
||||||
|
public fun innerTryCatchInitializes(): kotlin.Unit
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun outerComputation(): kotlin.Int
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun <T, R> T.myLet(block: (T) -> R): R {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun nonLocalReturnWithElvis(x: Int?): Int? {
|
||||||
|
x?.myLet { return 42 }
|
||||||
|
return x?.inc()
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun nonLocalReturnWithElvis(/*0*/ x: kotlin.Int?): kotlin.Int?
|
||||||
|
public inline fun </*0*/ T, /*1*/ R> T.myLet(/*0*/ block: (T) -> R): R
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun myRun(block: () -> Unit): Unit {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBool(): Boolean = false
|
||||||
|
|
||||||
|
fun withLabeledReturn() {
|
||||||
|
val y: Int
|
||||||
|
|
||||||
|
val x = myRun outer@ {
|
||||||
|
myRun { return@outer Unit }
|
||||||
|
<!UNREACHABLE_CODE!>y = 42<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
println(<!UNINITIALIZED_VARIABLE!>y<!>)
|
||||||
|
println(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withLabeledReturn2(y: Int) {
|
||||||
|
myRun outer@ {
|
||||||
|
myRun { return@outer Unit }
|
||||||
|
<!UNREACHABLE_CODE!>println(y)<!>
|
||||||
|
}
|
||||||
|
println(y)
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun getBool(): kotlin.Boolean
|
||||||
|
public inline fun myRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun withLabeledReturn(): kotlin.Unit
|
||||||
|
public fun withLabeledReturn2(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||||
+78
@@ -0,0 +1,78 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun exitOnlyThroughLocalReturns(b: Boolean) {
|
||||||
|
var x: Int
|
||||||
|
var s: String
|
||||||
|
|
||||||
|
myRun {
|
||||||
|
if (b) {
|
||||||
|
x = 42
|
||||||
|
return@myRun
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!b) {
|
||||||
|
s = "hello"
|
||||||
|
x = 42
|
||||||
|
return@myRun
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s = "world"
|
||||||
|
x = 239
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x.inc()
|
||||||
|
<!UNINITIALIZED_VARIABLE!>s<!>.length
|
||||||
|
}
|
||||||
|
|
||||||
|
fun exitOnlyThroughNonLocalReturns(b: Boolean?) {
|
||||||
|
var x: Int
|
||||||
|
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>s<!>: String
|
||||||
|
myRun {
|
||||||
|
if (b == null) {
|
||||||
|
x = 42
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (<!DEBUG_INFO_SMARTCAST!>b<!>.not()) {
|
||||||
|
x = 54
|
||||||
|
}
|
||||||
|
|
||||||
|
if (<!UNINITIALIZED_VARIABLE!>x<!> == 42) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = 42
|
||||||
|
s = "hello"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<!UNREACHABLE_CODE!>x.inc()<!>
|
||||||
|
<!UNREACHABLE_CODE!>s.length<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nonLocalReturnAndOrdinaryExit(b: Boolean) {
|
||||||
|
var x: Int
|
||||||
|
var s: String
|
||||||
|
myRun {
|
||||||
|
if (b) {
|
||||||
|
x = 42
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x = 54
|
||||||
|
s = "hello"
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
s.length
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun exitOnlyThroughLocalReturns(/*0*/ b: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun exitOnlyThroughNonLocalReturns(/*0*/ b: kotlin.Boolean?): kotlin.Unit
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun nonLocalReturnAndOrdinaryExit(/*0*/ b: kotlin.Boolean): kotlin.Unit
|
||||||
compiler/testData/diagnostics/testsWithStdLib/contracts/controlflow/flowInlining/throwIfNotCalled.kt
Vendored
+47
@@ -0,0 +1,47 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun myRun(block: () -> Unit) {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> unknownRun(block: () -> T): T = block()
|
||||||
|
|
||||||
|
fun throwIfNotCalled() {
|
||||||
|
val x: Int
|
||||||
|
myRun outer@ {
|
||||||
|
unknownRun {
|
||||||
|
myRun {
|
||||||
|
<!CAPTURED_VAL_INITIALIZATION!>x<!> = 42
|
||||||
|
return@outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw java.lang.IllegalArgumentException()
|
||||||
|
}
|
||||||
|
// x *is* initialized here, because if myRun was never called -> exception
|
||||||
|
// were thrown and control flow wouldn't be here
|
||||||
|
println(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun catchThrowIfNotCalled() {
|
||||||
|
val x: Int
|
||||||
|
try {
|
||||||
|
myRun outer@ {
|
||||||
|
unknownRun {
|
||||||
|
myRun {
|
||||||
|
<!CAPTURED_VAL_INITIALIZATION!>x<!> = 42
|
||||||
|
return@outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw java.lang.IllegalArgumentException()
|
||||||
|
}
|
||||||
|
} catch (ignored: java.lang.IllegalArgumentException) { }
|
||||||
|
|
||||||
|
// x *isn't* initialized here!
|
||||||
|
println(<!UNINITIALIZED_VARIABLE!>x<!>)
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun catchThrowIfNotCalled(): kotlin.Unit
|
||||||
|
public inline fun myRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun throwIfNotCalled(): kotlin.Unit
|
||||||
|
public inline fun </*0*/ T> unknownRun(/*0*/ block: () -> T): T
|
||||||
Vendored
+57
@@ -0,0 +1,57 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun someComputation(): Int = 42
|
||||||
|
|
||||||
|
fun tryCatchInlined() {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
myRun {
|
||||||
|
try {
|
||||||
|
x = someComputation()
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
catch (e: java.lang.Exception) {
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = 42
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun possibleReassignmentInTryCatch() {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
myRun {
|
||||||
|
try {
|
||||||
|
x = someComputation()
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
catch (e: java.lang.Exception) {
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = 42
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tryCatchOuter() {
|
||||||
|
val x: Int
|
||||||
|
try {
|
||||||
|
myRun { x = someComputation() }
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
catch (e: java.lang.Exception) {
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun possibleReassignmentInTryCatch(): kotlin.Unit
|
||||||
|
public fun someComputation(): kotlin.Int
|
||||||
|
public fun tryCatchInlined(): kotlin.Unit
|
||||||
|
public fun tryCatchOuter(): kotlin.Unit
|
||||||
Vendored
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun someComputation(): Int = 42
|
||||||
|
|
||||||
|
fun report(x: Int) = Unit
|
||||||
|
|
||||||
|
fun innerTryCatchFinally() {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
myRun {
|
||||||
|
try {
|
||||||
|
x = someComputation()
|
||||||
|
report(x)
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = 42
|
||||||
|
report(x)
|
||||||
|
} finally {
|
||||||
|
x = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
compiler/testData/diagnostics/testsWithStdLib/contracts/controlflow/flowInlining/tryCatchFinally.txt
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun innerTryCatchFinally(): kotlin.Unit
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun report(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||||
|
public fun someComputation(): kotlin.Int
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(x: Int): Int = x + 1
|
||||||
|
|
||||||
|
fun typeMismatchInLambda(y: String): Int {
|
||||||
|
val x = myRun { foo(<!TYPE_MISMATCH!>y<!>) }
|
||||||
|
return x
|
||||||
|
}
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ x: kotlin.Int): kotlin.Int
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun typeMismatchInLambda(/*0*/ y: kotlin.String): kotlin.Int
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
inline fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun throwInLambda(): Int {
|
||||||
|
<!UNREACHABLE_CODE!>val <!UNUSED_VARIABLE!>x<!> =<!> myRun { throw java.lang.IllegalArgumentException(); <!UNREACHABLE_CODE!>42<!> }
|
||||||
|
<!UNREACHABLE_CODE!>return x<!>
|
||||||
|
}
|
||||||
compiler/testData/diagnostics/testsWithStdLib/contracts/controlflow/flowInlining/unreachableCode.txt
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public inline fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun throwInLambda(): kotlin.Int
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> runTwice(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
return block();
|
||||||
|
};
|
||||||
|
|
||||||
|
fun <T> runOnce(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block();
|
||||||
|
};
|
||||||
|
|
||||||
|
fun valueReassignment() {
|
||||||
|
val x: Int
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
runTwice { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun shadowing() {
|
||||||
|
val x: Int
|
||||||
|
runTwice { val <!NAME_SHADOWING!>x<!>: Int; x = 42; x.inc() }
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun branchingFlow(a: Any?) {
|
||||||
|
val x: Int
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
if (a is String) {
|
||||||
|
runTwice { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = 43
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun branchingFlowWithMissingBranches(a: Any?) {
|
||||||
|
val x: Int
|
||||||
|
if (a is String) {
|
||||||
|
runTwice { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
}
|
||||||
|
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun repeatingFlow(n: Int) {
|
||||||
|
val x: Int
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
|
||||||
|
for (i in 1..n) {
|
||||||
|
runTwice { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
}
|
||||||
|
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun repeatingFlow2(n: Int) {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
for (i in 1..n) {
|
||||||
|
runTwice { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
}
|
||||||
|
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun branchingFlow(/*0*/ a: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun branchingFlowWithMissingBranches(/*0*/ a: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun repeatingFlow(/*0*/ n: kotlin.Int): kotlin.Unit
|
||||||
|
public fun repeatingFlow2(/*0*/ n: kotlin.Int): kotlin.Unit
|
||||||
|
public fun </*0*/ T> runOnce(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun </*0*/ T> runTwice(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, AT_LEAST_ONCE)
|
||||||
|
|
||||||
|
public fun shadowing(): kotlin.Unit
|
||||||
|
public fun valueReassignment(): kotlin.Unit
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> runTwice(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
return block();
|
||||||
|
};
|
||||||
|
|
||||||
|
fun testInitialization() {
|
||||||
|
var x: Int
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
runTwice { x = 42 }
|
||||||
|
x.inc()
|
||||||
|
x = 43
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun repeatingFlow(n: Int) {
|
||||||
|
var x: Int
|
||||||
|
for (i in 1..n) {
|
||||||
|
runTwice { x = 42 }
|
||||||
|
}
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun repeatingFlow(/*0*/ n: kotlin.Int): kotlin.Unit
|
||||||
|
public fun </*0*/ T> runTwice(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, AT_LEAST_ONCE)
|
||||||
|
|
||||||
|
public fun testInitialization(): kotlin.Unit
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> runTwice(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
return block();
|
||||||
|
};
|
||||||
|
|
||||||
|
fun <T> funWithUnknownInvocations(block: () -> T) = block()
|
||||||
|
|
||||||
|
fun indefiniteFlow() {
|
||||||
|
var x: Int
|
||||||
|
|
||||||
|
funWithUnknownInvocations { runTwice { x = 42 } }
|
||||||
|
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun shadowing() {
|
||||||
|
var x: Int
|
||||||
|
runTwice { val <!NAME_SHADOWING!>x<!>: Int; x = 42; x.inc() }
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> funWithUnknownInvocations(/*0*/ block: () -> T): T
|
||||||
|
public fun indefiniteFlow(): kotlin.Unit
|
||||||
|
public fun </*0*/ T> runTwice(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, AT_LEAST_ONCE)
|
||||||
|
|
||||||
|
public fun shadowing(): kotlin.Unit
|
||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initialization() {
|
||||||
|
val x: Int
|
||||||
|
myRun {
|
||||||
|
x = 42
|
||||||
|
42
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun shadowing() {
|
||||||
|
val x = 42
|
||||||
|
myRun {
|
||||||
|
val <!NAME_SHADOWING!>x<!> = 43
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nestedDefiniteAssignment() {
|
||||||
|
val x: Int
|
||||||
|
myRun {
|
||||||
|
val y = "Hello"
|
||||||
|
myRun {
|
||||||
|
x = 42
|
||||||
|
}
|
||||||
|
y.length
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deeplyNestedDefiniteAssignment() {
|
||||||
|
val x: Int
|
||||||
|
myRun {
|
||||||
|
val y: String
|
||||||
|
myRun {
|
||||||
|
val z: String
|
||||||
|
myRun {
|
||||||
|
z = "Hello"
|
||||||
|
y = "World"
|
||||||
|
x = 42
|
||||||
|
}
|
||||||
|
z.length
|
||||||
|
}
|
||||||
|
y.length
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun branchingFlow(a: Any?) {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
if (a is String) {
|
||||||
|
myRun { x = 42 }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myRun { x = 43 }
|
||||||
|
}
|
||||||
|
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun returningValue() {
|
||||||
|
val x: Int
|
||||||
|
val hello = myRun { x = 42; "hello" }
|
||||||
|
x.inc()
|
||||||
|
hello.length
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unknownRun(block: () -> Unit) = block()
|
||||||
|
|
||||||
|
class DefiniteInitializationInInitSection {
|
||||||
|
val x: Int
|
||||||
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val y: Int<!>
|
||||||
|
|
||||||
|
init {
|
||||||
|
myRun { x = 42 }
|
||||||
|
unknownRun { <!CAPTURED_MEMBER_VAL_INITIALIZATION!>y<!> = 239 }
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun branchingFlow(/*0*/ a: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun deeplyNestedDefiniteAssignment(): kotlin.Unit
|
||||||
|
public fun initialization(): kotlin.Unit
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun nestedDefiniteAssignment(): kotlin.Unit
|
||||||
|
public fun returningValue(): kotlin.Unit
|
||||||
|
public fun shadowing(): kotlin.Unit
|
||||||
|
public fun unknownRun(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
|
||||||
|
public final class DefiniteInitializationInInitSection {
|
||||||
|
public constructor DefiniteInitializationInInitSection()
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public final val y: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reassignmentInUsualFlow() {
|
||||||
|
val x: Int
|
||||||
|
myRun { x = 42 }
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = 43
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reassignment() {
|
||||||
|
val x = 42
|
||||||
|
myRun {
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = 43
|
||||||
|
}
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun reassignment(): kotlin.Unit
|
||||||
|
public fun reassignmentInUsualFlow(): kotlin.Unit
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun myRepeat(n: Int, action: () -> Unit) {
|
||||||
|
contract {
|
||||||
|
callsInPlace(action)
|
||||||
|
}
|
||||||
|
for (i in 1..n) action()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun branchingIndetermineFlow(a: Any?) {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
if (a is String) {
|
||||||
|
myRepeat(<!DEBUG_INFO_SMARTCAST!>a<!>.length) {
|
||||||
|
// Val reassignment because we know that repeat's lambda called in-place
|
||||||
|
myRun { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myRun { x = 43 }
|
||||||
|
}
|
||||||
|
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nonAnonymousLambdas() {
|
||||||
|
val x: Int
|
||||||
|
val initializer = { <!CAPTURED_VAL_INITIALIZATION!>x<!> = 42 }
|
||||||
|
myRun(initializer)
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun multipleAssignments() {
|
||||||
|
val x: Int
|
||||||
|
myRepeat(42) {
|
||||||
|
// Val reassignment because we know that repeat's lambda called in-place
|
||||||
|
myRun { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
}
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun funWithUnknownInvocations(block: () -> Unit) = block()
|
||||||
|
|
||||||
|
fun nestedIndefiniteAssignment() {
|
||||||
|
val x: Int
|
||||||
|
// Captured val initialization reported, because we don't know anything about funWithUnknownInvocations
|
||||||
|
funWithUnknownInvocations { myRun { <!CAPTURED_VAL_INITIALIZATION!>x<!> = 42 } }
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
class InitializationForbiddenInNonInitSection {
|
||||||
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val x: Int<!>
|
||||||
|
|
||||||
|
fun setup() {
|
||||||
|
myRun { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun branchingIndetermineFlow(/*0*/ a: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun funWithUnknownInvocations(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public fun multipleAssignments(): kotlin.Unit
|
||||||
|
public fun myRepeat(/*0*/ n: kotlin.Int, /*1*/ action: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
CallsInPlace(action, UNKNOWN)
|
||||||
|
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun nestedIndefiniteAssignment(): kotlin.Unit
|
||||||
|
public fun nonAnonymousLambdas(): kotlin.Unit
|
||||||
|
|
||||||
|
public final class InitializationForbiddenInNonInitSection {
|
||||||
|
public constructor InitializationForbiddenInNonInitSection()
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final fun setup(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun definiteVarInitialization() {
|
||||||
|
var x: Int
|
||||||
|
myRun { x = 42 }
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun definiteVarReassignment() {
|
||||||
|
var x: Int
|
||||||
|
myRun { x = 42 }
|
||||||
|
x.inc()
|
||||||
|
myRun { x = 43 }
|
||||||
|
x.inc()
|
||||||
|
x = 44
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nestedVarInitialization() {
|
||||||
|
var x: Int
|
||||||
|
myRun { myRun { myRun { x = 42 } } }
|
||||||
|
x.inc()
|
||||||
|
myRun { myRun { myRun { x = 42 } } }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun notAnExpression() {
|
||||||
|
var x: Int = 0
|
||||||
|
myRun { if (true) x = 42 }
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun definiteVarInitialization(): kotlin.Unit
|
||||||
|
public fun definiteVarReassignment(): kotlin.Unit
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun nestedVarInitialization(): kotlin.Unit
|
||||||
|
public fun notAnExpression(): kotlin.Unit
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> myRun(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun indefiniteVarReassignment(n: Int) {
|
||||||
|
var x: Int
|
||||||
|
repeat(n) {
|
||||||
|
myRun { x = 42 }
|
||||||
|
}
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nonAnonymousLambdas() {
|
||||||
|
// Named lambdas are not inlined, even in theory it could be done for some simple cases as this one
|
||||||
|
var x: Int
|
||||||
|
val initializer = { x = 42 }
|
||||||
|
myRun(initializer)
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun branchingIndetermineFlow(a: Any) {
|
||||||
|
var x: Int
|
||||||
|
|
||||||
|
if (a is String) {
|
||||||
|
repeat(<!DEBUG_INFO_SMARTCAST!>a<!>.length) {
|
||||||
|
myRun { x = 42 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myRun { x = 43 }
|
||||||
|
}
|
||||||
|
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun funWithUnknownInvocations(block: () -> Unit) = block()
|
||||||
|
|
||||||
|
fun nestedIndefiniteAssignment() {
|
||||||
|
val x: Int
|
||||||
|
funWithUnknownInvocations { myRun { <!CAPTURED_VAL_INITIALIZATION!>x<!> = 42 } }
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun branchingIndetermineFlow(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||||
|
public fun funWithUnknownInvocations(/*0*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public fun indefiniteVarReassignment(/*0*/ n: kotlin.Int): kotlin.Unit
|
||||||
|
public fun </*0*/ T> myRun(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
|
public fun nestedIndefiniteAssignment(): kotlin.Unit
|
||||||
|
public fun nonAnonymousLambdas(): kotlin.Unit
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T, R> T.myLet(block: (T) -> R): R {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return block(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initializationWithReceiver(y: String) {
|
||||||
|
val x: Int
|
||||||
|
y.myLet { x = 42 }
|
||||||
|
x.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initializationWithSafeCall(y: String?) {
|
||||||
|
val x: Int
|
||||||
|
y?.myLet { x = 42 }
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sanityCheck(x: Int, y: String): Int {
|
||||||
|
y.let { return x }
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun initializationWithReceiver(/*0*/ y: kotlin.String): kotlin.Unit
|
||||||
|
public fun initializationWithSafeCall(/*0*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
public fun sanityCheck(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String): kotlin.Int
|
||||||
|
public fun </*0*/ T, /*1*/ R> T.myLet(/*0*/ block: (T) -> R): R
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun <T> inPlace(block: () -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block)
|
||||||
|
}
|
||||||
|
return block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reassignmentAndNoInitializaiton() {
|
||||||
|
val x: Int
|
||||||
|
inPlace { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
|
<!UNINITIALIZED_VARIABLE!>x<!>.inc()
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> inPlace(/*0*/ block: () -> T): T
|
||||||
|
CallsInPlace(block, UNKNOWN)
|
||||||
|
|
||||||
|
public fun reassignmentAndNoInitializaiton(): kotlin.Unit
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun foo(b: Boolean): Boolean {
|
||||||
|
contract {
|
||||||
|
// pointless, can be reduced to just "b"
|
||||||
|
returns(true) implies (<!ERROR_IN_CONTRACT_DESCRIPTION(only equality comparisons with 'null' allowed)!>b == true<!>)
|
||||||
|
}
|
||||||
|
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(b: Boolean?): Boolean {
|
||||||
|
contract {
|
||||||
|
// not pointless, but not supported yet
|
||||||
|
returns(true) implies (<!ERROR_IN_CONTRACT_DESCRIPTION(only equality comparisons with 'null' allowed)!>b == true<!>)
|
||||||
|
}
|
||||||
|
if (b == null) throw java.lang.IllegalArgumentException("")
|
||||||
|
return <!DEBUG_INFO_SMARTCAST!>b<!>
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ b: kotlin.Boolean?): kotlin.Boolean
|
||||||
|
public fun foo(/*0*/ b: kotlin.Boolean): kotlin.Boolean
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun bar(x: Int): Boolean = x == 0
|
||||||
|
|
||||||
|
fun foo(x: Int): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (<!ERROR_IN_CONTRACT_DESCRIPTION(call-expressions are not supported yet)!>bar(x)<!>)
|
||||||
|
}
|
||||||
|
return x == 0
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ x: kotlin.Int): kotlin.Boolean
|
||||||
|
public fun foo(/*0*/ x: kotlin.Int): kotlin.Boolean
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun foo(boolean: Boolean) {
|
||||||
|
contract {
|
||||||
|
(returns() implies (boolean)) <!UNRESOLVED_REFERENCE!>implies<!> (!boolean)
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ boolean: kotlin.Boolean): kotlin.Unit
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun foo(y: Boolean) {
|
||||||
|
val <!UNUSED_VARIABLE!>x<!>: Int = 42
|
||||||
|
<!CONTRACT_NOT_ALLOWED!>contract {
|
||||||
|
returns() implies y
|
||||||
|
}<!>
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ y: kotlin.Boolean): kotlin.Unit
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
class Foo(val x: Int?) {
|
||||||
|
fun isXNull(): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (<!ERROR_IN_CONTRACT_DESCRIPTION(only references to parameters are allowed in contract description)!>x<!> != null)
|
||||||
|
}
|
||||||
|
return x != null
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class Foo {
|
||||||
|
public constructor Foo(/*0*/ x: kotlin.Int?)
|
||||||
|
public final val x: kotlin.Int?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final fun isXNull(): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun Any?.foo(): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (<!ERROR_IN_CONTRACT_DESCRIPTION(only references to parameters are allowed. Did you miss label on <this>?)!>this<!> <!EQUALS_MISSING!>!=<!> null)
|
||||||
|
}
|
||||||
|
return this != null
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun kotlin.Any?.foo(): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> <this> != null
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun test(x: Any?) {
|
||||||
|
if (isString(x)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun isString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun test(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun myAssert(condition: Boolean) {
|
||||||
|
contract {
|
||||||
|
returns() implies (condition)
|
||||||
|
}
|
||||||
|
if (!condition) throw kotlin.IllegalArgumentException("Assertion failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testWithCatch(x: Any?) {
|
||||||
|
try {
|
||||||
|
myAssert(x is String)
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
} catch (e: java.lang.IllegalArgumentException) { }
|
||||||
|
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun myAssert(/*0*/ condition: kotlin.Boolean): kotlin.Unit
|
||||||
|
Returns(WILDCARD) -> condition
|
||||||
|
|
||||||
|
public fun testWithCatch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun isString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testEqualsWithConstant(x: Any?) {
|
||||||
|
if (isString(x) == true) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testNotEqualsWithConstant(x: Any?) {
|
||||||
|
if (isString(x) != true) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unknownFunction(): Any? = 42
|
||||||
|
|
||||||
|
fun testEqualsWithUnknown(x: Any?) {
|
||||||
|
if (isString(x) == unknownFunction()) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testNotEqualsWithUnknown(x: Any?) {
|
||||||
|
if (isString(x) != unknownFunction()) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testEqualsWithVariable(x: Any?, b: Boolean) {
|
||||||
|
if (isString(x) == b) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testNotEqualsWithVariable(x: Any?, b: Boolean) {
|
||||||
|
if (isString(x) != b) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun isString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun testEqualsWithConstant(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testEqualsWithUnknown(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testEqualsWithVariable(/*0*/ x: kotlin.Any?, /*1*/ b: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun testNotEqualsWithConstant(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testNotEqualsWithUnknown(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testNotEqualsWithVariable(/*0*/ x: kotlin.Any?, /*1*/ b: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun unknownFunction(): kotlin.Any?
|
||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun myAssert(condition: Boolean) {
|
||||||
|
contract {
|
||||||
|
returns() implies (condition)
|
||||||
|
}
|
||||||
|
if (!condition) throw kotlin.IllegalArgumentException("Assertion failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isInt(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is Int)
|
||||||
|
}
|
||||||
|
return x is Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notEqualsNull(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x != null)
|
||||||
|
}
|
||||||
|
return x != null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun equalsTrue(x: Boolean): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies x
|
||||||
|
}
|
||||||
|
return x == true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nullWhenNotString(x: Any?): String? {
|
||||||
|
contract {
|
||||||
|
returnsNotNull() implies (x is String)
|
||||||
|
}
|
||||||
|
return x as? String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ========== Actual tests ============
|
||||||
|
|
||||||
|
fun nested1(x: Any?) {
|
||||||
|
if (equalsTrue(isString(x))) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nested2(x: Any?) {
|
||||||
|
myAssert(equalsTrue(isString(x)))
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nested3(x: Any?) {
|
||||||
|
myAssert(equalsTrue(notEqualsNull(nullWhenNotString(x))))
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
|
||||||
|
fun branchedAndNested(x: Any?, y: Any?) {
|
||||||
|
myAssert(equalsTrue(notEqualsNull(nullWhenNotString(x))) && equalsTrue(isString(y)))
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>y<!>.length
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun br(y: Any?) {
|
||||||
|
if (myAssert(y is Int) == Unit && myAssert(y is String) == Unit) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>y<!>.length
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>y<!>.inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun branchedAndNestedWithNativeOperators(x: Any?, y: Any?) {
|
||||||
|
myAssert(
|
||||||
|
equalsTrue(notEqualsNull(nullWhenNotString(x))) // x is String
|
||||||
|
&&
|
||||||
|
(
|
||||||
|
(myAssert(y is Int) == Unit && myAssert(y is String) == Unit) // y is Int, String
|
||||||
|
||
|
||||||
|
equalsTrue(isInt(y) && isString(y)) // y is Int, String
|
||||||
|
)
|
||||||
|
&&
|
||||||
|
(1 == 2 || y is Int || isString(y))
|
||||||
|
)
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
y.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
y.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun br(/*0*/ y: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun branchedAndNested(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun branchedAndNestedWithNativeOperators(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun equalsTrue(/*0*/ x: kotlin.Boolean): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x
|
||||||
|
|
||||||
|
public fun isInt(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is Int
|
||||||
|
|
||||||
|
public fun isString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun myAssert(/*0*/ condition: kotlin.Boolean): kotlin.Unit
|
||||||
|
Returns(WILDCARD) -> condition
|
||||||
|
|
||||||
|
public fun nested1(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun nested2(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun nested3(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun notEqualsNull(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x != null
|
||||||
|
|
||||||
|
public fun nullWhenNotString(/*0*/ x: kotlin.Any?): kotlin.String?
|
||||||
|
Returns(NOT_NULL) -> x is String
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun isString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun notIsString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notIsInt(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x !is Int)
|
||||||
|
}
|
||||||
|
return x !is Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun intersectingInfo(x: Any?, y: Any?) {
|
||||||
|
if ((isString(x) && y is String) || (!notIsString(x) && !notIsInt(y))) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
y.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
y.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
y.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
y.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun intersectingInfo2(x: Any?, y: Any?) {
|
||||||
|
// In each arg of "||"-operator presented fact "x is String" which should lead to smartcast.
|
||||||
|
// Also there are 3 additional facts: "x is Int", "y is String", "y is Int". One
|
||||||
|
// of them is absent in each arg of "||"-operator, so they *shouldn't* lead to smartcast
|
||||||
|
|
||||||
|
if ((isString(x) && !notIsInt(x) && y is String) ||
|
||||||
|
(!notIsString(x) && isString(y) && y is Int) ||
|
||||||
|
(x is String && !notIsInt(y) && x is Int)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
y.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
y.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
y.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
y.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun intersectingInfo(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun intersectingInfo2(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun isString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun notIsInt(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x !is Int
|
||||||
|
|
||||||
|
public fun notIsString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun notIsString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notIsInt(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is Int)
|
||||||
|
}
|
||||||
|
return x !is Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testDeMorgan(x: Any?) {
|
||||||
|
// !(x !is String || x !is Int)
|
||||||
|
// x is String && x is Int
|
||||||
|
if (!(notIsString(x) || notIsInt(x))) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testDeMorgan2(x: Any?) {
|
||||||
|
// x !is String || x !is Int
|
||||||
|
if (notIsString(x) || notIsInt(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun notIsInt(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is Int
|
||||||
|
|
||||||
|
public fun notIsString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
|
|
||||||
|
public fun testDeMorgan(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testDeMorgan2(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
Vendored
+86
@@ -0,0 +1,86 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun onlyTrue(b: Boolean): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (b)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onlyFalse(b: Boolean): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (!b)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
fun trueAndFalse(b: Boolean): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (b)
|
||||||
|
returns(false) implies (!b)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== actual tests ====
|
||||||
|
|
||||||
|
fun useOnlyTrueInTrueBranch(x: Any?) {
|
||||||
|
if (onlyTrue(x is String)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useOnlyTrueInFalseBranch(x: Any?) {
|
||||||
|
if (onlyTrue(x !is String)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No smartcast here, we don't know that condition is false here
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useOnlyFalseInTrueBranch(x: Any?) {
|
||||||
|
if (onlyFalse(x is String)) {
|
||||||
|
// No smartcast here, we don't know that condition is true here
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useOnlyFalseInFalseBranch(x: Any?) {
|
||||||
|
if (onlyFalse(x !is String)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useTrueAndFalseInTrueBranch(x: Any?) {
|
||||||
|
if (trueAndFalse(x is String)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useTrueAndFalseInFalseBranch(x: Any?) {
|
||||||
|
if (trueAndFalse(x !is String)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun onlyFalse(/*0*/ b: kotlin.Boolean): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> !b
|
||||||
|
|
||||||
|
public fun onlyTrue(/*0*/ b: kotlin.Boolean): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> b
|
||||||
|
|
||||||
|
public fun trueAndFalse(/*0*/ b: kotlin.Boolean): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> b
|
||||||
|
Returns(FALSE) -> !b
|
||||||
|
|
||||||
|
public fun useOnlyFalseInFalseBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun useOnlyFalseInTrueBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun useOnlyTrueInFalseBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun useOnlyTrueInTrueBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun useTrueAndFalseInFalseBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun useTrueAndFalseInTrueBranch(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
Vendored
+67
@@ -0,0 +1,67 @@
|
|||||||
|
// !LANGUAGE: +CallsInPlaceEffect +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun callsAndInverts(b: Boolean, block: () -> Unit): Boolean {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
returns(true) implies (!b)
|
||||||
|
returns(false) implies b
|
||||||
|
}
|
||||||
|
|
||||||
|
block()
|
||||||
|
return !b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun smartcastAndInitialization(x: Any?) {
|
||||||
|
val y: Int
|
||||||
|
|
||||||
|
if (callsAndInverts(x !is String) { y = 42 }) {
|
||||||
|
println(y)
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
} else {
|
||||||
|
println(y)
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
println(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inPresenceOfLazy(x: Any?, unknownBoolean: Boolean) {
|
||||||
|
val y: Int
|
||||||
|
|
||||||
|
if (unknownBoolean && callsAndInverts(x !is String) { y = 42 }) {
|
||||||
|
println(<!UNINITIALIZED_VARIABLE!>y<!>)
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println(y)
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
println(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isPresenceOfLazy2(x: Any?, unknownBoolean: Boolean) {
|
||||||
|
val y: Int
|
||||||
|
if (unknownBoolean && callsAndInverts(x !is String) { y = 42 }) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println(<!UNINITIALIZED_VARIABLE!>y<!>)
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
println(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isPresenceOfLazy3(x: Any?, unknownBoolean: Boolean) {
|
||||||
|
val y: Int
|
||||||
|
if (unknownBoolean && callsAndInverts(x !is String) { y = 42 }) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
println(<!UNINITIALIZED_VARIABLE!>y<!>)
|
||||||
|
}
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun callsAndInverts(/*0*/ b: kotlin.Boolean, /*1*/ block: () -> kotlin.Unit): kotlin.Boolean
|
||||||
|
CallsInPlace(block, EXACTLY_ONCE)
|
||||||
|
Returns(TRUE) -> !b
|
||||||
|
Returns(FALSE) -> b
|
||||||
|
|
||||||
|
public fun inPresenceOfLazy(/*0*/ x: kotlin.Any?, /*1*/ unknownBoolean: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun isPresenceOfLazy2(/*0*/ x: kotlin.Any?, /*1*/ unknownBoolean: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun isPresenceOfLazy3(/*0*/ x: kotlin.Any?, /*1*/ unknownBoolean: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun smartcastAndInitialization(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun nullWhenNull(x: Int?): Int? {
|
||||||
|
contract {
|
||||||
|
returnsNotNull() implies (x != null)
|
||||||
|
}
|
||||||
|
return x?.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testNullWhenNull(x: Int?) {
|
||||||
|
if (nullWhenNull(x) == null) {
|
||||||
|
x<!UNSAFE_CALL!>.<!>dec()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.dec()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nullWhenNull(x) != null) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.dec()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x<!UNSAFE_CALL!>.<!>dec()
|
||||||
|
}
|
||||||
|
|
||||||
|
x<!UNSAFE_CALL!>.<!>dec()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB. it is the same function as `nullWhenNull`, but annotations specifies other facet of the function behaviour
|
||||||
|
fun notNullWhenNotNull (x: Int?): Int? {
|
||||||
|
contract {
|
||||||
|
returns(null) implies (x == null)
|
||||||
|
}
|
||||||
|
return x?.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testNotNullWhenNotNull (x: Int?) {
|
||||||
|
if (notNullWhenNotNull(x) == null) {
|
||||||
|
<!SENSELESS_COMPARISON!><!DEBUG_INFO_CONSTANT!>x<!> == null<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x<!UNSAFE_CALL!>.<!>dec()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notNullWhenNotNull(x) != null) {
|
||||||
|
x<!UNSAFE_CALL!>.<!>dec()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!SENSELESS_COMPARISON!><!DEBUG_INFO_CONSTANT!>x<!> == null<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
x<!UNSAFE_CALL!>.<!>dec()
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun notNullWhenNotNull(/*0*/ x: kotlin.Int?): kotlin.Int?
|
||||||
|
Returns(NULL) -> x == null
|
||||||
|
|
||||||
|
public fun nullWhenNull(/*0*/ x: kotlin.Int?): kotlin.Int?
|
||||||
|
Returns(NOT_NULL) -> x != null
|
||||||
|
|
||||||
|
public fun testNotNullWhenNotNull(/*0*/ x: kotlin.Int?): kotlin.Unit
|
||||||
|
public fun testNullWhenNull(/*0*/ x: kotlin.Int?): kotlin.Unit
|
||||||
Vendored
+79
@@ -0,0 +1,79 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun trueWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun trueWhenInt(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is Int)
|
||||||
|
}
|
||||||
|
return x is Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenInt(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is Int)
|
||||||
|
}
|
||||||
|
return x !is Int
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Actual tests ====
|
||||||
|
|
||||||
|
fun truetrue(x: Any?) {
|
||||||
|
if (trueWhenString(x) && trueWhenInt(x)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun truefalse(x: Any?) {
|
||||||
|
if (trueWhenString(x) && falseWhenInt(x)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falsetrue(x: Any?) {
|
||||||
|
if (falseWhenString(x) && trueWhenInt(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falsefalse(x: Any?) {
|
||||||
|
if (falseWhenString(x) && falseWhenInt(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Note that we can't argue that we have any of smartcasts here,
|
||||||
|
// because we don't know which one of both arguments was 'false' to bring us here
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun falseWhenInt(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is Int
|
||||||
|
|
||||||
|
public fun falseWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
|
|
||||||
|
public fun falsefalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun falsetrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun trueWhenInt(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is Int
|
||||||
|
|
||||||
|
public fun trueWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun truefalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun truetrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun trueWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun annotatedTrueAndTrue(x: Any?) {
|
||||||
|
if (trueWhenString(x) && true) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedTrueAndFalse(x: Any?) {
|
||||||
|
if (trueWhenString(x) && false) {
|
||||||
|
// Unreachable
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalseAndTrue(x: Any?) {
|
||||||
|
if (falseWhenString(x) && true) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalseAndFalse(x: Any?) {
|
||||||
|
if (falseWhenString(x) && false) {
|
||||||
|
// Unreachable
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun annotatedFalseAndFalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedFalseAndTrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedTrueAndFalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedTrueAndTrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun falseWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
|
|
||||||
|
public fun trueWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun trueWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unknownFunction(x: Any?) = x == 42
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun annotatedTrue(x: Any?) {
|
||||||
|
if (trueWhenString(x) && unknownFunction(x)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalse(x: Any?) {
|
||||||
|
if (falseWhenString(x) && unknownFunction(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedTrueWithVariable(x: Any?, b: Boolean) {
|
||||||
|
if (trueWhenString(x) && b) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalseWithVariable(x: Any?, b: Boolean) {
|
||||||
|
if (falseWhenString(x) && b) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun annotatedFalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedFalseWithVariable(/*0*/ x: kotlin.Any?, /*1*/ b: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun annotatedTrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedTrueWithVariable(/*0*/ x: kotlin.Any?, /*1*/ b: kotlin.Boolean): kotlin.Unit
|
||||||
|
public fun falseWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
|
|
||||||
|
public fun trueWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun unknownFunction(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
Vendored
+45
@@ -0,0 +1,45 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun myEqualsNull(x: Int?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x != null)
|
||||||
|
}
|
||||||
|
return x == null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun myEqualsNotNull(x: Int?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x != null)
|
||||||
|
}
|
||||||
|
return x != null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testBasicEquals(x: Int?) {
|
||||||
|
x<!UNSAFE_CALL!>.<!>inc()
|
||||||
|
|
||||||
|
if (myEqualsNull(x)) {
|
||||||
|
x<!UNSAFE_CALL!>.<!>inc()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
x<!UNSAFE_CALL!>.<!>inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testBasicNotEquals(x: Int?) {
|
||||||
|
x<!UNSAFE_CALL!>.<!>inc()
|
||||||
|
|
||||||
|
if (myEqualsNotNull(x)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x<!UNSAFE_CALL!>.<!>inc()
|
||||||
|
}
|
||||||
|
|
||||||
|
x<!UNSAFE_CALL!>.<!>inc()
|
||||||
|
}
|
||||||
|
|
||||||
compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/operatorsTests/equalsOperator.txt
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun myEqualsNotNull(/*0*/ x: kotlin.Int?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x != null
|
||||||
|
|
||||||
|
public fun myEqualsNull(/*0*/ x: kotlin.Int?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x != null
|
||||||
|
|
||||||
|
public fun testBasicEquals(/*0*/ x: kotlin.Int?): kotlin.Unit
|
||||||
|
public fun testBasicNotEquals(/*0*/ x: kotlin.Int?): kotlin.Unit
|
||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun safeIsString(x: Any?): Boolean? {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x?.let { it is String }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun equalsTrue(x: Any?) {
|
||||||
|
if (safeIsString(x) == true) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun equalsFalse(x: Any?) {
|
||||||
|
if (safeIsString(x) == false) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun equalsNull(x: Any?) {
|
||||||
|
if (safeIsString(x) == null) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notEqualsTrue(x: Any?) {
|
||||||
|
if (safeIsString(x) != true) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notEqualsFalse(x: Any?) {
|
||||||
|
if (safeIsString(x) != false) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notEqualsNull(x: Any?) {
|
||||||
|
if (safeIsString(x) != null) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun equalsFalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun equalsNull(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun equalsTrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun notEqualsFalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun notEqualsNull(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun notEqualsTrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun safeIsString(/*0*/ x: kotlin.Any?): kotlin.Boolean?
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun isString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun notIsString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun testSimple(x: Any?) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
|
||||||
|
if (isString(x)) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSpilling(x: Any?) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
|
||||||
|
if (isString(x)) <!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testInversion(x: Any?) {
|
||||||
|
if (notIsString(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testInversionSpilling(x: Any?) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
|
||||||
|
if (notIsString(x)) else <!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun isString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun notIsString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
|
|
||||||
|
public fun testInversion(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testInversionSpilling(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testSimple(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun testSpilling(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
Vendored
+76
@@ -0,0 +1,76 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun trueWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun trueWhenInt(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is Int)
|
||||||
|
}
|
||||||
|
return x is Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenInt(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is Int)
|
||||||
|
}
|
||||||
|
return x !is Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun truetrue(x: Any?) {
|
||||||
|
if (trueWhenString(x) || trueWhenInt(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun truefalse(x: Any?) {
|
||||||
|
if (trueWhenString(x) || falseWhenInt(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falsetrue(x: Any?) {
|
||||||
|
if (falseWhenString(x) || trueWhenInt(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falsefalse(x: Any?) {
|
||||||
|
if (falseWhenString(x) || falseWhenInt(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
x.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inc<!>()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun falseWhenInt(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is Int
|
||||||
|
|
||||||
|
public fun falseWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
|
|
||||||
|
public fun falsefalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun falsetrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun trueWhenInt(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is Int
|
||||||
|
|
||||||
|
public fun trueWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
|
|
||||||
|
public fun truefalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun truetrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun trueWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedTrueOrTrue(x: Any?) {
|
||||||
|
if (trueWhenString(x) || true) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Unreachable
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedTrueOrFalse(x: Any?) {
|
||||||
|
if (trueWhenString(x) || false) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalseOrTrue(x: Any?) {
|
||||||
|
if (falseWhenString(x) || true) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Unreachable
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalseOrFalse(x: Any?) {
|
||||||
|
if (falseWhenString(x) || false) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun annotatedFalseOrFalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedFalseOrTrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedTrueOrFalse(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun annotatedTrueOrTrue(/*0*/ x: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun falseWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(FALSE) -> x is String
|
||||||
|
|
||||||
|
public fun trueWhenString(/*0*/ x: kotlin.Any?): kotlin.Boolean
|
||||||
|
Returns(TRUE) -> x is String
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// !LANGUAGE: +ReturnsEffect
|
||||||
|
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
|
||||||
|
|
||||||
|
import kotlin.internal.contracts.*
|
||||||
|
|
||||||
|
fun trueWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (x is String)
|
||||||
|
}
|
||||||
|
return x is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falseWhenString(x: Any?): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(false) implies (x is String)
|
||||||
|
}
|
||||||
|
return x !is String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unknownFunction(x: Any?) = x == 42
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun annotatedTrue(x: Any?) {
|
||||||
|
if (trueWhenString(x) || unknownFunction(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalse(x: Any?) {
|
||||||
|
if (falseWhenString(x) || unknownFunction(x)) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedTrueWithVariable(x: Any?, b: Boolean) {
|
||||||
|
if (trueWhenString(x) || b) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun annotatedFalseWithVariable(x: Any?, b: Boolean) {
|
||||||
|
if (falseWhenString(x) || b) {
|
||||||
|
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user