[FIR] Remove redundant checks from isUpcast() and isExactTypeCast()

`T.() -> R` and `(T) -> R` should only be
different for resolution, but casts are only
about typechecking. Values of either of
these types can always be put into variables
of the other type.
This commit is contained in:
Nikolay Lunyak
2024-03-07 14:04:24 +02:00
committed by Space Team
parent fbdf7e33bd
commit 4c0ec0fae4
3 changed files with 14 additions and 18 deletions
@@ -168,17 +168,8 @@ fun ConeKotlinType.isNonReifiedTypeParameter(): Boolean {
return this is ConeTypeParameterType && !this.lookupTag.typeParameterSymbol.isReified
}
fun isUpcast(context: CheckerContext, candidateType: ConeKotlinType, targetType: ConeKotlinType): Boolean {
if (!AbstractTypeChecker.isSubtypeOf(context.session.typeContext, candidateType, targetType, stubTypesEqualToAnything = false))
return false
// E.g., foo(p1: (X) -> Y), where p1 has a function type whose receiver type is X and return type is Y.
// For bar(p2: X.() -> Y), p2 has the same function type (with same receiver and return types).
// The only difference is the existence of type annotation, @ExtensionFunctionType,
// which indicates that the annotated type represents an extension function.
// If one casts p1 to p2 (or vice versa), it is _not_ up cast, i.e., not redundant, yet meaningful.
return candidateType.isExtensionFunctionType == targetType.isExtensionFunctionType
}
fun isUpcast(context: CheckerContext, candidateType: ConeKotlinType, targetType: ConeKotlinType): Boolean =
AbstractTypeChecker.isSubtypeOf(context.session.typeContext, candidateType, targetType, stubTypesEqualToAnything = false)
internal fun isRefinementUseless(
context: CheckerContext,
@@ -216,9 +207,5 @@ internal fun isRefinementUseless(
}
}
private fun isExactTypeCast(context: CheckerContext, lhsType: ConeKotlinType, targetType: ConeKotlinType): Boolean {
if (!AbstractTypeChecker.equalTypes(context.session.typeContext, lhsType, targetType, stubTypesEqualToAnything = false))
return false
// See comments at [isUpcast] why we need to check the existence of @ExtensionFunctionType
return lhsType.isExtensionFunctionType == targetType.isExtensionFunctionType
}
private fun isExactTypeCast(context: CheckerContext, lhsType: ConeKotlinType, targetType: ConeKotlinType): Boolean =
AbstractTypeChecker.equalTypes(context.session.typeContext, lhsType, targetType, stubTypesEqualToAnything = false)
@@ -0,0 +1,10 @@
fun f(a: (Int) -> Unit) {
a <!USELESS_CAST!>as Int.() -> Unit<!>
f1(a <!USELESS_CAST!>as Int.() -> Unit<!>)
}
fun f1(a: Int.() -> Unit) {
a <!USELESS_CAST!>as (Int) -> Unit<!>
f(a <!USELESS_CAST!>as (Int) -> Unit<!>)
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
fun f(a: (Int) -> Unit) {
a as Int.() -> Unit