From f97cc0b62d838215e1fffd1ed95873a52d913d88 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Sun, 15 Nov 2020 13:10:54 +0300 Subject: [PATCH] FIR: Rework receivers processing in resolution - Put extensionReceiver to candidate even if it's explicit (for sake of clarity) - Split CheckReceiver (dispatch part should only check nullability) --- .../resolveWithStdlib/plusAssignNullable.kt | 16 +++ .../resolveWithStdlib/plusAssignNullable.txt | 19 +++ ...FirDiagnosticsWithStdlibTestGenerated.java | 5 + .../kotlin/fir/resolve/calls/CallKind.kt | 20 +-- .../kotlin/fir/resolve/calls/Candidate.kt | 18 +-- .../fir/resolve/calls/CandidateFactory.kt | 6 +- .../kotlin/fir/resolve/calls/FirReceivers.kt | 7 +- .../fir/resolve/calls/ResolutionStages.kt | 130 ++++++------------ .../resolve/calls/tower/FirTowerResolver.kt | 7 +- .../resolve/calls/tower/TowerLevelHandler.kt | 24 ++-- .../fir/resolve/calls/tower/TowerLevels.kt | 30 ++-- .../toStringOfUnboxedNullable.kt | 1 - .../bound/expressionWithNullableType.fir.kt | 4 +- .../basicCollectionLiterals.fir.kt | 10 +- ...ocalVariablesWithTypeParameters_1_3.fir.kt | 2 +- ...ocalVariablesWithTypeParameters_1_4.fir.kt | 2 +- .../propertyDefferedType.fir.kt | 2 +- .../funInterfaceConversionOnReceiver.fir.kt | 2 +- ...t6541_extensionForExtensionFunction.fir.kt | 2 +- .../nullability/functionalBound.fir.kt | 4 +- .../nullability/smartCastRefinedClass.fir.kt | 2 +- .../generics/nullability/smartCasts.fir.kt | 2 +- .../nullability/smartCastsOnThis.fir.kt | 4 +- .../generics/nullability/useAsReceiver.fir.kt | 2 +- .../typeParameterBounds.fir.kt | 8 +- .../ReceiverNullability.fir.kt | 2 +- .../derefenceMember.fir.kt | 2 +- .../tests/typealias/kt15734.fir.kt | 2 +- .../smartcasts/extensionReceiver.fir.kt | 6 +- .../smartcasts/extensionReceiver_after.fir.kt | 6 +- .../operator-call/p-1/pos/2.1.fir.kt | 12 +- .../diagnostics/notLinked/dfa/neg/1.fir.kt | 4 +- .../diagnostics/notLinked/dfa/neg/23.fir.kt | 4 +- .../diagnostics/notLinked/dfa/neg/29.fir.kt | 4 +- .../diagnostics/notLinked/dfa/neg/42.fir.kt | 4 +- .../diagnostics/notLinked/dfa/neg/9.fir.kt | 4 +- .../diagnostics/notLinked/dfa/pos/13.fir.kt | 10 +- .../diagnostics/notLinked/dfa/pos/16.fir.kt | 6 +- .../diagnostics/notLinked/dfa/pos/18.fir.kt | 6 +- .../api/resolver/SingleCandidateResolver.kt | 6 +- 40 files changed, 194 insertions(+), 213 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.kt create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.txt diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.kt new file mode 100644 index 00000000000..2228508ca51 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.kt @@ -0,0 +1,16 @@ +interface A { + val list: List +} + +interface B { + val list: MutableList +} + +fun B.foo(a: A?) { + list.plusAssign(mutableListOf("")) + with(a) { + list.plusAssign(mutableListOf("")) + list += mutableListOf("") + } +} + diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.txt new file mode 100644 index 00000000000..fe4da4544ed --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.txt @@ -0,0 +1,19 @@ +FILE: plusAssignNullable.kt + public abstract interface A : R|kotlin/Any| { + public abstract val list: R|kotlin/collections/List| + public get(): R|kotlin/collections/List| + + } + public abstract interface B : R|kotlin/Any| { + public abstract val list: R|kotlin/collections/MutableList| + public get(): R|kotlin/collections/MutableList| + + } + public final fun R|B|.foo(a: R|A?|): R|kotlin/Unit| { + this@R|/foo|.R|/B.list|.R|kotlin/collections/plusAssign|(R|kotlin/collections/mutableListOf|(vararg(String()))) + R|kotlin/with|(R|/a|, = with@fun R|A?|.(): R|kotlin/Unit| { + this@R|/foo|.R|/B.list|.R|kotlin/collections/plusAssign|(R|kotlin/collections/mutableListOf|(vararg(String()))) + this@R|/foo|.R|/B.list|.R|kotlin/collections/plusAssign|(R|kotlin/collections/mutableListOf|(vararg(String()))) + } + ) + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index a867f43990c..75a1c08b174 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -208,6 +208,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/nullableTypeParameter.kt"); } + @TestMetadata("plusAssignNullable.kt") + public void testPlusAssignNullable() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/plusAssignNullable.kt"); + } + @TestMetadata("problems.kt") public void testProblems() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems.kt"); diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt index 7070991fecb..088286a4d26 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt @@ -12,8 +12,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CheckExplicitReceiverConsistency, NoTypeArguments, CreateFreshTypeVariableSubstitutorStage, - CheckReceivers.Dispatch, - CheckReceivers.Extension, + CheckDispatchReceiver, + CheckExtensionReceiver, CheckLowPriorityInOverloadResolution, PostponedVariablesInitializerResolutionStage ) @@ -33,8 +33,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CheckExplicitReceiverConsistency, MapTypeArguments, CreateFreshTypeVariableSubstitutorStage, - CheckReceivers.Dispatch, - CheckReceivers.Extension, + CheckDispatchReceiver, + CheckExtensionReceiver, CheckArguments, EagerResolveOfCallableReferences, CheckLowPriorityInOverloadResolution, @@ -47,8 +47,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { CheckExplicitReceiverConsistency, MapTypeArguments, CreateFreshTypeVariableSubstitutorStage, - CheckReceivers.Dispatch, - CheckReceivers.Extension, + CheckDispatchReceiver, + CheckExtensionReceiver, CheckArguments, EagerResolveOfCallableReferences ) @@ -58,8 +58,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) { DiscriminateSynthetics, NoTypeArguments, CreateFreshTypeVariableSubstitutorStage, - CheckReceivers.Dispatch, - CheckReceivers.Extension, + CheckDispatchReceiver, + CheckExtensionReceiver, CheckCallableReferenceExpectedType, CheckLowPriorityInOverloadResolution ) @@ -102,8 +102,8 @@ class ResolutionSequenceBuilder( if (checkExplicitReceiverConsistency) add(CheckExplicitReceiverConsistency) if (mapTypeArguments) add(MapTypeArguments) else add(NoTypeArguments) if (checkArguments || checkDispatchReceiver || checkExtensionReceiver) add(CreateFreshTypeVariableSubstitutorStage) - if (checkDispatchReceiver) add(CheckReceivers.Dispatch) - if (checkExtensionReceiver) add(CheckReceivers.Extension) + if (checkDispatchReceiver) add(CheckDispatchReceiver) + if (checkExtensionReceiver) add(CheckExtensionReceiver) if (checkArguments) add(CheckArguments) if (resolveCallableReferenceArguments) add(EagerResolveOfCallableReferences) if (checkLowPriorityInOverloadResolution) add(CheckLowPriorityInOverloadResolution) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index 5ba2bb7383f..f5324ae66f3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression -import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.PostponedResolvedAtom @@ -81,7 +80,7 @@ data class CallInfo( class Candidate( val symbol: AbstractFirBasedSymbol<*>, val dispatchReceiverValue: ReceiverValue?, - val implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, + val extensionReceiverValue: ReceiverValue?, val explicitReceiverKind: ExplicitReceiverKind, val constraintSystemFactory: InferenceComponents.ConstraintSystemFactory, private val baseSystem: ConstraintStorage, @@ -128,18 +127,11 @@ class Candidate( var passedStages: Int = 0 - fun dispatchReceiverExpression(): FirExpression = when (explicitReceiverKind) { - ExplicitReceiverKind.DISPATCH_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> - callInfo.explicitReceiver?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression - else -> dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression - } + fun dispatchReceiverExpression(): FirExpression = + dispatchReceiverValue?.receiverExpression?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression - fun extensionReceiverExpression(): FirExpression = when (explicitReceiverKind) { - ExplicitReceiverKind.EXTENSION_RECEIVER, ExplicitReceiverKind.BOTH_RECEIVERS -> - callInfo.explicitReceiver?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression - else -> - implicitExtensionReceiverValue?.receiverExpression ?: FirNoReceiverExpression - } + fun extensionReceiverExpression(): FirExpression = + extensionReceiverValue?.receiverExpression?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression override fun equals(other: Any?): Boolean { if (this === other) return true 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 ce91f453cd2..90c04fb789a 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 @@ -52,11 +52,11 @@ class CandidateFactory private constructor( explicitReceiverKind: ExplicitReceiverKind, scope: FirScope?, dispatchReceiverValue: ReceiverValue? = null, - implicitExtensionReceiverValue: ImplicitReceiverValue<*>? = null, + extensionReceiverValue: ReceiverValue? = null, builtInExtensionFunctionReceiverValue: ReceiverValue? = null ): Candidate { return Candidate( - symbol, dispatchReceiverValue, implicitExtensionReceiverValue, + symbol, dispatchReceiverValue, extensionReceiverValue, explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem, builtInExtensionFunctionReceiverValue?.receiverExpression?.let { callInfo.withReceiverAsArgument(it) @@ -78,7 +78,7 @@ class CandidateFactory private constructor( return Candidate( symbol, dispatchReceiverValue = null, - implicitExtensionReceiverValue = null, + extensionReceiverValue = null, explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, context.inferenceComponents.constraintSystemFactory, baseSystem, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt index 8e1a8201baa..a8eb72f0d49 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt @@ -22,8 +22,11 @@ import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol -import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.coneTypeSafe interface Receiver @@ -51,7 +54,7 @@ abstract class AbstractExplicitReceiverValue : AbstractExplic get() = explicitReceiver } -internal class ExpressionReceiverValue( +class ExpressionReceiverValue( override val explicitReceiver: FirExpression ) : AbstractExplicitReceiverValue(), ReceiverValue diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 36d405d9dd6..fbbcdfe2ecf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -22,8 +22,8 @@ import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.* +import org.jetbrains.kotlin.types.AbstractNullabilityChecker abstract class ResolutionStage { abstract suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) @@ -57,52 +57,44 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() { } } -internal sealed class CheckReceivers : ResolutionStage() { - object Dispatch : CheckReceivers() { - override fun ExplicitReceiverKind.shouldBeCheckedAgainstImplicit(): Boolean { - return this == EXTENSION_RECEIVER // For NO_EXPLICIT_RECEIVER we can check extension receiver only - } - - override fun ExplicitReceiverKind.shouldBeCheckedAgainstExplicit(): Boolean { - return this == DISPATCH_RECEIVER || this == BOTH_RECEIVERS - } - - override fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType? { - return dispatchReceiverValue?.type - } - } - - object Extension : CheckReceivers() { - override fun ExplicitReceiverKind.shouldBeCheckedAgainstImplicit(): Boolean { - return this == DISPATCH_RECEIVER || this == NO_EXPLICIT_RECEIVER - } - - override fun ExplicitReceiverKind.shouldBeCheckedAgainstExplicit(): Boolean { - return this == EXTENSION_RECEIVER || this == BOTH_RECEIVERS - } - - override fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType? { - val callableSymbol = symbol as? FirCallableSymbol<*> ?: return null - val callable = callableSymbol.fir - val receiverType = callable.receiverTypeRef?.coneType - if (receiverType != null) return receiverType - val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null - if (!returnTypeRef.type.isExtensionFunctionType(context.session)) return null - return (returnTypeRef.type.typeArguments.firstOrNull() as? ConeKotlinTypeProjection)?.type - } - } - - abstract fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType? - - abstract fun ExplicitReceiverKind.shouldBeCheckedAgainstExplicit(): Boolean - - abstract fun ExplicitReceiverKind.shouldBeCheckedAgainstImplicit(): Boolean - +object CheckExtensionReceiver : ResolutionStage() { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { - val expectedReceiverType = candidate.getReceiverType(context) - val explicitReceiverExpression = callInfo.explicitReceiver - val explicitReceiverKind = candidate.explicitReceiverKind + val expectedReceiverType = candidate.getReceiverType(context) ?: return + val argumentExtensionReceiverValue = candidate.extensionReceiverValue ?: return + val expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType.type) + val argumentType = captureFromTypeParameterUpperBoundIfNeeded( + argumentType = argumentExtensionReceiverValue.type, + expectedType = expectedType, + session = context.session + ) + candidate.resolvePlainArgumentType( + candidate.csBuilder, + argumentType = argumentType, + expectedType = expectedType, + sink = sink, + context = context, + isReceiver = true, + isDispatch = false, + ) + + sink.yieldIfNeed() + } + + private fun Candidate.getReceiverType(context: ResolutionContext): ConeKotlinType? { + val callableSymbol = symbol as? FirCallableSymbol<*> ?: return null + val callable = callableSymbol.fir + val receiverType = callable.receiverTypeRef?.coneType + if (receiverType != null) return receiverType + val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null + if (!returnTypeRef.type.isExtensionFunctionType(context.session)) return null + return (returnTypeRef.type.typeArguments.firstOrNull() as? ConeKotlinTypeProjection)?.type + } +} + +object CheckDispatchReceiver : ResolutionStage() { + override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { + val explicitReceiverExpression = callInfo.explicitReceiver if (explicitReceiverExpression.isSuperCall()) { val status = candidate.symbol.fir as? FirMemberDeclaration if (status?.modality == Modality.ABSTRACT) { @@ -110,49 +102,17 @@ internal sealed class CheckReceivers : ResolutionStage() { } } - if (expectedReceiverType != null) { - if (explicitReceiverExpression != null && - explicitReceiverKind.shouldBeCheckedAgainstExplicit() && - !explicitReceiverExpression.isSuperReferenceExpression() - ) { - candidate.resolvePlainExpressionArgument( - candidate.csBuilder, - argument = explicitReceiverExpression, - expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType), - sink = sink, - context = context, - isReceiver = true, - isDispatch = this is Dispatch - ) - sink.yieldIfNeed() - } else { - val argumentExtensionReceiverValue = candidate.implicitExtensionReceiverValue - if (argumentExtensionReceiverValue != null && explicitReceiverKind.shouldBeCheckedAgainstImplicit()) { - val expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType.type) - val argumentType = captureFromTypeParameterUpperBoundIfNeeded( - argumentType = argumentExtensionReceiverValue.type, - expectedType = expectedType, - session = context.session - ) - candidate.resolvePlainArgumentType( - candidate.csBuilder, - argumentType = argumentType, - expectedType = expectedType, - sink = sink, - context = context, - isReceiver = true, - isDispatch = this is Dispatch - ) - sink.yieldIfNeed() - } - } + val dispatchReceiverValueType = candidate.dispatchReceiverValue?.type ?: return + + if (!AbstractNullabilityChecker.isSubtypeOfAny(context.session.typeContext, dispatchReceiverValueType)) { + sink.yieldDiagnostic(InapplicableWrongReceiver) } } +} - private fun FirExpression?.isSuperCall(): Boolean { - if (this !is FirQualifiedAccessExpression) return false - return calleeReference is FirSuperReference - } +private fun FirExpression?.isSuperCall(): Boolean { + if (this !is FirQualifiedAccessExpression) return false + return calleeReference is FirSuperReference } private fun FirExpression.isSuperReferenceExpression(): Boolean { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt index 37879b83e89..ffb38b1c1fa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt @@ -65,9 +65,8 @@ class FirTowerResolver( } else -> { if (receiver is FirQualifiedAccessExpression) { - val calleeReference = receiver.calleeReference - if (calleeReference is FirSuperReference) { - manager.enqueueResolverTask { mainTask.runResolverForSuperReceiver(info, receiver.typeRef) } + if (receiver.calleeReference is FirSuperReference) { + manager.enqueueResolverTask { mainTask.runResolverForSuperReceiver(info, receiver) } return } } @@ -108,7 +107,7 @@ class FirTowerResolver( ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, scope, dispatchReceiver, - implicitExtensionReceiverValue = null, + extensionReceiverValue = null, builtInExtensionFunctionReceiverValue = null ), context diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt index 5b8ef780304..6390acef981 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt @@ -14,7 +14,10 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.typeContext -import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeStarProjection +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.constructClassType import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind @@ -68,19 +71,13 @@ internal class TowerLevelHandler { CallKind.CallableReference -> { val stubReceiver = info.stubReceiver if (stubReceiver != null) { - val stubReceiverValue = ExpressionReceiverValue(stubReceiver) val stubProcessor = TowerScopeLevelProcessor( info.explicitReceiver, - if (towerLevel is MemberScopeTowerLevel && towerLevel.dispatchReceiver is AbstractExplicitReceiver<*>) { - ExplicitReceiverKind.DISPATCH_RECEIVER - } else { - ExplicitReceiverKind.EXTENSION_RECEIVER - }, + explicitReceiverKind, collector, stubReceiverCandidateFactory!!, group ) - val towerLevelWithStubReceiver = towerLevel.replaceReceiverValue(stubReceiverValue) - towerLevelWithStubReceiver.processFunctionsAndProperties(info.name, stubProcessor) + towerLevel.processFunctionsAndProperties(info.name, stubProcessor) // NB: we don't perform this for implicit Unit if (!collector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) { towerLevel.processFunctionsAndProperties(info.name, processor) @@ -147,18 +144,17 @@ private class TowerScopeLevelProcessor( override fun consumeCandidate( symbol: AbstractFirBasedSymbol<*>, dispatchReceiverValue: ReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, + extensionReceiverValue: ReceiverValue?, scope: FirScope, builtInExtensionFunctionReceiverValue: ReceiverValue? ) { // Check explicit extension receiver for default package members if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null && - (implicitExtensionReceiverValue == null) != (explicitReceiver == null) && + extensionReceiverValue != null && explicitReceiver !is FirResolvedQualifier && symbol.callableId.packageName.startsWith(defaultPackage) ) { - val extensionReceiverType = explicitReceiver?.typeRef?.coneTypeSafe() - ?: implicitExtensionReceiverValue?.type as? ConeClassLikeType + val extensionReceiverType = extensionReceiverValue.type as? ConeClassLikeType if (extensionReceiverType != null) { val declarationReceiverType = (symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef?.coneType if (declarationReceiverType is ConeClassLikeType) { @@ -183,7 +179,7 @@ private class TowerScopeLevelProcessor( explicitReceiverKind, scope, dispatchReceiverValue, - implicitExtensionReceiverValue, + extensionReceiverValue, builtInExtensionFunctionReceiverValue ), candidateFactory.context ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index c27fa46eb11..e5e11b61a25 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.isInner import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull -import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.* @@ -21,9 +20,6 @@ import org.jetbrains.kotlin.fir.scopes.processClassifiersByName import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.ConeNullability -import org.jetbrains.kotlin.fir.types.withNullability import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions @@ -45,7 +41,7 @@ interface TowerScopeLevel { fun consumeCandidate( symbol: T, dispatchReceiverValue: ReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, + extensionReceiverValue: ReceiverValue?, scope: FirScope, builtInExtensionFunctionReceiverValue: ReceiverValue? = null ) @@ -69,7 +65,7 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel class MemberScopeTowerLevel( session: FirSession, private val bodyResolveComponents: BodyResolveComponents, - val dispatchReceiver: ReceiverValue, + val dispatchReceiverValue: ReceiverValue, private val extensionReceiver: ReceiverValue? = null, private val implicitExtensionInvokeMode: Boolean = false, private val scopeSession: ScopeSession @@ -79,7 +75,7 @@ class MemberScopeTowerLevel( processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit ): ProcessorAction { var empty = true - val scope = dispatchReceiver.scope(session, scopeSession) ?: return ProcessorAction.NONE + val scope = dispatchReceiverValue.scope(session, scopeSession) ?: return ProcessorAction.NONE scope.processScopeMembers { candidate -> empty = false if (candidate is FirCallableSymbol<*> && @@ -89,24 +85,23 @@ class MemberScopeTowerLevel( if ((fir as? FirConstructor)?.isInner == false) { return@processScopeMembers } - val dispatchReceiverValue = NotNullableReceiverValue(dispatchReceiver) output.consumeCandidate( candidate, dispatchReceiverValue, - implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>, + extensionReceiverValue = extensionReceiver, scope ) if (implicitExtensionInvokeMode) { output.consumeCandidate( candidate, dispatchReceiverValue, - implicitExtensionReceiverValue = null, + extensionReceiverValue = null, scope, builtInExtensionFunctionReceiverValue = this.extensionReceiver ) } } else if (candidate is FirClassLikeSymbol<*>) { - output.consumeCandidate(candidate, null, extensionReceiver as? ImplicitReceiverValue<*>, scope) + output.consumeCandidate(candidate, null, extensionReceiver, scope) } } @@ -114,7 +109,7 @@ class MemberScopeTowerLevel( val withSynthetic = FirSyntheticPropertiesScope(session, scope) withSynthetic.processScopeMembers { symbol -> empty = false - output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), null, scope) + output.consumeCandidate(symbol, dispatchReceiverValue, null, scope) } } return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT @@ -221,7 +216,7 @@ class ScopeTowerLevel( @Suppress("UNCHECKED_CAST") processor.consumeCandidate( unwrappedCandidate as T, dispatchReceiverValue, - implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>, + extensionReceiverValue = extensionReceiver, scope ) } @@ -252,7 +247,7 @@ class ScopeTowerLevel( empty = false processor.consumeCandidate( it as T, dispatchReceiverValue = null, - implicitExtensionReceiverValue = null, + extensionReceiverValue = null, scope = scope ) } @@ -261,13 +256,6 @@ class ScopeTowerLevel( } } -class NotNullableReceiverValue(val value: ReceiverValue) : ReceiverValue { - override val type: ConeKotlinType - get() = value.type.withNullability(ConeNullability.NOT_NULL) - override val receiverExpression: FirExpression - get() = value.receiverExpression -} - private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean { return fir.receiverTypeRef != null } diff --git a/compiler/testData/codegen/box/inlineClasses/toStringOfUnboxedNullable.kt b/compiler/testData/codegen/box/inlineClasses/toStringOfUnboxedNullable.kt index 1fa1e77dc94..fafb9d1de16 100644 --- a/compiler/testData/codegen/box/inlineClasses/toStringOfUnboxedNullable.kt +++ b/compiler/testData/codegen/box/inlineClasses/toStringOfUnboxedNullable.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +InlineClasses // IGNORE_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_LIGHT_ANALYSIS inline class IC(val x: String) diff --git a/compiler/testData/diagnostics/tests/callableReference/bound/expressionWithNullableType.fir.kt b/compiler/testData/diagnostics/tests/callableReference/bound/expressionWithNullableType.fir.kt index 2d28635fbe5..90bcf400396 100644 --- a/compiler/testData/diagnostics/tests/callableReference/bound/expressionWithNullableType.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/bound/expressionWithNullableType.fir.kt @@ -7,8 +7,8 @@ public interface J { // FILE: test.kt fun f1(x: Int?): Any = x::hashCode -fun f2(t: T): Any = t::hashCode -fun f3(s: S): Any = s::hashCode +fun f2(t: T): Any = t::hashCode +fun f3(s: S): Any = s::hashCode fun f4(u: U?): Any = u::hashCode fun f5(c: List<*>): Any = c[0]::hashCode diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt index 374e2afb643..b6236178bb0 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt @@ -14,11 +14,11 @@ fun test() { } fun check() { - [1, 2] checkType { _>() } - [""] checkType { _>() } + [1, 2] checkType { _>() } + [""] checkType { _>() } val f: IntArray = [1] - [f] checkType { _>() } + [f] checkType { _>() } - [1, ""] checkType { _>() } -} \ No newline at end of file + [1, ""] checkType { _>() } +} diff --git a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt index 947ed35dc4a..0da46b5fa6e 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt @@ -11,7 +11,7 @@ fun test() { const val a3 = 0 lateinit val a4 = 0 val a5 by Delegate() - val a6 by Delegate<T>() + val a6 by Delegate<T>() } class Delegate { diff --git a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt index 7665acd5aff..7e71a1f6c70 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt @@ -11,7 +11,7 @@ fun test() { const val a3 = 0 lateinit val a4 = 0 val a5 by Delegate() - val a6 by Delegate<T>() + val a6 by Delegate<T>() } class Delegate { diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/propertyDefferedType.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/propertyDefferedType.fir.kt index ebe6e435f98..7ad8d8e86df 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/propertyDefferedType.fir.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/propertyDefferedType.fir.kt @@ -5,7 +5,7 @@ import kotlin.reflect.KProperty class B { - val c by Delegate(ag) + val c by Delegate(ag) } class Delegate(val init: T) { diff --git a/compiler/testData/diagnostics/tests/funInterface/funInterfaceConversionOnReceiver.fir.kt b/compiler/testData/diagnostics/tests/funInterface/funInterfaceConversionOnReceiver.fir.kt index 78f2420bb8e..2c88e4dfe66 100644 --- a/compiler/testData/diagnostics/tests/funInterface/funInterfaceConversionOnReceiver.fir.kt +++ b/compiler/testData/diagnostics/tests/funInterface/funInterfaceConversionOnReceiver.fir.kt @@ -5,5 +5,5 @@ fun interface Bar { operator fun Bar.plus(b: Bar): String = invoke() + b.invoke() fun box(): String { - return { "O" } + { "K" } + return { "O" } + { "K" } } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/kt6541_extensionForExtensionFunction.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/kt6541_extensionForExtensionFunction.fir.kt index 32a662a6ce9..db815efa470 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/kt6541_extensionForExtensionFunction.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/kt6541_extensionForExtensionFunction.fir.kt @@ -7,4 +7,4 @@ object Z { infix fun add(b : Foo.() -> Unit) : Z = Z } -val t2 = Z add { } { } +val t2 = Z add { } { } diff --git a/compiler/testData/diagnostics/tests/generics/nullability/functionalBound.fir.kt b/compiler/testData/diagnostics/tests/generics/nullability/functionalBound.fir.kt index 1a95bf72e24..f5a37d10a32 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/functionalBound.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/functionalBound.fir.kt @@ -1,6 +1,6 @@ fun Unit)?> foo(x: E, y: T) { if (x != null) { - y(x) + y(x) } if (y != null) { @@ -10,4 +10,4 @@ fun Unit)?> foo(x: E, y: T) { if (x != null && y != null) { y(x) } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.fir.kt b/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.fir.kt index 914151e3715..b00a969aac8 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.fir.kt @@ -1,6 +1,6 @@ fun foo(x: T) { if (x is String?) { - x.length + x.length if (x != null) { x.length diff --git a/compiler/testData/diagnostics/tests/generics/nullability/smartCasts.fir.kt b/compiler/testData/diagnostics/tests/generics/nullability/smartCasts.fir.kt index f829414ef7f..1a3b014fcf5 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/smartCasts.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/smartCasts.fir.kt @@ -24,7 +24,7 @@ fun foo(x: T) { x?.bar1() } - x.length + x.length if (x is String) { x.length diff --git a/compiler/testData/diagnostics/tests/generics/nullability/smartCastsOnThis.fir.kt b/compiler/testData/diagnostics/tests/generics/nullability/smartCastsOnThis.fir.kt index afd4d5b9a6a..49bf2c04035 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/smartCastsOnThis.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/smartCastsOnThis.fir.kt @@ -23,7 +23,7 @@ fun T.foo() { this?.bar1() } - length + length if (this is String) { length @@ -33,4 +33,4 @@ fun T.foo() { bar2() bar3() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/generics/nullability/useAsReceiver.fir.kt b/compiler/testData/diagnostics/tests/generics/nullability/useAsReceiver.fir.kt index c8f52d3f8cc..dd30e3ef6da 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/useAsReceiver.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/useAsReceiver.fir.kt @@ -7,7 +7,7 @@ fun CharSequence?.bar2() {} fun T.bar3() {} fun foo(x: T) { - x.length + x.length x?.length if (1 == 1) { diff --git a/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.fir.kt b/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.fir.kt index 61d58b38e35..b7ec4f2145a 100644 --- a/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.fir.kt @@ -14,14 +14,14 @@ class A { fun foo2(a: A, b: A) { a.foo1(Out()) - a.foo1<Out>(Out()) + a.foo1>(Out()) a.foo1(Out()) a.foo1(Out()) a.foo2(Inv()) a.foo2(Inv()) - a.foo2<Inv>(Inv()) + a.foo2>(Inv()) a.foo3(In()) a.foo3(In()) @@ -33,11 +33,11 @@ fun foo2(a: A, b: A) { b.foo2(Inv()) b.foo2(Inv()) - b.foo2<Inv>(Inv()) + b.foo2>(Inv()) b.foo3(In()) - b.foo3<In>(In()) + b.foo3>(In()) b.foo3(In()) b.foo3(In()) diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/ReceiverNullability.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/ReceiverNullability.fir.kt index 803bcad34ce..f4c80d04a33 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/ReceiverNullability.fir.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/ReceiverNullability.fir.kt @@ -30,7 +30,7 @@ fun A.test2() { } fun A?.test3() { - foo() // error + foo() // error bar() // error buzz() diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/derefenceMember.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/derefenceMember.fir.kt index 16310cc8fb5..e63bffd9e8d 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/derefenceMember.fir.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/derefenceMember.fir.kt @@ -32,7 +32,7 @@ fun test() { foo() } with(platformN) { - foo() + foo() } with(platformJ) { foo() diff --git a/compiler/testData/diagnostics/tests/typealias/kt15734.fir.kt b/compiler/testData/diagnostics/tests/typealias/kt15734.fir.kt index f35a9e1befc..b7a667b24da 100644 --- a/compiler/testData/diagnostics/tests/typealias/kt15734.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/kt15734.fir.kt @@ -15,5 +15,5 @@ val test5: List = TODO() val test6: () -> List = TODO() fun test(x: TNString) { - x.hashCode() + x.hashCode() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver.fir.kt index deb0801d3fc..c1f71e56f15 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver.fir.kt @@ -17,7 +17,7 @@ fun CharSequence?.isNullOrEmpty(): Boolean { fun smartcastOnReceiver(s: String?) { with(s) { if (isNullOrEmpty()) { - length + length } else { length @@ -32,7 +32,7 @@ fun mixedReceiver(s: String?) { } } else { with(s) { - length + length } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver_after.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver_after.fir.kt index d0ba672130a..d82ea265323 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver_after.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/extensionReceiver_after.fir.kt @@ -17,7 +17,7 @@ fun CharSequence?.isNullOrEmpty(): Boolean { fun smartcastOnReceiver(s: String?) { with(s) { if (isNullOrEmpty()) { - length + length } else { length @@ -32,7 +32,7 @@ fun mixedReceiver(s: String?) { } } else { with(s) { - length + length } } -} \ No newline at end of file +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/operator-call/p-1/pos/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/operator-call/p-1/pos/2.1.fir.kt index fbf2e9f05b8..55a95cd8b2b 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/operator-call/p-1/pos/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/operator-call/p-1/pos/2.1.fir.kt @@ -9,17 +9,17 @@ package testPackCase1 fun case1(a: A, c: C) { - a?.b += c - a?.b .plusAssign(c) + a?.b += c + a?.b .plusAssign(c) val x = { - a?.b += c - a?.b.plusAssign(c) + a?.b += c + a?.b.plusAssign(c) }() - a?.b += { c }() + a?.b += { c }() - a?.b.plusAssign({ c }()) + a?.b.plusAssign({ c }()) } class A(val b: B) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt index a1a07494265..02adb3416d6 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt @@ -103,8 +103,8 @@ fun case_7() { // TESTCASE NUMBER: 8 fun case_8(x: TypealiasNullableString) { - if (x !== null === null && x != null != null) x.get(0) - if (x !== null != null && x != null === null) x.get(0) + if (x !== null === null && x != null != null) x.get(0) + if (x !== null != null && x != null === null) x.get(0) } // TESTCASE NUMBER: 9 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/23.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/23.fir.kt index b3f9d7c25aa..1f7569cc23c 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/23.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/23.fir.kt @@ -20,7 +20,7 @@ inline fun case_1(x: T) { inline fun case_2(x: T) { x as K x - x.equals(x) + x.equals(x) } /* @@ -49,7 +49,7 @@ inline fun case_4(x: T?) { inline fun case_5(x: T) { if (x is K?) { x - x.equals(x) + x.equals(x) } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/29.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/29.fir.kt index 28fb0f53e69..c31bf6671be 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/29.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/29.fir.kt @@ -22,8 +22,8 @@ fun case_2(a: Any?) { } })() - a - a.equals(10) + a + a.equals(10) } // TESTCASE NUMBER: 3 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/42.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/42.fir.kt index f54f3479e0c..3f3d9c5291d 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/42.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/42.fir.kt @@ -75,7 +75,7 @@ fun case_6(x: T) { fun case_7(x: T) { if (x is Int? || x is Float?) { ? & T & T")!>x - ? & T & T")!>x.toByte() + ? & T & T")!>x.toByte() } } @@ -86,7 +86,7 @@ fun case_7(x: T) { inline fun case_8(x: T) { if (x is Int? || x is Float?) { ? & T & T")!>x - ? & T & T")!>x.toByte() + ? & T & T")!>x.toByte() } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/9.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/9.fir.kt index de592327951..33826d89042 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/9.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/9.fir.kt @@ -8,7 +8,7 @@ fun case_1(x: T?, y: K?) { y as K val z = x ?: y - x.equals(10) + x.equals(10) z z.equals(10) } @@ -18,5 +18,5 @@ inline fun case_2(y: K?) { y as K y - y.equals(10) + y.equals(10) } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt index 856f27e7993..520b79e3e46 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/13.fir.kt @@ -8,7 +8,7 @@ fun case_1(x: T) { if (y != x) { x - x.equals(null) + x.equals(null) x.propT x.propAny x.propNullableT @@ -17,7 +17,7 @@ fun case_1(x: T) { x.funAny() x.funNullableT() x.funNullableAny() - x.apply { equals(null) } + x.apply { equals(null) } x.apply { propT } x.apply { propAny } x.apply { propNullableT } @@ -25,8 +25,8 @@ fun case_1(x: T) { x.apply { funT() } x.apply { funAny() } x.apply { funNullableT() } - x.apply { funNullableAny(); x.equals(null) } - x.also { it.equals(null) } + x.apply { funNullableAny(); x.equals(null) } + x.also { it.equals(null) } x.also { it.propT } x.also { it.propAny } x.also { it.propNullableT } @@ -51,7 +51,7 @@ fun case_2(x: T?, y: Nothing?) { x.funAny() x.funNullableT() x.funNullableAny() - x.apply { equals(null) } + x.apply { equals(null) } x.apply { propT } x.apply { propAny } x.apply { propNullableT } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/16.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/16.fir.kt index 0a0564a5320..3f1728cb83a 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/16.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/16.fir.kt @@ -334,7 +334,7 @@ fun case_24(x: Inv?, y: Nothing?) { fun case_25(x: Int?) { val x = (l@ { if (x == null) return@l - x + x x.inv() })() } @@ -660,7 +660,7 @@ fun case_44(x: Inv>> fun case_45(x: T) { val y = (l@ { if (x == null) return@l - x + x x.equals(null) x.propT x.propAny @@ -677,7 +677,7 @@ fun case_45(x: T) { fun case_46(x: T?) { (l@ { if (x === null) return@l - x + x x.equals(null) x.propT x.propAny diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/18.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/18.fir.kt index 707ddf6652d..973070c70d5 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/18.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/18.fir.kt @@ -244,7 +244,7 @@ fun case_18(x: T, f: Boolean) { while (f) { if (false || false || false || x == nullableNothingProperty) break x - x.equals(null) + x.equals(null) x.propT x.propAny x.propNullableT @@ -261,7 +261,7 @@ fun case_19(map: MutableMap, y: Nothing?) { for ((k, v) in map) { if (k !== implicitNullableNothingProperty && true && v != y) else { break } k - k.equals(null) + k.equals(null) k.propT k.propAny k.propNullableT @@ -271,7 +271,7 @@ fun case_19(map: MutableMap, y: Nothing?) { k.funNullableT() k.funNullableAny() v - v.equals(null) + v.equals(null) v.propT v.propAny v.propNullableT diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt index 52efff7391d..da9904b68b7 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt @@ -68,7 +68,11 @@ class SingleCandidateResolver( resolutionParameters.callableSymbol, explicitReceiverKind = explicitReceiverKind, dispatchReceiverValue = dispatchReceiverValue, - implicitExtensionReceiverValue = implicitExtensionReceiverValue, + extensionReceiverValue = + if (explicitReceiverKind.isExtensionReceiver) + callInfo.explicitReceiver?.let { ExpressionReceiverValue(it) } + else + implicitExtensionReceiverValue, scope = null, )