From 871b5a2174ef326250d757c8c9e179ca31ddbec0 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Thu, 1 Apr 2021 11:28:06 -0700 Subject: [PATCH] FIR: fix nullability computation of intersection of flexible types Without this, currently, it(ft(J..J?), ft(J..J?) => J which should be ft(J..J?) instead. --- .../org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt | 7 ++++++- .../smartcastToNothingAfterCheckingForNull.fir.kt | 6 +++--- .../tests/smartCasts/varnotnull/toFlexibleType.fir.kt | 6 +++--- .../logical-conjunction-expression/p-2/neg/1.1.fir.kt | 2 +- .../logical-disjunction-expression/p-2/neg/1.1.fir.kt | 2 +- .../not-null-assertion-expression/p-3/pos/1.1.fir.kt | 4 ++-- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt index af54703d90f..3648d2ce65d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeIntersector.kt @@ -145,8 +145,13 @@ object ConeTypeIntersector { protected fun ConeKotlinType.resultNullability(context: ConeTypeContext): ResultNullability = when { isMarkedNullable -> ACCEPT_NULL + // Technically, upper bound's nullability is more accurate, e.g., a type from Java with @NotNull. + // However, it requires one more recursive call here. In contrast, UNKNOWN here is a safe approximation: for even such + // flexible type case, as long as the upper bound is still used in the intersection computation (and it indeed is), + // we will still get the same nullability from the resulting intersected type. + this is ConeFlexibleType -> UNKNOWN ConeNullabilityChecker.isSubtypeOfAny(context, this) -> NOT_NULL else -> UNKNOWN } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/smartcastToNothingAfterCheckingForNull.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/smartcastToNothingAfterCheckingForNull.fir.kt index 26fa0e97dea..3c61a09af0b 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/smartcastToNothingAfterCheckingForNull.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/smartcastToNothingAfterCheckingForNull.fir.kt @@ -23,7 +23,7 @@ fun g(x: B) { } if (y is Nothing?) { - f(y) - g(y) + f(y) + g(y) } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt index 97a21e52d45..bf5f20bb8b2 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt @@ -9,8 +9,8 @@ class J { fun bar() { var v: String? v = J.foo() - v.length - gav(v) + v.length + gav(v) } -fun gav(v: String) = v \ No newline at end of file +fun gav(v: String) = v diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-conjunction-expression/p-2/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-conjunction-expression/p-2/neg/1.1.fir.kt index fa246996883..e30431cfb93 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-conjunction-expression/p-2/neg/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-conjunction-expression/p-2/neg/1.1.fir.kt @@ -41,7 +41,7 @@ fun case2() { fun case3() { val a1 = false val a2 = JavaClass.VALUE - a2 + a2 val x3 = a1 && a2 x3 diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-disjunction-expression/p-2/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-disjunction-expression/p-2/neg/1.1.fir.kt index abc2a7b3b9c..086ec2bf430 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-disjunction-expression/p-2/neg/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/logical-disjunction-expression/p-2/neg/1.1.fir.kt @@ -41,7 +41,7 @@ fun case2() { fun case3() { val a1 = false val a2 = JavaClass.VALUE - a2 + a2 val x3 = a1 || a2 x3 diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/not-null-assertion-expression/p-3/pos/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/not-null-assertion-expression/p-3/pos/1.1.fir.kt index 983d85c5502..037b81acd5b 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/not-null-assertion-expression/p-3/pos/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/not-null-assertion-expression/p-3/pos/1.1.fir.kt @@ -22,7 +22,7 @@ import checkSubtype // TESTCASE NUMBER: 1 fun case1() { val a = JavaClass.STR - a + a val res = a!! res } @@ -30,7 +30,7 @@ fun case1() { // TESTCASE NUMBER: 2 fun case2() { val a = JavaClass.obj - a + a val x = a!! x }