[FIR] When call candidates resolve to errors, select the least bad ones

This fixes a scenario when INVISIBLE_REFERENCE is suppressed, but we
resolved to the wrong overload because when none of the candidates were
applicable, more or less the first one was chosen.

Because we call `fullyProcessCandidate` on the candidates, their
applicability can change which can lead to a situation where the
applicability of a ConeAmbiguityError is different to all its
candidates. The changes in coneDiagnosticToFirDiagnostic.kt account for
that, otherwise code like candidates.first { it.applicability ==
CandidateApplicability.UNSAFE_CALL } can throw NoSuchElementException.

#KT-57776 Fixed
This commit is contained in:
Kirill Rakhman
2023-04-05 17:21:24 +02:00
committed by Space Team
parent 09ea0ef757
commit 592baee852
24 changed files with 345 additions and 52 deletions
@@ -345,22 +345,22 @@ class case_14_class {
if (!funWithReturnsTrueAndInvertCondition(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (funWithReturnsNotNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) == null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (funWithReturnsNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) != null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
}
}
@@ -414,26 +414,26 @@ class case_17_class {
if (contracts.case_17_1(value_1, value_2, o.prop_1, this.prop_1)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (contracts.case_17_2(value_1, value_2, o.prop_1, this.prop_1)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (contracts.case_17_3(value_1, value_2, o.prop_1, this.prop_1) == null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (contracts.case_17_4(value_1, value_2, o.prop_1, this.prop_1) != null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(this.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
}
}
@@ -37,7 +37,7 @@ class case_5_class {
funWithReturns(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null)
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
}
@@ -130,22 +130,22 @@ class case_10_class {
if (funWithReturnsTrue(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (!funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (funWithReturnsNotNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) != null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (funWithReturnsNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) == null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
}
}
@@ -105,7 +105,7 @@ class case_3_class {
contracts.case_3(value_1, value_2, o.prop_1, this.prop_1)
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
}
@@ -158,22 +158,22 @@ class case_6_class {
if (contracts.case_6_1(value_1, value_2, o.prop_1, this.prop_1)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (!contracts.case_6_2(value_1, value_2, o.prop_1, this.prop_1)) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (contracts.case_6_3(value_1, value_2, o.prop_1, this.prop_1) == null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
if (contracts.case_6_4(value_1, value_2, o.prop_1, this.prop_1) != null) {
println(value_1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>dec<!>())
println(value_2?.toByte())
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
println(o.prop_1<!UNSAFE_CALL!>.<!>plus(3))
}
}
}