From 374b59dee31e0c95e3aa1fe379f2874d75c19262 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 28 May 2019 20:36:17 +0300 Subject: [PATCH] FIR resolve: add early explicit receiver type check Before this commit, explicit extension receiver type check was performed during found candidates analysis (together with arguments type check etc.) Now we do it just after candidate is found, and filter the candidate out if explicit receiver type is inappropriate. This commit slightly changes resolve semantics, replacing WRONG_RECEIVER with UNRESOLVED_REFERENCE in certain situations. However, it provides significant performance boost. --- .../kotlin/fir/resolve/calls/CallResolver.kt | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt index 694198df82d..006f18437b5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.constructClassType import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator @@ -29,12 +30,15 @@ import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage +import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind +import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.utils.addToStdlib.cast import kotlin.coroutines.* import kotlin.coroutines.intrinsics.createCoroutineUnintercepted @@ -544,14 +548,34 @@ class ExplicitReceiverTowerDataConsumer( dispatchReceiverValue: ClassDispatchReceiverValue?, implicitExtensionReceiverValue: ImplicitReceiverValue? ): ProcessorAction { + val explicitReceiverType = explicitReceiver.type + if (dispatchReceiverValue == null && explicitReceiverType is ConeClassType) { + val declarationReceiverTypeRef = (symbol as? FirCallableSymbol)?.fir?.receiverTypeRef as? FirResolvedTypeRef + val declarationReceiverType = declarationReceiverTypeRef?.type + if (declarationReceiverType is ConeClassType) { + if (!AbstractTypeChecker.isSubtypeOf( + candidateFactory.inferenceComponents.ctx, + explicitReceiverType, + declarationReceiverType.lookupTag.constructClassType( + declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(), + isNullable = true + ) + ) + ) { + return ProcessorAction.NEXT + } + } + } + val candidate = candidateFactory.createCandidate( + symbol, + dispatchReceiverValue, + implicitExtensionReceiverValue, + ExplicitReceiverKind.EXTENSION_RECEIVER + ) + resultCollector.consumeCandidate( group, - candidateFactory.createCandidate( - symbol, - dispatchReceiverValue, - implicitExtensionReceiverValue, - ExplicitReceiverKind.EXTENSION_RECEIVER - ) + candidate ) return ProcessorAction.NEXT } @@ -690,9 +714,6 @@ enum class CandidateApplicability { RESOLVED } - -var ID = "" - class CandidateCollector(val callInfo: CallInfo, val components: InferenceComponents) { val groupNumbers = mutableListOf()