From 84f41b7d68264389ec90981390d808f535ae71ff Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 10 Oct 2023 12:55:53 +0300 Subject: [PATCH] [FIR] Use lower bound of supertype in `findClassRepresentation` for intersection types --- ...LightTreeBlackBoxCodegenTestGenerated.java | 6 +++ ...hIrFakeOverrideGeneratorTestGenerated.java | 6 +++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 +++ .../kotlin/fir/resolve/LookupTagUtils.kt | 10 +++-- ...ectionWithCapturedTypeWithRawUpperBound.kt | 43 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 +++ 9 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index 16dda1745e2..786fb34e92b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -19047,6 +19047,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/fir/internalPotentialOverride.kt"); } + @Test + @TestMetadata("intersectionWithCapturedTypeWithRawUpperBound.kt") + public void testIntersectionWithCapturedTypeWithRawUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java index db1ddc89e2f..425f6b7bf25 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java @@ -19047,6 +19047,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated runTest("compiler/testData/codegen/box/fir/internalPotentialOverride.kt"); } + @Test + @TestMetadata("intersectionWithCapturedTypeWithRawUpperBound.kt") + public void testIntersectionWithCapturedTypeWithRawUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index d09695bcaf7..89793fae24c 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -19047,6 +19047,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/fir/internalPotentialOverride.kt"); } + @Test + @TestMetadata("intersectionWithCapturedTypeWithRawUpperBound.kt") + public void testIntersectionWithCapturedTypeWithRawUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt index 4854d0952ed..6c1c019e692 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt @@ -22,12 +22,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl -import org.jetbrains.kotlin.fir.utils.exceptions.withFirLookupTagEntry import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.util.WeakPair -import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment /** * Main operation on the [ConeClassifierLookupTag] @@ -150,4 +148,10 @@ private fun ConeTypeParameterLookupTag.findClassRepresentationThatIsSubtypeOf( private fun Collection.findClassRepresentationThatIsSubtypeOf( supertype: ConeKotlinType, session: FirSession -): ConeClassLikeLookupTag? = firstOrNull { it.isSubtypeOf(supertype, session) }?.findClassRepresentation(supertype, session) +): ConeClassLikeLookupTag? { + val supertypeLowerBound = supertype.lowerBoundIfFlexible() + val compatibleComponent = this.firstOrNull { + it.isSubtypeOf(supertypeLowerBound, session) + } ?: return null + return compatibleComponent.findClassRepresentation(supertypeLowerBound, session) +} diff --git a/compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt b/compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt new file mode 100644 index 00000000000..a800e53227a --- /dev/null +++ b/compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt @@ -0,0 +1,43 @@ +// TARGET_BACKEND: JVM +// WITH_STDLIB +// MODULE: lib +// FILE: lib.kt +interface A { + fun foo() +} + +interface B : A + +interface C : B + +// FILE: FirstHolder.java +public interface FirstHolder { + K1 getValue(); +} +// FILE: SecondHolder.java +public interface SecondHolder { // <--- A is raw + K2 getValue(); +} + +// FILE: HolderImpl.java +public interface HolderImpl extends FirstHolder {} + +// MODULE: main(lib) +// FILE: main.kt +fun test(s: Any) { + require(s is SecondHolder<*> && s is HolderImpl) + /* + * - Type of s.getValue() is ft & C), C?> + * - foo` is found in scope of it(A & C) + * - there are two candidates (A.foo and C.foo) + * - they have same signatures, so we chose first of them (`A.foo` in this case) + * - fir2ir needs to find correct f/o lookup tag for this call + * - `findClassRepresentation` for `ft & C), C?>` in this case should return `null`, + * since there is no actual representation for this type + * - if it won't then fir2ir may decide to generate f/o with `C` lookup tag, based on `A.foo` function, + * which is incorrect (there is another f/o in the hierarchy between `C` and `A` + */ + s.getValue().foo() +} + +fun box(): String = "OK" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index b5db28b4f9c..10bac06bf26 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -18135,6 +18135,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/fir/incorrectBytecodeWithEnhancedNullability.kt"); } + @Test + @TestMetadata("intersectionWithCapturedTypeWithRawUpperBound.kt") + public void testIntersectionWithCapturedTypeWithRawUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index ae9c6f27f44..2fa7dbbc049 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -19047,6 +19047,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/fir/internalPotentialOverride.kt"); } + @Test + @TestMetadata("intersectionWithCapturedTypeWithRawUpperBound.kt") + public void testIntersectionWithCapturedTypeWithRawUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index 99c403b416c..6093b88341b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -19047,6 +19047,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack runTest("compiler/testData/codegen/box/fir/internalPotentialOverride.kt"); } + @Test + @TestMetadata("intersectionWithCapturedTypeWithRawUpperBound.kt") + public void testIntersectionWithCapturedTypeWithRawUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 47e8d0975b3..5d967b9273b 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15861,6 +15861,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/fir/internalPotentialOverride.kt"); } + @TestMetadata("intersectionWithCapturedTypeWithRawUpperBound.kt") + public void testIntersectionWithCapturedTypeWithRawUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/fir/intersectionWithCapturedTypeWithRawUpperBound.kt"); + } + @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { runTest("compiler/testData/codegen/box/fir/IrBuiltIns.kt");