[FIR] Threat some error candidate applicabilities with same priority
There is a thing that `CandidateCollector` adds error candidate to the list of resulting candidates only if its applicability at least the same as current applicability of the collector Also there is a problem, that deserialized symbol provider in CLI compiler and stub-based symbol provider in AA may return the same declarations in different order. This provokes the difference in the resulting set of candidates between the two modes: ``` val x by unresolved ``` During the resolution of this code compiler tries to find function `getValue`, and there are 6 of them in the stdlib. From them we are interseted in specific three: 1. `fun <K, V> Map<K, V>.getValue(key: R|K|): R|V|` 2. `inline operator fun <V, V1 : V> Map<in String, @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1` 3. `inline operator fun <V, V1 : V> MutableMap<in String, out @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1` - (1) is inapplicable with `INAPPLICABLE_ARGUMENTS_MAPPING_ERROR` - (2) and (3) are inapplicable with `INAPPLICABLE_WRONG_RECEIVER` - `INAPPLICABLE_ARGUMENTS_MAPPING_ERROR` is more specific applicability than `INAPPLICABLE_WRONG_RECEIVER` - CLI compiler always sees those functions in order 1 -> 2 -> 3 - AA providers sometimes returns them in order 2 -> 3 -> 1 So in CLI compilation candidates (2) and (3) are not added to the resulting set, as they are "less applicable" than (1), but in AA compilation they can be added to the set before (1), which causes sporadic change in FIR dump of `unsafeAssignmentExtra.kt` To workaround this problem it was decided to treat `INAPPLICABLE_ARGUMENTS_MAPPING_ERROR` and `INAPPLICABLE_WRONG_RECEIVER` applicabilities as "equally specific" ^KT-65218 Fixed
This commit is contained in:
committed by
Space Team
parent
d88092aa94
commit
30e2af7b66
+13
-1
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.INAPPLICABLE_ARGUMENTS_MAPPING_ERROR
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.shouldStopResolve
|
||||
|
||||
@@ -51,7 +53,17 @@ open class CandidateCollector(
|
||||
bestGroup = group
|
||||
}
|
||||
|
||||
if (applicability == currentApplicability && group == bestGroup) {
|
||||
/*
|
||||
* Here we would like to consider error candidates with `INAPPLICABLE_WRONG_RECEIVER` and `INAPPLICABLE_ARGUMENTS_MAPPING_ERROR` kinda
|
||||
* "same error level". Generally it's questionable which candidates we should keep and which of those applicabilities is more
|
||||
* specific and we should consider it during work on improvement of error reporting. But this particular check is needed
|
||||
* to fix the KT-65218, which provoked by different stdlib declarations order in CLI compilation mode and AA mode (see
|
||||
* the issue for more details)
|
||||
*/
|
||||
if (
|
||||
(applicability == currentApplicability && group == bestGroup) ||
|
||||
(currentApplicability == INAPPLICABLE_ARGUMENTS_MAPPING_ERROR && applicability == INAPPLICABLE_WRONG_RECEIVER)
|
||||
) {
|
||||
candidates.add(candidate)
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ class SomeClass
|
||||
fun test(identifier: SomeClass, fn: String.() -> Unit) {
|
||||
<!NONE_APPLICABLE!>identifier<!>()
|
||||
<!NONE_APPLICABLE!>identifier<!>(123)
|
||||
<!OPERATOR_MODIFIER_REQUIRED!>identifier<!>(<!ARGUMENT_TYPE_MISMATCH!>1<!>, <!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
<!NONE_APPLICABLE!>identifier<!>(1, 2)
|
||||
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>fn<!>()
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -60,7 +60,7 @@ FILE: unsafeAssignmentExtra.fir.kt
|
||||
}
|
||||
}
|
||||
|
||||
lval x: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/getValue, kotlin/getValue, kotlin/getValue, kotlin/collections/getValue]>by this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/Int|>|
|
||||
lval x: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/getValue, kotlin/getValue, kotlin/getValue, kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>by this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/Int|>|
|
||||
this@R|special/anonymous|.R|/change|<R|kotlin/Int|>(<L> = change@fun R|Foo<kotlin/Int>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/Int|>| = Int(99)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user