[FIR] Move tracking candidate applicability from CheckerSink to Candidate
This commit is contained in:
+1
-1
@@ -158,7 +158,7 @@ class FirOverloadByLambdaReturnTypeResolver(
|
||||
val successfulCandidates = mutableSetOf<Candidate>()
|
||||
|
||||
for (candidate in candidates) {
|
||||
if (candidate.isSuccessful()) {
|
||||
if (candidate.isSuccessful) {
|
||||
successfulCandidates += candidate
|
||||
} else {
|
||||
errorCandidates += candidate
|
||||
|
||||
@@ -109,17 +109,22 @@ class Candidate(
|
||||
lateinit var typeArgumentMapping: TypeArgumentMapping
|
||||
val postponedAtoms = mutableListOf<PostponedResolvedAtom>()
|
||||
|
||||
val diagnostics: MutableList<ResolutionDiagnostic> = mutableListOf()
|
||||
var currentApplicability = CandidateApplicability.RESOLVED
|
||||
private set
|
||||
|
||||
private val _diagnostics: MutableList<ResolutionDiagnostic> = mutableListOf()
|
||||
val diagnostics: List<ResolutionDiagnostic>
|
||||
get() = _diagnostics
|
||||
|
||||
fun addDiagnostic(diagnostic: ResolutionDiagnostic) {
|
||||
diagnostics += diagnostic
|
||||
_diagnostics += diagnostic
|
||||
if (diagnostic.applicability < currentApplicability) {
|
||||
currentApplicability = diagnostic.applicability
|
||||
}
|
||||
}
|
||||
|
||||
fun isSuccessful(): Boolean {
|
||||
if (system.hasContradiction) return false
|
||||
val currentApplicability = diagnostics.map { it.applicability }.minOrNull() ?: CandidateApplicability.RESOLVED
|
||||
return currentApplicability.isSuccess
|
||||
}
|
||||
val isSuccessful: Boolean
|
||||
get() = currentApplicability.isSuccess && (!systemInitialized || !system.hasContradiction)
|
||||
|
||||
var passedStages: Int = 0
|
||||
|
||||
|
||||
@@ -32,20 +32,12 @@ suspend inline fun CheckerSink.yieldDiagnostic(diagnostic: ResolutionDiagnostic)
|
||||
}
|
||||
|
||||
class CheckerSinkImpl(
|
||||
private val candidate: Candidate,
|
||||
var continuation: Continuation<Unit>? = null,
|
||||
val stopOnFirstError: Boolean = true
|
||||
val stopOnFirstError: Boolean = true,
|
||||
) : CheckerSink() {
|
||||
var currentApplicability = CandidateApplicability.RESOLVED
|
||||
private set
|
||||
|
||||
private val _diagnostics: MutableList<ResolutionDiagnostic> = mutableListOf()
|
||||
|
||||
val diagnostics: List<ResolutionDiagnostic>
|
||||
get() = _diagnostics
|
||||
|
||||
override fun reportDiagnostic(diagnostic: ResolutionDiagnostic) {
|
||||
_diagnostics += diagnostic
|
||||
if (diagnostic.applicability < currentApplicability) currentApplicability = diagnostic.applicability
|
||||
candidate.addDiagnostic(diagnostic)
|
||||
}
|
||||
|
||||
@PrivateForInline
|
||||
@@ -55,6 +47,5 @@ class CheckerSinkImpl(
|
||||
}
|
||||
|
||||
override val needYielding: Boolean
|
||||
get() = stopOnFirstError && !currentApplicability.isSuccess
|
||||
|
||||
get() = stopOnFirstError && !candidate.isSuccessful
|
||||
}
|
||||
|
||||
+3
-4
@@ -15,7 +15,7 @@ import kotlin.coroutines.resume
|
||||
|
||||
class ResolutionStageRunner {
|
||||
fun processCandidate(candidate: Candidate, context: ResolutionContext, stopOnFirstError: Boolean = true): CandidateApplicability {
|
||||
val sink = CheckerSinkImpl(stopOnFirstError = stopOnFirstError)
|
||||
val sink = CheckerSinkImpl(candidate, stopOnFirstError = stopOnFirstError)
|
||||
var finished = false
|
||||
sink.continuation = suspend {
|
||||
candidate.callInfo.callKind.resolutionSequence.forEachIndexed { index, stage ->
|
||||
@@ -35,11 +35,10 @@ class ResolutionStageRunner {
|
||||
|
||||
while (!finished) {
|
||||
sink.continuation!!.resume(Unit)
|
||||
if (!sink.currentApplicability.isSuccess) {
|
||||
if (!candidate.isSuccessful) {
|
||||
break
|
||||
}
|
||||
}
|
||||
candidate.diagnostics += sink.diagnostics
|
||||
return sink.currentApplicability
|
||||
return candidate.currentApplicability
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -162,7 +162,7 @@ class PostponedArgumentsAnalyzer(
|
||||
|
||||
returnArguments.forEach { c.addSubsystemFromExpression(it) }
|
||||
|
||||
val checkerSink: CheckerSink = CheckerSinkImpl()
|
||||
val checkerSink: CheckerSink = CheckerSinkImpl(candidate)
|
||||
|
||||
var hasExpressionInReturnArguments = false
|
||||
val lambdaReturnType = lambda.returnType.let(substitute).takeUnless { it.isUnit }
|
||||
|
||||
Vendored
+2
-2
@@ -11,10 +11,10 @@ fun test() {
|
||||
const val <T> a3 = 0
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit val <T> a4 = 0<!>
|
||||
val <T> a5 by Delegate<Int>()
|
||||
val <T> a6 by <!INAPPLICABLE_CANDIDATE!>Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()<!>
|
||||
val <T> a6 by Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()
|
||||
}
|
||||
|
||||
class Delegate<F> {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = ""
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -11,10 +11,10 @@ fun test() {
|
||||
const val <T> a3 = 0
|
||||
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit val <T> a4 = 0<!>
|
||||
val <T> a5 by Delegate<Int>()
|
||||
val <T> a6 by <!INAPPLICABLE_CANDIDATE!>Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()<!>
|
||||
val <T> a6 by Delegate<<!UNRESOLVED_REFERENCE!>T<!>>()
|
||||
}
|
||||
|
||||
class Delegate<F> {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = ""
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class B {
|
||||
val c by <!INAPPLICABLE_CANDIDATE!><!INAPPLICABLE_CANDIDATE!>Delegate<!>(<!UNRESOLVED_REFERENCE!>ag<!>)<!>
|
||||
val c by <!INAPPLICABLE_CANDIDATE!>Delegate<!>(<!UNRESOLVED_REFERENCE!>ag<!>)
|
||||
}
|
||||
|
||||
class Delegate<T: Any>(val init: T) {
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ fun interface Bar {
|
||||
operator fun Bar.plus(b: Bar): String = invoke() + b.invoke()
|
||||
|
||||
fun box(): String {
|
||||
return { "O" } <!INAPPLICABLE_CANDIDATE!>+<!> { "K" }
|
||||
return { "O" } + { "K" }
|
||||
}
|
||||
|
||||
+4
-4
@@ -14,14 +14,14 @@ class A<T> {
|
||||
|
||||
fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo1<!>(Out<CharSequence>())
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo1<!><Out<CharSequence>>(Out())
|
||||
a.foo1<<!UPPER_BOUND_VIOLATED!>Out<CharSequence><!>>(Out())
|
||||
|
||||
a.foo1(Out())
|
||||
a.foo1(Out<Nothing>())
|
||||
|
||||
a.foo2(Inv())
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo2<!>(Inv<CharSequence>())
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo2<!><Inv<CharSequence>>(Inv())
|
||||
a.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(Inv())
|
||||
|
||||
a.foo3(In())
|
||||
a.foo3(In<CharSequence>())
|
||||
@@ -33,11 +33,11 @@ fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||
|
||||
b.foo2(Inv())
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo2<!>(Inv<CharSequence>())
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo2<!><Inv<CharSequence>>(Inv())
|
||||
b.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(Inv())
|
||||
|
||||
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo3<!>(In<CharSequence>())
|
||||
b.<!INAPPLICABLE_CANDIDATE!>foo3<!><In<CharSequence>>(In())
|
||||
b.foo3<<!UPPER_BOUND_VIOLATED!>In<CharSequence><!>>(In())
|
||||
|
||||
b.foo3(In<Any?>())
|
||||
b.foo3(In())
|
||||
|
||||
Reference in New Issue
Block a user