KT-27705: Use proper types for captured outer class instance
Call typeMapper only if we have an inline class.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -309,8 +309,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user