From ea4afdaebe9400e46a4933d3f7ad542f3ed534d8 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 19 Oct 2018 16:48:18 +0300 Subject: [PATCH] KT-27705: Use proper types for captured outer class instance Call typeMapper only if we have an inline class. --- .../kotlin/codegen/ConstructorCodegen.java | 4 +-- .../codegen/context/CodegenContext.java | 4 +-- .../codegen/context/ConstructorContext.java | 29 +++++++++++++++---- .../codegen/box/inlineClasses/kt27705.kt | 17 +++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 ++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 ++++ .../IrJsCodegenBoxTestGenerated.java | 5 ++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 ++++ 9 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/kt27705.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java index 635381bae7a..2612499b6fd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ConstructorCodegen.java @@ -86,7 +86,7 @@ public class ConstructorCodegen { ClassConstructorDescriptor constructorDescriptor = descriptor.getUnsubstitutedPrimaryConstructor(); if (constructorDescriptor == null) return; - ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); + ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper); KtPrimaryConstructor primaryConstructor = myClass.getPrimaryConstructor(); JvmDeclarationOrigin origin = JvmDeclarationOriginKt @@ -127,7 +127,7 @@ public class ConstructorCodegen { ) { if (!canHaveDeclaredConstructors(descriptor)) return; - ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); + ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper); KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java index cedb3496f09..7adb01ea696 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java @@ -309,8 +309,8 @@ public abstract class CodegenContext { } @NotNull - public ConstructorContext intoConstructor(@NotNull ConstructorDescriptor descriptor) { - return new ConstructorContext(descriptor, getContextKind(), this, closure); + public ConstructorContext intoConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull KotlinTypeMapper typeMapper) { + return new ConstructorContext(descriptor, getContextKind(), this, closure, typeMapper); } @NotNull diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java index bed153cc044..e5ee4c4bc61 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/ConstructorContext.java @@ -21,26 +21,45 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.OwnerKind; import org.jetbrains.kotlin.codegen.StackValue; import org.jetbrains.kotlin.codegen.binding.MutableClosure; +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; +import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ConstructorDescriptor; - -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; +import org.jetbrains.kotlin.resolve.jvm.AsmTypes; +import org.jetbrains.kotlin.types.SimpleType; +import org.jetbrains.org.objectweb.asm.Type; public class ConstructorContext extends MethodContext { - private static final StackValue LOCAL_1 = StackValue.local(1, OBJECT_TYPE); private boolean thisInitialized = false; + private final KotlinTypeMapper kotlinTypeMapper; public ConstructorContext( @NotNull ConstructorDescriptor contextDescriptor, @NotNull OwnerKind kind, @NotNull CodegenContext parent, - @Nullable MutableClosure closure + @Nullable MutableClosure closure, + @NotNull KotlinTypeMapper kotlinTypeMapper ) { super(contextDescriptor, kind, parent, closure, false); + this.kotlinTypeMapper = kotlinTypeMapper; } @Override public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) { - StackValue stackValue = closure != null && closure.getCapturedOuterClassDescriptor() != null ? LOCAL_1 : null; + ClassDescriptor capturedOuterClassDescriptor = closure != null ? closure.getCapturedOuterClassDescriptor() : null; + StackValue stackValue; + if (capturedOuterClassDescriptor != null) { + if (capturedOuterClassDescriptor.isInline()) { + SimpleType outerClassKotlinType = capturedOuterClassDescriptor.getDefaultType(); + Type outerClassType = kotlinTypeMapper.mapType(capturedOuterClassDescriptor); + stackValue = StackValue.local(1, outerClassType, outerClassKotlinType); + } + else { + stackValue = StackValue.local(1, AsmTypes.OBJECT_TYPE); + } + } + else { + stackValue = null; + } if (!ignoreNoOuter && stackValue == null) { throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor()); } diff --git a/compiler/testData/codegen/box/inlineClasses/kt27705.kt b/compiler/testData/codegen/box/inlineClasses/kt27705.kt new file mode 100644 index 00000000000..5bb5f300099 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt27705.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +InlineClasses +// WITH_RUNTIME +// IGNORE_BACKEND: JVM_IR + +inline class Z(val x: Int) { + inner class Inner(val y: Int) { + val xx = x + } +} + +fun box(): String { + val zi = Z(42).Inner(100) + if (zi.xx != 42) throw AssertionError() + if (zi.y != 100) throw AssertionError() + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index ebf28c4c659..7945300f910 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -12055,6 +12055,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); } + @TestMetadata("kt27705.kt") + public void testKt27705() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 56eb7a61994..9ae8b78083a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -12055,6 +12055,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); } + @TestMetadata("kt27705.kt") + public void testKt27705() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 6c89d15f362..d1d3fc24f2f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -12060,6 +12060,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); } + @TestMetadata("kt27705.kt") + public void testKt27705() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.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 ae0fd560850..9b868fc4aee 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 @@ -10455,6 +10455,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); } + @TestMetadata("kt27705.kt") + public void testKt27705() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.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 e2def4c6bbd..1f423e9b0b2 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 @@ -11500,6 +11500,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt"); } + @TestMetadata("kt27705.kt") + public void testKt27705() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");