diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index ee445859742..48b52692805 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -12957,6 +12957,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inlineClasses/unsignedLiteralsWithoutArtifactOnClasspath.kt"); } + @TestMetadata("varPropertyWithInlineClassReceiver.kt") + public void testVarPropertyWithInlineClassReceiver() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.kt"); + } + @TestMetadata("varargsOnParametersOfInlineClassType.kt") public void testVarargsOnParametersOfInlineClassType() throws Exception { runTest("compiler/testData/diagnostics/tests/inlineClasses/varargsOnParametersOfInlineClassType.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index af6d60a3286..23bb2e07731 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -347,7 +347,7 @@ public interface Errors { DiagnosticFactory0 NON_PRIVATE_CONSTRUCTOR_IN_ENUM = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 NON_PRIVATE_CONSTRUCTOR_IN_SEALED = DiagnosticFactory0.create(ERROR); - // Inline classes + // Inline and value classes DiagnosticFactory0 INLINE_CLASS_NOT_TOP_LEVEL = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INLINE_CLASS_NOT_FINAL = DiagnosticFactory0.create(ERROR); @@ -355,6 +355,7 @@ public interface Errors { DiagnosticFactory0 INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory0 RESERVED_VAR_PROPERTY_OF_VALUE_CLASS = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 DELEGATED_PROPERTY_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR); DiagnosticFactory1 INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION = DiagnosticFactory0.create(ERROR); 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 135f8d5ebd7..997874e2a62 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -710,6 +710,7 @@ public class DefaultErrorMessages { MAP.put(INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, "Inline class must have exactly one primary constructor parameter"); MAP.put(INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER, "Value class primary constructor must have only final read-only (val) property parameter"); MAP.put(PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS, "Inline class cannot have properties with backing fields"); + MAP.put(RESERVED_VAR_PROPERTY_OF_VALUE_CLASS, "'var' properties with value class receivers are reserved for future use"); MAP.put(DELEGATED_PROPERTY_INSIDE_INLINE_CLASS, "Inline class cannot have delegated properties"); MAP.put(INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE, "Inline class cannot have value parameter of type ''{0}''", RENDER_TYPE); MAP.put(INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION, "Inline class cannot implement an interface by delegation"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt index 10c744d58d3..25ff6d7309b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt @@ -27,8 +27,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf( KClassWithIncorrectTypeArgumentChecker, SuspendLimitationsChecker, InlineClassDeclarationChecker, - PropertiesWithBackingFieldsInsideInlineClass(), InnerClassInsideInlineClass(), + PropertiesWithInlineClassAsReceiver(), AnnotationClassTargetAndRetentionChecker(), ReservedMembersAndConstructsForInlineClass(), ResultClassInReturnTypeChecker(), 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 97bc3378858..e17df9f33b1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/InlineClassDeclarationChecker.kt @@ -107,19 +107,27 @@ object InlineClassDeclarationChecker : DeclarationChecker { } } -class PropertiesWithBackingFieldsInsideInlineClass : DeclarationChecker { +class PropertiesWithInlineClassAsReceiver : DeclarationChecker { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { if (declaration !is KtProperty) return if (descriptor !is PropertyDescriptor) return - if (!descriptor.containingDeclaration.isInlineClass()) return + if (descriptor.containingDeclaration.isInlineClass()) { + if (context.trace.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor) == true) { + context.trace.report(Errors.PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS.on(declaration)) + } - if (context.trace.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor) == true) { - context.trace.report(Errors.PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS.on(declaration)) + declaration.delegate?.let { + context.trace.report(Errors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS.on(it)) + } } - declaration.delegate?.let { - context.trace.report(Errors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS.on(it)) + if (!descriptor.isVar) return + + if (descriptor.containingDeclaration.isInlineClass() || + descriptor.extensionReceiverParameter?.type?.isInlineClassType() == true + ) { + context.trace.report(Errors.RESERVED_VAR_PROPERTY_OF_VALUE_CLASS.on(declaration.valOrVarKeyword)) } } } diff --git a/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.kt b/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.kt index 8a64831f52d..02356440d3f 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.kt @@ -21,8 +21,8 @@ object VarObject { inline class Z(val data: Int) { val testVal by Val() - var testVar by Var() + var testVar by Var() val testValBySingleton by ValObject - var testVarBySingleton by VarObject + var testVarBySingleton by VarObject } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.kt b/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.kt index f5774f75596..5fba5d676df 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.kt @@ -15,11 +15,11 @@ inline class Foo(val x: Int) : A, B { val a1 = 0 - var a2: Int + var a2: Int get() = 1 set(value) {} - var a3: Int = 0 + var a3: Int = 0 get() = 1 set(value) { field = value @@ -30,5 +30,5 @@ inline class Foo(val x: Int) : A, B { override val badSize: Int = 0 - lateinit var lateinitProperty: String + lateinit var lateinitProperty: String } diff --git a/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.fir.kt new file mode 100644 index 00000000000..7c4ae085dee --- /dev/null +++ b/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.fir.kt @@ -0,0 +1,12 @@ +// !LANGUAGE: +InlineClasses +// !DIAGNOSTICS: -UNUSED_PARAMETER + +inline class IC(val a: Any) { + var member: Any + get() = a + set(value) {} +} + +var IC.extension: Any + get() = a + set(value) {} diff --git a/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.kt b/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.kt new file mode 100644 index 00000000000..e005b0cbf2a --- /dev/null +++ b/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.kt @@ -0,0 +1,12 @@ +// !LANGUAGE: +InlineClasses +// !DIAGNOSTICS: -UNUSED_PARAMETER + +inline class IC(val a: Any) { + var member: Any + get() = a + set(value) {} +} + +var IC.extension: Any + get() = a + set(value) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.txt b/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.txt new file mode 100644 index 00000000000..65ffcfbb852 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.txt @@ -0,0 +1,12 @@ +package + +public var IC.extension: kotlin.Any + +public final inline class IC { + public constructor IC(/*0*/ a: kotlin.Any) + public final val a: kotlin.Any + public final var member: 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/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.kt b/compiler/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.kt index f000be7da44..1cd281daed8 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.kt @@ -26,8 +26,8 @@ object VarObject { @JvmInline value class Z(val data: Int) { val testVal by Val() - var testVar by Var() + var testVar by Var() val testValBySingleton by ValObject - var testVarBySingleton by VarObject + var testVarBySingleton by VarObject } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.kt b/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.kt index 8267ab02d03..c3d2df146d4 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.kt @@ -20,11 +20,11 @@ value class Foo(val x: Int) : A, B { val a1 = 0 - var a2: Int + var a2: Int get() = 1 set(value) {} - var a3: Int = 0 + var a3: Int = 0 get() = 1 set(value) { field = value @@ -35,5 +35,5 @@ value class Foo(val x: Int) : A, B { override val badSize: Int = 0 - lateinit var lateinitProperty: String + lateinit var lateinitProperty: String } diff --git a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index da47f330b4a..0b9c4617760 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -12964,6 +12964,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/inlineClasses/unsignedLiteralsWithoutArtifactOnClasspath.kt"); } + @TestMetadata("varPropertyWithInlineClassReceiver.kt") + public void testVarPropertyWithInlineClassReceiver() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.kt"); + } + @TestMetadata("varargsOnParametersOfInlineClassType.kt") public void testVarargsOnParametersOfInlineClassType() throws Exception { runTest("compiler/testData/diagnostics/tests/inlineClasses/varargsOnParametersOfInlineClassType.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 6d1619ed9ba..8f13c7f2b56 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -12959,6 +12959,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inlineClasses/unsignedLiteralsWithoutArtifactOnClasspath.kt"); } + @TestMetadata("varPropertyWithInlineClassReceiver.kt") + public void testVarPropertyWithInlineClassReceiver() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/varPropertyWithInlineClassReceiver.kt"); + } + @TestMetadata("varargsOnParametersOfInlineClassType.kt") public void testVarargsOnParametersOfInlineClassType() throws Exception { runTest("compiler/testData/diagnostics/tests/inlineClasses/varargsOnParametersOfInlineClassType.kt");