[FIR] fix subtyping for definitely notnull types.
The current implementation doesn't consider Foo a subtype of Captured<in Foo>!!, since AbstractTypeCheckerContext::checkSubtypeForSpecialCases does not handle DefinitelyNotNullType cases. This PR adds handling of DefinitelyNotNullType by looking at its original type. ^KT-42824 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
eb804709da
commit
9486f58fb1
@@ -404,15 +404,18 @@ object AbstractTypeChecker {
|
||||
|
||||
if (subType.isStubType() || superType.isStubType()) return isStubTypeEqualsToAnything
|
||||
|
||||
val superTypeCaptured = superType.asCapturedType()
|
||||
// superType might be a definitely notNull type (see KT-42824)
|
||||
val superOriginalType = superType.asDefinitelyNotNullType()?.original() ?: superType
|
||||
val superTypeCaptured = superOriginalType.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
|
||||
val nullableLowerType = if (superType.isMarkedNullable()) {
|
||||
lowerType.withNullability(true)
|
||||
} else {
|
||||
if (superType.isDefinitelyNotNullType()) lowerType.makeDefinitelyNotNullOrNotNull() else lowerType
|
||||
}
|
||||
when (getLowerCapturedTypePolicy(subType, superTypeCaptured)) {
|
||||
CHECK_ONLY_LOWER -> return isSubtypeOf(this, subType, nullableLowerType)
|
||||
CHECK_SUBTYPE_AND_LOWER -> if (isSubtypeOf(this, subType, nullableLowerType)) return true
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.types.model
|
||||
|
||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
@@ -144,9 +143,6 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
||||
|
||||
fun KotlinTypeMarker.isBuiltinFunctionalTypeOrSubtype(): Boolean
|
||||
|
||||
fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker
|
||||
fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker
|
||||
|
||||
fun createCapturedType(
|
||||
constructorProjection: TypeArgumentMarker,
|
||||
constructorSupertypes: List<KotlinTypeMarker>,
|
||||
@@ -171,8 +167,6 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
||||
fun CapturedTypeMarker.typeParameter(): TypeParameterMarker?
|
||||
fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker
|
||||
|
||||
fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker
|
||||
|
||||
fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker
|
||||
fun createEmptySubstitutor(): TypeSubstitutorMarker
|
||||
|
||||
@@ -249,6 +243,9 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
||||
fun KotlinTypeMarker.isCapturedType() = asSimpleType()?.asCapturedType() != null
|
||||
|
||||
fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker?
|
||||
fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker
|
||||
fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker
|
||||
fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker
|
||||
fun SimpleTypeMarker.isMarkedNullable(): Boolean
|
||||
fun KotlinTypeMarker.isMarkedNullable(): Boolean =
|
||||
this is SimpleTypeMarker && isMarkedNullable()
|
||||
|
||||
Reference in New Issue
Block a user