[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
Generated
+5
@@ -16041,6 +16041,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt42824.kt")
|
||||||
|
public void testKt42824() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42824.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt42825.kt")
|
@TestMetadata("kt42825.kt")
|
||||||
public void testKt42825() throws Exception {
|
public void testKt42825() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.ir.types
|
|||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
|
||||||
|
|
||||||
open class IrTypeCheckerContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext, AbstractTypeCheckerContext() {
|
open class IrTypeCheckerContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext, AbstractTypeCheckerContext() {
|
||||||
|
|
||||||
@@ -49,4 +47,15 @@ open class IrTypeCheckerContext(override val irBuiltIns: IrBuiltIns) : IrTypeSys
|
|||||||
|
|
||||||
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? =
|
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? =
|
||||||
error("Captured type is unsupported in IR")
|
error("Captured type is unsupported in IR")
|
||||||
|
|
||||||
|
override fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker =
|
||||||
|
error("DefinitelyNotNull type is unsupported in IR")
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
|
||||||
|
error("makeDefinitelyNotNullOrNotNull is not supported in IR")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker {
|
||||||
|
error("makeSimpleTypeDefinitelyNotNullOrNotNull is not yet supported in IR")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// FILE: DiagnosticFactory0.java
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class DiagnosticFactory0<E> {
|
||||||
|
@NotNull
|
||||||
|
public SimpleDiagnostic<E> on(@NotNull E element) {
|
||||||
|
return new SimpleDiagnostic<>(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
class SimpleDiagnostic<E>(val element: E)
|
||||||
|
interface KtAnnotationEntry
|
||||||
|
|
||||||
|
fun foo(error: DiagnosticFactory0<in KtAnnotationEntry>, entry: KtAnnotationEntry) {
|
||||||
|
error.on(entry) // used to be INAPPLICABLE_CANDIDATE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = "OK"
|
||||||
+5
@@ -17441,6 +17441,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt42824.kt")
|
||||||
|
public void testKt42824() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42824.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt42825.kt")
|
@TestMetadata("kt42825.kt")
|
||||||
public void testKt42825() throws Exception {
|
public void testKt42825() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
||||||
|
|||||||
+5
@@ -17441,6 +17441,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt42824.kt")
|
||||||
|
public void testKt42824() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42824.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt42825.kt")
|
@TestMetadata("kt42825.kt")
|
||||||
public void testKt42825() throws Exception {
|
public void testKt42825() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
||||||
|
|||||||
+5
@@ -16041,6 +16041,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/javaNestedSamInterface.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt42824.kt")
|
||||||
|
public void testKt42824() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42824.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt42825.kt")
|
@TestMetadata("kt42825.kt")
|
||||||
public void testKt42825() throws Exception {
|
public void testKt42825() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
||||||
|
|||||||
@@ -404,15 +404,18 @@ object AbstractTypeChecker {
|
|||||||
|
|
||||||
if (subType.isStubType() || superType.isStubType()) return isStubTypeEqualsToAnything
|
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()
|
val lowerType = superTypeCaptured?.lowerType()
|
||||||
if (superTypeCaptured != null && lowerType != null) {
|
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?,
|
// 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
|
// against the nullable version of the lower type of RHS. See KT-42825
|
||||||
val nullableLowerType =
|
val nullableLowerType = if (superType.isMarkedNullable()) {
|
||||||
if (superType.isMarkedNullable())
|
lowerType.withNullability(true)
|
||||||
lowerType.withNullability(true)
|
} else {
|
||||||
else lowerType
|
if (superType.isDefinitelyNotNullType()) lowerType.makeDefinitelyNotNullOrNotNull() else lowerType
|
||||||
|
}
|
||||||
when (getLowerCapturedTypePolicy(subType, superTypeCaptured)) {
|
when (getLowerCapturedTypePolicy(subType, superTypeCaptured)) {
|
||||||
CHECK_ONLY_LOWER -> return isSubtypeOf(this, subType, nullableLowerType)
|
CHECK_ONLY_LOWER -> return isSubtypeOf(this, subType, nullableLowerType)
|
||||||
CHECK_SUBTYPE_AND_LOWER -> if (isSubtypeOf(this, subType, nullableLowerType)) return true
|
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.AbstractTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@@ -144,9 +143,6 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
|||||||
|
|
||||||
fun KotlinTypeMarker.isBuiltinFunctionalTypeOrSubtype(): Boolean
|
fun KotlinTypeMarker.isBuiltinFunctionalTypeOrSubtype(): Boolean
|
||||||
|
|
||||||
fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker
|
|
||||||
fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker
|
|
||||||
|
|
||||||
fun createCapturedType(
|
fun createCapturedType(
|
||||||
constructorProjection: TypeArgumentMarker,
|
constructorProjection: TypeArgumentMarker,
|
||||||
constructorSupertypes: List<KotlinTypeMarker>,
|
constructorSupertypes: List<KotlinTypeMarker>,
|
||||||
@@ -171,8 +167,6 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
|||||||
fun CapturedTypeMarker.typeParameter(): TypeParameterMarker?
|
fun CapturedTypeMarker.typeParameter(): TypeParameterMarker?
|
||||||
fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker
|
fun CapturedTypeMarker.withNotNullProjection(): KotlinTypeMarker
|
||||||
|
|
||||||
fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker
|
|
||||||
|
|
||||||
fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker
|
fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): TypeSubstitutorMarker
|
||||||
fun createEmptySubstitutor(): TypeSubstitutorMarker
|
fun createEmptySubstitutor(): TypeSubstitutorMarker
|
||||||
|
|
||||||
@@ -249,6 +243,9 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
|||||||
fun KotlinTypeMarker.isCapturedType() = asSimpleType()?.asCapturedType() != null
|
fun KotlinTypeMarker.isCapturedType() = asSimpleType()?.asCapturedType() != null
|
||||||
|
|
||||||
fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker?
|
fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker?
|
||||||
|
fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker
|
||||||
|
fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker
|
||||||
|
fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker
|
||||||
fun SimpleTypeMarker.isMarkedNullable(): Boolean
|
fun SimpleTypeMarker.isMarkedNullable(): Boolean
|
||||||
fun KotlinTypeMarker.isMarkedNullable(): Boolean =
|
fun KotlinTypeMarker.isMarkedNullable(): Boolean =
|
||||||
this is SimpleTypeMarker && isMarkedNullable()
|
this is SimpleTypeMarker && isMarkedNullable()
|
||||||
|
|||||||
Generated
+5
@@ -13896,6 +13896,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/generics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/generics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt42824.kt")
|
||||||
|
public void testKt42824() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42824.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt42825.kt")
|
@TestMetadata("kt42825.kt")
|
||||||
public void testKt42825() throws Exception {
|
public void testKt42825() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
||||||
|
|||||||
Generated
+5
@@ -13896,6 +13896,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/generics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/generics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt42824.kt")
|
||||||
|
public void testKt42824() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42824.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt42825.kt")
|
@TestMetadata("kt42825.kt")
|
||||||
public void testKt42825() throws Exception {
|
public void testKt42825() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
||||||
|
|||||||
+5
@@ -13961,6 +13961,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/generics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/generics"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt42824.kt")
|
||||||
|
public void testKt42824() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42824.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt42825.kt")
|
@TestMetadata("kt42825.kt")
|
||||||
public void testKt42825() throws Exception {
|
public void testKt42825() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
runTest("compiler/testData/codegen/box/javaInterop/generics/kt42825.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user