diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 5bdc9fa4d6e..bc33d456e0f 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -33418,6 +33418,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingTypeMultiField.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithUniversal()); } + @Test + @TestMetadata("valueClassWithGenericUnderlyingTypeNoFeature.kt") + public void testValueClassWithGenericUnderlyingTypeNoFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithGenericUnderlyingTypeNoFeature.kt"); + } + @Test @TestMetadata("valueClassesInsideAnnotations.kt") public void testValueClassesInsideAnnotations() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 99f3c860255..6d915e1c30f 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -33418,6 +33418,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingTypeMultiField.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithUniversal()); } + @Test + @TestMetadata("valueClassWithGenericUnderlyingTypeNoFeature.kt") + public void testValueClassWithGenericUnderlyingTypeNoFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithGenericUnderlyingTypeNoFeature.kt"); + } + @Test @TestMetadata("valueClassesInsideAnnotations.kt") public void testValueClassesInsideAnnotations() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 290b280e1af..37eb99e774c 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -33418,6 +33418,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingTypeMultiField.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithUniversal()); } + @Test + @TestMetadata("valueClassWithGenericUnderlyingTypeNoFeature.kt") + public void testValueClassWithGenericUnderlyingTypeNoFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithGenericUnderlyingTypeNoFeature.kt"); + } + @Test @TestMetadata("valueClassesInsideAnnotations.kt") public void testValueClassesInsideAnnotations() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt index 9d369d88778..2d4f8884822 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt @@ -164,20 +164,25 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() { context ) + !context.languageVersionSettings.supportsFeature(LanguageFeature.GenericInlineClassParameter) && + primaryConstructorParameter.returnTypeRef.coneType.let { + it is ConeTypeParameterType || it.isGenericArrayOfTypeParameter() + } -> { + reporter.reportOn( + primaryConstructorParameter.returnTypeRef.source, + FirErrors.UNSUPPORTED_FEATURE, + LanguageFeature.GenericInlineClassParameter to context.languageVersionSettings, + context + ) + } + primaryConstructorParameter.returnTypeRef.isInapplicableParameterType() -> { - val inlineClassHasGenericUnderlyingType = primaryConstructorParameter.returnTypeRef.coneType.let { - (it is ConeTypeParameterType || it.isGenericArrayOfTypeParameter()) - } - if (!(context.languageVersionSettings.supportsFeature(LanguageFeature.GenericInlineClassParameter) && - inlineClassHasGenericUnderlyingType) - ) { - reporter.reportOn( - primaryConstructorParameter.returnTypeRef.source, - FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE, - primaryConstructorParameter.returnTypeRef.coneType, - context - ) - } + reporter.reportOn( + primaryConstructorParameter.returnTypeRef.source, + FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE, + primaryConstructorParameter.returnTypeRef.coneType, + context + ) } primaryConstructorParameter.returnTypeRef.coneType.isRecursiveInlineClassType(context.session) -> { @@ -202,7 +207,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() { } private fun FirTypeRef.isInapplicableParameterType() = - isUnit || isNothing || coneType is ConeTypeParameterType || coneType.isGenericArrayOfTypeParameter() + isUnit || isNothing private fun ConeKotlinType.isGenericArrayOfTypeParameter(): Boolean { if (this.typeArguments.firstOrNull() is ConeStarProjection || !isPotentiallyArray()) 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 276f6063952..4a4cd28a1bd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt @@ -103,10 +103,20 @@ object InlineClassDeclarationChecker : DeclarationChecker { val baseParameterTypeReference = baseParameter.typeReference if (baseParameterType != null && baseParameterTypeReference != null) { - if (baseParameterType.isInapplicableParameterType() && - !(context.languageVersionSettings.supportsFeature(LanguageFeature.GenericInlineClassParameter) && - (baseParameterType.isTypeParameter() || baseParameterType.isGenericArrayOfTypeParameter())) + if (!context.languageVersionSettings.supportsFeature(LanguageFeature.GenericInlineClassParameter) && + (baseParameterType.isTypeParameter() || baseParameterType.isGenericArrayOfTypeParameter()) ) { + trace.report( + Errors.UNSUPPORTED_FEATURE.on( + baseParameterTypeReference, + LanguageFeature.GenericInlineClassParameter to context.languageVersionSettings + ) + ) + baseParametersOk = false + continue + } + + if (baseParameterType.isInapplicableParameterType()) { trace.report(Errors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE.on(baseParameterTypeReference, baseParameterType)) baseParametersOk = false continue @@ -154,7 +164,7 @@ object InlineClassDeclarationChecker : DeclarationChecker { } private fun KotlinType.isInapplicableParameterType() = - isUnit() || isNothing() || isTypeParameter() || isGenericArrayOfTypeParameter() + isUnit() || isNothing() private fun KotlinType.isGenericArrayOfTypeParameter(): Boolean { if (!KotlinBuiltIns.isArray(this)) return false diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt index e3027f45bbf..81d39c028dc 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt @@ -1,5 +1,6 @@ // FIR_IDENTICAL // !SKIP_JAVAC +// SKIP_TXT // !LANGUAGE: +InlineClasses package kotlin.jvm diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.txt b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.txt deleted file mode 100644 index 4b61d6575f6..00000000000 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.txt +++ /dev/null @@ -1,94 +0,0 @@ -package - -package kotlin { - - package kotlin.jvm { - - @kotlin.jvm.JvmInline public final value class Bar { - public constructor Bar(/*0*/ u: kotlin.Unit) - public final val u: kotlin.Unit - 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 - } - - @kotlin.jvm.JvmInline public final value class BarNullable { - public constructor BarNullable(/*0*/ u: kotlin.Unit?) - public final val u: kotlin.Unit? - 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 - } - - @kotlin.jvm.JvmInline public final value class Baz { - public constructor Baz(/*0*/ u: kotlin.Nothing) - public final val u: kotlin.Nothing - 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 - } - - @kotlin.jvm.JvmInline public final value class BazNullable { - public constructor BazNullable(/*0*/ u: kotlin.Nothing?) - public final val u: kotlin.Nothing? - 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 - } - - @kotlin.jvm.JvmInline public final value class Foo { - public constructor Foo(/*0*/ x: T) - public final val x: T - 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 - } - - @kotlin.jvm.JvmInline public final value class FooGenericArray { - public constructor FooGenericArray(/*0*/ x: kotlin.Array) - public final val x: kotlin.Array - 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 - } - - @kotlin.jvm.JvmInline public final value class FooGenericArray2 { - public constructor FooGenericArray2(/*0*/ x: kotlin.Array>) - public final val x: kotlin.Array> - 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 - } - - @kotlin.jvm.JvmInline public final value class FooNullable { - public constructor FooNullable(/*0*/ x: T?) - public final val x: T? - 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 - } - - @kotlin.jvm.JvmInline public final value class FooStarProjectedArray { - public constructor FooStarProjectedArray(/*0*/ x: kotlin.Array<*>) - public final val x: kotlin.Array<*> - 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 - } - - @kotlin.jvm.JvmInline public final value class FooStarProjectedArray2 { - public constructor FooStarProjectedArray2(/*0*/ x: kotlin.Array>) - public final val x: kotlin.Array> - 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 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 - } - } -} diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithGenericUnderlyingTypeNoFeature.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithGenericUnderlyingTypeNoFeature.kt new file mode 100644 index 00000000000..a4e70b94829 --- /dev/null +++ b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithGenericUnderlyingTypeNoFeature.kt @@ -0,0 +1,20 @@ +// FIR_IDENTICAL +// !SKIP_JAVAC +// SKIP_TXT +// !LANGUAGE: +InlineClasses, -GenericInlineClassParameter + +package kotlin.jvm + +annotation class JvmInline + +@JvmInline +value class Foo(val x: T) +@JvmInline +value class FooNullable(val x: T?) + +@JvmInline +value class FooGenericArray(val x: Array) +@JvmInline +value class FooGenericArray2(val x: Array>) + + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 9dc8d5042f6..8e602951456 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -33508,6 +33508,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingTypeMultiField.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithUniversal()); } + @Test + @TestMetadata("valueClassWithGenericUnderlyingTypeNoFeature.kt") + public void testValueClassWithGenericUnderlyingTypeNoFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithGenericUnderlyingTypeNoFeature.kt"); + } + @Test @TestMetadata("valueClassesInsideAnnotations.kt") public void testValueClassesInsideAnnotations() throws Exception {