From 289dafa331dfc028926583f393277d31f88dd639 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 21 Aug 2023 19:19:17 +0200 Subject: [PATCH] FIR2IR: don't apply SAM conversion for type parameter based types #KT-58893 Fixed #KT-58884 Fixed --- .../backend/generators/AdapterGenerator.kt | 11 ++++- ...LightTreeBlackBoxCodegenTestGenerated.java | 6 +++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 +++ compiler/testData/codegen/box/fir/Mockito.kt | 47 +++++++++++++++++++ .../samConversionsWithSmartCasts.fir.ir.txt | 3 +- .../samConversionsWithSmartCasts.fir.kt.txt | 2 +- .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 ++ 10 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/codegen/box/fir/Mockito.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt index cf735ee9a9d..d9a4186afbd 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt @@ -562,7 +562,7 @@ internal class AdapterGenerator( } // If the expected type is a built-in functional type, we don't need SAM conversion. val expectedType = argument.getExpectedType(parameter) - if (expectedType is ConeTypeParameterType || expectedType.isSomeFunctionType(session)) { + if (expectedType.isTypeParameterBased() || expectedType.isSomeFunctionType(session)) { return false } // On the other hand, the actual type should be either a functional type or a subtype of a class that has a contributed `invoke`. @@ -570,6 +570,15 @@ internal class AdapterGenerator( return argument.isFunctional(session, scopeSession, expectedFunctionType, ReturnTypeCalculatorForFullBodyResolve.Default) } + private fun ConeKotlinType.isTypeParameterBased(): Boolean { + return when (this) { + is ConeTypeParameterType -> true + is ConeDefinitelyNotNullType -> original.isTypeParameterBased() + is ConeFlexibleType -> lowerBound.isTypeParameterBased() + else -> false + } + } + internal fun getFunctionTypeForPossibleSamType(parameterType: ConeKotlinType): ConeKotlinType? { return samResolver.getFunctionTypeForPossibleSamType(parameterType) } 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 515c2843a54..f99929c754d 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 @@ -18815,6 +18815,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/fir/manyImplFromOneJavaInterfaceWithDelegation2.kt"); } + @Test + @TestMetadata("Mockito.kt") + public void testMockito() throws Exception { + runTest("compiler/testData/codegen/box/fir/Mockito.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() 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 acdfde0c095..3cc74a5e19b 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 @@ -18815,6 +18815,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/fir/manyImplFromOneJavaInterfaceWithDelegation2.kt"); } + @Test + @TestMetadata("Mockito.kt") + public void testMockito() throws Exception { + runTest("compiler/testData/codegen/box/fir/Mockito.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() throws Exception { diff --git a/compiler/testData/codegen/box/fir/Mockito.kt b/compiler/testData/codegen/box/fir/Mockito.kt new file mode 100644 index 00000000000..7064770e70a --- /dev/null +++ b/compiler/testData/codegen/box/fir/Mockito.kt @@ -0,0 +1,47 @@ +// ISSUE: KT-58893 +// TARGET_BACKEND: JVM +// WITH_STDLIB +// IGNORE_INLINER: IR + +// FILE: InOrder.java + +public class InOrder { + T verify(T mock) { + String s = mock.getClass().toString(); + if (!s.equals(TestKt.expected)) throw new IllegalStateException(s); + return mock; + } +} + +// FILE: test.kt + +inline fun mock(s: String = ""): T = MOCK as T + +val MOCK = {} + +inline fun inOrder( + vararg mocks: Any, + evaluation: InOrder.() -> Unit +) { + inOrder.evaluation() + InOrder().evaluation() +} + +val inOrder = object : InOrder() { + override fun verify(mock: T): T { + val s = mock!!.javaClass.toString() + if (s != expected) throw IllegalStateException(s) + return mock + } +} + +lateinit var expected: String + +fun box(): String { + val mock = mock<() -> Unit>() + expected = mock.javaClass.toString() + inOrder(mock) { + verify(mock)() + } + return "OK" +} diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.ir.txt b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.ir.txt index 0580ad9f7b4..9f99fd178cc 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.ir.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.ir.txt @@ -104,8 +104,7 @@ FILE fqName: fileName:/samConversionsWithSmartCasts.kt r: TYPE_OP type=@[FlexibleNullability] java.lang.Runnable? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.lang.Runnable? CALL 'public open fun id (x: @[FlexibleNullability] T of .J.id?): @[FlexibleNullability] T of .J.id? declared in .J' type=@[FlexibleNullability] kotlin.Function0? origin=null : @[FlexibleNullability] kotlin.Function0? - x: TYPE_OP type=@[FlexibleNullability] kotlin.Function0? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] kotlin.Function0? - GET_VAR 'a: kotlin.Function0 declared in .test8' type=kotlin.Function0 origin=null + x: GET_VAR 'a: kotlin.Function0 declared in .test8' type=kotlin.Function0 origin=null FUN name:test9 visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY CALL 'public open fun run1 (r: @[FlexibleNullability] java.lang.Runnable?): kotlin.Unit declared in .J' type=kotlin.Unit origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt index e8005fc8b86..3ff8dc7041b 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionsWithSmartCasts.fir.kt.txt @@ -48,7 +48,7 @@ fun test7(a: Function1) { } fun test8(a: Function0) { - J().run1(r = id<@FlexibleNullability Function0?>(x = a /*-> @FlexibleNullability Function0? */) /*-> @FlexibleNullability Runnable? */) + J().run1(r = id<@FlexibleNullability Function0?>(x = a) /*-> @FlexibleNullability Runnable? */) } fun test9() { 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 5081ed7f547..1011b846195 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 @@ -17909,6 +17909,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/fir/LookupTags.kt"); } + @Test + @TestMetadata("Mockito.kt") + public void testMockito() throws Exception { + runTest("compiler/testData/codegen/box/fir/Mockito.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() 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 65d01bd95f3..2cad722032b 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 @@ -18815,6 +18815,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/fir/manyImplFromOneJavaInterfaceWithDelegation2.kt"); } + @Test + @TestMetadata("Mockito.kt") + public void testMockito() throws Exception { + runTest("compiler/testData/codegen/box/fir/Mockito.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() 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 2355863d9d0..1f9a21bfbfd 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 @@ -18815,6 +18815,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack runTest("compiler/testData/codegen/box/fir/manyImplFromOneJavaInterfaceWithDelegation2.kt"); } + @Test + @TestMetadata("Mockito.kt") + public void testMockito() throws Exception { + runTest("compiler/testData/codegen/box/fir/Mockito.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() 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 f030786b65b..96a9fa8b475 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15663,6 +15663,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/fir/manyImplFromOneJavaInterfaceWithDelegation2.kt"); } + @TestMetadata("Mockito.kt") + public void testMockito() throws Exception { + runTest("compiler/testData/codegen/box/fir/Mockito.kt"); + } + @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() throws Exception { runTest("compiler/testData/codegen/box/fir/NameHighlighter.kt");