FIR: take lower priority into account during references EagerResolve

#KT-48158 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-08-11 18:36:30 +03:00
parent a21d281c19
commit 4e4d36f85a
3 changed files with 15 additions and 7 deletions
@@ -339,7 +339,7 @@ class FirCallResolver(
fun resolveCallableReference( fun resolveCallableReference(
constraintSystemBuilder: ConstraintSystemBuilder, constraintSystemBuilder: ConstraintSystemBuilder,
resolvedCallableReferenceAtom: ResolvedCallableReferenceAtom, resolvedCallableReferenceAtom: ResolvedCallableReferenceAtom,
): Boolean { ): Pair<CandidateApplicability, Boolean> {
val callableReferenceAccess = resolvedCallableReferenceAtom.reference val callableReferenceAccess = resolvedCallableReferenceAtom.reference
val lhs = resolvedCallableReferenceAtom.lhs val lhs = resolvedCallableReferenceAtom.lhs
val coneSubstitutor = constraintSystemBuilder.buildCurrentSubstitutor() as ConeSubstitutor val coneSubstitutor = constraintSystemBuilder.buildCurrentSubstitutor() as ConeSubstitutor
@@ -383,7 +383,7 @@ class FirCallResolver(
callableReferenceAccess.source callableReferenceAccess.source
) )
resolvedCallableReferenceAtom.resultingReference = errorReference resolvedCallableReferenceAtom.resultingReference = errorReference
return false return applicability to false
} }
reducedCandidates.size > 1 -> { reducedCandidates.size > 1 -> {
if (resolvedCallableReferenceAtom.hasBeenPostponed) { if (resolvedCallableReferenceAtom.hasBeenPostponed) {
@@ -393,10 +393,10 @@ class FirCallResolver(
callableReferenceAccess.source callableReferenceAccess.source
) )
resolvedCallableReferenceAtom.resultingReference = errorReference resolvedCallableReferenceAtom.resultingReference = errorReference
return false return applicability to false
} }
resolvedCallableReferenceAtom.hasBeenPostponed = true resolvedCallableReferenceAtom.hasBeenPostponed = true
return true return applicability to true
} }
} }
@@ -417,7 +417,7 @@ class FirCallResolver(
resolvedCallableReferenceAtom.resultingReference = reference resolvedCallableReferenceAtom.resultingReference = reference
resolvedCallableReferenceAtom.resultingTypeForCallableReference = chosenCandidate.resultingTypeForCallableReference resolvedCallableReferenceAtom.resultingTypeForCallableReference = chosenCandidate.resultingTypeForCallableReference
return true return applicability to true
} }
fun resolveDelegatingConstructorCall( fun resolveDelegatingConstructorCall(
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name 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.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.types.AbstractNullabilityChecker import org.jetbrains.kotlin.types.AbstractNullabilityChecker
abstract class ResolutionStage { abstract class ResolutionStage {
@@ -179,8 +180,15 @@ internal object EagerResolveOfCallableReferences : CheckerStage() {
if (candidate.postponedAtoms.isEmpty()) return if (candidate.postponedAtoms.isEmpty()) return
for (atom in candidate.postponedAtoms) { for (atom in candidate.postponedAtoms) {
if (atom is ResolvedCallableReferenceAtom) { 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) sink.yieldDiagnostic(InapplicableCandidate)
} else when (applicability) {
CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY ->
candidate.addDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic)
else -> {
}
} }
} }
} }
@@ -20,6 +20,6 @@ public interface Executor {
fun f(): String = "test" fun f(): String = "test"
class A { class A {
fun schedule1(e: Executor): Future<String> = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>e.submit(::f)<!> fun schedule1(e: Executor): Future<String> = e.submit(::f)
fun schedule2(e: Executor): Future<String> = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>e.submit { f() }<!> fun schedule2(e: Executor): Future<String> = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>e.submit { f() }<!>
} }