[FIR] fix subtyping for nullable captured types.
The issue is the type checker doesn't consider P? a subtype of CapturedType<in P>?, whereas P a subtype of CapturedType<in P>?. In AbstractTypeCheckerContext::checkSubtypeForSpecialCases, it checks if P? is a subtype of the lower type of the captured type, which is P, and returns false. This fix uses nullable version of the lower type when the captured type is marked nullable. To check if P? is a subtype of Captured<in P>?, we check the LHS, P?, against the nullable lower type of RHS, P?. ^KT-42825 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
d96223a2ff
commit
eb804709da
@@ -407,9 +407,15 @@ object AbstractTypeChecker {
|
||||
val superTypeCaptured = superType.asCapturedType()
|
||||
val lowerType = superTypeCaptured?.lowerType()
|
||||
if (superTypeCaptured != null && lowerType != null) {
|
||||
// If superType is nullable, e.g., to check if Foo? a subtype of Captured<in Foo>?, we check the LHS, Foo?,
|
||||
// against the nullable version of the lower type of RHS. See KT-42825
|
||||
val nullableLowerType =
|
||||
if (superType.isMarkedNullable())
|
||||
lowerType.withNullability(true)
|
||||
else lowerType
|
||||
when (getLowerCapturedTypePolicy(subType, superTypeCaptured)) {
|
||||
CHECK_ONLY_LOWER -> return isSubtypeOf(this, subType, lowerType)
|
||||
CHECK_SUBTYPE_AND_LOWER -> if (isSubtypeOf(this, subType, lowerType)) return true
|
||||
CHECK_ONLY_LOWER -> return isSubtypeOf(this, subType, nullableLowerType)
|
||||
CHECK_SUBTYPE_AND_LOWER -> if (isSubtypeOf(this, subType, nullableLowerType)) return true
|
||||
SKIP_LOWER -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,9 +144,6 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
||||
|
||||
fun KotlinTypeMarker.isBuiltinFunctionalTypeOrSubtype(): Boolean
|
||||
|
||||
fun KotlinTypeMarker.withNullability(nullable: Boolean): KotlinTypeMarker
|
||||
|
||||
|
||||
fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker
|
||||
fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker
|
||||
|
||||
@@ -241,7 +238,6 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
||||
fun KotlinTypeMarker.isError(): Boolean
|
||||
fun TypeConstructorMarker.isError(): Boolean
|
||||
fun KotlinTypeMarker.isUninferredParameter(): Boolean
|
||||
|
||||
fun FlexibleTypeMarker.asDynamicType(): DynamicTypeMarker?
|
||||
|
||||
fun FlexibleTypeMarker.asRawType(): RawTypeMarker?
|
||||
@@ -259,6 +255,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
||||
|
||||
fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker
|
||||
fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker
|
||||
fun KotlinTypeMarker.withNullability(nullable: Boolean): KotlinTypeMarker
|
||||
|
||||
fun CapturedTypeMarker.typeConstructor(): CapturedTypeConstructorMarker
|
||||
fun CapturedTypeMarker.captureStatus(): CaptureStatus
|
||||
|
||||
Reference in New Issue
Block a user