From a8abd8cceb9de17c83dc7d8bf876935ebd00dc6d Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Thu, 11 Oct 2018 11:02:00 +0300 Subject: [PATCH] Fix boxing/unboxing for generic functions on index expressions Unsubstituted type should be used for coercion to box value of inline class type if it's needed. For the substituted value it's not known if it was a generic parameter or not. #KT-27502 Fixed --- .../kotlin/codegen/ExpressionCodegen.java | 4 ++-- .../jetbrains/kotlin/codegen/StackValue.java | 2 +- .../unboxValueOfAnyBeforeMethodInvocation.kt | 22 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++++ .../IrJsCodegenBoxTestGenerated.java | 10 ++++----- .../semantics/JsCodegenBoxTestGenerated.java | 10 ++++----- 8 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 12baa7e42a4..f4c37e5a911 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -4370,8 +4370,8 @@ public class ExpressionCodegen extends KtVisitor impleme Type elementType = isGetter ? callableMethod.getReturnType() : ArrayUtil.getLastElement(argumentTypes); KotlinType elementKotlinType = isGetter ? - operationDescriptor.getReturnType() : - CollectionsKt.last(operationDescriptor.getValueParameters()).getType(); + operationDescriptor.getOriginal().getReturnType() : + CollectionsKt.last(operationDescriptor.getOriginal().getValueParameters()).getType(); return StackValue.collectionElement( collectionElementReceiver, elementType, elementKotlinType, resolvedGetCall, resolvedSetCall, this ); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 8730123ad27..422a2b49c98 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -1449,7 +1449,7 @@ public abstract class StackValue { Type lastParameterType = ArraysKt.last(setter.getParameterTypes()); KotlinType lastParameterKotlinType = - CollectionsKt.last(resolvedSetCall.getResultingDescriptor().getValueParameters()).getType(); + CollectionsKt.last(resolvedSetCall.getResultingDescriptor().getOriginal().getValueParameters()).getType(); coerce(topOfStackType, topOfStackKotlinType, lastParameterType, lastParameterKotlinType, v); diff --git a/compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt b/compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt new file mode 100644 index 00000000000..9a1c00de1ec --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME +// IGNORE_BACKEND: JVM_IR + +inline class NullableInt(private val holder: Any?) { + val intValue: Int get() = holder as Int +} + +val prop: ArrayList = arrayListOf(NullableInt(0)) + +fun box(): String { + val a = prop[0].intValue + if (a != 0) return "Error 1: $a" + + val local = mutableListOf(NullableInt(1)) + val b = local[0].intValue + if (b != 1) return "Error 2: $b" + + prop[0] = NullableInt(2) + if (prop[0].intValue != 2) return "Error 3: ${prop[0].intValue}" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 50a6f0beca5..225476d985e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11984,6 +11984,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/unboxValueFromPlatformType.kt"); } + @TestMetadata("unboxValueOfAnyBeforeMethodInvocation.kt") + public void testUnboxValueOfAnyBeforeMethodInvocation() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt"); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 866f2b0bff3..d238187badf 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11984,6 +11984,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/unboxValueFromPlatformType.kt"); } + @TestMetadata("unboxValueOfAnyBeforeMethodInvocation.kt") + public void testUnboxValueOfAnyBeforeMethodInvocation() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt"); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 940085c5117..0c1947cf8a0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -11989,6 +11989,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/unboxValueFromPlatformType.kt"); } + @TestMetadata("unboxValueOfAnyBeforeMethodInvocation.kt") + public void testUnboxValueOfAnyBeforeMethodInvocation() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt"); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index 891cb567c16..f4293d21f57 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -5160,11 +5160,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt", "kotlin.coroutines"); } - @TestMetadata("createCoroutinesOnManualInstances.kt") - public void testCreateCoroutinesOnManualInstances() throws Exception { - runTest("compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances.kt"); - } - @TestMetadata("createCoroutinesOnManualInstances_1_2.kt") public void testCreateCoroutinesOnManualInstances_1_2() throws Exception { runTest("compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt"); @@ -10524,6 +10519,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/unboxValueFromPlatformType.kt"); } + @TestMetadata("unboxValueOfAnyBeforeMethodInvocation.kt") + public void testUnboxValueOfAnyBeforeMethodInvocation() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt"); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.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 ba28239adef..f974fe44fe3 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 @@ -5245,11 +5245,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt", "kotlin.coroutines"); } - @TestMetadata("createCoroutinesOnManualInstances.kt") - public void testCreateCoroutinesOnManualInstances() throws Exception { - runTest("compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances.kt"); - } - @TestMetadata("createCoroutinesOnManualInstances_1_2.kt") public void testCreateCoroutinesOnManualInstances_1_2() throws Exception { runTest("compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt"); @@ -11569,6 +11564,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/unboxValueFromPlatformType.kt"); } + @TestMetadata("unboxValueOfAnyBeforeMethodInvocation.kt") + public void testUnboxValueOfAnyBeforeMethodInvocation() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/unboxValueOfAnyBeforeMethodInvocation.kt"); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt");