diff --git a/compiler/fir/analysis-tests/testData/resolve/kt41984.kt b/compiler/fir/analysis-tests/testData/resolve/kt41984.kt new file mode 100644 index 00000000000..e693f6acce1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/kt41984.kt @@ -0,0 +1,31 @@ +// ISSUE: KT-41984 + +// FILE: A.java + +import org.jetbrains.annotations.NotNull; + +public abstract class A { + @NotNull + public abstract String take(@NotNull V value); + + @NotNull + public abstract String takeInv(@NotNull Inv<@NotNull V> value); +} + +// FILE: main.kt + +class Inv + +open class B : A() { + override fun take(value: V): String { + return "" + } + + override fun takeInv(value: Inv): String = "" +} + +fun test_1(b: B, x: Int, inv: Inv) { + b.take(x) + b.take(null) + b.takeInv(inv) +} diff --git a/compiler/fir/analysis-tests/testData/resolve/kt41984.txt b/compiler/fir/analysis-tests/testData/resolve/kt41984.txt new file mode 100644 index 00000000000..bc0de1d73c0 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/kt41984.txt @@ -0,0 +1,26 @@ +FILE: main.kt + public final class Inv : R|kotlin/Any| { + public constructor(): R|Inv| { + super() + } + + } + public open class B : R|A| { + public constructor(): R|B| { + super|>() + } + + public open override fun take(value: R|V|): R|kotlin/String| { + ^take String() + } + + public open override fun takeInv(value: R|Inv|): R|kotlin/String| { + ^takeInv String() + } + + } + public final fun test_1(b: R|B|, x: R|kotlin/Int|, inv: R|Inv|): R|kotlin/Unit| { + R|/b|.R|FakeOverride|(R|/x|) + R|/b|.#(Null(null)) + R|/b|.R|FakeOverride|(R|/inv|) + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 066c8d2c226..d8edca83afc 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -243,6 +243,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/analysis-tests/testData/resolve/javaStaticScopeInheritance.kt"); } + @TestMetadata("kt41984.kt") + public void testKt41984() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/kt41984.kt"); + } + @TestMetadata("kt41990.kt") public void testKt41990() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/kt41990.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 692dfe029e9..3e15e033e89 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -243,6 +243,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/javaStaticScopeInheritance.kt"); } + @TestMetadata("kt41984.kt") + public void testKt41984() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/kt41984.kt"); + } + @TestMetadata("kt41990.kt") public void testKt41990() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/kt41990.kt"); diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt index dd0d3a7a641..dc50ddd3560 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt @@ -41,11 +41,16 @@ class FirStandardOverrideChecker(session: FirSession) : FirAbstractOverrideCheck } private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor): Boolean { - val substitutedCandidateType = substitutor.substituteOrSelf(candidateType) - val substitutedBaseType = substitutor.substituteOrSelf(baseType) + val substitutedCandidateType = substitutor.substituteOrSelf(candidateType).unwrapDefinitelyNotNullType() + val substitutedBaseType = substitutor.substituteOrSelf(baseType).unwrapDefinitelyNotNullType() return isEqualTypes(substitutedCandidateType, substitutedBaseType) } + private fun ConeKotlinType.unwrapDefinitelyNotNullType(): ConeKotlinType = when (this) { + is ConeDefinitelyNotNullType -> original + else -> this + } + override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) = isEqualTypes(candidateTypeRef.coneType, baseTypeRef.coneType, substitutor)