From 4e4d36f85a503c134e3dfc167c62a2caa6beffce Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 11 Aug 2021 18:36:30 +0300 Subject: [PATCH] FIR: take lower priority into account during references EagerResolve #KT-48158 Fixed --- .../src/org/jetbrains/kotlin/fir/FirCallResolver.kt | 10 +++++----- .../kotlin/fir/resolve/calls/ResolutionStages.kt | 10 +++++++++- .../unitAdaptationForReferenceCompatibility.fir.kt | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 2e6075803eb..66a6c04b851 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -339,7 +339,7 @@ class FirCallResolver( fun resolveCallableReference( constraintSystemBuilder: ConstraintSystemBuilder, resolvedCallableReferenceAtom: ResolvedCallableReferenceAtom, - ): Boolean { + ): Pair { val callableReferenceAccess = resolvedCallableReferenceAtom.reference val lhs = resolvedCallableReferenceAtom.lhs val coneSubstitutor = constraintSystemBuilder.buildCurrentSubstitutor() as ConeSubstitutor @@ -383,7 +383,7 @@ class FirCallResolver( callableReferenceAccess.source ) resolvedCallableReferenceAtom.resultingReference = errorReference - return false + return applicability to false } reducedCandidates.size > 1 -> { if (resolvedCallableReferenceAtom.hasBeenPostponed) { @@ -393,10 +393,10 @@ class FirCallResolver( callableReferenceAccess.source ) resolvedCallableReferenceAtom.resultingReference = errorReference - return false + return applicability to false } resolvedCallableReferenceAtom.hasBeenPostponed = true - return true + return applicability to true } } @@ -417,7 +417,7 @@ class FirCallResolver( resolvedCallableReferenceAtom.resultingReference = reference resolvedCallableReferenceAtom.resultingTypeForCallableReference = chosenCandidate.resultingTypeForCallableReference - return true + return applicability to true } fun resolveDelegatingConstructorCall( 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 dbd3062cc73..495673e709a 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 @@ -29,6 +29,7 @@ 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.tower.CandidateApplicability import org.jetbrains.kotlin.types.AbstractNullabilityChecker abstract class ResolutionStage { @@ -179,8 +180,15 @@ internal object EagerResolveOfCallableReferences : CheckerStage() { if (candidate.postponedAtoms.isEmpty()) return for (atom in candidate.postponedAtoms) { if (atom is ResolvedCallableReferenceAtom) { - if (!context.bodyResolveComponents.callResolver.resolveCallableReference(candidate.csBuilder, atom)) { + val (applicability, success) = + context.bodyResolveComponents.callResolver.resolveCallableReference(candidate.csBuilder, atom) + if (!success) { sink.yieldDiagnostic(InapplicableCandidate) + } else when (applicability) { + CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY -> + candidate.addDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic) + else -> { + } } } } diff --git a/compiler/testData/diagnostics/tests/callableReference/unitAdaptationForReferenceCompatibility.fir.kt b/compiler/testData/diagnostics/tests/callableReference/unitAdaptationForReferenceCompatibility.fir.kt index 923a6141a5f..4d8efb74ac4 100644 --- a/compiler/testData/diagnostics/tests/callableReference/unitAdaptationForReferenceCompatibility.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/unitAdaptationForReferenceCompatibility.fir.kt @@ -20,6 +20,6 @@ public interface Executor { fun f(): String = "test" class A { - fun schedule1(e: Executor): Future = e.submit(::f) + fun schedule1(e: Executor): Future = e.submit(::f) fun schedule2(e: Executor): Future = e.submit { f() } }