diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallReceiver.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallReceiver.java index 27da29f5dd7..ec46d15e72a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallReceiver.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallReceiver.java @@ -29,19 +29,22 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; public class CallReceiver extends StackValue { private final StackValue dispatchReceiver; private final StackValue extensionReceiver; + private final Type secondReceiverType; private CallReceiver( @NotNull StackValue dispatchReceiver, @NotNull StackValue extensionReceiver, - @NotNull Type type + @NotNull Type type, + @Nullable Type secondReceiverType ) { super(type, dispatchReceiver.canHaveSideEffects() || extensionReceiver.canHaveSideEffects()); this.dispatchReceiver = dispatchReceiver; this.extensionReceiver = extensionReceiver; + this.secondReceiverType = secondReceiverType; } public StackValue withoutReceiverArgument() { - return new CallReceiver(dispatchReceiver, none(), type); + return new CallReceiver(dispatchReceiver, none(), type, secondReceiverType); } public static StackValue generateCallReceiver( @@ -57,8 +60,12 @@ public class CallReceiver extends StackValue { GenerationState state = codegen.getState(); Type type; + Type secondReceiverType = null; if (extensionReceiverParameter != null) { type = calcExtensionReceiverType(resolvedCall, extensionReceiverParameter, typeMapper, callableMethod, state); + if (dispatchReceiverParameter != null) { + secondReceiverType = calcDispatchReceiverType(resolvedCall, dispatchReceiverParameter, typeMapper, callableMethod); + } } else if (dispatchReceiverParameter != null) { type = calcDispatchReceiverType(resolvedCall, dispatchReceiverParameter, typeMapper, callableMethod); @@ -72,7 +79,7 @@ public class CallReceiver extends StackValue { assert type != null : "Could not map receiver type for " + resolvedCall; - return new CallReceiver(dispatchReceiver, extensionReceiver, type); + return new CallReceiver(dispatchReceiver, extensionReceiver, type, secondReceiverType); } private static Type calcDispatchReceiverType( @@ -135,10 +142,13 @@ public class CallReceiver extends StackValue { currentExtensionReceiver = StackValue.onStack(currentExtensionReceiver.type); } - dispatchReceiver.put(hasExtensionReceiver ? dispatchReceiver.type : type, v); + Type dispatchReceiverType = secondReceiverType != null ? secondReceiverType : + hasExtensionReceiver ? dispatchReceiver.type : + type; + dispatchReceiver.put(dispatchReceiverType, v); currentExtensionReceiver - .moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiver.type.getSize()); + .moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiverType.getSize()); } @Override diff --git a/compiler/testData/codegen/box/smartCasts/kt17725.kt b/compiler/testData/codegen/box/smartCasts/kt17725.kt new file mode 100644 index 00000000000..71334c4f85b --- /dev/null +++ b/compiler/testData/codegen/box/smartCasts/kt17725.kt @@ -0,0 +1,10 @@ +class Bob { + fun Bob.bar() = "OK" +} + +fun Any.foo() = when(this) { + is Bob -> bar() + else -> throw AssertionError() +} + +fun box(): String = Bob().foo() \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 444c795607b..caee19fe08a 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -17600,6 +17600,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("kt17725.kt") + public void testKt17725() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt"); + doTest(fileName); + } + @TestMetadata("kt19058.kt") public void testKt19058() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19058.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 54242d1b47b..29505ec4ae9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -17600,6 +17600,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt17725.kt") + public void testKt17725() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt"); + doTest(fileName); + } + @TestMetadata("kt19058.kt") public void testKt19058() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19058.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index b922373dadc..b4f1118b4ee 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -17600,6 +17600,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("kt17725.kt") + public void testKt17725() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt"); + doTest(fileName); + } + @TestMetadata("kt19058.kt") public void testKt19058() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19058.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 17b1e3b5c96..ee75a75a52e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -21506,6 +21506,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("kt17725.kt") + public void testKt17725() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt"); + doTest(fileName); + } + @TestMetadata("kt19100.kt") public void testKt19100() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19100.kt");