diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/12.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/12.kt index d52201e3d7c..3aca9db01e2 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/12.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/12.kt @@ -1,7 +1,6 @@ // !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect // !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts -// !WITH_CONTRACT_FUNCTIONS /* KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) @@ -9,9 +8,9 @@ SECTION: contracts CATEGORY: analysis, smartcasts NUMBER: 12 - DESCRIPTION: Check smartcasts with passing same fields of instances of the same class in contract function with conjunction not-null condition. + DESCRIPTION: Check smartcast to upper bound of the types in disjunction. UNEXPECTED BEHAVIOUR - ISSUES: KT-26300 + ISSUES: KT-1982 */ // FILE: contracts.kt @@ -20,62 +19,26 @@ package contracts import kotlin.contracts.* -fun case_3(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?) { - contract { returns() implies (value_1 is Float? && value_1 != null && value_2 != null && value_3 != null && value_4 != null) } - if (!(value_1 is Float? && value_1 != null && value_2 != null && value_3 != null && value_4 != null)) throw Exception() +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() } -fun case_4(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 +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.* -class case_1 { - val prop_1: Int? = 10 - fun case_1(value_1: Any?, value_2: Number?) { - val o = case_1() - funWithReturns(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null && this.prop_1 != null) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } +fun case_1(value_1: Any?) { + value_1.case_1() + println(value_1.toByte()) } -class case_2 { - val prop_1: Int? = 10 - fun case_2(value_1: Any?, value_2: Number?) { - val o = case_2() - if (funWithReturnsTrue(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null && this.prop_1 != null)) { - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } - if (!funWithReturnsTrueAndInvertCondition(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null && this.prop_1 != null)) { - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } - } -} - -class case_3 { - val prop_1: Int? = 10 - fun case_3(value_1: Any?, value_2: Number?) { - val o = case_3() - contracts.case_3(value_1, value_2, o.prop_1, this.prop_1) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } -} - -class case_4 { - val prop_1: Int? = 10 - fun case_4(value_1: Any?, value_2: Number?) { - val o = case_4() - if (contracts.case_4(value_1, value_2, o.prop_1, this.prop_1)) { - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) - } - } +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/neg/12.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/12.txt index 7c453c50349..701299baed8 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/12.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/12.txt @@ -1,154 +1,13 @@ package -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_1 { - public constructor case_1() - public final val prop_1: kotlin.Int? = 10 - public final fun case_1(/*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_2 { - public constructor case_2() - public final val prop_1: kotlin.Int? = 10 - public final fun case_2(/*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_3 { - public constructor case_3() - public final val prop_1: kotlin.Int? = 10 - public final fun case_3(/*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_4 { - public constructor case_4() - public final val prop_1: kotlin.Int? = 10 - public final fun case_4(/*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 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 case_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Unit - Returns(WILDCARD) -> value_1 is Float? && value_1 != null && value_2 != null && value_3 != null && value_4 != null + public fun T?.case_1(): kotlin.Unit + Returns(WILDCARD) -> is Number || is Int - public fun case_4(/*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 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/neg/13.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.kt index 14f257cb960..68622107367 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.kt @@ -1,4 +1,5 @@ -// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !WITH_CONTRACT_FUNCTIONS // !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER // !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts @@ -8,9 +9,7 @@ SECTION: contracts CATEGORY: analysis, smartcasts NUMBER: 13 - DESCRIPTION: Check smartcast to upper bound of the types in disjunction. - UNEXPECTED BEHAVIOUR - ISSUES: KT-1982 + DESCRIPTION: Smartcast using many of the various Returns effects on the same values. */ // FILE: contracts.kt @@ -19,14 +18,24 @@ 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() +fun T?.case_1_1(): Boolean { + contract { returns(false) implies (this@case_1_1 != null) } + return !(this@case_1_1 != null) } -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() +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 T?.case_2_1(): Boolean { + contract { returns(true) implies (this@case_2_1 is Float) } + return this@case_2_1 is Float +} + +fun T?.case_2_2(): Boolean { + contract { returns(false) implies (this@case_2_2 is Double) } + return !(this@case_2_2 is Double) } // FILE: usages.kt @@ -34,11 +43,17 @@ inline fun T?.case_2(value_2: Number, value_3: Any?, value_4: import contracts.* fun case_1(value_1: Any?) { - value_1.case_1() - println(value_1.toByte()) + if (!(value_1.case_1_1() || value_1.case_1_2() == null)) { + println(value_1.length) + } } -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()) +/* + UNEXPECTED BEHAVIOUR + ISSUES: KT-1982 + */ +fun case_2(value_1: Any?) { + if (value_1.case_2_1() || !value_1.case_2_2()) { + println(value_1.toByte()) + } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.txt index 701299baed8..f7bb2754dee 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.txt @@ -1,13 +1,126 @@ 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 +public fun case_2(/*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) package contracts { - public fun T?.case_1(): kotlin.Unit - Returns(WILDCARD) -> is Number || is Int + public fun T?.case_1_1(): kotlin.Boolean + Returns(FALSE) -> != null - 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 + public fun T?.case_1_2(): kotlin.Boolean? + Returns(NULL) -> is String + + public fun T?.case_2_1(): kotlin.Boolean + Returns(TRUE) -> is Float + + public fun T?.case_2_2(): kotlin.Boolean + Returns(FALSE) -> is Double } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/14.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/14.kt deleted file mode 100644 index 6b09e361653..00000000000 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/14.kt +++ /dev/null @@ -1,59 +0,0 @@ -// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect -// !WITH_CONTRACT_FUNCTIONS -// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts - -/* - KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) - - SECTION: contracts - CATEGORY: analysis, smartcasts - NUMBER: 14 - DESCRIPTION: Smartcast using many of the various Returns effects on the same values. - */ - -// FILE: contracts.kt - -package contracts - -import kotlin.contracts.* - -fun T?.case_1_1(): Boolean { - contract { returns(false) implies (this@case_1_1 != null) } - return !(this@case_1_1 != null) -} - -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 T?.case_2_1(): Boolean { - contract { returns(true) implies (this@case_2_1 is Float) } - return this@case_2_1 is Float -} - -fun T?.case_2_2(): Boolean { - contract { returns(false) implies (this@case_2_2 is Double) } - return !(this@case_2_2 is Double) -} - -// FILE: usages.kt - -import contracts.* - -fun case_1(value_1: Any?) { - if (!(value_1.case_1_1() || value_1.case_1_2() == null)) { - println(value_1.length) - } -} - -/* - UNEXPECTED BEHAVIOUR - ISSUES: KT-1982 - */ -fun case_2(value_1: Any?) { - if (value_1.case_2_1() || !value_1.case_2_2()) { - println(value_1.toByte()) - } -} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/11.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/11.kt new file mode 100644 index 00000000000..48e531688fe --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/11.kt @@ -0,0 +1,76 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !WITH_CONTRACT_FUNCTIONS + +/* + KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE) + + SECTION: contracts + CATEGORY: analysis, smartcasts + NUMBER: 11 + DESCRIPTION: Check smartcasts with passing same fields of instances of the same class in contract function with conjunction not-null condition. + ISSUES: KT-26300 + */ + +// FILE: contracts.kt + +package contracts + +import kotlin.contracts.* + +fun case_3(value_1: Any?, value_2: Any?, value_3: Any?, value_4: Any?) { + contract { returns() implies (value_1 is Float? && value_1 != null && value_2 != null && value_3 != null && value_4 != null) } + if (!(value_1 is Float? && value_1 != null && value_2 != null && value_3 != null && value_4 != null)) throw Exception() +} + +fun case_4(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 +} + +// FILE: usages.kt + +import contracts.* + +class case_1 { + val prop_1: Int? = 10 + fun case_1(value_1: Any?, value_2: Number?) { + val o = case_1() + funWithReturns(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null && this.prop_1 != null) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } +} + +class case_2 { + val prop_1: Int? = 10 + fun case_2(value_1: Any?, value_2: Number?) { + val o = case_2() + if (funWithReturnsTrue(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null && this.prop_1 != null)) { + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } + } +} + +class case_3 { + val prop_1: Int? = 10 + fun case_3(value_1: Any?, value_2: Number?) { + val o = case_3() + contracts.case_3(value_1, value_2, o.prop_1, this.prop_1) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } +} + +class case_4 { + val prop_1: Int? = 10 + fun case_4(value_1: Any?, value_2: Number?) { + val o = case_4() + if (contracts.case_4(value_1, value_2, o.prop_1, this.prop_1)) { + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) + } + } +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/14.txt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/11.txt similarity index 65% rename from compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/14.txt rename to compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/11.txt index f7bb2754dee..7c453c50349 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/14.txt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/11.txt @@ -1,7 +1,5 @@ package -public fun case_1(/*0*/ value_1: kotlin.Any?): kotlin.Unit -public fun case_2(/*0*/ value_1: kotlin.Any?): kotlin.Unit public inline fun funWithAtLeastOnceCallsInPlace(/*0*/ block: () -> T): T CallsInPlace(block, AT_LEAST_ONCE) @@ -110,17 +108,47 @@ 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_1 { + public constructor case_1() + public final val prop_1: kotlin.Int? = 10 + public final fun case_1(/*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_2 { + public constructor case_2() + public final val prop_1: kotlin.Int? = 10 + public final fun case_2(/*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_3 { + public constructor case_3() + public final val prop_1: kotlin.Int? = 10 + public final fun case_3(/*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_4 { + public constructor case_4() + public final val prop_1: kotlin.Int? = 10 + public final fun case_4(/*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 T?.case_1_1(): kotlin.Boolean - Returns(FALSE) -> != null + public fun case_3(/*0*/ value_1: kotlin.Any?, /*1*/ value_2: kotlin.Any?, /*2*/ value_3: kotlin.Any?, /*3*/ value_4: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> value_1 is Float? && value_1 != null && value_2 != null && value_3 != null && value_4 != null - public fun T?.case_1_2(): kotlin.Boolean? - Returns(NULL) -> is String - - public fun T?.case_2_1(): kotlin.Boolean - Returns(TRUE) -> is Float - - public fun T?.case_2_2(): kotlin.Boolean - Returns(FALSE) -> is Double + public fun case_4(/*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 } diff --git a/compiler/tests-spec/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestSpecGenerated.java b/compiler/tests-spec/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestSpecGenerated.java index cd5f6cc34a6..2c459d60a26 100644 --- a/compiler/tests-spec/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestSpecGenerated.java +++ b/compiler/tests-spec/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestSpecGenerated.java @@ -906,11 +906,6 @@ public class DiagnosticsTestSpecGenerated extends AbstractDiagnosticsTestSpec { runTest("compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/13.kt"); } - @TestMetadata("14.kt") - public void test14() throws Exception { - runTest("compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/14.kt"); - } - @TestMetadata("2.kt") public void test2() throws Exception { runTest("compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.kt"); @@ -974,6 +969,11 @@ public class DiagnosticsTestSpecGenerated extends AbstractDiagnosticsTestSpec { runTest("compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/10.kt"); } + @TestMetadata("11.kt") + public void test11() throws Exception { + runTest("compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/11.kt"); + } + @TestMetadata("2.kt") public void test2() throws Exception { runTest("compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/2.kt");