From e483f836660e83566baa9f3af68905a66ff33103 Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Tue, 15 Jan 2019 11:37:37 +0300 Subject: [PATCH] Make 'is'-operator more stupid Consider following expression: 'call() is Foo'. Suppose that we know something about the 'call()', e.g. 'returns(foo) -> ' Previously, we've tried to re-use knowledge about 'call()', constructing some smart clause, like 'returns(true) -> foo is Foo && '. The conceptual error here is that *we can't* argue that holds. Imagine that 'call()' actually has unspecified 'returns(foo2) -> ', and 'foo2 is Foo' also holds. Then we would get 'returns(true) -> foo2 is Foo && ' <=> 'returns(true) -> ' for the whole call, which is not correct. More concrete example would be something like: 'if (!x.isNullOrEmpty() is Boolean)' ^KT-27241 Fixed --- .../kotlin/contracts/model/functors/IsFunctor.kt | 15 +++++---------- .../valueOfContractedFunctionIngored.kt | 2 +- .../valueOfContractedFunctionIngored.txt | 3 +-- .../contracts/analysis/smartcasts/neg/15.kt | 7 +++---- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt index e3ff55ad804..648125c9207 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/IsFunctor.kt @@ -29,22 +29,17 @@ class IsFunctor(val type: KotlinType, val isNegated: Boolean) : AbstractReducing fun invokeWithArguments(arg: Computation): List { return if (arg is ESValue) - invokeWithValue(arg, null) + invokeWithValue(arg) else - arg.effects.flatMap { - if (it !is ConditionalEffect || it.simpleEffect !is ESReturns || it.simpleEffect.value == ESConstant.WILDCARD) - listOf(it) - else - invokeWithValue(it.simpleEffect.value, it.condition) - } + emptyList() } - private fun invokeWithValue(value: ESValue, additionalCondition: ESExpression?): List { + private fun invokeWithValue(value: ESValue): List { val trueIs = ESIs(value, this) val falseIs = ESIs(value, IsFunctor(type, isNegated.not())) - val trueResult = ConditionalEffect(trueIs.and(additionalCondition), ESReturns(true.lift())) - val falseResult = ConditionalEffect(falseIs.and(additionalCondition), ESReturns(false.lift())) + val trueResult = ConditionalEffect(trueIs, ESReturns(true.lift())) + val falseResult = ConditionalEffect(falseIs, ESReturns(false.lift())) return listOf(trueResult, falseResult) } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt index 892df9c1bb4..719b21a4480 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.kt @@ -6,6 +6,6 @@ import kotlin.contracts.* fun f3(value: String?) { if (!value.isNullOrEmpty() is Boolean) { - value.length + value.length } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.txt index 267a3e4b146..7780a7bf0ea 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/valueOfContractedFunctionIngored.txt @@ -1,4 +1,3 @@ package -public fun myIf(/*0*/ cond: kotlin.Boolean): kotlin.Any -public fun test(/*0*/ x: kotlin.Any?): kotlin.Unit +public fun f3(/*0*/ value: kotlin.String?): kotlin.Unit diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt index 41e89f4f24f..e559b576d4d 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.kt @@ -7,7 +7,6 @@ * SECTIONS: contracts, analysis, smartcasts * NUMBER: 15 * DESCRIPTION: Check smartcasts working if type checking for contract function is used - * UNEXPECTED BEHAVIOUR * ISSUES: KT-27241 */ @@ -40,20 +39,20 @@ import contracts.* // TESTCASE NUMBER: 1 fun case_1(value: Any) { if (contracts.case_1_2(contracts.case_1_1(value is Char))) { - println(value.category) + println(value.category) } } // TESTCASE NUMBER: 2 fun case_2(value: Any) { if (contracts.case_2(value is Char) is Boolean) { - println(value.category) + println(value.category) } } // TESTCASE NUMBER: 3 fun case_3(value: String?) { if (!value.isNullOrEmpty() is Boolean) { - value.length + value.length } }