diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index 2b3ab1dd206..55b8a38c789 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -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 ) diff --git a/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.kt b/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.kt index 21ab6befc9b..d06ff805808 100644 --- a/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.kt +++ b/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.kt @@ -1,10 +1,9 @@ fun Any.withInvoke(f: String.() -> Unit) { if (this is String) { - f() // Should be OK + f() // Should be OK } } fun String.withInvoke(f: String.() -> Unit) { f() } - diff --git a/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.txt b/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.txt index cb95e977c61..abe72bc3c04 100644 --- a/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.txt +++ b/compiler/fir/resolve/testData/resolve/smartcasts/problems/invoke.txt @@ -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|) -> { - #() + R|/f|.R|FakeOverride|(this@R|/withInvoke|) } }