[FIR2IR] Treat assignment on smartcasted this in classes using FIR instead of IR
KT-57105
This commit is contained in:
committed by
Space Team
parent
56a48b1148
commit
39063e59f6
@@ -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()
|
||||
|
||||
+19
-13
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// ISSUE: KT-57105
|
||||
// IGNORE_CODEGEN_WITH_IR_FAKE_OVERRIDE_GENERATION
|
||||
// DUMP_IR
|
||||
|
||||
// simpleCase
|
||||
|
||||
Reference in New Issue
Block a user