diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 6be454af10e..d6cf5807e18 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1179,6 +1179,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val OVERRIDE_BY_INLINE by warning(PositioningStrategy.DECLARATION_SIGNATURE) val REIFIED_TYPE_PARAMETER_IN_OVERRIDE by error(PositioningStrategy.REIFIED_MODIFIER) + + val INLINE_PROPERTY_WITH_BACKING_FIELD by error(PositioningStrategy.DECLARATION_SIGNATURE) } val IMPORTS by object : DiagnosticGroup("Imports") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index aa77ca6ed7a..5aa47710461 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -611,6 +611,7 @@ object FirErrors { val DECLARATION_CANT_BE_INLINED by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val OVERRIDE_BY_INLINE by warning0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val REIFIED_TYPE_PARAMETER_IN_OVERRIDE by error0(SourceElementPositioningStrategies.REIFIED_MODIFIER) + val INLINE_PROPERTY_WITH_BACKING_FIELD by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) // Imports val CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON by error1(SourceElementPositioningStrategies.IMPORT_LAST_NAME) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlinePropertyChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlinePropertyChecker.kt index 95e729d67f2..aadaf365872 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlinePropertyChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlinePropertyChecker.kt @@ -7,14 +7,21 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField import org.jetbrains.kotlin.fir.declarations.utils.isInline object FirInlinePropertyChecker : FirPropertyChecker() { override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { - if (declaration.getter?.isInline == true || declaration.setter?.isInline == true) { - FirInlineDeclarationChecker.checkCallableDeclaration(declaration, context, reporter) + if (declaration.getter?.isInline != true && declaration.setter?.isInline != true) return + + FirInlineDeclarationChecker.checkCallableDeclaration(declaration, context, reporter) + + if (declaration.hasBackingField || declaration.delegate != null) { + reporter.reportOn(declaration.source, FirErrors.INLINE_PROPERTY_WITH_BACKING_FIELD, context) } } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 214b22e6964..b6ebc3473a4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -225,6 +225,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CONS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_NOT_FINAL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_NOT_TOP_LEVEL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_PROPERTY_WITH_BACKING_FIELD import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_INSIDE_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL @@ -934,6 +935,7 @@ class FirDefaultErrorMessages { map.put(DECLARATION_CANT_BE_INLINED, "'inline' modifier is not allowed on virtual members. Only private or final members can be inlined") map.put(OVERRIDE_BY_INLINE, "Override by an inline function") map.put(REIFIED_TYPE_PARAMETER_IN_OVERRIDE, "Override by a function with reified type parameter") + map.put(INLINE_PROPERTY_WITH_BACKING_FIELD, "Inline property cannot have backing field") map.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", TO_STRING) map.put( SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS, diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index bfdee4fd0d2..e2605aed46b 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -416,7 +416,9 @@ fun FirPropertyBuilder.generateAccessorsByDelegate( origin = FirDeclarationOrigin.Source returnTypeRef = buildImplicitTypeRef() isGetter = true - status = FirDeclarationStatusImpl(Visibilities.Unknown, Modality.FINAL) + status = FirDeclarationStatusImpl(Visibilities.Unknown, Modality.FINAL).apply { + isInline = this@generateAccessorsByDelegate.getter?.status?.isInline ?: isInline + } symbol = FirPropertyAccessorSymbol() body = FirSingleExpressionBlock( @@ -449,7 +451,9 @@ fun FirPropertyBuilder.generateAccessorsByDelegate( origin = FirDeclarationOrigin.Source returnTypeRef = moduleData.session.builtinTypes.unitType isGetter = false - status = FirDeclarationStatusImpl(Visibilities.Unknown, Modality.FINAL) + status = FirDeclarationStatusImpl(Visibilities.Unknown, Modality.FINAL).apply { + isInline = this@generateAccessorsByDelegate.setter?.status?.isInline ?: isInline + } val parameter = buildValueParameter { source = fakeSource this.moduleData = moduleData diff --git a/compiler/testData/diagnostics/tests/inline/property/propertyWithBackingField.fir.kt b/compiler/testData/diagnostics/tests/inline/property/propertyWithBackingField.fir.kt deleted file mode 100644 index 39a890ae51d..00000000000 --- a/compiler/testData/diagnostics/tests/inline/property/propertyWithBackingField.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -// WITH_REFLECT -// WITH_RUNTIME - -import kotlin.reflect.KProperty - -class Delegate { - operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 -} - -open class A { - inline val z1 = 1 - - val z1_1 = 1 - inline get() = field + 1 - - inline var z2 = 1 - - var z2_1 = 1 - inline set(p: Int) {} - - inline val z by Delegate() -} diff --git a/compiler/testData/diagnostics/tests/inline/property/propertyWithBackingField.kt b/compiler/testData/diagnostics/tests/inline/property/propertyWithBackingField.kt index bf9fee39bb3..8062056e1e5 100644 --- a/compiler/testData/diagnostics/tests/inline/property/propertyWithBackingField.kt +++ b/compiler/testData/diagnostics/tests/inline/property/propertyWithBackingField.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // WITH_REFLECT // WITH_RUNTIME diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index a8a810c1846..3f516d61bdf 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -3185,6 +3185,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.INLINE_PROPERTY_WITH_BACKING_FIELD) { firDiagnostic -> + InlinePropertyWithBackingFieldImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON) { firDiagnostic -> CannotAllUnderImportFromSingletonImpl( firDiagnostic.a, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index d416ef7e69b..2cc3f64deed 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2222,6 +2222,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = ReifiedTypeParameterInOverride::class } + abstract class InlinePropertyWithBackingField : KtFirDiagnostic() { + override val diagnosticClass get() = InlinePropertyWithBackingField::class + } + abstract class CannotAllUnderImportFromSingleton : KtFirDiagnostic() { override val diagnosticClass get() = CannotAllUnderImportFromSingleton::class abstract val objectName: Name diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 16b7488cbc3..adf08360b88 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -3588,6 +3588,13 @@ internal class ReifiedTypeParameterInOverrideImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class InlinePropertyWithBackingFieldImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.InlinePropertyWithBackingField(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class CannotAllUnderImportFromSingletonImpl( override val objectName: Name, firDiagnostic: FirPsiDiagnostic,