[FIR] Store expressions of receivers inside candidates instead of ReceiverValue

This is needed because of mutable nature of receiver values: implicit
  receiver values can be modified because of smartcasts, but in candidate
  we need to store snapshot of receiver in the form it was at the beginning
  of the resolution

^KT-58823 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-06-05 10:36:55 +03:00
committed by Space Team
parent b564260a33
commit 6409bf2fe8
26 changed files with 255 additions and 181 deletions
@@ -447,15 +447,15 @@ internal class KtFirCallResolver(
) {
// Implicit invoke (e.g., `x()`) will have a different callee symbol (e.g., `x`) than the candidate (e.g., `invoke`).
createKtPartiallyAppliedSymbolForImplicitInvoke(
candidate.dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression,
candidate.chosenExtensionReceiverValue?.receiverExpression ?: FirNoReceiverExpression,
candidate.dispatchReceiver ?: FirNoReceiverExpression,
candidate.chosenExtensionReceiver ?: FirNoReceiverExpression,
candidate.explicitReceiverKind
)
} else {
KtPartiallyAppliedSymbol(
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
candidate.dispatchReceiverValue?.receiverExpression?.toKtReceiverValue(),
candidate.chosenExtensionReceiverValue?.receiverExpression?.toKtReceiverValue(),
candidate.dispatchReceiver?.toKtReceiverValue(),
candidate.chosenExtensionReceiver?.toKtReceiverValue(),
)
}
} else if (fir is FirImplicitInvokeCall) {
@@ -57,9 +57,7 @@ internal class KtFirVisibilityChecker(
val dispatchReceiverCanBeExplicit = candidateSymbol is KtCallableSymbol && !candidateSymbol.isExtension
val explicitDispatchReceiver = runIf(dispatchReceiverCanBeExplicit) {
receiverExpression
?.getOrBuildFirSafe<FirExpression>(analysisSession.firResolveSession)
?.let { ExpressionReceiverValue(it) }
receiverExpression?.getOrBuildFirSafe<FirExpression>(analysisSession.firResolveSession)
}
val candidateFirSymbol = candidateSymbol.firSymbol.fir as FirMemberDeclaration
@@ -53,12 +53,12 @@ class SingleCandidateResolver(
callInfo,
resolutionParameters.callableSymbol,
explicitReceiverKind = explicitReceiverKind,
dispatchReceiverValue = dispatchReceiverValue,
dispatchReceiver = dispatchReceiverValue?.receiverExpression,
givenExtensionReceiverOptions = listOfNotNull(
if (explicitReceiverKind.isExtensionReceiver)
callInfo.explicitReceiver?.let { ExpressionReceiverValue(it) }
callInfo.explicitReceiver
else
implicitExtensionReceiverValue
implicitExtensionReceiverValue?.receiverExpression
),
scope = null,
)