From 2d42e64c1745ad511cba177b8b8ea23aba1c6cc8 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Sun, 4 Apr 2021 23:05:00 -0700 Subject: [PATCH] FIR: prefer flexible type over other equal types when computing intersection --- .../kotlin/fir/types/ConeTypeIntersector.kt | 15 ++++++++++++++- .../smartCasts/varnotnull/toFlexibleType.fir.kt | 4 ++-- 2 files changed, 16 insertions(+), 3 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 654bcc140bb..af6609548ca 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 @@ -74,7 +74,20 @@ object ConeTypeIntersector { // TODO // IntegerLiteralTypeConstructor.findIntersectionType(filteredEqualTypes)?.let { return it } - val filteredSuperAndEqualTypes = filterTypes(filteredEqualTypes) { a, b -> + /* + * For the case like it(ft(String..String?), String?), where ft(String..String?) == String?, we prefer to _keep_ flexible type. + * When a == b, the former, i.e., the one in the list will be filtered out, and the other one will remain. + * So, here, we sort the interim list such that flexible types appear later. + */ + val sortedEqualTypes = filteredEqualTypes.sortedWith { p0, p1 -> + when { + p0 is ConeFlexibleType && p1 is ConeFlexibleType -> 0 + p0 is ConeFlexibleType -> 1 + p1 is ConeFlexibleType -> -1 + else -> 0 + } + } + val filteredSuperAndEqualTypes = filterTypes(sortedEqualTypes) { a, b -> AbstractTypeChecker.equalTypes(context, a, b) } assert(filteredSuperAndEqualTypes.isNotEmpty(), errorMessage) diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt index 38791473438..110e2486c8d 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/toFlexibleType.fir.kt @@ -14,8 +14,8 @@ class J { fun bar() { var v: String? v = J.foo() - v.length - gav(v) + v.length + gav(v) var l: List? l = J.bar()