diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 48e13480e7a..e887825e0c9 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -14157,6 +14157,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 42bf6d53016..1d7d12906bc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -704,7 +704,7 @@ public class DefaultErrorMessages { MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_ENUM, "Constructor must be private in enum class"); MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_SEALED, "Constructor must be private in sealed class"); - MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes are only allowed on top level"); + MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes cannot be local or inner"); MAP.put(INLINE_CLASS_NOT_FINAL, "Inline classes can be only final"); MAP.put(ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS, "Primary constructor is required for inline class"); MAP.put(INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, "Inline class must have exactly one primary constructor parameter"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt index 64f026ace36..66616901983 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt @@ -29,7 +29,7 @@ object InlineClassDeclarationChecker : DeclarationChecker { require(inlineOrValueKeyword != null) { "Declaration of inline class must have 'inline' keyword" } val trace = context.trace - if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) { + if (descriptor.isInner || DescriptorUtils.isLocal(descriptor)) { trace.report(Errors.INLINE_CLASS_NOT_TOP_LEVEL.on(inlineOrValueKeyword)) return } diff --git a/compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt b/compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt new file mode 100644 index 00000000000..e3e8528ae0c --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt @@ -0,0 +1,25 @@ +// !LANGUAGE: +InlineClasses + +class C { + inline class IC1(val s: String) + + companion object { + inline class IC2(val s: String) + } +} + +object O { + inline class IC3(val s: String) +} + +interface I { + inline class IC4(val s: String) +} + +fun box(): String { + if (C.IC1("OK").s != "OK") return "FAIL 1" + if (C.Companion.IC2("OK").s != "OK") return "FAIL 2" + if (O.IC3("OK").s != "OK") return "FAIL 3" + if (I.IC4("OK").s != "OK") return "FAIL 4" + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt index a16404c9a45..5911eaa8f3e 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt @@ -16,13 +16,20 @@ inline class A9(final val x: Int) class B1 { companion object { inline class C1(val x: Int) + inner inline class C11(val x: Int) } inline class C2(val x: Int) + inner inline class C21(val x: Int) } object B2 { inline class C3(val x: Int) + inner inline class C31(val x: Int) +} + +fun foo() { + inline class C4(val x: Int) } final inline class D0(val x: Int) diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.kt index 492c52e6a14..cd55c8f55f5 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.kt @@ -15,14 +15,21 @@ inline class A9(final val x: Int) class B1 { companion object { - inline class C1(val x: Int) + inline class C1(val x: Int) + inner inline class C11(val x: Int) } - inline class C2(val x: Int) + inline class C2(val x: Int) + inner inline class C21(val x: Int) } object B2 { - inline class C3(val x: Int) + inline class C3(val x: Int) + inner inline class C31(val x: Int) +} + +fun foo() { + inline class C4(val x: Int) } final inline class D0(val x: Int) diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.txt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.txt index 1ff6b483611..0933b86cc72 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.txt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.txt @@ -1,5 +1,7 @@ package +public fun foo(): kotlin.Unit + public final inline class A0 { public constructor A0(/*0*/ x: kotlin.Int) public final val x: kotlin.Int @@ -92,6 +94,14 @@ public final class B1 { public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String } + public final inner inline class C21 { + public constructor C21(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String + } + public companion object Companion { private constructor Companion() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -105,6 +115,14 @@ public final class B1 { public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String } + + public final inline class C11 { + public constructor C11(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String + } } } @@ -121,6 +139,14 @@ public object B2 { public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String } + + public final inline class C31 { + public constructor C31(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String + } } public final inline class D0 { diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.kt index a55cfb64cb4..8deb953d413 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.kt @@ -30,16 +30,16 @@ value class A9(final val x: Int) class B1 { companion object { @JvmInline - value class C1(val x: Int) + value class C1(val x: Int) } @JvmInline - value class C2(val x: Int) + value class C2(val x: Int) } object B2 { @JvmInline - value class C3(val x: Int) + value class C3(val x: Int) } @JvmInline diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index d311c012888..a2faa93e722 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -15557,6 +15557,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index dbfd03b0ea2..467716f9c04 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15567,6 +15567,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/mappingOfBoxedFlexibleInlineClassType.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 08eaf8c8cfd..e1c4edc5dd4 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -14157,6 +14157,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index f7c791c06be..ea6edae111a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -12152,6 +12152,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index ee3c62390c2..eb22ec13451 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -12152,6 +12152,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 4a23106375d..c5181fd0c2c 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -12217,6 +12217,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index edfa36732fd..7bf5699dec3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -6627,6 +6627,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/inlineClasses/mangledSuperCalls.kt"); } + @TestMetadata("nestedInlineClass.kt") + public void testNestedInlineClass() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt"); + } + @TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt") public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");