[FIR-TEST] Add new testdata generated after changes in previous commit

This commit is contained in:
Dmitriy Novozhilov
2019-12-11 16:16:22 +03:00
parent e9c02a1cca
commit 2536fa0cd5
4578 changed files with 104067 additions and 1 deletions
@@ -0,0 +1,17 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun myAssert(condition: Boolean, message: String = "") {
contract {
returns() implies (condition)
}
if (!condition) throw kotlin.<!UNRESOLVED_REFERENCE!>IllegalArgumentException<!>(message)
}
fun test(x: Any?) {
myAssert(x is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun myAssert(condition: Boolean) {
contract {
returns() implies (condition)
}
if (!condition) throw kotlin.<!UNRESOLVED_REFERENCE!>IllegalArgumentException<!>("Assertion failed")
}
fun testWithCatch(x: Any?) {
try {
myAssert(x is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
} catch (e: java.lang.IllegalArgumentException) { }
x.<!UNRESOLVED_REFERENCE!>length<!>
}
@@ -0,0 +1,70 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun testNotEqualsWithConstant(x: Any?) {
if (isString(x) != true) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>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<!>
}
}
@@ -0,0 +1,104 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.contracts.*
fun myAssert(condition: Boolean) {
contract {
returns() implies (condition)
}
if (!condition) throw kotlin.<!UNRESOLVED_REFERENCE!>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))) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun nested2(x: Any?) {
myAssert(equalsTrue(isString(x)))
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun nested3(x: Any?) {
myAssert(equalsTrue(notEqualsNull(nullWhenNotString(x))))
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun branchedAndNested(x: Any?, y: Any?) {
myAssert(equalsTrue(notEqualsNull(nullWhenNotString(x))) && equalsTrue(isString(y)))
x.<!UNRESOLVED_REFERENCE!>length<!>
y.<!UNRESOLVED_REFERENCE!>length<!>
}
fun br(y: Any?) {
if (myAssert(y is Int) == Unit && myAssert(y is String) == Unit) {
y.<!UNRESOLVED_REFERENCE!>length<!>
y.<!AMBIGUITY!>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))
)
x.<!UNRESOLVED_REFERENCE!>length<!>
y.<!UNRESOLVED_REFERENCE!>length<!>
y.<!AMBIGUITY!>inc<!>()
}
@@ -0,0 +1,38 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
//
// ISSUE: KT-28672
import kotlin.contracts.*
fun CharSequence?.isNullOrEmpty(): Boolean {
contract {
returns(false) implies (this@isNullOrEmpty != null)
}
return this == null || this.length == 0
}
fun smartcastOnReceiver(s: String?) {
with(s) {
if (isNullOrEmpty()) {
length
}
else {
length
}
}
}
fun mixedReceiver(s: String?) {
if (!s.isNullOrEmpty()) {
with(s) {
length
}
} else {
with(s) {
length
}
}
}
@@ -0,0 +1,38 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +ContractsOnCallsWithImplicitReceiver
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
//
// ISSUE: KT-28672
import kotlin.contracts.*
fun CharSequence?.isNullOrEmpty(): Boolean {
contract {
returns(false) implies (this@isNullOrEmpty != null)
}
return this == null || this.length == 0
}
fun smartcastOnReceiver(s: String?) {
with(s) {
if (isNullOrEmpty()) {
length
}
else {
length
}
}
}
fun mixedReceiver(s: String?) {
if (!s.isNullOrEmpty()) {
with(s) {
length
}
} else {
with(s) {
length
}
}
}
@@ -0,0 +1,61 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.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))) {
x.<!UNRESOLVED_REFERENCE!>length<!>
y.<!UNRESOLVED_REFERENCE!>length<!>
y.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
y.<!UNRESOLVED_REFERENCE!>length<!>
y.<!AMBIGUITY!>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)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
y.<!UNRESOLVED_REFERENCE!>length<!>
y.<!AMBIGUITY!>inc<!>()
}
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
y.<!UNRESOLVED_REFERENCE!>length<!>
y.<!AMBIGUITY!>inc<!>()
}
@@ -0,0 +1,45 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.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))) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
fun testDeMorgan2(x: Any?) {
// x !is String || x !is Int
if (notIsString(x) || notIsInt(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
@@ -0,0 +1,87 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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)) {
x.<!UNRESOLVED_REFERENCE!>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 {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun useTrueAndFalseInTrueBranch(x: Any?) {
if (trueAndFalse(x is String)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun useTrueAndFalseInFalseBranch(x: Any?) {
if (trueAndFalse(x !is String)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,68 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +UseCallsInPlaceEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun callsAndInverts(b: Boolean, block: () -> Unit): Boolean {
contract {
<!INAPPLICABLE_CANDIDATE!>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)
x.<!UNRESOLVED_REFERENCE!>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(y)
x.<!UNRESOLVED_REFERENCE!>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 }) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
println(y)
x.<!UNRESOLVED_REFERENCE!>length<!>
}
println(y)
}
fun isPresenceOfLazy3(x: Any?, unknownBoolean: Boolean) {
val y: Int
if (unknownBoolean && callsAndInverts(x !is String) { y = 42 }) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
println(y)
}
@@ -0,0 +1,57 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.contracts.*
fun nullWhenNull(x: Int?): Int? {
contract {
returnsNotNull() implies (x != null)
}
return x?.inc()
}
fun testNullWhenNull(x: Int?) {
if (nullWhenNull(x) == null) {
x.<!AMBIGUITY!>dec<!>()
}
else {
x.<!AMBIGUITY!>dec<!>()
}
if (nullWhenNull(x) != null) {
x.<!AMBIGUITY!>dec<!>()
}
else {
x.<!AMBIGUITY!>dec<!>()
}
x.<!AMBIGUITY!>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) {
x == null
}
else {
x.<!AMBIGUITY!>dec<!>()
}
if (notNullWhenNotNull(x) != null) {
x.<!AMBIGUITY!>dec<!>()
}
else {
x == null
}
x.<!AMBIGUITY!>dec<!>()
}
@@ -0,0 +1,81 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.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)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
fun truefalse(x: Any?) {
if (trueWhenString(x) && falseWhenInt(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
fun falsetrue(x: Any?) {
if (falseWhenString(x) && trueWhenInt(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
fun falsefalse(x: Any?) {
if (falseWhenString(x) && falseWhenInt(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>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.<!AMBIGUITY!>inc<!>()
}
}
@@ -0,0 +1,60 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun annotatedTrueAndFalse(x: Any?) {
if (trueWhenString(x) && false) {
// Unreachable
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun annotatedFalseAndTrue(x: Any?) {
if (falseWhenString(x) && true) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun annotatedFalseAndFalse(x: Any?) {
if (falseWhenString(x) && false) {
// Unreachable
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,60 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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 {
x.<!UNRESOLVED_REFERENCE!>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 {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,47 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.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.<!AMBIGUITY!>inc<!>()
if (myEqualsNull(x)) {
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!AMBIGUITY!>inc<!>()
}
x.<!AMBIGUITY!>inc<!>()
}
fun testBasicNotEquals(x: Int?) {
x.<!AMBIGUITY!>inc<!>()
if (myEqualsNotNull(x)) {
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!AMBIGUITY!>inc<!>()
}
x.<!AMBIGUITY!>inc<!>()
}
@@ -0,0 +1,69 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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) {
x.<!UNRESOLVED_REFERENCE!>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 {
x.<!UNRESOLVED_REFERENCE!>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<!>
}
}
@@ -0,0 +1,60 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun testSpilling(x: Any?) {
x.<!UNRESOLVED_REFERENCE!>length<!>
if (isString(x)) x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun testInversion(x: Any?) {
if (notIsString(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun testInversionSpilling(x: Any?) {
x.<!UNRESOLVED_REFERENCE!>length<!>
if (notIsString(x)) else x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!UNRESOLVED_REFERENCE!>length<!>
}
@@ -0,0 +1,78 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.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.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
fun truefalse(x: Any?) {
if (trueWhenString(x) || falseWhenInt(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
fun falsetrue(x: Any?) {
if (falseWhenString(x) || trueWhenInt(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
fun falsefalse(x: Any?) {
if (falseWhenString(x) || falseWhenInt(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
x.<!AMBIGUITY!>inc<!>()
}
}
@@ -0,0 +1,57 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun annotatedFalseOrTrue(x: Any?) {
if (falseWhenString(x) || true) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
// Unreachable
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun annotatedFalseOrFalse(x: Any?) {
if (falseWhenString(x) || false) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,60 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.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 {
x.<!UNRESOLVED_REFERENCE!>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 {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun isString(x: Any?): Boolean {
contract {
returns(true) implies (x is String)
}
return x is String
}
fun incorrectPartDoesntMatter(x: Any?) {
if (isString(x) && 1) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,36 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
// !WITH_NEW_INFERENCE
import kotlin.contracts.*
fun Any?.isNull(): Boolean {
contract {
returns(false) implies (this@isNull != null)
}
return this == null
}
fun smartcastOnReceiver(x: Int?) {
if (x.isNull()) {
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!AMBIGUITY!>dec<!>()
}
}
class UnstableReceiver {
var x: Int? = 42
fun smartcastOnUnstableReceiver() {
if (x.isNull()) {
x.<!AMBIGUITY!>inc<!>()
}
else {
x.<!AMBIGUITY!>dec<!>()
}
}
}
@@ -0,0 +1,17 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
import kotlin.contracts.*
fun Any.nullWhenString(): Any? {
contract {
returns(null) implies (this@nullWhenString is String)
}
return if (this is String) null else this
}
fun test(x: Int?) {
if (x?.nullWhenString() == null) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,66 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun myAssert(condition: Boolean) {
contract {
returns() implies (condition)
}
if (!condition) throw kotlin.<!UNRESOLVED_REFERENCE!>IllegalArgumentException<!>("Assertion failed")
}
fun testAssertSmartcast(x: Any?) {
myAssert(x is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun testInvertedAssert(x: Any?) {
myAssert(x !is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun testSpilling(x: Any?) {
if (x != null) {
myAssert(x is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun testAssertInIf(x: Any?) {
if (myAssert(x is String) == Unit) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun testTryCatch(x: Any?) {
try {
myAssert(x is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
} catch (e: kotlin.IllegalArgumentException) {
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun testUncertainFlow(x: Any?) {
repeat(x.toString().length) {
myAssert(x is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
fun testAtLeastOnceFlow(x: Any?) {
do {
myAssert(x is String)
x.<!UNRESOLVED_REFERENCE!>length<!>
} while (x != null)
x.<!UNRESOLVED_REFERENCE!>length<!>
}
@@ -0,0 +1,59 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun nullWhenString(x: Any?): Int? {
contract {
returns(null) implies (x is String)
}
return if (x is String) null else 42
}
fun nullWhenNotString(x: Any?): Int? {
contract {
returns(null) implies (x !is String)
}
return if (x !is String) null else 42
}
// ==== Actual tests =====
fun test1(x: Any?) {
// condition == true <=> function returned null <=> 'x' is String
if (nullWhenString(x) == null) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun test2(x: Any?) {
// Observe that condition == false <=>* function returned null <=> 'x' is String
// *correct only for at most binary types, which is exactly the case for nullability comparisons
if (nullWhenString(x) != null) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun test3(x: Any?) {
// condition == false <=> function returned not-null, but we don't know anything about when function returns not-null
if (nullWhenNotString(x) == null) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,32 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
// ===== Definitions ====
fun isString(x: Any?): Boolean {
contract {
returns(true) implies (x is String)
}
return x is String
}
// ==== Actual tests =======
fun implicitAlwaysFalse(x: Any?) {
if (isString(x) && !isString(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
else {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun implicitAlwaysFalseSpilling(x: Any?) {
if (isString(x) && !isString(x)) {
x.<!UNRESOLVED_REFERENCE!>length<!>
}
x.<!UNRESOLVED_REFERENCE!>length<!>
}
@@ -0,0 +1,11 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun f3(value: String?) {
if (!value.isNullOrEmpty() is Boolean) {
value.<!INAPPLICABLE_CANDIDATE!>length<!>
}
}
@@ -0,0 +1,36 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun isString(x: Any?): Boolean {
contract {
returns(true) implies (x is String)
}
return x is String
}
fun exhaustive(x: Any?) {
when (isString(x)) {
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when(!isString(x)) {
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun smartcastInElse(x: Any?) {
when (isString(x)) {
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
else -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when (!isString(x)) {
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
else -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,56 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun safeIsString(x: Any?): Boolean? {
contract {
returns(true) implies (x is String)
}
return x?.let { it is String }
}
fun elseWithNullableResult(x: Any?) {
when (safeIsString(x)) {
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
else -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when (safeIsString(x)) {
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
else -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when (safeIsString(x)) {
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
else -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when (safeIsString(x)) {
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
null -> x.<!UNRESOLVED_REFERENCE!>length<!>
else -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun exhaustiveWithNullableResult(x: Any?) {
when (safeIsString(x)) {
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
null -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when (safeIsString(x)) {
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
null -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when (safeIsString(x)) {
false -> x.<!UNRESOLVED_REFERENCE!>length<!>
null -> x.<!UNRESOLVED_REFERENCE!>length<!>
true -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
@@ -0,0 +1,31 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun isString(x: Any?): Boolean {
contract {
returns(true) implies (x is String)
}
return x is String
}
fun exhaustive(x: Any?) {
when {
isString(x) -> x.<!UNRESOLVED_REFERENCE!>length<!>
!isString(x) -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
when {
!isString(x) -> x.<!UNRESOLVED_REFERENCE!>length<!>
isString(x) -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun smartcastInElse(x: Any?) {
when {
!isString(x) -> x.<!UNRESOLVED_REFERENCE!>length<!>
else -> x.<!UNRESOLVED_REFERENCE!>length<!>
}
}