diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt index 7168c995248..8a507c78ced 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt @@ -10,11 +10,13 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe -import org.jetbrains.kotlin.idea.frontend.api.* +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartCast +import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.psi.KtExpression internal class KtFirSmartcastProvider( @@ -23,6 +25,7 @@ internal class KtFirSmartcastProvider( ) : KtSmartCastProvider(), KtFirAnalysisSessionComponent { override fun getSmartCastedToType(expression: KtExpression): KtType? = withValidityAssertion { expression.getOrBuildFirSafe(analysisSession.firResolveState) + ?.takeIf { it.isStable } ?.typeRef ?.coneTypeSafe() ?.asKtType() @@ -32,17 +35,19 @@ internal class KtFirSmartcastProvider( override fun getImplicitReceiverSmartCast(expression: KtExpression): Collection = withValidityAssertion { val qualifiedExpression = expression.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() - if (qualifiedExpression.dispatchReceiver !is FirExpressionWithSmartcast - && qualifiedExpression.extensionReceiver !is FirExpressionWithSmartcast + val dispatchReceiver = qualifiedExpression.dispatchReceiver + val extensionReceiver = qualifiedExpression.extensionReceiver + if ((dispatchReceiver !is FirExpressionWithSmartcast || !dispatchReceiver.isStable) && + (extensionReceiver !is FirExpressionWithSmartcast || !extensionReceiver.isStable) ) return emptyList() buildList { - (qualifiedExpression.dispatchReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> + (dispatchReceiver as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.let { smartCasted -> ImplicitReceiverSmartCast( smartCasted.typeRef.coneTypeSafe()?.asKtType() ?: return@let null, ImplicitReceiverSmartcastKind.DISPATCH ) }?.let(::add) - (qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> + (extensionReceiver as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.let { smartCasted -> ImplicitReceiverSmartCast( smartCasted.typeRef.coneTypeSafe()?.asKtType() ?: return@let null, ImplicitReceiverSmartcastKind.EXTENSION