[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
|
// See the comment to generateUnboundFakeOverrides function itself
|
||||||
@OptIn(LeakedDeclarationCaches::class)
|
@OptIn(LeakedDeclarationCaches::class)
|
||||||
declarationStorage.generateUnboundFakeOverrides()
|
declarationStorage.generateUnboundFakeOverrides()
|
||||||
|
|||||||
+19
-13
@@ -649,7 +649,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val symbol = calleeReference.toSymbolForCall(
|
val symbol = calleeReference.toSymbolForCall(
|
||||||
variableAssignment.dispatchReceiver,
|
extractDispatchReceiverOfAssignment(variableAssignment),
|
||||||
explicitReceiver = variableAssignment.explicitReceiver,
|
explicitReceiver = variableAssignment.explicitReceiver,
|
||||||
preferGetter = false,
|
preferGetter = false,
|
||||||
)
|
)
|
||||||
@@ -683,15 +683,9 @@ class CallAndReferenceGenerator(
|
|||||||
|
|
||||||
is IrPropertySymbol -> {
|
is IrPropertySymbol -> {
|
||||||
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
||||||
var backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
val backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
||||||
val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir
|
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 {
|
when {
|
||||||
setterSymbol != null -> IrCallImpl(
|
setterSymbol != null -> IrCallImpl(
|
||||||
startOffset, endOffset, type, setterSymbol,
|
startOffset, endOffset, type, setterSymbol,
|
||||||
@@ -744,11 +738,23 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnsafeDuringIrConstructionAPI::class)
|
|
||||||
private fun IrPropertySymbol.overriddenBackingFieldOrNull(): IrFieldSymbol? {
|
/**
|
||||||
return owner.overriddenSymbols.firstNotNullOfOrNull {
|
* If we have assignment like `this.x = ...` and this `this` is a dispatch this of some class, then we should unwrap
|
||||||
val owner = it.owner
|
* smartcast if possible to generate SetField instead of setter call
|
||||||
owner.backingField?.symbol ?: it.overriddenBackingFieldOrNull()
|
*
|
||||||
|
* 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
|
// ISSUE: KT-57105
|
||||||
// IGNORE_CODEGEN_WITH_IR_FAKE_OVERRIDE_GENERATION
|
|
||||||
// DUMP_IR
|
// DUMP_IR
|
||||||
|
|
||||||
// simpleCase
|
// simpleCase
|
||||||
|
|||||||
Reference in New Issue
Block a user