diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt index bed41c3165b..21053197d8f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt @@ -119,8 +119,7 @@ object ModifierCheckerCore { EXPECT_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects), ACTUAL_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects), LATEINIT_KEYWORD to listOf(LanguageFeature.LateinitTopLevelProperties, LanguageFeature.LateinitLocalVariables), - FUN_KEYWORD to listOf(LanguageFeature.FunctionalInterfaceConversion), - VALUE_KEYWORD to listOf(LanguageFeature.InlineClasses) + FUN_KEYWORD to listOf(LanguageFeature.FunctionalInterfaceConversion) ) private val featureDependenciesTargets = mapOf( @@ -128,6 +127,7 @@ object ModifierCheckerCore { LanguageFeature.LateinitLocalVariables to setOf(LOCAL_VARIABLE), LanguageFeature.LateinitTopLevelProperties to setOf(TOP_LEVEL_PROPERTY), LanguageFeature.InlineClasses to setOf(CLASS_ONLY), + LanguageFeature.JvmInlineValueClasses to setOf(CLASS_ONLY), LanguageFeature.FunctionalInterfaceConversion to setOf(INTERFACE) ) 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 b122fefe91b..e16ee31e38e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.checkers import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.KtTokens @@ -32,11 +33,28 @@ object InlineClassDeclarationChecker : DeclarationChecker { if (descriptor !is ClassDescriptor || !descriptor.isInline && !descriptor.isValue) return if (descriptor.kind != ClassKind.CLASS) return - val inlineOrValueKeyword = declaration.modifierList?.getModifier(KtTokens.INLINE_KEYWORD) - ?: declaration.modifierList?.getModifier(KtTokens.VALUE_KEYWORD) + val trace = context.trace + + val valueKeyword = declaration.modifierList?.getModifier(KtTokens.VALUE_KEYWORD) + + // The check cannot be done in ModifierCheckerCore, since `value` keyword is enabled by one of two features, not by both of + // them simultaneously + if (valueKeyword != null) { + if (!context.languageVersionSettings.supportsFeature(LanguageFeature.JvmInlineValueClasses) && + !context.languageVersionSettings.supportsFeature(LanguageFeature.InlineClasses) + ) { + trace.report( + Errors.UNSUPPORTED_FEATURE.on( + valueKeyword, LanguageFeature.JvmInlineValueClasses to context.languageVersionSettings + ) + ) + return + } + } + + val inlineOrValueKeyword = declaration.modifierList?.getModifier(KtTokens.INLINE_KEYWORD) ?: valueKeyword require(inlineOrValueKeyword != null) { "Declaration of inline class must have 'inline' keyword" } - val trace = context.trace if (descriptor.isInner || DescriptorUtils.isLocal(descriptor)) { trace.report(Errors.INLINE_CLASS_NOT_TOP_LEVEL.on(inlineOrValueKeyword)) return diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt index 04eb74373a2..44105ea956b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt @@ -21,7 +21,8 @@ class ResultClassInReturnTypeChecker : DeclarationChecker { val languageVersionSettings = context.languageVersionSettings if ( languageVersionSettings.getFlag(AnalysisFlags.allowResultReturnType) || - languageVersionSettings.getFeatureSupport(LanguageFeature.InlineClasses) == LanguageFeature.State.ENABLED && + (languageVersionSettings.getFeatureSupport(LanguageFeature.InlineClasses) == LanguageFeature.State.ENABLED || + languageVersionSettings.supportsFeature(LanguageFeature.JvmInlineValueClasses)) && languageVersionSettings.supportsFeature(LanguageFeature.AllowResultInReturnType) ) return diff --git a/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.kt b/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.kt index 32b3ed08bd6..fc43d08330e 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.kt @@ -13,4 +13,4 @@ annotation class JvmInline value enum class InlineEnum @JvmInline -value class NotVal(x: Int) +value class NotVal(x: Int) diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.kt b/compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.kt new file mode 100644 index 00000000000..b2f80249614 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.kt @@ -0,0 +1,9 @@ +// !LANGUAGE: +JvmInlineValueClasses +// WITH_RUNTIME + +package kotlin.jvm + +annotation class JvmInline + +@JvmInline +value class VC(val a: Any) \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.txt b/compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.txt new file mode 100644 index 00000000000..6d7af7593f8 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.txt @@ -0,0 +1,23 @@ +package + +package kotlin { + + package kotlin.jvm { + + public final annotation class JvmInline : kotlin.Annotation { + public constructor JvmInline() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + @kotlin.jvm.JvmInline public final value class VC { + public constructor VC(/*0*/ a: kotlin.Any) + public final val a: kotlin.Any + 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 + } + } +} + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJvmIrBackendGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJvmIrBackendGenerated.java index 34721d6790f..d34cae2329b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJvmIrBackendGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithJvmIrBackendGenerated.java @@ -43,6 +43,12 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic runTest("compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.kt"); } + @Test + @TestMetadata("noWarningInLV1_5.kt") + public void testNoWarningInLV1_5() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.kt"); + } + @Test @TestMetadata("suspendInlineCycle_ir.kt") public void testSuspendInlineCycle_ir() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithOldJvmBackendGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithOldJvmBackendGenerated.java index 88ab881fcb9..74c5731f993 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithOldJvmBackendGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticsTestWithOldJvmBackendGenerated.java @@ -43,6 +43,12 @@ public class DiagnosticsTestWithOldJvmBackendGenerated extends AbstractDiagnosti runTest("compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.kt"); } + @Test + @TestMetadata("noWarningInLV1_5.kt") + public void testNoWarningInLV1_5() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.kt"); + } + @Test @TestMetadata("suspendInlineCycle.kt") public void testSuspendInlineCycle() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index c58faa1f7aa..f18abdfe537 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -194,6 +194,7 @@ enum class LanguageFeature( // Next features can be enabled regardless of new inference InlineClasses(sinceVersion = KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE), + JvmInlineValueClasses(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), ; val presentableName: String