KT-30780 Fix erased inline class context in class context hierarchy

In SourceCompilerForInline we could enter ERASED_INLINE_CLASS context
from containing declaration context. That broke codegen context
hierarchy invariants assumed in accessor generation.
This commit is contained in:
Dmitry Petrov
2019-04-04 16:56:19 +03:00
parent e1915ec99e
commit bbeb65905e
9 changed files with 67 additions and 12 deletions
@@ -30,6 +30,14 @@ public class ClassContext extends FieldOwnerContext<ClassDescriptor> {
super(contextDescriptor, contextKind, parentContext, typeMapper.getBindingContext().get(CLOSURE, contextDescriptor),
contextDescriptor, localLookup);
if (contextKind == OwnerKind.ERASED_INLINE_CLASS) {
assert parentContext instanceof ClassContext &&
parentContext.getContextKind() == OwnerKind.IMPLEMENTATION &&
parentContext.getContextDescriptor() == contextDescriptor:
"Erased inline class context should be created inside implementation context for the same class:" + contextDescriptor +
"parent: " + parentContext;
}
this.typeMapper = typeMapper;
}
@@ -393,13 +393,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
public CodegenContext findParentContextWithDescriptor(DeclarationDescriptor descriptor) {
CodegenContext c = this;
while (c != null) {
if (!c.shouldSkipThisContextInHierarchy() && c.getContextDescriptor() == descriptor) break;
if (!c.isShadowedByParentContext() && c.getContextDescriptor() == descriptor) break;
c = c.getParentContext();
}
return c;
}
private boolean shouldSkipThisContextInHierarchy() {
private boolean isShadowedByParentContext() {
return getContextKind() == OwnerKind.ERASED_INLINE_CLASS;
}
@@ -429,7 +429,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
}
val container = descriptor.containingDeclaration ?: error("No container for descriptor: $descriptor")
val parent = getContext(
val containerContext = getContext(
container,
descriptor,
state,
@@ -440,7 +440,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
return when (descriptor) {
is ScriptDescriptor -> {
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
parent.intoScript(
containerContext.intoScript(
descriptor,
earlierScripts ?: emptyList(),
descriptor as ClassDescriptor, state.typeMapper
@@ -449,21 +449,27 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
is ClassDescriptor -> {
val kind =
when {
DescriptorUtils.isInterface(descriptor) && innerDescriptor !is ClassDescriptor &&
!innerDescriptor.isCallableMemberWithJvmDefaultAnnotation() -> OwnerKind.DEFAULT_IMPLS
descriptor.isInlineClass() -> OwnerKind.ERASED_INLINE_CLASS
else -> OwnerKind.IMPLEMENTATION
DescriptorUtils.isInterface(descriptor) &&
innerDescriptor !is ClassDescriptor &&
!innerDescriptor.isCallableMemberWithJvmDefaultAnnotation() ->
OwnerKind.DEFAULT_IMPLS
else ->
OwnerKind.IMPLEMENTATION
}
additionalInners.addIfNotNull(
InnerClassConsumer.classForInnerClassRecord(descriptor, kind == OwnerKind.DEFAULT_IMPLS)
)
parent.intoClass(descriptor, kind, state)
if (descriptor.isInlineClass()) {
containerContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state)
.intoClass(descriptor, OwnerKind.ERASED_INLINE_CLASS, state)
} else {
containerContext.intoClass(descriptor, kind, state)
}
}
is FunctionDescriptor -> {
parent.intoFunction(descriptor)
containerContext.intoFunction(descriptor)
}
else -> {
throw IllegalStateException("Couldn't build context for $descriptor")
@@ -0,0 +1,16 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
inline class Test(val x: Int) {
private companion object {
private const val CONSTANT = "OK"
}
fun crash() = getInlineConstant()
private inline fun getInlineConstant(): String {
return CONSTANT
}
}
fun box() = Test(1).crash()
@@ -12693,6 +12693,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
}
@TestMetadata("kt30780.kt")
public void testKt30780() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt30780.kt");
}
@TestMetadata("lambdaInInlineClassFun.kt")
public void testLambdaInInlineClassFun() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
@@ -12693,6 +12693,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
}
@TestMetadata("kt30780.kt")
public void testKt30780() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt30780.kt");
}
@TestMetadata("lambdaInInlineClassFun.kt")
public void testLambdaInInlineClassFun() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
@@ -12698,6 +12698,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
}
@TestMetadata("kt30780.kt")
public void testKt30780() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt30780.kt");
}
@TestMetadata("lambdaInInlineClassFun.kt")
public void testLambdaInInlineClassFun() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
@@ -10128,6 +10128,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
}
@TestMetadata("kt30780.kt")
public void testKt30780() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt30780.kt");
}
@TestMetadata("lambdaInInlineClassFun.kt")
public void testLambdaInInlineClassFun() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
@@ -11298,6 +11298,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
}
@TestMetadata("kt30780.kt")
public void testKt30780() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt30780.kt");
}
@TestMetadata("lambdaInInlineClassFun.kt")
public void testLambdaInInlineClassFun() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");