From 6ee6d019ee63d6a8ed86d8951934235cad4621a7 Mon Sep 17 00:00:00 2001 From: pyos Date: Tue, 8 Nov 2022 20:21:41 +0100 Subject: [PATCH] FIR DFA: align return-implies checker closer to smartcasts --- .../kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt | 6 ++++-- .../smartcasts/nullabilitySmartcastWhenNullability.fir.kt | 4 ++-- .../notLinked/contracts/analysis/common/neg/1.fir.kt | 2 +- .../notLinked/contracts/analysis/smartcasts/neg/8.fir.kt | 6 +++--- .../notLinked/contracts/analysis/smartcasts/pos/8.fir.kt | 4 ++-- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt index 8719f621185..accd2a96962 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirReturnsImpliesAnalyzer.kt @@ -195,8 +195,10 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() { } private fun RealVariable.nullabilityStatement(builtinTypes: BuiltinTypes, isNull: Boolean) = - // TODO: opposite for builtinTypes.nullableNothingType.type - if (isNull) this typeNotEq builtinTypes.anyType.type else this typeEq builtinTypes.anyType.type + if (isNull) + this typeEq builtinTypes.nullableNothingType.type andTypeNotEq builtinTypes.anyType.type + else + this typeEq builtinTypes.anyType.type andTypeNotEq builtinTypes.nullableNothingType.type private fun TypeStatement.singleton(): TypeStatements = mapOf(variable to this) diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/nullabilitySmartcastWhenNullability.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/nullabilitySmartcastWhenNullability.fir.kt index 9cb0a48acc3..13f8547f10b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/nullabilitySmartcastWhenNullability.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/nullabilitySmartcastWhenNullability.fir.kt @@ -31,9 +31,9 @@ fun testNullWhenNull(x: Int?) { // NB. it is the same function as `nullWhenNull`, but annotations specifies other facet of the function behaviour fun notNullWhenNotNull (x: Int?): Int? { - contract { + contract { returns(null) implies (x == null) - } + } return x?.inc() } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/common/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/common/neg/1.fir.kt index ba255372aa7..2698224e1c6 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/common/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/common/neg/1.fir.kt @@ -20,7 +20,7 @@ inline fun case_1(value_1: Int?, block: () -> Unit): Boolean { // TESTCASE NUMBER: 2 inline fun T?.case_2(value_1: Int?, value_2: Any?, block: () -> Unit): Boolean? { - contract { + contract { callsInPlace(block, InvocationKind.AT_MOST_ONCE) returns(true) implies (value_1 == null && this@case_2 == null && value_2 !is Boolean?) returns(false) implies (value_2 is Boolean?) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.fir.kt index 3028943b8af..48e529c3fb6 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/8.fir.kt @@ -8,7 +8,7 @@ import kotlin.contracts.* // TESTCASE NUMBER: 3 fun T?.case_3(value_1: Int?, value_2: Boolean): Boolean { - contract { + contract { returns(true) implies (value_1 != null) returns(false) implies (value_1 == null && !value_2) returns(null) implies (value_1 == null && value_2) @@ -30,7 +30,7 @@ fun case_4(value_1: Number, block: (() -> Unit)?): Boolean? { // TESTCASE NUMBER: 5 fun String?.case_5(value_1: Number?): Boolean? { - contract { + contract { returns(true) implies (value_1 == null) returns(false) implies (this@case_5 == null) returnsNotNull() implies (value_1 is Int) @@ -41,7 +41,7 @@ fun String?.case_5(value_1: Number?): Boolean? { // TESTCASE NUMBER: 6 fun T?.case_6(value_1: Number, value_2: String?): Boolean? { - contract { + contract { returns(true) implies (this@case_6 == null) returns(false) implies (value_1 is Int) returns(null) implies (this@case_6 is String) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.fir.kt index e26c1df5efb..2b60f436dcd 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/8.fir.kt @@ -19,11 +19,11 @@ fun T?.case_3(value_1: Int?, value_2: Boolean): Boolean { // TESTCASE NUMBER: 4 fun case_4(value_1: Number, block: (() -> Unit)?): Boolean? { - contract { + contract { returns(true) implies (value_1 is Int) returns(false) implies (block == null) returns(null) implies (block != null) - } + } return value_1 == null }