[FIR] Don't update expression in receiver value with smartcast in candidate factory

This commit is contained in:
Dmitriy Novozhilov
2020-02-17 13:47:07 +03:00
parent e302e06c73
commit 811ed1ade4
2 changed files with 18 additions and 20 deletions
@@ -49,23 +49,10 @@ class CandidateFactory private constructor(
implicitExtensionReceiverValue: ImplicitReceiverValue<*>? = null, implicitExtensionReceiverValue: ImplicitReceiverValue<*>? = null,
builtInExtensionFunctionReceiverValue: ReceiverValue? = null builtInExtensionFunctionReceiverValue: ReceiverValue? = null
): Candidate { ): Candidate {
val receiverExpression = builtInExtensionFunctionReceiverValue?.let {
val receiverExpression = builtInExtensionFunctionReceiverValue.receiverExpression
if (receiverExpression is FirQualifiedAccessExpression &&
it.type != builtInExtensionFunctionReceiverValue.receiverExpression.typeRef.coneTypeUnsafe()) {
buildExpressionWithSmartcast {
originalExpression = receiverExpression
typeRef = receiverExpression.typeRef.resolvedTypeFromPrototype(it.type)
typesFromSmartCast = listOf(it.type)
}
} else {
receiverExpression
}
}
return Candidate( return Candidate(
symbol, dispatchReceiverValue, implicitExtensionReceiverValue, symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
explicitReceiverKind, bodyResolveComponents, baseSystem, explicitReceiverKind, bodyResolveComponents, baseSystem,
receiverExpression?.let { builtInExtensionFunctionReceiverValue?.receiverExpression?.let {
callInfo.withReceiverAsArgument(it) callInfo.withReceiverAsArgument(it)
} ?: callInfo } ?: callInfo
) )
@@ -10,12 +10,15 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.builder.buildThisReceiverExpression import org.jetbrains.kotlin.fir.expressions.builder.buildThisReceiverExpression
import org.jetbrains.kotlin.fir.references.builder.buildImplicitThisReference import org.jetbrains.kotlin.fir.references.builder.buildImplicitThisReference
import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirQualifierScope import org.jetbrains.kotlin.fir.scopes.impl.FirQualifierScope
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
@@ -23,11 +26,8 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeStarProjection
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -44,7 +44,7 @@ interface ReceiverValue : Receiver {
type.scope(useSiteSession, scopeSession) type.scope(useSiteSession, scopeSession)
} }
private fun receiverExpression(symbol: AbstractFirBasedSymbol<*>, type: ConeKotlinType): FirExpression = private fun receiverExpression(symbol: AbstractFirBasedSymbol<*>, type: ConeKotlinType): FirThisReceiverExpression =
buildThisReceiverExpression { buildThisReceiverExpression {
calleeReference = buildImplicitThisReference { calleeReference = buildImplicitThisReference {
boundSymbol = symbol boundSymbol = symbol
@@ -96,7 +96,9 @@ sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = implicitScope override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = implicitScope
override val receiverExpression: FirExpression = receiverExpression(boundSymbol, type) private val originalReceiverExpression: FirThisReceiverExpression = receiverExpression(boundSymbol, type)
final override var receiverExpression: FirExpression = originalReceiverExpression
private set
/* /*
* Should be called only in ImplicitReceiverStack * Should be called only in ImplicitReceiverStack
@@ -104,6 +106,15 @@ sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
internal fun replaceType(type: ConeKotlinType) { internal fun replaceType(type: ConeKotlinType) {
if (type == this.type) return if (type == this.type) return
this.type = type this.type = type
receiverExpression = if (type == originalReceiverExpression.typeRef.coneTypeUnsafe()) {
originalReceiverExpression
} else {
buildExpressionWithSmartcast {
originalExpression = originalReceiverExpression
typeRef = originalReceiverExpression.typeRef.resolvedTypeFromPrototype(type)
typesFromSmartCast = listOf(type)
}
}
implicitScope = type.scope(useSiteSession, scopeSession) implicitScope = type.scope(useSiteSession, scopeSession)
} }
} }