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:
@@ -30,6 +30,14 @@ public class ClassContext extends FieldOwnerContext<ClassDescriptor> {
|
|||||||
super(contextDescriptor, contextKind, parentContext, typeMapper.getBindingContext().get(CLOSURE, contextDescriptor),
|
super(contextDescriptor, contextKind, parentContext, typeMapper.getBindingContext().get(CLOSURE, contextDescriptor),
|
||||||
contextDescriptor, localLookup);
|
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;
|
this.typeMapper = typeMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -393,13 +393,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
public CodegenContext findParentContextWithDescriptor(DeclarationDescriptor descriptor) {
|
public CodegenContext findParentContextWithDescriptor(DeclarationDescriptor descriptor) {
|
||||||
CodegenContext c = this;
|
CodegenContext c = this;
|
||||||
while (c != null) {
|
while (c != null) {
|
||||||
if (!c.shouldSkipThisContextInHierarchy() && c.getContextDescriptor() == descriptor) break;
|
if (!c.isShadowedByParentContext() && c.getContextDescriptor() == descriptor) break;
|
||||||
c = c.getParentContext();
|
c = c.getParentContext();
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldSkipThisContextInHierarchy() {
|
private boolean isShadowedByParentContext() {
|
||||||
return getContextKind() == OwnerKind.ERASED_INLINE_CLASS;
|
return getContextKind() == OwnerKind.ERASED_INLINE_CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-10
@@ -429,7 +429,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
}
|
}
|
||||||
|
|
||||||
val container = descriptor.containingDeclaration ?: error("No container for descriptor: $descriptor")
|
val container = descriptor.containingDeclaration ?: error("No container for descriptor: $descriptor")
|
||||||
val parent = getContext(
|
val containerContext = getContext(
|
||||||
container,
|
container,
|
||||||
descriptor,
|
descriptor,
|
||||||
state,
|
state,
|
||||||
@@ -440,7 +440,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
return when (descriptor) {
|
return when (descriptor) {
|
||||||
is ScriptDescriptor -> {
|
is ScriptDescriptor -> {
|
||||||
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
|
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
|
||||||
parent.intoScript(
|
containerContext.intoScript(
|
||||||
descriptor,
|
descriptor,
|
||||||
earlierScripts ?: emptyList(),
|
earlierScripts ?: emptyList(),
|
||||||
descriptor as ClassDescriptor, state.typeMapper
|
descriptor as ClassDescriptor, state.typeMapper
|
||||||
@@ -449,21 +449,27 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
is ClassDescriptor -> {
|
is ClassDescriptor -> {
|
||||||
val kind =
|
val kind =
|
||||||
when {
|
when {
|
||||||
DescriptorUtils.isInterface(descriptor) && innerDescriptor !is ClassDescriptor &&
|
DescriptorUtils.isInterface(descriptor) &&
|
||||||
!innerDescriptor.isCallableMemberWithJvmDefaultAnnotation() -> OwnerKind.DEFAULT_IMPLS
|
innerDescriptor !is ClassDescriptor &&
|
||||||
|
!innerDescriptor.isCallableMemberWithJvmDefaultAnnotation() ->
|
||||||
descriptor.isInlineClass() -> OwnerKind.ERASED_INLINE_CLASS
|
OwnerKind.DEFAULT_IMPLS
|
||||||
|
else ->
|
||||||
else -> OwnerKind.IMPLEMENTATION
|
OwnerKind.IMPLEMENTATION
|
||||||
}
|
}
|
||||||
|
|
||||||
additionalInners.addIfNotNull(
|
additionalInners.addIfNotNull(
|
||||||
InnerClassConsumer.classForInnerClassRecord(descriptor, kind == OwnerKind.DEFAULT_IMPLS)
|
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 -> {
|
is FunctionDescriptor -> {
|
||||||
parent.intoFunction(descriptor)
|
containerContext.intoFunction(descriptor)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalStateException("Couldn't build context for $descriptor")
|
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()
|
||||||
+5
@@ -12693,6 +12693,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
|
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")
|
@TestMetadata("lambdaInInlineClassFun.kt")
|
||||||
public void testLambdaInInlineClassFun() throws Exception {
|
public void testLambdaInInlineClassFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
||||||
|
|||||||
+5
@@ -12693,6 +12693,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
|
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")
|
@TestMetadata("lambdaInInlineClassFun.kt")
|
||||||
public void testLambdaInInlineClassFun() throws Exception {
|
public void testLambdaInInlineClassFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
||||||
|
|||||||
+5
@@ -12698,6 +12698,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
|
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")
|
@TestMetadata("lambdaInInlineClassFun.kt")
|
||||||
public void testLambdaInInlineClassFun() throws Exception {
|
public void testLambdaInInlineClassFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
||||||
|
|||||||
Generated
+5
@@ -10128,6 +10128,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
|
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")
|
@TestMetadata("lambdaInInlineClassFun.kt")
|
||||||
public void testLambdaInInlineClassFun() throws Exception {
|
public void testLambdaInInlineClassFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
||||||
|
|||||||
+5
@@ -11298,6 +11298,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/kt27513.kt");
|
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")
|
@TestMetadata("lambdaInInlineClassFun.kt")
|
||||||
public void testLambdaInInlineClassFun() throws Exception {
|
public void testLambdaInInlineClassFun() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/lambdaInInlineClassFun.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user