diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index b52886bb26c..d509e0db14a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -115,7 +115,10 @@ class Fir2IrConverter( } } - if (components.session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) { + if ( + !configuration.useIrFakeOverrideBuilder && + components.session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) + ) { // See the comment to generateUnboundFakeOverrides function itself @OptIn(LeakedDeclarationCaches::class) declarationStorage.generateUnboundFakeOverrides() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 6400078eb7c..2e354b8070a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -649,7 +649,7 @@ class CallAndReferenceGenerator( } val symbol = calleeReference.toSymbolForCall( - variableAssignment.dispatchReceiver, + extractDispatchReceiverOfAssignment(variableAssignment), explicitReceiver = variableAssignment.explicitReceiver, preferGetter = false, ) @@ -683,15 +683,9 @@ class CallAndReferenceGenerator( is IrPropertySymbol -> { val setterSymbol = declarationStorage.findSetterOfProperty(symbol) - var backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol) + val backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol) val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir - // If we found neither a setter nor a backing field, check if we have an override (possibly fake) of a val with - // backing field. This can happen in a class initializer where `this` was smart-casted. See KT-57105. - if (setterSymbol == null && backingFieldSymbol == null) { - backingFieldSymbol = symbol.overriddenBackingFieldOrNull() - } - when { setterSymbol != null -> IrCallImpl( startOffset, endOffset, type, setterSymbol, @@ -744,11 +738,23 @@ class CallAndReferenceGenerator( } } - @OptIn(UnsafeDuringIrConstructionAPI::class) - private fun IrPropertySymbol.overriddenBackingFieldOrNull(): IrFieldSymbol? { - return owner.overriddenSymbols.firstNotNullOfOrNull { - val owner = it.owner - owner.backingField?.symbol ?: it.overriddenBackingFieldOrNull() + + /** + * If we have assignment like `this.x = ...` and this `this` is a dispatch this of some class, then we should unwrap + * smartcast if possible to generate SetField instead of setter call + * + * See KT-57105 + */ + private fun extractDispatchReceiverOfAssignment(variableAssignment: FirVariableAssignment): FirExpression? { + val receiver = variableAssignment.dispatchReceiver ?: return null + if (receiver !is FirSmartCastExpression) return receiver + val thisReceiver = receiver.originalExpression as? FirThisReceiverExpression ?: return receiver + val thisClass = thisReceiver.calleeReference.boundSymbol as? FirClassSymbol<*> ?: return receiver + val propertySymbol = variableAssignment.calleeReference?.toResolvedPropertySymbol() ?: return receiver + val propertyDispatchReceiverType = propertySymbol.dispatchReceiverType ?: return receiver + return when (thisClass.defaultType().isSubtypeOf(propertyDispatchReceiverType, session)) { + true -> thisReceiver + false -> receiver } } diff --git a/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.kt b/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.kt index a16ba38d8a4..eada9530652 100644 --- a/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.kt +++ b/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.kt @@ -1,5 +1,4 @@ // ISSUE: KT-57105 -// IGNORE_CODEGEN_WITH_IR_FAKE_OVERRIDE_GENERATION // DUMP_IR // simpleCase