[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:
committed by
Space Team
parent
09ea0ef757
commit
592baee852
+3
-5
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.types.EmptyIntersectionTypeKind
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
|
||||
private fun ConeDiagnostic.toKtDiagnostic(
|
||||
@@ -68,14 +68,12 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
||||
is ConeAmbiguityError -> when {
|
||||
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
|
||||
applicability == CandidateApplicability.UNSAFE_CALL -> {
|
||||
val candidate = candidates.first { it.applicability == CandidateApplicability.UNSAFE_CALL }
|
||||
val unsafeCall = candidate.diagnostics.firstIsInstance<UnsafeCall>()
|
||||
val (unsafeCall, candidate) = candidates.firstNotNullOf { it.diagnostics.firstIsInstanceOrNull<UnsafeCall>()?.to(it) }
|
||||
mapUnsafeCallError(candidate, unsafeCall, source, qualifiedAccessSource)
|
||||
}
|
||||
|
||||
applicability == CandidateApplicability.UNSTABLE_SMARTCAST -> {
|
||||
val unstableSmartcast =
|
||||
this.candidates.first { it.applicability == CandidateApplicability.UNSTABLE_SMARTCAST }.diagnostics.firstIsInstance<UnstableSmartCast>()
|
||||
val unstableSmartcast = this.candidates.firstNotNullOf { it.diagnostics.firstIsInstanceOrNull<UnstableSmartCast>() }
|
||||
FirErrors.SMARTCAST_IMPOSSIBLE.createOn(
|
||||
unstableSmartcast.argument.source,
|
||||
unstableSmartcast.targetType,
|
||||
|
||||
Reference in New Issue
Block a user