[FIR] Add smartcast info to argument of invoke of function with receiver

This commit is contained in:
Dmitriy Novozhilov
2020-02-13 15:57:42 +03:00
parent 4fbed9b363
commit 50ac8eb95b
3 changed files with 19 additions and 4 deletions
@@ -6,9 +6,12 @@
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionWithSmartcast
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.returnExpressions
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
@@ -46,10 +49,23 @@ class CandidateFactory private constructor(
implicitExtensionReceiverValue: ImplicitReceiverValue<*>? = null,
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
): 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(
symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
explicitReceiverKind, bodyResolveComponents, baseSystem,
builtInExtensionFunctionReceiverValue?.receiverExpression?.let {
receiverExpression?.let {
callInfo.withReceiverAsArgument(it)
} ?: callInfo
)
@@ -1,10 +1,9 @@
fun Any.withInvoke(f: String.() -> Unit) {
if (this is String) {
<!INAPPLICABLE_CANDIDATE!>f<!>() // Should be OK
f() // Should be OK
}
}
fun String.withInvoke(f: String.() -> Unit) {
f()
}
@@ -2,7 +2,7 @@ FILE: invoke.kt
public final fun R|kotlin/Any|.withInvoke(f: R|kotlin/String.() -> kotlin/Unit|): R|kotlin/Unit| {
when () {
(this@R|/withInvoke| is R|kotlin/String|) -> {
<Inapplicable(INAPPLICABLE): [kotlin/Function1.invoke]>#()
R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(this@R|/withInvoke|)
}
}