FIR: prefer flexible type over other equal types when computing intersection

This commit is contained in:
Jinseong Jeon
2021-04-04 23:05:00 -07:00
committed by Dmitriy Novozhilov
parent 0d3969597c
commit 2d42e64c17
2 changed files with 16 additions and 3 deletions
@@ -74,7 +74,20 @@ object ConeTypeIntersector {
// TODO // TODO
// IntegerLiteralTypeConstructor.findIntersectionType(filteredEqualTypes)?.let { return it } // 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) AbstractTypeChecker.equalTypes(context, a, b)
} }
assert(filteredSuperAndEqualTypes.isNotEmpty(), errorMessage) assert(filteredSuperAndEqualTypes.isNotEmpty(), errorMessage)
@@ -14,8 +14,8 @@ class J {
fun bar() { fun bar() {
var v: String? var v: String?
v = J.foo() v = J.foo()
v<!UNSAFE_CALL!>.<!>length v.length
<!INAPPLICABLE_CANDIDATE!>gav<!>(v) gav(v)
var l: List<String>? var l: List<String>?
l = J.bar() l = J.bar()