From ecb3f10e47a0c0334526625dad8a30636129033b Mon Sep 17 00:00:00 2001 From: "victor.petukhov" Date: Tue, 25 Sep 2018 12:16:29 +0300 Subject: [PATCH] Add 'mute' concept: move tests with unexpected behaviour to the corresponding folder --- .../linked/when-expression/p-11/neg/7.1.kt | 6 +- .../linked/when-expression/p-11/neg/8.2.kt | 30 +- .../linked/when-expression/p-11/neg/8.3.kt | 16 - .../linked/when-expression/p-11/pos/6.1.kt | 19 + .../linked/when-expression/p-11/pos/8.2.kt | 9 + .../linked/when-expression/p-11/pos/8.3.kt | 9 + .../linked/when-expression/p-9/neg/1.1.kt | 16 +- .../linked/when-expression/p-9/pos/1.1.kt | 4 + .../controlFlow/initialization/pos/6.kt | 58 ++ .../controlFlow/initialization/pos/6.txt | 120 +++++ .../contracts/analysis/smartcasts/neg/10.kt | 493 ++++++++++++++++- .../contracts/analysis/smartcasts/neg/10.txt | 276 ++++++++++ .../contracts/analysis/smartcasts/neg/11.kt | 505 +----------------- .../contracts/analysis/smartcasts/neg/11.txt | 164 +----- .../contracts/analysis/smartcasts/neg/2.kt | 7 + .../contracts/analysis/smartcasts/neg/9.kt | 16 +- .../contracts/analysis/smartcasts/pos/12.kt | 37 ++ .../contracts/analysis/smartcasts/pos/13.kt | 44 ++ .../contracts/analysis/smartcasts/pos/13.txt | 13 + .../contracts/analysis/smartcasts/pos/2.kt | 11 + .../contracts/analysis/smartcasts/pos/4.kt | 23 +- .../contracts/analysis/smartcasts/pos/4.txt | 10 +- .../contracts/analysis/smartcasts/pos/8.kt | 2 + .../contracts/analysis/smartcasts/pos/9.kt | 6 - .../contractBuilder/common/neg/14.kt | 58 ++ .../contractBuilder/common/neg/14.txt | 11 + .../common/{pos/5.kt => neg/15.kt} | 8 +- .../common/{pos/5.txt => neg/15.txt} | 0 .../contractBuilder/common/neg/16.kt | 54 ++ .../contractBuilder/common/neg/16.txt | 7 + .../contractBuilder/common/neg/17.kt | 31 ++ .../contractBuilder/common/neg/17.txt | 5 + .../contractBuilder/common/neg/5.kt | 19 +- .../contractBuilder/common/pos/2.kt | 46 +- .../contractBuilder/common/pos/2.txt | 15 +- .../contractBuilder/common/pos/3.kt | 46 +- .../contractBuilder/common/pos/3.txt | 11 +- .../contractBuilder/common/pos/4.kt | 48 +- .../contractBuilder/common/pos/4.txt | 10 +- .../effects/callsInPlace/neg/2.kt | 32 ++ .../effects/callsInPlace/neg/2.txt | 9 + .../effects/callsInPlace/pos/2.kt | 22 +- .../effects/callsInPlace/pos/2.txt | 7 +- .../declarations/contractFunction/neg/2.kt | 10 +- .../declarations/contractFunction/neg/3.kt | 27 + .../declarations/contractFunction/neg/3.txt | 5 + .../declarations/contractFunction/pos/1.kt | 32 +- .../declarations/contractFunction/pos/1.txt | 11 +- 48 files changed, 1505 insertions(+), 913 deletions(-) create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.txt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.txt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/12.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.txt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.txt rename compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/{pos/5.kt => neg/15.kt} (78%) rename compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/{pos/5.txt => neg/15.txt} (100%) create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.txt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.txt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.txt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.kt create mode 100644 compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.txt diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/7.1.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/7.1.kt index 0001763dc26..d279561a5a8 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/7.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/7.1.kt @@ -50,5 +50,9 @@ fun case_6(value_1: _EnumClass): String { } } -// CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty enum class. +/* + CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty enum class. + DISCUSSION + ISSUES: KT-26044 + */ fun case_7(value_1: _EnumClassEmpty): String = when (value_1) { } diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.2.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.2.kt index d6170dbf258..6d985d82b68 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.2.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.2.kt @@ -64,15 +64,6 @@ fun case_8(value_1: _SealedClassMixed?): String = when(val _SealedMixedChildObject1 -> "" } -/* - CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty nullable sealed class (without subtypes). - UNEXPECTED BEHAVIOUR: must be exhaustive - ISSUES: KT-26044 - */ -fun case_9(value: _SealedClassEmpty?): String = when (value) { - null -> "" -} - /* CASE DESCRIPTION: Checking for not exhaustive 'when' on the nullable Any. DISCUSSION: maybe make exhaustive without else? @@ -82,28 +73,9 @@ fun case_10(value_1: Any?): String = when (value_1) { null -> "" } -/* - CASE DESCRIPTION: Checking for not exhaustive 'when' on opposite types. - UNEXPECTED BEHAVIOUR: must be exhaustive - ISSUES: KT-22996 - */ -fun case_11(value: _SealedClass?): String = when (value) { - is _SealedChild1, !is _SealedChild3?, is _SealedChild3? -> "" -} - -/* - CASE DESCRIPTION: Checking for not exhaustive 'when' on opposite types. - UNEXPECTED BEHAVIOUR: must be exhaustive - ISSUES: KT-22996 - */ -fun case_12(value: _SealedClass?): String = when (value) { - is _SealedChild1, !is _SealedChild3 -> "" - is _SealedChild3? -> "" -} - /* CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty sealed class (without subtypes). DISCUSSION ISSUES: KT-26044 */ -fun case_13(value: _SealedClassEmpty): String = when (value) {} +fun case_11(value: _SealedClassEmpty): String = when (value) {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.3.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.3.kt index 415a7fb9c85..ece11e6a51f 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.3.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/neg/8.3.kt @@ -44,19 +44,3 @@ fun case_5(value_1: _EnumClassSingle?): String = when(valu fun case_6(value_1: _EnumClassSingle?): String = when(value_1) { null -> "" } - -/* - CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty nullable enum class. - UNEXPECTED BEHAVIOUR - ISSUES: KT-26044 - */ -fun case_7(value: _EnumClassEmpty?): String = when(value) { - null -> "" -} - -/* - CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty enum class. - DISCUSSION - ISSUES: KT-26044 - */ -fun case_13(value: _EnumClassEmpty): String = when (value) {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/6.1.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/6.1.kt index 6641bffdc81..8f909712253 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/6.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/6.1.kt @@ -64,3 +64,22 @@ fun case_6(value_1: _SealedClassMixed): String = when (value_1) { fun case_7(value_1: _SealedClassEmpty): String = when (value_1) { else -> "" } + +/* + CASE DESCRIPTION: Checking for not exhaustive 'when' on opposite types. + UNEXPECTED BEHAVIOUR: must be exhaustive + ISSUES: KT-22996 + */ +fun case_8(value: _SealedClass?): String = when (value) { + is _SealedChild1, !is _SealedChild3?, is _SealedChild3? -> "" +} + +/* + CASE DESCRIPTION: Checking for not exhaustive 'when' on opposite types. + UNEXPECTED BEHAVIOUR: must be exhaustive + ISSUES: KT-22996 + */ +fun case_9(value: _SealedClass?): String = when (value) { + is _SealedChild1, !is _SealedChild3 -> "" + is _SealedChild3? -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.2.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.2.kt index 8e041d991f5..c6a87649dcb 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.2.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.2.kt @@ -24,3 +24,12 @@ fun case_2(value_1: _EnumClassSingle?): String = when (value_1) { _EnumClassSingle.EVERYTHING -> "" null -> "" } + +/* + CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty nullable enum class. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26044 + */ +fun case_3(value_1: _EnumClassEmpty?): String = when(value_1) { + null -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.3.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.3.kt index c25200d422e..2225144d12d 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.3.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-11/pos/8.3.kt @@ -64,3 +64,12 @@ fun case_6(value_1: _SealedClassMixed?): String = when (value_1) { is _SealedMixedChildObject3 -> "" null -> "" } + +/* + CASE DESCRIPTION: Checking for not exhaustive 'when' on the empty nullable sealed class (without subtypes). + UNEXPECTED BEHAVIOUR: must be exhaustive + ISSUES: KT-26044 + */ +fun case_7(value: _SealedClassEmpty?): String = when (value) { + null -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/neg/1.1.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/neg/1.1.kt index c3320fe2955..7266d0e5ba2 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/neg/1.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/neg/1.1.kt @@ -51,11 +51,7 @@ fun case_2(value_1: Int): String { return "" } -/* - CASE DESCRIPTION: Checking all types except the correct one (numbers) in 'when' without bound value. - UNEXPECTED BEHAVIOUR - ISSUES: KT-25268 -*/ +// CASE DESCRIPTION: Checking all types except the correct one (numbers) in 'when' without bound value. fun case_3(value_1: Int): String { val whenValue = when { value_1 == 0 -> 1 + 1 @@ -72,23 +68,17 @@ fun case_3(value_1: Int): String { whenValue checkType { _() } whenValue checkType { _() } whenValue checkType { _() } - whenValue checkType { _() } // unexpected behaviour! checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) - checkSubtype(whenValue) // unexpected behaviour! return "" } -/* - CASE DESCRIPTION: Checking all types except the correct one (numbers) in 'when' with bound value. - UNEXPECTED BEHAVIOUR - ISSUES: KT-25268 - */ +// CASE DESCRIPTION: Checking all types except the correct one (numbers) in 'when' with bound value. fun case_4(value_1: Int): String { val whenValue = when (value_1) { 0 -> 1 + 1 @@ -105,14 +95,12 @@ fun case_4(value_1: Int): String { whenValue checkType { _() } whenValue checkType { _() } whenValue checkType { _() } - whenValue checkType { _() } // unexpected behaviour! checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) checkSubtype(whenValue) - checkSubtype(whenValue) // unexpected behaviour! return "" } diff --git a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/pos/1.1.kt b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/pos/1.1.kt index 97c41e9a116..3d588f0bfba 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/pos/1.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/when-expression/p-9/pos/1.1.kt @@ -57,6 +57,8 @@ fun case_3(value_1: Int): String { } whenValue checkType { _() } + whenValue checkType { _() } // unexpected behaviour! + checkSubtype(whenValue) // unexpected behaviour! return "" } @@ -77,6 +79,8 @@ fun case_4(value_1: Int): String { } whenValue checkType { _() } + whenValue checkType { _() } // unexpected behaviour! + checkSubtype(whenValue) // unexpected behaviour! return "" } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.kt new file mode 100644 index 00000000000..266cbbbf3ac --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.kt @@ -0,0 +1,58 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !WITH_CONTRACT_FUNCTIONS + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE) + + SECTION: contracts + CATEGORIES: analysis, controlFlow, initialization + NUMBER: 6 + DESCRIPTION: Check the lack of CallsInPlace effect on the lambda in the parentheses. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26229 + */ + +// FILE: contracts.kt + +package contracts + +import kotlin.contracts.* + +inline fun case_3(block1: () -> Unit, block2: () -> Unit, block3: () -> Unit) { + contract { + callsInPlace(block1, InvocationKind.EXACTLY_ONCE) + callsInPlace(block2, InvocationKind.AT_LEAST_ONCE) + callsInPlace(block3, InvocationKind.EXACTLY_ONCE) + } + block1() + block2() + block2() + block3() +} + +// FILE: usages.kt + +import contracts.* + +fun case_1() { + val value_1: Int + funWithExactlyOnceCallsInPlace({ value_1 = 11 }) + value_1.inc() +} + +fun case_2() { + var value_1: Int + funWithAtLeastOnceCallsInPlace({ value_1 = 11 }) + value_1.inc() +} + +fun case_3() { + val value_1: Int + var value_2: Int + val value_3: Int + contracts.case_3({ value_1 = 1 }, { value_2 = 2 }, { value_3 = 3 }) + value_1.inc() + value_2.inc() + value_3.inc() +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.txt new file mode 100644 index 00000000000..454b7a098fd --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/controlFlow/initialization/pos/6.txt @@ -0,0 +1,120 @@ +package + +public fun case_1(): kotlin.Unit +public fun case_2(): kotlin.Unit +public fun case_3(): kotlin.Unit +public inline fun funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> T): T + CallsInPlace(block, AT_LEAST_ONCE) + +public inline fun funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, AT_LEAST_ONCE) + +public inline fun funWithAtMostOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, AT_MOST_ONCE) + +public inline fun funWithExactlyOnceCallsInPlace(/*0*/ block: () -> T): T + CallsInPlace(block, EXACTLY_ONCE) + +public inline fun funWithExactlyOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, EXACTLY_ONCE) + +public fun funWithReturns(/*0*/ cond: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> cond + +public fun funWithReturnsAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> !cond + +public fun funWithReturnsAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 !is String + +public fun funWithReturnsAndNotNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 != null + +public fun funWithReturnsAndNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 == null + +public fun funWithReturnsAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 is String + +public fun funWithReturnsFalse(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(FALSE) -> cond + +public fun funWithReturnsFalseAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(FALSE) -> !cond + +public fun funWithReturnsFalseAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(FALSE) -> value_1 !is String + +public fun funWithReturnsFalseAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean + Returns(FALSE) -> value_1 != null + +public fun funWithReturnsFalseAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean + Returns(FALSE) -> value_1 == null + +public fun funWithReturnsFalseAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(FALSE) -> value_1 is String + +public fun funWithReturnsNotNull(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NOT_NULL) -> cond + +public fun funWithReturnsNotNullAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NOT_NULL) -> !cond + +public fun funWithReturnsNotNullAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 !is String + +public fun funWithReturnsNotNullAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 != null + +public fun funWithReturnsNotNullAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 == null + +public fun funWithReturnsNotNullAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 is String + +public fun funWithReturnsNull(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NULL) -> cond + +public fun funWithReturnsNullAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NULL) -> !cond + +public fun funWithReturnsNullAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NULL) -> value_1 !is String + +public fun funWithReturnsNullAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NULL) -> value_1 != null + +public fun funWithReturnsNullAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NULL) -> value_1 == null + +public fun funWithReturnsNullAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NULL) -> value_1 is String + +public fun funWithReturnsTrue(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(TRUE) -> cond + +public fun funWithReturnsTrueAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(TRUE) -> !cond + +public fun funWithReturnsTrueAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 !is String + +public fun funWithReturnsTrueAndNotNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 != null + +public fun funWithReturnsTrueAndNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 == null + +public fun funWithReturnsTrueAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 is String + +public inline fun funWithUnknownCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, UNKNOWN) + +package contracts { + public inline fun case_3(/*0*/ block1: () -> kotlin.Unit, /*1*/ block2: () -> kotlin.Unit, /*2*/ block3: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block1, EXACTLY_ONCE) + CallsInPlace(block2, AT_LEAST_ONCE) + CallsInPlace(block3, EXACTLY_ONCE) + +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.kt index f213bd2aab2..30afcd32a52 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.kt @@ -1,7 +1,7 @@ // !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts // !WITH_CONTRACT_FUNCTIONS -// SKIP_TXT /* KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) @@ -9,27 +9,488 @@ SECTION: contracts CATEGORIES: analysis, smartcasts NUMBER: 10 - DESCRIPTION: Check the lack of smartcasts after non-null assertions or not-null value assignment in lambdas of contract function with 'unknown' or 'at most once' CallsInPlace effects. + DESCRIPTION: Check smartcasts using double negation (returnsFalse/invert type checking/not operator). + ISSUES: KT-26176 */ -fun case_1(arg: Int?) { - funWithAtMostOnceCallsInPlace { arg!! } - arg.inc() +// FILE: contracts.kt + +package contracts + +import kotlin.contracts.* + +fun case_1(x: Any?): Boolean { + contract { returns(true) implies (x !is Number) } + return x !is Number } -fun case_2(arg: Int?) { - funWithUnknownCallsInPlace { arg!! } - arg.inc() +fun case_2(x: Any?): Boolean { + contract { returns(true) implies (x !is Number?) } + return x !is Number? } -fun case_3() { - val value_1: Boolean? - funWithAtMostOnceCallsInPlace { value_1 = false } - value_1.not() +fun case_16_1(value_1: Any?, value_2: Any?): Boolean { + contract { returns(true) implies (value_1 !is String || value_2 !is Number) } + return value_1 !is String || value_2 !is Number +} +fun case_16_2(value_1: Any?, value_2: Any?): Boolean { + contract { returns(false) implies (value_1 !is String || value_2 !is Number) } + return !(value_1 !is String || value_2 !is Number) +} +fun case_16_3(value_1: Any?, value_2: Any?): Boolean? { + contract { returnsNotNull() implies (value_1 !is String || value_2 !is Number) } + return if (value_1 !is String || value_2 !is Number) true else null +} +fun case_16_4(value_1: Any?, value_2: Any?): Boolean? { + contract { returns(null) implies (value_1 !is String || value_2 !is Number) } + return if (value_1 !is String || value_2 !is Number) null else true } -fun case_4() { - val value_1: Boolean? - funWithUnknownCallsInPlace { value_1 = true } - value_1.not() +fun case_17_1(value_1: Any?, value_2: Any?): Boolean { + contract { returns(true) implies (value_1 !is String || value_2 != null) } + return value_1 !is String || value_2 != null +} +fun case_17_2(value_1: Any?, value_2: Any?): Boolean { + contract { returns(false) implies (value_1 !is String || value_2 != null) } + return !(value_1 !is String || value_2 != null) +} +fun case_17_3(value_1: Any?, value_2: Any?): Boolean? { + contract { returnsNotNull() implies (value_1 !is String || value_2 != null) } + return if (value_1 !is String || value_2 != null) true else null +} +fun case_17_4(value_1: Any?, value_2: Any?): Boolean? { + contract { returns(null) implies (value_1 !is String || value_2 != null) } + return if (value_1 !is String || value_2 != null) null else true +} + +fun case_18_1(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean { + contract { returns(true) implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } + return value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null +} +fun case_18_2(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean { + contract { returns(false) implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } + return !(value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) +} +fun case_18_3(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean? { + contract { returnsNotNull() implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } + return if (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) true else null +} +fun case_18_4(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean? { + contract { returns(null) implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } + return if (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) null else true +} + +fun T.case_19_1(): Boolean { + contract { returns(true) implies (this@case_19_1 !is String) } + return this@case_19_1 !is String +} +fun T.case_19_2(): Boolean { + contract { returns(false) implies (this@case_19_2 is String) } + return !(this@case_19_2 is String) +} +fun T.case_19_3(): Boolean? { + contract { returnsNotNull() implies (this@case_19_3 is String) } + return if (this@case_19_3 is String) true else null +} +fun T.case_19_4(): Boolean? { + contract { returns(null) implies (this@case_19_4 is String) } + return if (this@case_19_4 is String) null else true +} + +fun T.case_20_1(): Boolean { + contract { returns(true) implies (this@case_20_1 !is Int) } + return this@case_20_1 !is Int +} +fun T.case_20_2(): Boolean { + contract { returns(false) implies (this@case_20_2 is Int) } + return !(this@case_20_2 is Int) +} +fun T.case_20_3(): Boolean? { + contract { returnsNotNull() implies (this@case_20_3 is Int) } + return if (this@case_20_3 is Int) true else null +} +fun T.case_20_4(): Boolean? { + contract { returns(null) implies (this@case_20_4 is Int) } + return if (this@case_20_4 is Int) null else true +} + +fun String> T?.case_21_1(): Boolean { + contract { returns(true) implies (this@case_21_1 != null) } + return this@case_21_1 != null +} +fun String> T?.case_21_2(): Boolean { + contract { returns(true) implies (this@case_21_2 == null) } + return this@case_21_2 == null +} +fun String> T?.case_21_3(): Boolean { + contract { returns(false) implies (this@case_21_3 != null) } + return !(this@case_21_3 != null) +} + +fun T.case_22_1(): Boolean { + contract { returns(true) implies (this@case_22_1 != null) } + return this@case_22_1 != null +} +fun T.case_22_2(): Boolean { + contract { returns(true) implies (this@case_22_2 == null) } + return this@case_22_2 == null +} +fun String> T?.case_22_5(): Boolean? { + contract { returnsNotNull() implies (this@case_22_5 != null) } + return if (this@case_22_5 != null) true else null +} +fun String> T?.case_22_7(): Boolean? { + contract { returns(null) implies (this@case_22_7 != null) } + return if (this@case_22_7 != null) null else true +} + +fun T?.case_23_1(): Boolean { + contract { returns(false) implies (this@case_23_1 == null || this@case_23_1 !is String) } + return !(this@case_23_1 == null || this@case_23_1 !is String) +} +fun T?.case_23_2(): Boolean? { + contract { returnsNotNull() implies (this@case_23_2 == null || this@case_23_2 !is String) } + return if (this@case_23_2 == null || this@case_23_2 !is String) true else null +} +fun T?.case_23_3(): Boolean? { + contract { returns(null) implies (this@case_23_3 == null || this@case_23_3 !is String) } + return if (this@case_23_3 == null || this@case_23_3 !is String) null else true +} + +fun T.case_24_1(): Boolean { + contract { returns(false) implies (this@case_24_1 !is Int || this@case_24_1 == null) } + return !(this@case_24_1 !is Int || this@case_24_1 == null) +} +fun T.case_24_2(): Boolean? { + contract { returnsNotNull() implies (this@case_24_2 !is Int || this@case_24_2 == null) } + return if (this@case_24_2 !is Int || this@case_24_2 == null) true else null +} +fun T.case_24_3(): Boolean? { + contract { returns(null) implies (this@case_24_3 !is Int || this@case_24_3 == null) } + return if (this@case_24_3 !is Int || this@case_24_3 == null) null else true +} + +inline fun T?.case_25_1(): Boolean { + contract { returns(false) implies (this@case_25_1 !is Number || this@case_25_1 !is Int || this@case_25_1 == null) } + return !(this@case_25_1 !is Number || this@case_25_1 !is Int || this@case_25_1 == null) +} +inline fun T?.case_25_2(): Boolean? { + contract { returnsNotNull() implies (this@case_25_2 !is Number || this@case_25_2 !is Int || this@case_25_2 == null) } + return if (this@case_25_2 !is Number || this@case_25_2 !is Int || this@case_25_2 == null) true else null +} +inline fun T?.case_25_3(): Boolean? { + contract { returns(null) implies (this@case_25_3 !is Number || this@case_25_3 !is Int || this@case_25_3 == null) } + return if (this@case_25_3 !is Number || this@case_25_3 !is Int || this@case_25_3 == null) null else true +} + +fun T?.case_26_1(value_1: Int?): Boolean { + contract { returns(false) implies (this@case_26_1 == null || this@case_26_1 !is String || value_1 == null) } + return !(this@case_26_1 == null || this@case_26_1 !is String || value_1 == null) +} +fun T?.case_26_2(value_1: Int?): Boolean? { + contract { returnsNotNull() implies (this@case_26_2 == null || this@case_26_2 !is String || value_1 == null) } + return if (this@case_26_2 == null || this@case_26_2 !is String || value_1 == null) true else null +} +fun T?.case_26_3(value_1: Int?): Boolean? { + contract { returns(null) implies (this@case_26_3 == null || this@case_26_3 !is String || value_1 == null) } + return if (this@case_26_3 == null || this@case_26_3 !is String || value_1 == null) null else true +} + +// FILE: usages.kt + +import contracts.* + +fun case_1(value_1: Any?) { + if (!contracts.case_1(value_1)) println(value_1.toByte()) // no smartcast +} + +fun case_2(value_1: Any?) { + if (!contracts.case_2(value_1)) println(value_1?.toByte()) // no smartcast +} + +fun case_3(number: Int?) { + if (!funWithReturnsTrueAndNullCheck(number)) number.inc() // nullable receiver +} + +fun case_5(value_1: Any?) { + if (!funWithReturnsTrue(value_1 !is String)) println(value_1.length) +} + +fun case_6(value_1: Any?) { + if (!funWithReturnsTrueAndInvertCondition(value_1 is String)) println(value_1.length) + if (funWithReturnsFalse(value_1 !is String)) println(value_1.length) + if (funWithReturnsFalseAndInvertCondition(value_1 is String)) println(value_1.length) + if (!(funWithReturnsNotNullAndInvertCondition(value_1 !is String) != null)) println(value_1.length) + if (!(funWithReturnsNullAndInvertCondition(value_1 !is String) == null)) println(value_1.length) +} + +fun case_7(value_1: Any?) { + if (!funWithReturnsTrue(value_1 == null)) println(value_1.length) +} + +fun case_8(value_1: Any?) { + if (!funWithReturnsTrueAndInvertCondition(value_1 != null)) println(value_1.length) + if (funWithReturnsFalse(value_1 == null)) println(value_1.length) + if (funWithReturnsFalseAndInvertCondition(value_1 != null)) println(value_1.length) +} + +fun case_9(value_1: Any?) { + if (!funWithReturnsTrueAndInvertTypeCheck(value_1)) println(value_1.length) + if (funWithReturnsFalseAndInvertTypeCheck(value_1)) println(value_1.length) +} + +fun case_10(value_1: Number?) { + if (!funWithReturnsTrueAndNullCheck(value_1)) println(value_1.toByte()) + if (funWithReturnsFalseAndNullCheck(value_1)) println(value_1.toByte()) + if (funWithReturnsFalseAndNotNullCheck(value_1)) println(value_1) + if (!(funWithReturnsNotNullAndNullCheck(value_1) != null)) println(value_1) + if (!(funWithReturnsNullAndNullCheck(value_1) == null)) println(value_1) +} + +fun case_11(value_1: Any?, value_2: Any?) { + if (!funWithReturnsTrueAndInvertCondition(value_1 is String && value_2 is Number)) { + println(value_1.length) + println(value_2.toByte()) + } +} + +fun case_12(value_1: Any?, value_2: Any?) { + if (!funWithReturnsTrue(value_1 !is String || value_2 !is Number)) { + println(value_1.length) + println(value_2.toByte()) + } + if (funWithReturnsFalse(value_1 !is String || value_2 !is Number)) { + println(value_1.length) + println(value_2.toByte()) + } +} + +fun case_13(value_1: Any?, value_2: Any?) { + if (!funWithReturnsTrue(value_1 !is String || value_2 != null)) { + println(value_1.length) + println(value_2?.toByte()) + } + if (funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null)) { + println(value_1.dec()) + println(value_2?.toByte()) + } + if (funWithReturnsNotNull(value_1 !is String || value_2 !is Number) == null) { + println(value_1.length) + println(value_2.toByte()) + } + if (funWithReturnsNull(value_1 !is String || value_2 !is Number) != null) { + println(value_1.length) + println(value_2.toByte()) + } +} + +fun case_14(value_1: Any?, value_2: Any?) { + if (!funWithReturnsTrueAndInvertCondition(value_1 is Float? && value_1 != null && value_2 != null)) { + println(value_1.dec()) + println(value_2?.toByte()) + } + if (funWithReturnsFalseAndInvertCondition(value_1 is String && value_2 is Number)) { + println(value_1.length) + println(value_2.toByte()) + } + if (funWithReturnsFalseAndInvertCondition(value_1 is String && value_2 == null)) { + println(value_1.length) + println(value_2?.toByte()) + } + if (funWithReturnsNotNullAndInvertCondition(value_1 is String && value_2 is Number) == null) { + println(value_1.length) + println(value_2.toByte()) + } + if (funWithReturnsNotNullAndInvertCondition(value_1 is String && value_2 == null) == null) { + println(value_1.length) + println(value_2?.toByte()) + } + if (funWithReturnsNotNull(value_1 is Float? && value_1 != null && value_2 != null) == null) { + println(value_1.dec()) + println(value_2?.toByte()) + } + if (funWithReturnsNullAndInvertCondition(value_1 is String && value_2 is Number) != null) { + println(value_1.length) + println(value_2.toByte()) + } + if (funWithReturnsNullAndInvertCondition(value_1 is String && value_2 == null) != null) { + println(value_1.length) + println(value_2?.toByte()) + } + if (funWithReturnsNull(value_1 is Float? && value_1 != null && value_2 != null) != null) { + println(value_1.dec()) + println(value_2?.toByte()) + } +} + +class case_15_class { + val prop_1: Int? = 10 + + fun case_15(value_1: Any?, value_2: Number?) { + val o = case_15_class() + if (!funWithReturnsTrueAndInvertCondition(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null)) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + } + if (funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + } + if (funWithReturnsNotNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) == null) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + } + if (funWithReturnsNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) != null) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + } + } +} + +fun case_16(value_1: Any?, value_2: Any?) { + if (!contracts.case_16_1(value_1, value_2)) { + println(value_1.length) + println(value_2.toByte()) + } + if (contracts.case_16_2(value_1, value_2)) { + println(value_1.length) + println(value_2.toByte()) + } + if (!(contracts.case_16_3(value_1, value_2) != null)) { + println(value_1.length) + println(value_2.toByte()) + } + if (!(contracts.case_16_4(value_1, value_2) == null)) { + println(value_1.length) + println(value_2.toByte()) + } +} + +fun case_17(value_1: Any?, value_2: Any?) { + if (!contracts.case_17_1(value_1, value_2)) { + println(value_1.length) + println(value_2?.toByte()) + } + if (contracts.case_17_2(value_1, value_2)) { + println(value_1.length) + println(value_2?.toByte()) + } + if (contracts.case_17_3(value_1, value_2) == null) { + println(value_1.length) + println(value_2?.toByte()) + } + if (contracts.case_17_4(value_1, value_2) != null) { + println(value_1.length) + println(value_2?.toByte()) + } +} + +class case_18_class { + val prop_1: Int? = 10 + fun case_18(value_1: Any?, value_2: Number?) { + val o = case_18_class() + if (contracts.case_18_1(value_1, value_2, o.prop_1, this.prop_1)) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } + if (contracts.case_18_2(value_1, value_2, o.prop_1, this.prop_1)) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } + if (contracts.case_18_3(value_1, value_2, o.prop_1, this.prop_1) == null) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } + if (contracts.case_18_4(value_1, value_2, o.prop_1, this.prop_1) != null) { + println(value_1.dec()) + println(value_2?.toByte()) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } + } +} + +fun case_19(value_1: Any?) { + if (!value_1.case_19_1()) println(value_1.length) + if (value_1.case_19_2()) println(value_1.length) + if (value_1.case_19_3() == null) println(value_1.length) + if (value_1.case_19_4() != null) println(value_1.length) +} + +fun case_20(value_1: Number) { + when { !value_1.case_20_1() -> println(value_1.inv()) } + when { value_1.case_20_2() -> println(value_1.inv()) } + when { value_1.case_20_3() == null -> println(value_1.inv()) } + when { value_1.case_20_4() != null -> println(value_1.inv()) } +} + +fun case_21(value_1: String?, value_2: String?, value_3: String?, value_4: String?) { + if (!value_1.case_21_1()) println(value_1) + if (!value_2.case_21_2()) println(value_2.length) + when (value_3.case_21_3()) { + true -> println(value_4.length) + false -> println(value_3) + } +} + +fun case_22(value_1: String?) { + when { !value_1.case_22_1() -> println(value_1) } + when { !value_1.case_22_2() -> println(value_1.length) } + when { + value_1.case_22_5() == null -> println(value_1.length) + value_1.case_22_5() != null -> println(value_1) + } + when { + value_1.case_22_7() != null -> println(value_1.length) + value_1.case_22_7() == null -> println(value_1) + } +} + +fun case_23(value_1: Any?, value_2: Any?) { + when { value_1.case_23_1() -> println(value_1.length) } + when { value_2.case_23_2() == null -> println(value_2.length) } + when { value_2.case_23_3() != null -> println(value_2.length) } +} + +fun case_24(value_1: Number?, value_2: Number?) { + if (value_1.case_24_1()) println(value_1.inv()) + if (value_2.case_24_2() == null) println(value_2.inv()) + if (value_2.case_24_3() != null) println(value_2.inv()) +} + +fun case_25(value_1: Any?, value_2: Any?) { + if (value_1.case_25_1()) println(value_1.inv()) + if (value_2.case_25_2() != null) println(value_2.inv()) + if (value_2.case_25_3() == null) println(value_2.inv()) +} + +fun case_26(value_1: Any?, value_2: Int?, value_3: Any?, value_4: Int?) { + when { + value_1.case_26_1(value_2) -> { + println(value_1.length) + println(value_2.inv()) + } + } + when { + value_3.case_26_2(value_4) == null -> { + println(value_3.length) + println(value_4.inv()) + } + } + when { + value_3.case_26_3(value_4) != null -> { + println(value_3.length) + println(value_4.inv()) + } + } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.txt new file mode 100644 index 00000000000..38cae413c7e --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.txt @@ -0,0 +1,276 @@ +package + +public fun case_1(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_10(/*0*/ value_1: kotlin.Number?): kotlin.Unit +public fun case_11(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_12(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_13(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_14(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_16(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_17(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_19(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_2(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_20(/*0*/ value_1: kotlin.Number): kotlin.Unit +public fun case_21(/*0*/ value_1: kotlin.String?, /*1*/ value_2: kotlin.String?, /*2*/ value_3: kotlin.String?, /*3*/ value_4: kotlin.String?): kotlin.Unit +public fun case_22(/*0*/ value_1: kotlin.String?): kotlin.Unit +public fun case_23(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_24(/*0*/ value_1: kotlin.Number?, /*1*/ value_2: kotlin.Number?): kotlin.Unit +public fun case_25(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit +public fun case_26(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Int?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Int?): kotlin.Unit +public fun case_3(/*0*/ number: kotlin.Int?): kotlin.Unit +public fun case_5(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_6(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_7(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_8(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_9(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public inline fun funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> T): T + CallsInPlace(block, AT_LEAST_ONCE) + +public inline fun funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, AT_LEAST_ONCE) + +public inline fun funWithAtMostOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, AT_MOST_ONCE) + +public inline fun funWithExactlyOnceCallsInPlace(/*0*/ block: () -> T): T + CallsInPlace(block, EXACTLY_ONCE) + +public inline fun funWithExactlyOnceCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, EXACTLY_ONCE) + +public fun funWithReturns(/*0*/ cond: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> cond + +public fun funWithReturnsAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> !cond + +public fun funWithReturnsAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 !is String + +public fun funWithReturnsAndNotNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 != null + +public fun funWithReturnsAndNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 == null + +public fun funWithReturnsAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 is String + +public fun funWithReturnsFalse(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(FALSE) -> cond + +public fun funWithReturnsFalseAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(FALSE) -> !cond + +public fun funWithReturnsFalseAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(FALSE) -> value_1 !is String + +public fun funWithReturnsFalseAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean + Returns(FALSE) -> value_1 != null + +public fun funWithReturnsFalseAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean + Returns(FALSE) -> value_1 == null + +public fun funWithReturnsFalseAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(FALSE) -> value_1 is String + +public fun funWithReturnsNotNull(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NOT_NULL) -> cond + +public fun funWithReturnsNotNullAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NOT_NULL) -> !cond + +public fun funWithReturnsNotNullAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 !is String + +public fun funWithReturnsNotNullAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 != null + +public fun funWithReturnsNotNullAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 == null + +public fun funWithReturnsNotNullAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 is String + +public fun funWithReturnsNull(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NULL) -> cond + +public fun funWithReturnsNullAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean? + Returns(NULL) -> !cond + +public fun funWithReturnsNullAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NULL) -> value_1 !is String + +public fun funWithReturnsNullAndNotNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NULL) -> value_1 != null + +public fun funWithReturnsNullAndNullCheck(/*0*/ value_1: kotlin.Number?): kotlin.Boolean? + Returns(NULL) -> value_1 == null + +public fun funWithReturnsNullAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean? + Returns(NULL) -> value_1 is String + +public fun funWithReturnsTrue(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(TRUE) -> cond + +public fun funWithReturnsTrueAndInvertCondition(/*0*/ cond: kotlin.Boolean): kotlin.Boolean + Returns(TRUE) -> !cond + +public fun funWithReturnsTrueAndInvertTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 !is String + +public fun funWithReturnsTrueAndNotNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 != null + +public fun funWithReturnsTrueAndNullCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 == null + +public fun funWithReturnsTrueAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 is String + +public inline fun funWithUnknownCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, UNKNOWN) + +public final class case_15_class { + public constructor case_15_class() + public final val prop_1: kotlin.Int? = 10 + public final fun case_15(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Number?): kotlin.Unit + 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 +} + +public final class case_18_class { + public constructor case_18_class() + public final val prop_1: kotlin.Int? = 10 + public final fun case_18(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Number?): kotlin.Unit + 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 +} + +package contracts { + public fun case_1(/*0*/ x: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> x !is Number + + public fun case_16_1(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 !is String || value_2 !is Number + + public fun case_16_2(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean + Returns(FALSE) -> value_1 !is String || value_2 !is Number + + public fun case_16_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 !is String || value_2 !is Number + + public fun case_16_4(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? + Returns(NULL) -> value_1 !is String || value_2 !is Number + + public fun case_17_1(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 !is String || value_2 != null + + public fun case_17_2(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean + Returns(FALSE) -> value_1 !is String || value_2 != null + + public fun case_17_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 !is String || value_2 != null + + public fun case_17_4(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? + Returns(NULL) -> value_1 !is String || value_2 != null + + public fun case_18_1(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null + + public fun case_18_2(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean + Returns(FALSE) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null + + public fun case_18_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean? + Returns(NOT_NULL) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null + + public fun case_18_4(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean? + Returns(NULL) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null + + public fun case_2(/*0*/ x: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> x !is Number? + + public fun T.case_19_1(): kotlin.Boolean + Returns(TRUE) -> !is String + + public fun T.case_19_2(): kotlin.Boolean + Returns(FALSE) -> is String + + public fun T.case_19_3(): kotlin.Boolean? + Returns(NOT_NULL) -> is String + + public fun T.case_19_4(): kotlin.Boolean? + Returns(NULL) -> is String + + public fun T.case_20_1(): kotlin.Boolean + Returns(TRUE) -> !is Int + + public fun T.case_20_2(): kotlin.Boolean + Returns(FALSE) -> is Int + + public fun T.case_20_3(): kotlin.Boolean? + Returns(NOT_NULL) -> is Int + + public fun T.case_20_4(): kotlin.Boolean? + Returns(NULL) -> is Int + + public fun T?.case_21_1(): kotlin.Boolean + Returns(TRUE) -> != null + + public fun T?.case_21_2(): kotlin.Boolean + Returns(TRUE) -> == null + + public fun T?.case_21_3(): kotlin.Boolean + Returns(FALSE) -> != null + + public fun T.case_22_1(): kotlin.Boolean + Returns(TRUE) -> != null + + public fun T.case_22_2(): kotlin.Boolean + Returns(TRUE) -> == null + + public fun T?.case_22_5(): kotlin.Boolean? + Returns(NOT_NULL) -> != null + + public fun T?.case_22_7(): kotlin.Boolean? + Returns(NULL) -> != null + + public fun T?.case_23_1(): kotlin.Boolean + Returns(FALSE) -> == null || !is String + + public fun T?.case_23_2(): kotlin.Boolean? + Returns(NOT_NULL) -> == null || !is String + + public fun T?.case_23_3(): kotlin.Boolean? + Returns(NULL) -> == null || !is String + + public fun T.case_24_1(): kotlin.Boolean + Returns(FALSE) -> !is Int || == null + + public fun T.case_24_2(): kotlin.Boolean? + Returns(NOT_NULL) -> !is Int || == null + + public fun T.case_24_3(): kotlin.Boolean? + Returns(NULL) -> !is Int || == null + + public inline fun T?.case_25_1(): kotlin.Boolean + Returns(FALSE) -> !is Number || !is Int || == null + + public inline fun T?.case_25_2(): kotlin.Boolean? + Returns(NOT_NULL) -> !is Number || !is Int || == null + + public inline fun T?.case_25_3(): kotlin.Boolean? + Returns(NULL) -> !is Number || !is Int || == null + + public fun T?.case_26_1(/*0*/ value_1: kotlin.Int?): kotlin.Boolean + Returns(FALSE) -> == null || !is String || value_1 == null + + public fun T?.case_26_2(/*0*/ value_1: kotlin.Int?): kotlin.Boolean? + Returns(NOT_NULL) -> == null || !is String || value_1 == null + + public fun T?.case_26_3(/*0*/ value_1: kotlin.Int?): kotlin.Boolean? + Returns(NULL) -> == null || !is String || value_1 == null + +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.kt index dc2ee44c1ea..106d9851edf 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.kt @@ -1,7 +1,7 @@ -// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !WITH_CONTRACT_FUNCTIONS // !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts -// !WITH_CONTRACT_FUNCTIONS /* KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) @@ -9,9 +9,7 @@ SECTION: contracts CATEGORIES: analysis, smartcasts NUMBER: 11 - DESCRIPTION: Check smartcasts using double negation (returnsFalse/invert type checking/not operator). - UNEXPECTED BEHAVIOUR - ISSUES: KT-26176 + DESCRIPTION: Smartcast using many of the various Returns effects on the same values. */ // FILE: contracts.kt @@ -20,181 +18,23 @@ package contracts import kotlin.contracts.* -fun case_1(x: Any?): Boolean { - contract { returns(true) implies (x !is Number) } - return x !is Number +fun T?.case_1_1(): Boolean { + contract { returns(false) implies (this@case_1_1 != null) } + return !(this@case_1_1 != null) } -fun case_2(x: Any?): Boolean { - contract { returns(true) implies (x !is Number?) } - return x !is Number? +fun T?.case_1_2(): Boolean? { + contract { returns(null) implies (this@case_1_2 is String) } + return if (this@case_1_2 is String) null else true } -fun case_16_1(value_1: Any?, value_2: Any?): Boolean { - contract { returns(true) implies (value_1 !is String || value_2 !is Number) } - return value_1 !is String || value_2 !is Number +fun T.case_2_1(): Boolean? { + contract { returnsNotNull() implies (this@case_2_1 != null) } + return if (this@case_2_1 != null) true else null } -fun case_16_2(value_1: Any?, value_2: Any?): Boolean { - contract { returns(false) implies (value_1 !is String || value_2 !is Number) } - return !(value_1 !is String || value_2 !is Number) -} -fun case_16_3(value_1: Any?, value_2: Any?): Boolean? { - contract { returnsNotNull() implies (value_1 !is String || value_2 !is Number) } - return if (value_1 !is String || value_2 !is Number) true else null -} -fun case_16_4(value_1: Any?, value_2: Any?): Boolean? { - contract { returns(null) implies (value_1 !is String || value_2 !is Number) } - return if (value_1 !is String || value_2 !is Number) null else true -} - -fun case_17_1(value_1: Any?, value_2: Any?): Boolean { - contract { returns(true) implies (value_1 !is String || value_2 != null) } - return value_1 !is String || value_2 != null -} -fun case_17_2(value_1: Any?, value_2: Any?): Boolean { - contract { returns(false) implies (value_1 !is String || value_2 != null) } - return !(value_1 !is String || value_2 != null) -} -fun case_17_3(value_1: Any?, value_2: Any?): Boolean? { - contract { returnsNotNull() implies (value_1 !is String || value_2 != null) } - return if (value_1 !is String || value_2 != null) true else null -} -fun case_17_4(value_1: Any?, value_2: Any?): Boolean? { - contract { returns(null) implies (value_1 !is String || value_2 != null) } - return if (value_1 !is String || value_2 != null) null else true -} - -fun case_18_1(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean { - contract { returns(true) implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } - return value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null -} -fun case_18_2(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean { - contract { returns(false) implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } - return !(value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) -} -fun case_18_3(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean? { - contract { returnsNotNull() implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } - return if (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) true else null -} -fun case_18_4(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?): Boolean? { - contract { returns(null) implies (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) } - return if (value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null) null else true -} - -fun T.case_19_1(): Boolean { - contract { returns(true) implies (this@case_19_1 !is String) } - return this@case_19_1 !is String -} -fun T.case_19_2(): Boolean { - contract { returns(false) implies (this@case_19_2 is String) } - return !(this@case_19_2 is String) -} -fun T.case_19_3(): Boolean? { - contract { returnsNotNull() implies (this@case_19_3 is String) } - return if (this@case_19_3 is String) true else null -} -fun T.case_19_4(): Boolean? { - contract { returns(null) implies (this@case_19_4 is String) } - return if (this@case_19_4 is String) null else true -} - -fun T.case_20_1(): Boolean { - contract { returns(true) implies (this@case_20_1 !is Int) } - return this@case_20_1 !is Int -} -fun T.case_20_2(): Boolean { - contract { returns(false) implies (this@case_20_2 is Int) } - return !(this@case_20_2 is Int) -} -fun T.case_20_3(): Boolean? { - contract { returnsNotNull() implies (this@case_20_3 is Int) } - return if (this@case_20_3 is Int) true else null -} -fun T.case_20_4(): Boolean? { - contract { returns(null) implies (this@case_20_4 is Int) } - return if (this@case_20_4 is Int) null else true -} - -fun String> T?.case_21_1(): Boolean { - contract { returns(true) implies (this@case_21_1 != null) } - return this@case_21_1 != null -} -fun String> T?.case_21_2(): Boolean { - contract { returns(true) implies (this@case_21_2 == null) } - return this@case_21_2 == null -} -fun String> T?.case_21_3(): Boolean { - contract { returns(false) implies (this@case_21_3 != null) } - return !(this@case_21_3 != null) -} - -fun T.case_22_1(): Boolean { - contract { returns(true) implies (this@case_22_1 != null) } - return this@case_22_1 != null -} -fun T.case_22_2(): Boolean { - contract { returns(true) implies (this@case_22_2 == null) } - return this@case_22_2 == null -} -fun String> T?.case_22_5(): Boolean? { - contract { returnsNotNull() implies (this@case_22_5 != null) } - return if (this@case_22_5 != null) true else null -} -fun String> T?.case_22_7(): Boolean? { - contract { returns(null) implies (this@case_22_7 != null) } - return if (this@case_22_7 != null) null else true -} - -fun T?.case_23_1(): Boolean { - contract { returns(false) implies (this@case_23_1 == null || this@case_23_1 !is String) } - return !(this@case_23_1 == null || this@case_23_1 !is String) -} -fun T?.case_23_2(): Boolean? { - contract { returnsNotNull() implies (this@case_23_2 == null || this@case_23_2 !is String) } - return if (this@case_23_2 == null || this@case_23_2 !is String) true else null -} -fun T?.case_23_3(): Boolean? { - contract { returns(null) implies (this@case_23_3 == null || this@case_23_3 !is String) } - return if (this@case_23_3 == null || this@case_23_3 !is String) null else true -} - -fun T.case_24_1(): Boolean { - contract { returns(false) implies (this@case_24_1 !is Int || this@case_24_1 == null) } - return !(this@case_24_1 !is Int || this@case_24_1 == null) -} -fun T.case_24_2(): Boolean? { - contract { returnsNotNull() implies (this@case_24_2 !is Int || this@case_24_2 == null) } - return if (this@case_24_2 !is Int || this@case_24_2 == null) true else null -} -fun T.case_24_3(): Boolean? { - contract { returns(null) implies (this@case_24_3 !is Int || this@case_24_3 == null) } - return if (this@case_24_3 !is Int || this@case_24_3 == null) null else true -} - -inline fun T?.case_25_1(): Boolean { - contract { returns(false) implies (this@case_25_1 !is Number || this@case_25_1 !is Int || this@case_25_1 == null) } - return !(this@case_25_1 !is Number || this@case_25_1 !is Int || this@case_25_1 == null) -} -inline fun T?.case_25_2(): Boolean? { - contract { returnsNotNull() implies (this@case_25_2 !is Number || this@case_25_2 !is Int || this@case_25_2 == null) } - return if (this@case_25_2 !is Number || this@case_25_2 !is Int || this@case_25_2 == null) true else null -} -inline fun T?.case_25_3(): Boolean? { - contract { returns(null) implies (this@case_25_3 !is Number || this@case_25_3 !is Int || this@case_25_3 == null) } - return if (this@case_25_3 !is Number || this@case_25_3 !is Int || this@case_25_3 == null) null else true -} - -fun T?.case_26_1(value_1: Int?): Boolean { - contract { returns(false) implies (this@case_26_1 == null || this@case_26_1 !is String || value_1 == null) } - return !(this@case_26_1 == null || this@case_26_1 !is String || value_1 == null) -} -fun T?.case_26_2(value_1: Int?): Boolean? { - contract { returnsNotNull() implies (this@case_26_2 == null || this@case_26_2 !is String || value_1 == null) } - return if (this@case_26_2 == null || this@case_26_2 !is String || value_1 == null) true else null -} -fun T?.case_26_3(value_1: Int?): Boolean? { - contract { returns(null) implies (this@case_26_3 == null || this@case_26_3 !is String || value_1 == null) } - return if (this@case_26_3 == null || this@case_26_3 !is String || value_1 == null) null else true +fun T.case_2_2(): Boolean? { + contract { returns(null) implies (this@case_2_2 != null) } + return if (this@case_2_2 != null) null else true } // FILE: usages.kt @@ -202,316 +42,13 @@ fun T?.case_26_3(value_1: Int?): Boolean? { import contracts.* fun case_1(value_1: Any?) { - if (!contracts.case_1(value_1)) println(value_1.toByte()) // no smartcast -} - -fun case_2(value_1: Any?) { - if (!contracts.case_2(value_1)) println(value_1?.toByte()) // no smartcast -} - -fun case_3(number: Int?) { - if (!funWithReturnsTrueAndNullCheck(number)) number.inc() // nullable receiver -} - -fun case_5(value_1: Any?) { - if (!funWithReturnsTrue(value_1 !is String)) println(value_1.length) -} - -fun case_6(value_1: Any?) { - if (!funWithReturnsTrueAndInvertCondition(value_1 is String)) println(value_1.length) - if (funWithReturnsFalse(value_1 !is String)) println(value_1.length) - if (funWithReturnsFalseAndInvertCondition(value_1 is String)) println(value_1.length) - if (!(funWithReturnsNotNullAndInvertCondition(value_1 !is String) != null)) println(value_1.length) - if (!(funWithReturnsNullAndInvertCondition(value_1 !is String) == null)) println(value_1.length) -} - -fun case_7(value_1: Any?) { - if (!funWithReturnsTrue(value_1 == null)) println(value_1.length) -} - -fun case_8(value_1: Any?) { - if (!funWithReturnsTrueAndInvertCondition(value_1 != null)) println(value_1.length) - if (funWithReturnsFalse(value_1 == null)) println(value_1.length) - if (funWithReturnsFalseAndInvertCondition(value_1 != null)) println(value_1.length) -} - -fun case_9(value_1: Any?) { - if (!funWithReturnsTrueAndInvertTypeCheck(value_1)) println(value_1.length) - if (funWithReturnsFalseAndInvertTypeCheck(value_1)) println(value_1.length) -} - -fun case_10(value_1: Number?) { - if (!funWithReturnsTrueAndNullCheck(value_1)) println(value_1.toByte()) - if (funWithReturnsFalseAndNullCheck(value_1)) println(value_1.toByte()) - if (funWithReturnsFalseAndNotNullCheck(value_1)) println(value_1) - if (!(funWithReturnsNotNullAndNullCheck(value_1) != null)) println(value_1) - if (!(funWithReturnsNullAndNullCheck(value_1) == null)) println(value_1) -} - -fun case_11(value_1: Any?, value_2: Any?) { - if (!funWithReturnsTrueAndInvertCondition(value_1 is String && value_2 is Number)) { + if (!(value_1.case_1_1() || value_1.case_1_2() == null)) { println(value_1.length) - println(value_2.toByte()) } } -fun case_12(value_1: Any?, value_2: Any?) { - if (!funWithReturnsTrue(value_1 !is String || value_2 !is Number)) { - println(value_1.length) - println(value_2.toByte()) - } - if (funWithReturnsFalse(value_1 !is String || value_2 !is Number)) { - println(value_1.length) - println(value_2.toByte()) - } -} - -fun case_13(value_1: Any?, value_2: Any?) { - if (!funWithReturnsTrue(value_1 !is String || value_2 != null)) { - println(value_1.length) - println(value_2?.toByte()) - } - if (funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null)) { - println(value_1.dec()) - println(value_2?.toByte()) - } - if (funWithReturnsNotNull(value_1 !is String || value_2 !is Number) == null) { - println(value_1.length) - println(value_2.toByte()) - } - if (funWithReturnsNull(value_1 !is String || value_2 !is Number) != null) { - println(value_1.length) - println(value_2.toByte()) - } -} - -fun case_14(value_1: Any?, value_2: Any?) { - if (!funWithReturnsTrueAndInvertCondition(value_1 is Float? && value_1 != null && value_2 != null)) { - println(value_1.dec()) - println(value_2?.toByte()) - } - if (funWithReturnsFalseAndInvertCondition(value_1 is String && value_2 is Number)) { - println(value_1.length) - println(value_2.toByte()) - } - if (funWithReturnsFalseAndInvertCondition(value_1 is String && value_2 == null)) { - println(value_1.length) - println(value_2?.toByte()) - } - if (funWithReturnsNotNullAndInvertCondition(value_1 is String && value_2 is Number) == null) { - println(value_1.length) - println(value_2.toByte()) - } - if (funWithReturnsNotNullAndInvertCondition(value_1 is String && value_2 == null) == null) { - println(value_1.length) - println(value_2?.toByte()) - } - if (funWithReturnsNotNull(value_1 is Float? && value_1 != null && value_2 != null) == null) { - println(value_1.dec()) - println(value_2?.toByte()) - } - if (funWithReturnsNullAndInvertCondition(value_1 is String && value_2 is Number) != null) { - println(value_1.length) - println(value_2.toByte()) - } - if (funWithReturnsNullAndInvertCondition(value_1 is String && value_2 == null) != null) { - println(value_1.length) - println(value_2?.toByte()) - } - if (funWithReturnsNull(value_1 is Float? && value_1 != null && value_2 != null) != null) { - println(value_1.dec()) - println(value_2?.toByte()) - } -} - -class case_15_class { - val prop_1: Int? = 10 - - fun case_15(value_1: Any?, value_2: Number?) { - val o = case_15_class() - if (!funWithReturnsTrueAndInvertCondition(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null)) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - } - if (funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - } - if (funWithReturnsNotNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) == null) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - } - if (funWithReturnsNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) != null) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - } - } -} - -fun case_16(value_1: Any?, value_2: Any?) { - if (!contracts.case_16_1(value_1, value_2)) { - println(value_1.length) - println(value_2.toByte()) - } - if (contracts.case_16_2(value_1, value_2)) { - println(value_1.length) - println(value_2.toByte()) - } - if (!(contracts.case_16_3(value_1, value_2) != null)) { - println(value_1.length) - println(value_2.toByte()) - } - if (!(contracts.case_16_4(value_1, value_2) == null)) { - println(value_1.length) - println(value_2.toByte()) - } -} - -fun case_17(value_1: Any?, value_2: Any?) { - if (!contracts.case_17_1(value_1, value_2)) { - println(value_1.length) - println(value_2?.toByte()) - } - if (contracts.case_17_2(value_1, value_2)) { - println(value_1.length) - println(value_2?.toByte()) - } - if (contracts.case_17_3(value_1, value_2) == null) { - println(value_1.length) - println(value_2?.toByte()) - } - if (contracts.case_17_4(value_1, value_2) != null) { - println(value_1.length) - println(value_2?.toByte()) - } -} - -class case_18_class { - val prop_1: Int? = 10 - fun case_18(value_1: Any?, value_2: Number?) { - val o = case_18_class() - if (contracts.case_18_1(value_1, value_2, o.prop_1, this.prop_1)) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } - if (contracts.case_18_2(value_1, value_2, o.prop_1, this.prop_1)) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } - if (contracts.case_18_3(value_1, value_2, o.prop_1, this.prop_1) == null) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } - if (contracts.case_18_4(value_1, value_2, o.prop_1, this.prop_1) != null) { - println(value_1.dec()) - println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } - } -} - -fun case_19(value_1: Any?) { - if (!value_1.case_19_1()) println(value_1.length) - if (value_1.case_19_2()) println(value_1.length) - if (value_1.case_19_3() == null) println(value_1.length) - if (value_1.case_19_4() != null) println(value_1.length) -} - -fun case_20(value_1: Number) { - when { !value_1.case_20_1() -> println(value_1.inv()) } - when { value_1.case_20_2() -> println(value_1.inv()) } - when { value_1.case_20_3() == null -> println(value_1.inv()) } - when { value_1.case_20_4() != null -> println(value_1.inv()) } -} - -fun case_21(value_1: String?, value_2: String?, value_3: String?, value_4: String?) { - if (!value_1.case_21_1()) println(value_1) - if (!value_2.case_21_2()) println(value_2.length) - when (value_3.case_21_3()) { - true -> println(value_4.length) - false -> println(value_3) - } -} - -fun case_22(value_1: String?) { - when { !value_1.case_22_1() -> println(value_1) } - when { !value_1.case_22_2() -> println(value_1.length) } - when { - value_1.case_22_5() == null -> println(value_1.length) - value_1.case_22_5() != null -> println(value_1) - } - when { - value_1.case_22_7() != null -> println(value_1.length) - value_1.case_22_7() == null -> println(value_1) - } -} - -fun case_23(value_1: Any?, value_2: Any?) { - when { value_1.case_23_1() -> println(value_1.length) } - when { value_2.case_23_2() == null -> println(value_2.length) } - when { value_2.case_23_3() != null -> println(value_2.length) } -} - -fun case_24(value_1: Number?, value_2: Number?) { - if (value_1.case_24_1()) println(value_1.inv()) - if (value_2.case_24_2() == null) println(value_2.inv()) - if (value_2.case_24_3() != null) println(value_2.inv()) -} - -fun case_25(value_1: Any?, value_2: Any?) { - if (value_1.case_25_1()) println(value_1.inv()) - if (value_2.case_25_2() != null) println(value_2.inv()) - if (value_2.case_25_3() == null) println(value_2.inv()) -} - -fun case_26(value_1: Any?, value_2: Int?, value_3: Any?, value_4: Int?) { - when { - value_1.case_26_1(value_2) -> { - println(value_1.length) - println(value_2.inv()) - } - } - when { - value_3.case_26_2(value_4) == null -> { - println(value_3.length) - println(value_4.inv()) - } - } - when { - value_3.case_26_3(value_4) != null -> { - println(value_3.length) - println(value_4.inv()) - } - } -} - -/* - UNEXPECTED BEHAVIOUR - */ -fun case_27(value_1: Any?, value_2: Any?, value_3: Any?) { - funWithReturnsAndInvertCondition(value_1 !is String? || value_2 !is Number && value_3 !is Float) - println(value_1!!.length) - println(value_2.toByte()) - println(value_3.dec()) -} - -/* - UNEXPECTED BEHAVIOUR - */ -fun case_28(value_1: Any?, value_2: Any?, value_3: Any?) { - funWithReturnsAndInvertCondition(value_1 !is String || value_2 !is Number || value_3 !is Any?) - println(value_1!!.length) - println(value_2?.toByte()) - println(value_3.dec()) -} +// DISCUSSION: maybe make unreachable code in the second condition? +fun case_2(value_1: Number?) { + if (value_1?.case_2_1() != null) println(value_1.toByte()) + if (value_1?.case_2_2() != null) println(value_1.toByte()) +} \ No newline at end of file diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.txt index 34994fa3fac..9cc80112b41 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/11.txt @@ -1,30 +1,7 @@ package public fun case_1(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_10(/*0*/ value_1: kotlin.Number?): kotlin.Unit -public fun case_11(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_12(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_13(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_14(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_16(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_17(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_19(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_2(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_20(/*0*/ value_1: kotlin.Number): kotlin.Unit -public fun case_21(/*0*/ value_1: kotlin.String?, /*1*/ value_2: kotlin.String?, /*2*/ value_3: kotlin.String?, /*3*/ value_4: kotlin.String?): kotlin.Unit -public fun case_22(/*0*/ value_1: kotlin.String?): kotlin.Unit -public fun case_23(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_24(/*0*/ value_1: kotlin.Number?, /*1*/ value_2: kotlin.Number?): kotlin.Unit -public fun case_25(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Unit -public fun case_26(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Int?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Int?): kotlin.Unit -public fun case_27(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?): kotlin.Unit -public fun case_28(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?): kotlin.Unit -public fun case_3(/*0*/ number: kotlin.Int?): kotlin.Unit -public fun case_5(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_6(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_7(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_8(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_9(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_2(/*0*/ value_1: kotlin.Number?): kotlin.Unit public inline fun funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> T): T CallsInPlace(block, AT_LEAST_ONCE) @@ -133,146 +110,17 @@ public fun funWithReturnsTrueAndTypeCheck(/*0*/ value_1: kotlin.Any?): kotlin.Bo public inline fun funWithUnknownCallsInPlace(/*0*/ block: () -> kotlin.Unit): kotlin.Unit CallsInPlace(block, UNKNOWN) -public final class case_15_class { - public constructor case_15_class() - public final val prop_1: kotlin.Int? = 10 - public final fun case_15(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Number?): kotlin.Unit - 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 -} - -public final class case_18_class { - public constructor case_18_class() - public final val prop_1: kotlin.Int? = 10 - public final fun case_18(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Number?): kotlin.Unit - 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 -} - package contracts { - public fun case_1(/*0*/ x: kotlin.Any?): kotlin.Boolean - Returns(TRUE) -> x !is Number - - public fun case_16_1(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean - Returns(TRUE) -> value_1 !is String || value_2 !is Number - - public fun case_16_2(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean - Returns(FALSE) -> value_1 !is String || value_2 !is Number - - public fun case_16_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? - Returns(NOT_NULL) -> value_1 !is String || value_2 !is Number - - public fun case_16_4(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? - Returns(NULL) -> value_1 !is String || value_2 !is Number - - public fun case_17_1(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean - Returns(TRUE) -> value_1 !is String || value_2 != null - - public fun case_17_2(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean - Returns(FALSE) -> value_1 !is String || value_2 != null - - public fun case_17_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? - Returns(NOT_NULL) -> value_1 !is String || value_2 != null - - public fun case_17_4(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?): kotlin.Boolean? - Returns(NULL) -> value_1 !is String || value_2 != null - - public fun case_18_1(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean - Returns(TRUE) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null - - public fun case_18_2(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean - Returns(FALSE) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null - - public fun case_18_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean? - Returns(NOT_NULL) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null - - public fun case_18_4(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Boolean? - Returns(NULL) -> value_1 !is Float? || value_1 == null || value_2 == null || value_3 == null || value_4 == null - - public fun case_2(/*0*/ x: kotlin.Any?): kotlin.Boolean - Returns(TRUE) -> x !is Number? - - public fun T.case_19_1(): kotlin.Boolean - Returns(TRUE) -> !is String - - public fun T.case_19_2(): kotlin.Boolean - Returns(FALSE) -> is String - - public fun T.case_19_3(): kotlin.Boolean? - Returns(NOT_NULL) -> is String - - public fun T.case_19_4(): kotlin.Boolean? - Returns(NULL) -> is String - - public fun T.case_20_1(): kotlin.Boolean - Returns(TRUE) -> !is Int - - public fun T.case_20_2(): kotlin.Boolean - Returns(FALSE) -> is Int - - public fun T.case_20_3(): kotlin.Boolean? - Returns(NOT_NULL) -> is Int - - public fun T.case_20_4(): kotlin.Boolean? - Returns(NULL) -> is Int - - public fun T?.case_21_1(): kotlin.Boolean - Returns(TRUE) -> != null - - public fun T?.case_21_2(): kotlin.Boolean - Returns(TRUE) -> == null - - public fun T?.case_21_3(): kotlin.Boolean + public fun T?.case_1_1(): kotlin.Boolean Returns(FALSE) -> != null - public fun T.case_22_1(): kotlin.Boolean - Returns(TRUE) -> != null + public fun T?.case_1_2(): kotlin.Boolean? + Returns(NULL) -> is String - public fun T.case_22_2(): kotlin.Boolean - Returns(TRUE) -> == null - - public fun T?.case_22_5(): kotlin.Boolean? + public fun T.case_2_1(): kotlin.Boolean? Returns(NOT_NULL) -> != null - public fun T?.case_22_7(): kotlin.Boolean? + public fun T.case_2_2(): kotlin.Boolean? Returns(NULL) -> != null - public fun T?.case_23_1(): kotlin.Boolean - Returns(FALSE) -> == null || !is String - - public fun T?.case_23_2(): kotlin.Boolean? - Returns(NOT_NULL) -> == null || !is String - - public fun T?.case_23_3(): kotlin.Boolean? - Returns(NULL) -> == null || !is String - - public fun T.case_24_1(): kotlin.Boolean - Returns(FALSE) -> !is Int || == null - - public fun T.case_24_2(): kotlin.Boolean? - Returns(NOT_NULL) -> !is Int || == null - - public fun T.case_24_3(): kotlin.Boolean? - Returns(NULL) -> !is Int || == null - - public inline fun T?.case_25_1(): kotlin.Boolean - Returns(FALSE) -> !is Number || !is Int || == null - - public inline fun T?.case_25_2(): kotlin.Boolean? - Returns(NOT_NULL) -> !is Number || !is Int || == null - - public inline fun T?.case_25_3(): kotlin.Boolean? - Returns(NULL) -> !is Number || !is Int || == null - - public fun T?.case_26_1(/*0*/ value_1: kotlin.Int?): kotlin.Boolean - Returns(FALSE) -> == null || !is String || value_1 == null - - public fun T?.case_26_2(/*0*/ value_1: kotlin.Int?): kotlin.Boolean? - Returns(NOT_NULL) -> == null || !is String || value_1 == null - - public fun T?.case_26_3(/*0*/ value_1: kotlin.Int?): kotlin.Boolean? - Returns(NULL) -> == null || !is String || value_1 == null - } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.kt index 5701a580268..9586ae845a2 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.kt @@ -151,3 +151,10 @@ class case_10_class { } } } + +fun case_11(value_1: Any?, value_2: Any?, value_3: Any?) { + funWithReturnsAndInvertCondition(value_1 !is String? || value_2 !is Number && value_3 !is Float) + println(value_1!!.length) + println(value_2.toByte()) + println(value_3.dec()) +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/9.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/9.kt index 60a5fc2eba4..33617034d7d 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/9.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/9.kt @@ -9,29 +9,27 @@ SECTION: contracts CATEGORIES: analysis, smartcasts NUMBER: 9 - DESCRIPTION: Smartcasts after non-null assertions or not-null value assignment in lambdas of contract function with 'exactly once' or 'at least once' CallsInPlace effects. - UNEXPECTED BEHAVIOUR - ISSUES: KT-26148 + DESCRIPTION: Check the lack of smartcasts after non-null assertions or not-null value assignment in lambdas of contract function with 'unknown' or 'at most once' CallsInPlace effects. */ fun case_1(arg: Int?) { - funWithExactlyOnceCallsInPlace { arg!! } + funWithAtMostOnceCallsInPlace { arg!! } arg.inc() } fun case_2(arg: Int?) { - funWithAtLeastOnceCallsInPlace { arg!! } + funWithUnknownCallsInPlace { arg!! } arg.inc() } fun case_3() { val value_1: Boolean? - funWithExactlyOnceCallsInPlace { value_1 = false } - value_1.not() + funWithAtMostOnceCallsInPlace { value_1 = false } + value_1.not() } fun case_4() { val value_1: Boolean? - funWithAtLeastOnceCallsInPlace { value_1 = true } - value_1.not() + funWithUnknownCallsInPlace { value_1 = true } + value_1.not() } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/12.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/12.kt new file mode 100644 index 00000000000..bd481a63b01 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/12.kt @@ -0,0 +1,37 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !WITH_CONTRACT_FUNCTIONS +// SKIP_TXT + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE) + + SECTION: contracts + CATEGORIES: analysis, smartcasts + NUMBER: 12 + DESCRIPTION: Smartcasts after non-null assertions or not-null value assignment in lambdas of contract function with 'exactly once' or 'at least once' CallsInPlace effects. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26148 + */ + +fun case_1(arg: Int?) { + funWithExactlyOnceCallsInPlace { arg!! } + arg.inc() +} + +fun case_2(arg: Int?) { + funWithAtLeastOnceCallsInPlace { arg!! } + arg.inc() +} + +fun case_3() { + val value_1: Boolean? + funWithExactlyOnceCallsInPlace { value_1 = false } + value_1.not() +} + +fun case_4() { + val value_1: Boolean? + funWithAtLeastOnceCallsInPlace { value_1 = true } + value_1.not() +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.kt new file mode 100644 index 00000000000..5394d6c5918 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.kt @@ -0,0 +1,44 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE) + + SECTION: contracts + CATEGORIES: analysis, smartcasts + NUMBER: 13 + DESCRIPTION: Check smartcast to upper bound of the types in disjunction. + UNEXPECTED BEHAVIOUR + ISSUES: KT-1982 + */ + +// FILE: contracts.kt + +package contracts + +import kotlin.contracts.* + +fun T?.case_1() { + contract { returns() implies (this@case_1 is Number || this@case_1 is Int) } + if (!(this@case_1 is Number || this@case_1 is Int)) throw Exception() +} + +inline fun T?.case_2(value_2: Number, value_3: Any?, value_4: String?) { + contract { returns() implies ((this@case_2 is Number || this@case_2 is Int) && value_2 is Int && value_3 != null && value_3 is Number && value_4 != null) } + if (!((this is Number || this is Int) && value_2 is Int && value_3 != null && value_3 is Number && value_4 != null)) throw Exception() +} + +// FILE: usages.kt + +import contracts.* + +fun case_1(value_1: Any?) { + value_1.case_1() + println(value_1.toByte()) +} + +fun case_2(value_1: Any?, value_2: Number, value_3: Any?, value_4: String?) { + value_1.case_2(value_2, value_3, value_4) + println(value_1.toByte()) +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.txt new file mode 100644 index 00000000000..701299baed8 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/13.txt @@ -0,0 +1,13 @@ +package + +public fun case_1(/*0*/ value_1: kotlin.Any?): kotlin.Unit +public fun case_2(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Number, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.String?): kotlin.Unit + +package contracts { + public fun T?.case_1(): kotlin.Unit + Returns(WILDCARD) -> is Number || is Int + + public inline fun T?.case_2(/*0*/ value_2: kotlin.Number, /*1*/ value_3: kotlin.Any?, /*2*/ value_4: kotlin.String?): kotlin.Unit + Returns(WILDCARD) -> ( is Number || is Int) && value_2 is Int && value_3 != null && value_3 is Number && value_4 != null + +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.kt index 798a19e12ec..161af83d1a6 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.kt @@ -151,3 +151,14 @@ class case_10_class { } } } + +/* + CASE DESCRIPTION: check resolve reference when is used not null assertion and safe call operators + UNEXPECTED BEHAVIOUR + ISSUES: KT-26747 + */ +fun case_12(value_1: Any?, value_2: Any?, value_3: Any?) { + funWithReturnsAndInvertCondition(value_1 !is String || value_2 !is Number || value_3 !is Any?) + println(value_1!!.length) + println(value_2?.toByte()) +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.kt index f887741d0ba..94adb3b41de 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.kt @@ -141,13 +141,14 @@ fun T.case_8_4(): Boolean? { return if (this@case_8_4 == null) null else true } -fun T.case_9_1(): Boolean? { - contract { returnsNotNull() implies (this@case_9_1 != null) } - return if (this@case_9_1 != null) true else null +fun T?.case_9_1(): Boolean { + contract { returns(true) implies (this@case_9_1 is Float) } + return this@case_9_1 is Float } -fun T.case_9_2(): Boolean? { - contract { returns(null) implies (this@case_9_2 != null) } - return if (this@case_9_2 != null) null else true + +fun T?.case_9_2(): Boolean { + contract { returns(false) implies (this@case_9_2 is Double) } + return !(this@case_9_2 is Double) } // FILE: usages.kt @@ -231,10 +232,12 @@ fun case_8(value_1: String?, value_2: String?) { } /* + CASE DESCRIPTION: check the infererence of the Number super type UNEXPECTED BEHAVIOUR - KT-26382 + ISSUES: KT-1982 */ -fun case_9(value_1: Number?) { - if (value_1?.case_9_1() != null) println(value_1.toByte()) - if (value_1?.case_9_2() != null) println(value_1.toByte()) +fun case_9(value_1: Any?) { + if (value_1.case_9_1() || !value_1.case_9_2()) { + println(value_1.toByte()) + } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.txt index dd86efe89fb..256e3ac06b4 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/4.txt @@ -8,7 +8,7 @@ public fun case_5(/*0*/ value_1: kotlin.Any?): kotlin.Unit public fun case_6(/*0*/ value_1: kotlin.Number): kotlin.Unit public fun case_7(/*0*/ value_1: kotlin.String?): kotlin.Unit public fun case_8(/*0*/ value_1: kotlin.String?, /*1*/ value_2: kotlin.String?): kotlin.Unit -public fun case_9(/*0*/ value_1: kotlin.Number?): kotlin.Unit +public fun case_9(/*0*/ value_1: kotlin.Any?): kotlin.Unit package contracts { public fun T.case_1(): kotlin.Unit @@ -98,10 +98,10 @@ package contracts { public fun T.case_8_4(): kotlin.Boolean? Returns(NULL) -> == null - public fun T.case_9_1(): kotlin.Boolean? - Returns(NOT_NULL) -> != null + public fun T?.case_9_1(): kotlin.Boolean + Returns(TRUE) -> is Float - public fun T.case_9_2(): kotlin.Boolean? - Returns(NULL) -> != null + public fun T?.case_9_2(): kotlin.Boolean + Returns(FALSE) -> is Double } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt index 2ca64bc2a89..af5d964ecdf 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.kt @@ -103,6 +103,7 @@ fun case_4(value_1: Number, value_2: (() -> Unit)?) { } /* + CASE DESCRIPTION: check the conclusion that not-null conditions corresponds to the contract with not null effect UNEXPECTED BEHAVIOUR: unsafe calls ISSUES: KT-26612 */ @@ -120,6 +121,7 @@ fun case_5(value_1: Number?, value_2: String?) { } /* + CASE DESCRIPTION: check the conclusion that not-null conditions corresponds to the contract with not null effect (with null branch) UNEXPECTED BEHAVIOUR: unsafe calls ISSUES: KT-26612 */ diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt index 03c279ec113..f0e99392818 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt @@ -101,9 +101,6 @@ fun case_8(value_1: Any?) { } } -/* - UNEXPECTED BEHAVIOUR: unreachable code - */ fun case_9(value_1: Any?) { if (funWithReturnsFalse(value_1 is String) || funWithReturnsFalse(value_1 is Int)) { @@ -113,9 +110,6 @@ fun case_9(value_1: Any?) { } } -/* - UNEXPECTED BEHAVIOUR: unreachable code - */ fun case_10(value_1: Any?) { if (funWithReturnsFalse(value_1 is String) || getBoolean()) { diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.kt new file mode 100644 index 00000000000..cb98e8ee20f --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.kt @@ -0,0 +1,58 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !WITH_FUNCTIONS + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) + + SECTION: contracts + CATEGORIES: declarations, contractBuilder, common + NUMBER: 14 + DESCRIPTION: Contract is first statement in control flow terms, but not in tokens order terms. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26153 + */ + +import kotlin.contracts.* + +internal inline fun case_1(block: () -> Unit) { + return contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } +} + +fun case_2() = contract { } + +inline fun case_3(block: () -> Unit) { + val value_1 = contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + block() +} + +inline fun case_4(block: () -> Unit) { + (contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + }) + return block() +} + +inline fun case_5(block: () -> Unit) { + test@ contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +inline fun case_6(block: () -> Unit) { + throw Exception(contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + }.toString()) +} + +inline fun case_7(block: () -> Unit) { + _funWithAnyArg(contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + }) +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.txt new file mode 100644 index 00000000000..cfffa64eac8 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/14.txt @@ -0,0 +1,11 @@ +package + +public fun _funWithAnyArg(/*0*/ value_1: kotlin.Any): kotlin.Int +public fun _funWithoutArgs(): kotlin.Int +internal inline fun case_1(/*0*/ block: () -> kotlin.Unit): kotlin.Unit +public fun case_2(): kotlin.Unit +public inline fun case_3(/*0*/ block: () -> kotlin.Unit): kotlin.Unit +public inline fun case_4(/*0*/ block: () -> kotlin.Unit): kotlin.Unit +public inline fun case_5(/*0*/ block: () -> kotlin.Unit): kotlin.Unit +public inline fun case_6(/*0*/ block: () -> kotlin.Unit): kotlin.Unit +public inline fun case_7(/*0*/ block: () -> kotlin.Unit): kotlin.Unit diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/5.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/15.kt similarity index 78% rename from compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/5.kt rename to compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/15.kt index 2fa2bd9f330..ba5808ee0e2 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/5.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/15.kt @@ -3,12 +3,12 @@ // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts /* - KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE) + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) SECTION: contracts - CATEGORY: declarations, contractBuilder, common - NUMBER: 5 - DESCRIPTION: contracts with not allowed conditions with boolean constants or constant expressions in implies. + CATEGORIES: declarations, contractBuilder, common + NUMBER: 15 + DESCRIPTION: contracts with not allowed conditions with boolean constants or boolean constant expressions in implies. UNEXPECTED BEHAVIOUR ISSUES: KT-26491 */ diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/5.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/15.txt similarity index 100% rename from compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/5.txt rename to compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/15.txt diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.kt new file mode 100644 index 00000000000..edacc5a027c --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.kt @@ -0,0 +1,54 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) + + SECTION: contracts + CATEGORIES: declarations, contractBuilder, common + NUMBER: 16 + DESCRIPTION: Contract isn't in the first position. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26191 + */ + +import kotlin.contracts.* + +fun case_1(value_1: Int?) { + println("!") + contract { + returns(true) implies (value_1 != null) + } as ContractBuilder +} + +fun case_2(value_1: Int?) { + 100 + 10 + throw Exception(contract { + returns(true) implies (value_1 != null) + }.toString()) +} + +fun case_3(value_1: Int?) { + for (i in 0..10) { + println(i) + } + return contract { + returns(true) implies (value_1 != null) + } +} + +fun case_4(value_1: Int?) { + val f = 10 - 20 + val g = contract { + returns(true) implies (value_1 != null) + } +} + +fun case_5(number: Int?): Boolean { + val value_1 = number != null + contract { + returns(false) implies (value_1) + } as ContractBuilder + return number == null +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.txt new file mode 100644 index 00000000000..49234c3e061 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/16.txt @@ -0,0 +1,7 @@ +package + +public fun case_1(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_2(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_3(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_4(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_5(/*0*/ number: kotlin.Int?): kotlin.Boolean diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.kt new file mode 100644 index 00000000000..fd9ee098541 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.kt @@ -0,0 +1,31 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE -UNUSED_PARAMETER -UNREACHABLE_CODE -UNUSED_EXPRESSION +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) + + SECTION: contracts + CATEGORIES: declarations, contractBuilder, common + NUMBER: 17 + DESCRIPTION: contracts with Nothing expressions in implies. + DISCUSSION + ISSUES: KT-25948 + */ + +import kotlin.contracts.* + +fun case_1(): Boolean { + contract { returns(null) implies throw Exception() } + return true +} + +fun case_2(): Boolean { + contract { returns(null) implies return return return false } + return true +} + +fun case_3(): Boolean { + contract { returns(null) implies return return return false && throw throw throw throw Exception() } + return true +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.txt new file mode 100644 index 00000000000..58b708a0a41 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/17.txt @@ -0,0 +1,5 @@ +package + +public fun case_1(): kotlin.Boolean +public fun case_2(): kotlin.Boolean +public fun case_3(): kotlin.Boolean diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/5.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/5.kt index b6fb238876f..832842707d0 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/5.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/5.kt @@ -19,7 +19,7 @@ fun case_1(): Boolean { } fun case_2(): Boolean { - contract { returnsNotNull() implies (return return return) } + contract { returnsNotNull() implies (return return return true) } return true } @@ -28,30 +28,21 @@ fun case_3(): Boolean { return true } -/* - UNEXPECTED BEHAVIOUR - ISSUES: KT-25948 - */ -fun case_4(): Boolean { - contract { returns(null) implies throw Exception() } - return true -} - /* UNEXPECTED BEHAVIOUR ISSUES: KT-26386 */ -fun case_5(): Boolean? { - contract { returns(null) implies case_5() } +fun case_4(): Boolean? { + contract { returns(null) implies case_4() } return null } -fun case_6(): Boolean? { +fun case_5(): Boolean? { contract { returns(null) implies listOf(0) } return null } -fun case_7(value_1: Boolean): Boolean? { +fun case_6(value_1: Boolean): Boolean? { contract { returns(null) implies contract { returns(null) implies (!value_1) } } return null } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.kt index aea90abcdbc..ee1f8873b1f 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect -// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts -// !WITH_FUNCTIONS /* KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE) @@ -9,50 +8,17 @@ SECTION: contracts CATEGORIES: declarations, contractBuilder, common NUMBER: 2 - DESCRIPTION: Contract is first statement in control flow terms, but not in tokens order terms. - UNEXPECTED BEHAVIOUR - ISSUES: KT-26153 + DESCRIPTION: Functions with contract and builder lambda in parentheses. */ import kotlin.contracts.* -internal inline fun case_1(block: () -> Unit) { - return contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) - } -} - -fun case_2() = contract { } - -inline fun case_3(block: () -> Unit) { - val value_1 = contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) - } - block() -} - -inline fun case_4(block: () -> Unit) { - (contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) - }) +inline fun case_1(block: () -> Unit) { + contract({ callsInPlace(block, InvocationKind.EXACTLY_ONCE) }) return block() } -inline fun case_5(block: () -> Unit) { - test@ contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) - } +inline fun case_2(block: () -> Unit) { + contract(builder = { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }) return block() } - -inline fun case_6(block: () -> Unit) { - throw Exception(contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) - }.toString()) -} - -inline fun case_7(block: () -> Unit) { - _funWithAnyArg(contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) - }) -} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.txt index cfffa64eac8..75f54d017b5 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/2.txt @@ -1,11 +1,8 @@ package -public fun _funWithAnyArg(/*0*/ value_1: kotlin.Any): kotlin.Int -public fun _funWithoutArgs(): kotlin.Int -internal inline fun case_1(/*0*/ block: () -> kotlin.Unit): kotlin.Unit -public fun case_2(): kotlin.Unit -public inline fun case_3(/*0*/ block: () -> kotlin.Unit): kotlin.Unit -public inline fun case_4(/*0*/ block: () -> kotlin.Unit): kotlin.Unit -public inline fun case_5(/*0*/ block: () -> kotlin.Unit): kotlin.Unit -public inline fun case_6(/*0*/ block: () -> kotlin.Unit): kotlin.Unit -public inline fun case_7(/*0*/ block: () -> kotlin.Unit): kotlin.Unit +public inline fun case_1(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, EXACTLY_ONCE) + +public inline fun case_2(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, EXACTLY_ONCE) + diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.kt index 0762c12f1d3..43f2cf0d798 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.kt @@ -1,5 +1,5 @@ // !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect -// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts /* @@ -8,17 +8,47 @@ SECTION: contracts CATEGORIES: declarations, contractBuilder, common NUMBER: 3 - DESCRIPTION: Functions with contract and builder lambda in parentheses. + DESCRIPTION: Contract isn't in the first position. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26191 */ import kotlin.contracts.* -inline fun case_1(block: () -> Unit) { - contract({ callsInPlace(block, InvocationKind.EXACTLY_ONCE) }) - return block() +fun case_1(value_1: Int?) { + println("!") + contract { + returns(true) implies (value_1 != null) + } as ContractBuilder } -inline fun case_2(block: () -> Unit) { - contract(builder = { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }) - return block() +fun case_2(value_1: Int?) { + 100 + 10 + throw Exception(contract { + returns(true) implies (value_1 != null) + }.toString()) +} + +fun case_3(value_1: Int?) { + for (i in 0..10) { + println(i) + } + return contract { + returns(true) implies (value_1 != null) + } +} + +fun case_4(value_1: Int?) { + val f = 10 - 20 + val g = contract { + returns(true) implies (value_1 != null) + } +} + +fun case_5(number: Int?): Boolean { + val value_1 = number != null + contract { + returns(false) implies (value_1) + } as ContractBuilder + return number == null } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.txt index 75f54d017b5..49234c3e061 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/3.txt @@ -1,8 +1,7 @@ package -public inline fun case_1(/*0*/ block: () -> kotlin.Unit): kotlin.Unit - CallsInPlace(block, EXACTLY_ONCE) - -public inline fun case_2(/*0*/ block: () -> kotlin.Unit): kotlin.Unit - CallsInPlace(block, EXACTLY_ONCE) - +public fun case_1(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_2(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_3(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_4(/*0*/ value_1: kotlin.Int?): kotlin.Unit +public fun case_5(/*0*/ number: kotlin.Int?): kotlin.Boolean diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.kt index d27755f0bbd..717ffbc78a3 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.kt @@ -1,5 +1,5 @@ // !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect -// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE -UNUSED_PARAMETER -UNREACHABLE_CODE -UNUSED_EXPRESSION // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts /* @@ -8,47 +8,19 @@ SECTION: contracts CATEGORIES: declarations, contractBuilder, common NUMBER: 4 - DESCRIPTION: Contract isn't in the first position. + DESCRIPTION: contracts with not allowed conditions with boolean constants or constant expressions in implies. UNEXPECTED BEHAVIOUR - ISSUES: KT-26191 + ISSUES: KT-26491 */ import kotlin.contracts.* -fun case_1(value_1: Int?) { - println("!") - contract { - returns(true) implies (value_1 != null) - } as ContractBuilder +fun case_1(): Boolean { + contract { returns(true) implies true } + return true } -fun case_2(value_1: Int?) { - 100 + 10 - throw Exception(contract { - returns(true) implies (value_1 != null) - }.toString()) -} - -fun case_3(value_1: Int?) { - for (i in 0..10) { - println(i) - } - return contract { - returns(true) implies (value_1 != null) - } -} - -fun case_4(value_1: Int?) { - val f = 10 - 20 - val g = contract { - returns(true) implies (value_1 != null) - } -} - -fun case_5(number: Int?): Boolean { - val value_1 = number != null - contract { - returns(false) implies (value_1) - } as ContractBuilder - return number == null -} +fun case_2(): Boolean { + contract { returns(true) implies (true || false) } + return true || false +} \ No newline at end of file diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.txt index 49234c3e061..2f6a1654cbb 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/pos/4.txt @@ -1,7 +1,7 @@ package -public fun case_1(/*0*/ value_1: kotlin.Int?): kotlin.Unit -public fun case_2(/*0*/ value_1: kotlin.Int?): kotlin.Unit -public fun case_3(/*0*/ value_1: kotlin.Int?): kotlin.Unit -public fun case_4(/*0*/ value_1: kotlin.Int?): kotlin.Unit -public fun case_5(/*0*/ number: kotlin.Int?): kotlin.Boolean +public fun case_1(): kotlin.Boolean + Returns(TRUE) -> TRUE + +public fun case_2(): kotlin.Boolean + Returns(TRUE) -> TRUE || FALSE diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.kt new file mode 100644 index 00000000000..f772b7e6597 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.kt @@ -0,0 +1,32 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) + + SECTION: contracts + CATEGORIES: declarations, contractBuilder, effects, callsInPlace + NUMBER: 2 + DESCRIPTION: functions with contract and duplicate CallsInPlace. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26150 + */ + +import kotlin.contracts.* + +inline fun case_1(block: () -> Unit) { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return block() +} + +inline fun case_2(block: () -> Unit) { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + callsInPlace(block, InvocationKind.AT_MOST_ONCE) + } + return block() +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.txt new file mode 100644 index 00000000000..aba002d3c4c --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/neg/2.txt @@ -0,0 +1,9 @@ +package + +public inline fun case_1(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, EXACTLY_ONCE) + CallsInPlace(block, EXACTLY_ONCE) + +public inline fun case_2(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, EXACTLY_ONCE) + CallsInPlace(block, AT_MOST_ONCE) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.kt index 5a34ead72f8..c9cfc18931b 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.kt @@ -1,5 +1,5 @@ // !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect -// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -UNUSED_VARIABLE // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts /* @@ -8,25 +8,19 @@ SECTION: contracts CATEGORIES: declarations, contractBuilder, effects, callsInPlace NUMBER: 2 - DESCRIPTION: functions with contract and duplicate CallsInPlace. + DESCRIPTION: Contract with 'this' in first parameter of CallsInPlace. + DISCUSSION UNEXPECTED BEHAVIOUR - ISSUES: KT-26150 + ISSUES: KT-26294 */ import kotlin.contracts.* -inline fun case_1(block: () -> Unit) { +inline fun > T.case_1(block: () -> Unit) { contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) + callsInPlace(this@case_1, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return block() -} - -inline fun case_2(block: () -> Unit) { - contract { - callsInPlace(block, InvocationKind.EXACTLY_ONCE) - callsInPlace(block, InvocationKind.AT_MOST_ONCE) - } - return block() + block() + this@case_1() } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.txt index aba002d3c4c..4e518f0177b 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/callsInPlace/pos/2.txt @@ -1,9 +1,6 @@ package -public inline fun case_1(/*0*/ block: () -> kotlin.Unit): kotlin.Unit - CallsInPlace(block, EXACTLY_ONCE) +public inline fun > T.case_1(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(, EXACTLY_ONCE) CallsInPlace(block, EXACTLY_ONCE) -public inline fun case_2(/*0*/ block: () -> kotlin.Unit): kotlin.Unit - CallsInPlace(block, EXACTLY_ONCE) - CallsInPlace(block, AT_MOST_ONCE) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt index d4255e3e25b..f77cb029c15 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt @@ -42,10 +42,7 @@ object case_3 { } } -/* - UNEXPECTED BEHAVIOUR - ISSUES: KT-26244 - */ +// ISSUES: KT-26244 class case_4 : _ClassLevel3() { fun T.case_4_1(): Boolean { contract { returns(false) implies (this@case_4 !is _ClassLevel1) } @@ -79,10 +76,7 @@ class case_4 : _ClassLevel3() { fun case_4_5() = _ClassLevel3().case_4_5_wrap() } -/* - UNEXPECTED BEHAVIOUR - ISSUES: KT-26244 - */ +// ISSUES: KT-26244 class case_5 : _ClassLevel5() { inner class case_5_1 { fun K.case_5_1_1() { diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.kt new file mode 100644 index 00000000000..3284a5276a0 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.kt @@ -0,0 +1,27 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) + + SECTION: contracts + CATEGORIES: declarations, contractFunction + NUMBER: 3 + DESCRIPTION: Check that fun with contract and CallsInPlace effect is an inline function. + UNEXPECTED BEHAVIOUR + ISSUES: KT-26126 + */ + +import kotlin.contracts.* + +fun funWithContractExactlyOnce(block: () -> Unit) { // report about not-inline function is expected + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return block() +} + +fun case_1() { + val value_1: Int + funWithContractExactlyOnce { value_1 = 10 } // back-end exception + value_1.inc() +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.txt new file mode 100644 index 00000000000..e5749664606 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/3.txt @@ -0,0 +1,5 @@ +package + +public fun case_1(): kotlin.Unit +public fun funWithContractExactlyOnce(/*0*/ block: () -> kotlin.Unit): kotlin.Unit + CallsInPlace(block, EXACTLY_ONCE) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.kt index a213eb163da..97ff34f6485 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.kt @@ -1,4 +1,4 @@ -// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect // !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts @@ -8,20 +8,30 @@ SECTION: contracts CATEGORIES: declarations, contractFunction NUMBER: 1 - DESCRIPTION: Check that fun with contract and CallsInPlace effect is an inline function. - UNEXPECTED BEHAVIOUR - ISSUES: KT-26126 + DESCRIPTION: Contract function usage before declaration it */ import kotlin.contracts.* -fun funWithContractExactlyOnce(block: () -> Unit) { // report about not-inline function is expected - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return block() +fun case_1_1(x: Any?) { + if (case_1_2(x)) { + x.length + } } -fun case_1() { - val value_1: Int - funWithContractExactlyOnce { value_1 = 10 } // back-end exception - value_1.inc() +fun case_2_1(x: Number?) { + case_2_2(x) + println(x.toByte()) } + +fun case_1_2(x: Any?): Boolean { + contract { returns(true) implies (x is String) } + return x is String +} + +fun case_2_2(x: Any?) { + contract { returns() implies(x != null) } + if (x == null) throw Exception() +} + + diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.txt index e5749664606..365216337a8 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/pos/1.txt @@ -1,5 +1,10 @@ package -public fun case_1(): kotlin.Unit -public fun funWithContractExactlyOnce(/*0*/ block: () -> kotlin.Unit): kotlin.Unit - CallsInPlace(block, EXACTLY_ONCE) +public fun case_1_1(/*0*/ x: kotlin.Any?): kotlin.Unit +public fun case_1_2(/*0*/ x: kotlin.Any?): kotlin.Boolean + Returns(TRUE) -> x is String + +public fun case_2_1(/*0*/ x: kotlin.Number?): kotlin.Unit +public fun case_2_2(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x != null +