[FIR] Fix candidate success check by checking if no diagnostic is unsuccessful
Checking the current applicability isn't enough because in the presence of multiple diagnostics, the lowest applicability can be successful but a higher one isn't. #KT-63147 Fixed
This commit is contained in:
committed by
Space Team
parent
0d36462c58
commit
6b7eeec181
+6
@@ -28455,6 +28455,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt46969.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lowPriority.kt")
|
||||
public void testLowPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/lowPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("markedReceiverWithCapturedTypeArgument.kt")
|
||||
public void testMarkedReceiverWithCapturedTypeArgument() throws Exception {
|
||||
|
||||
+6
@@ -28455,6 +28455,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt46969.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lowPriority.kt")
|
||||
public void testLowPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/lowPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("markedReceiverWithCapturedTypeArgument.kt")
|
||||
public void testMarkedReceiverWithCapturedTypeArgument() throws Exception {
|
||||
|
||||
+6
@@ -28443,6 +28443,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt46969.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lowPriority.kt")
|
||||
public void testLowPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/lowPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("markedReceiverWithCapturedTypeArgument.kt")
|
||||
public void testMarkedReceiverWithCapturedTypeArgument() throws Exception {
|
||||
|
||||
+6
@@ -28455,6 +28455,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt46969.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lowPriority.kt")
|
||||
public void testLowPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/lowPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("markedReceiverWithCapturedTypeArgument.kt")
|
||||
public void testMarkedReceiverWithCapturedTypeArgument() throws Exception {
|
||||
|
||||
@@ -776,18 +776,18 @@ class FirCallResolver(
|
||||
|
||||
candidates.size > 1 -> ConeAmbiguityError(name, applicability, candidates)
|
||||
|
||||
!applicability.isSuccess -> {
|
||||
else -> {
|
||||
val candidate = candidates.single()
|
||||
if (needTreatErrorCandidateAsResolved(candidate)) {
|
||||
@OptIn(CodeFragmentAdjustment::class)
|
||||
candidate.resetToResolved()
|
||||
null
|
||||
} else {
|
||||
createConeDiagnosticForCandidateWithError(applicability, candidate)
|
||||
runIf(!candidate.isSuccessful) {
|
||||
if (needTreatErrorCandidateAsResolved(candidate)) {
|
||||
@OptIn(CodeFragmentAdjustment::class)
|
||||
candidate.resetToResolved()
|
||||
null
|
||||
} else {
|
||||
createConeDiagnosticForCandidateWithError(applicability, candidate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (diagnostic != null) {
|
||||
|
||||
@@ -129,8 +129,15 @@ class Candidate(
|
||||
_diagnostics.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that [currentApplicability]`.isSuccessful == true` doesn't imply [isSuccessful].
|
||||
*
|
||||
* This is because [currentApplicability] is equal to the lowest [ResolutionDiagnostic.applicability] of all [diagnostics],
|
||||
* but in presence of more than one diagnostic, the lowest one can be successful while a higher one isn't, e.g., the combination
|
||||
* of [CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY] and [CandidateApplicability.RESOLVED_WITH_ERROR].
|
||||
*/
|
||||
val isSuccessful: Boolean
|
||||
get() = currentApplicability.isSuccess && (!systemInitialized || !system.hasContradiction)
|
||||
get() = diagnostics.all { it.applicability.isSuccess } && (!systemInitialized || !system.hasContradiction)
|
||||
|
||||
var passedStages: Int = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER, -ERROR_SUPPRESSION
|
||||
@DslMarker
|
||||
annotation class Ann
|
||||
|
||||
@Ann
|
||||
class A {
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@kotlin.internal.LowPriorityInOverloadResolution
|
||||
fun a() = 1
|
||||
}
|
||||
|
||||
@Ann
|
||||
class B {
|
||||
fun b() = 2
|
||||
}
|
||||
|
||||
fun foo(x: A.() -> Unit) {}
|
||||
fun bar(x: B.() -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
foo {
|
||||
a()
|
||||
bar {
|
||||
<!DSL_SCOPE_VIOLATION!>a<!>()
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+6
@@ -30443,6 +30443,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt46969.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lowPriority.kt")
|
||||
public void testLowPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/lowPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("markedReceiverWithCapturedTypeArgument.kt")
|
||||
public void testMarkedReceiverWithCapturedTypeArgument() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user