[FIR] Report NONE_APPLICABLE on callable references with multiple failed candidates

This commit is contained in:
Kirill Rakhman
2023-11-07 15:33:31 +01:00
committed by Space Team
parent 6d2ab92d91
commit d54068b8ab
12 changed files with 33 additions and 31 deletions
@@ -57,6 +57,6 @@ FILE: main.kt
R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|)
R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|)
R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
R|/foo2<Inapplicable(INAPPLICABLE): /foo2>#|(Q|KotlinClass2|::<Unresolved reference: bar>#)
R|/foo2<Inapplicable(INAPPLICABLE): /foo2>#|(Q|KotlinClass2|::<Ambiguity: bar, [/KotlinClass2.bar, /KotlinClass2.Companion.bar]>#)
R|/foo3|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
}
@@ -40,7 +40,7 @@ fun main() {
foo1(KotlinClass2::bar)
// Type mismatch
foo2(KotlinClass2::<!UNRESOLVED_REFERENCE!>bar<!>)
foo2(KotlinClass2::<!NONE_APPLICABLE!>bar<!>)
foo3(KotlinClass2::bar)
}
@@ -402,7 +402,7 @@ class FirCallResolver(
}
val (reducedCandidates, newApplicability) = reduceCandidates(result, callableReferenceAccess.explicitReceiver)
val isSuccess = reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isSuccessful }
val nonEmptyAndAllSuccessful = reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isSuccessful }
val applicability = newApplicability ?: result.currentApplicability
(callableReferenceAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
@@ -412,14 +412,16 @@ class FirCallResolver(
resolvedCallableReferenceAtom.hasBeenResolvedOnce = true
when {
!isSuccess -> {
!nonEmptyAndAllSuccessful -> {
val errorReference = buildReferenceWithErrorCandidate(
info,
when {
applicability == CandidateApplicability.K2_UNSUPPORTED -> {
val unsupportedResolutionDiagnostic = reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported
val unsupportedResolutionDiagnostic =
reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported
ConeUnsupported(unsupportedResolutionDiagnostic?.message ?: "", unsupportedResolutionDiagnostic?.source)
}
reducedCandidates.size > 1 -> ConeAmbiguityError(info.name, applicability, reducedCandidates)
reducedCandidates.size == 1 -> createConeDiagnosticForCandidateWithError(applicability, reducedCandidates.single())
else -> ConeUnresolvedReferenceError(info.name)
},
@@ -10,7 +10,7 @@ fun test() {
val x2: (Int) -> Unit = baz(id(::foo), ::foo)
val x3: (Int) -> Unit = baz(id(::foo), id(id(::foo)))
val x4: (String) -> Unit = baz(id(::foo), id(id(::foo)))
val x5: (Double) -> Unit = baz(id(::<!UNRESOLVED_REFERENCE!>foo<!>), id(id(::<!UNRESOLVED_REFERENCE!>foo<!>)))
val x5: (Double) -> Unit = baz(id(::<!NONE_APPLICABLE!>foo<!>), id(id(::<!NONE_APPLICABLE!>foo<!>)))
id<(Int) -> Unit>(id(id(::foo)))
@@ -16,7 +16,7 @@ fun test1() {
baz<String>(::foo).checkType { _<String?>() }
baz<Boolean>(::foo).checkType { _<Boolean?>() }
val b1: Int = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>baz(::<!UNRESOLVED_REFERENCE!>foo<!>)<!>
val b2: String = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>baz(::<!UNRESOLVED_REFERENCE!>foo<!>)<!>
val b3: Boolean = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>baz(::<!UNRESOLVED_REFERENCE!>foo<!>)<!>
val b1: Int = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>baz(::<!NONE_APPLICABLE!>foo<!>)<!>
val b2: String = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>baz(::<!NONE_APPLICABLE!>foo<!>)<!>
val b3: Boolean = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>baz(::<!NONE_APPLICABLE!>foo<!>)<!>
}
@@ -4,9 +4,9 @@ fun test() {
val a1: Array<Double.(Double) -> Double> = arrayOf(Double::plus, Double::minus)
val a2: Array<Double.(Int) -> Double> = arrayOf(Double::plus, Double::minus)
val a3: Array<Int.(Int) -> Double> = arrayOf(Double::<!UNRESOLVED_REFERENCE!>plus<!>, Double::<!UNRESOLVED_REFERENCE!>minus<!>)
val a4: Array<Int.(Double) -> Double> = arrayOf(Int::plus, Double::<!UNRESOLVED_REFERENCE!>minus<!>)
val a5: Array<Double.(Double) -> Double> = arrayOf(Double::plus, Int::<!UNRESOLVED_REFERENCE!>minus<!>)
val a3: Array<Int.(Int) -> Double> = arrayOf(Double::<!NONE_APPLICABLE!>plus<!>, Double::<!NONE_APPLICABLE!>minus<!>)
val a4: Array<Int.(Double) -> Double> = arrayOf(Int::plus, Double::<!NONE_APPLICABLE!>minus<!>)
val a5: Array<Double.(Double) -> Double> = arrayOf(Double::plus, Int::<!NONE_APPLICABLE!>minus<!>)
}
fun foo(x: Int) {}
@@ -17,5 +17,5 @@ fun <T> bar(x: T, f: (T) -> Unit) {}
fun test2() {
bar(1, ::foo)
bar("", ::foo)
bar(1.0, ::<!UNRESOLVED_REFERENCE!>foo<!>)
bar(1.0, ::<!NONE_APPLICABLE!>foo<!>)
}
@@ -7,4 +7,4 @@ fun foo(s: String) {}
val x1 = ofType<() -> Unit>(::foo)
val x2 = ofType<(String) -> Unit>(::foo)
val x3 = ofType<(Int) -> Unit>(::<!UNRESOLVED_REFERENCE!>foo<!>)
val x3 = ofType<(Int) -> Unit>(::<!NONE_APPLICABLE!>foo<!>)
@@ -8,4 +8,4 @@ fun foo(s: String) {}
val x1 = apply(1, ::foo)
val x2 = apply("hello", ::foo)
val x3 = apply(true, ::<!UNRESOLVED_REFERENCE!>foo<!>)
val x3 = apply(true, ::<!NONE_APPLICABLE!>foo<!>)
+12 -12
View File
@@ -27,22 +27,22 @@ interface Foo {
// CR on property with to receivers are forbidden
fun <T: Foo> test() {
// with LHS and property
bar8<T>(Foo::<!UNRESOLVED_REFERENCE!>x1<!>)
bar8<Foo>(Foo::<!UNRESOLVED_REFERENCE!>x1<!>)
bar8(Foo::<!UNRESOLVED_REFERENCE!>x1<!>)
bar8<T>(Foo::<!NONE_APPLICABLE!>x1<!>)
bar8<Foo>(Foo::<!NONE_APPLICABLE!>x1<!>)
bar8(Foo::<!NONE_APPLICABLE!>x1<!>)
// with LHS and mutable property
bar8<T>(Foo::<!UNRESOLVED_REFERENCE!>x2<!>)
bar8<Foo>(Foo::<!UNRESOLVED_REFERENCE!>x2<!>)
bar8(Foo::<!UNRESOLVED_REFERENCE!>x2<!>)
bar8<T>(Foo::<!NONE_APPLICABLE!>x2<!>)
bar8<Foo>(Foo::<!NONE_APPLICABLE!>x2<!>)
bar8(Foo::<!NONE_APPLICABLE!>x2<!>)
// with LHS and propery + mutable property (mixed)
bar8<T>(Foo::<!UNRESOLVED_REFERENCE!>x3<!>)
bar8<Foo>(Foo::<!UNRESOLVED_REFERENCE!>x3<!>)
bar8(Foo::<!UNRESOLVED_REFERENCE!>x3<!>)
bar9<T>(Foo::<!UNRESOLVED_REFERENCE!>x3<!>)
bar9<Foo>(Foo::<!UNRESOLVED_REFERENCE!>x3<!>)
bar9(Foo::<!UNRESOLVED_REFERENCE!>x3<!>)
bar8<T>(Foo::<!NONE_APPLICABLE!>x3<!>)
bar8<Foo>(Foo::<!NONE_APPLICABLE!>x3<!>)
bar8(Foo::<!NONE_APPLICABLE!>x3<!>)
bar9<T>(Foo::<!NONE_APPLICABLE!>x3<!>)
bar9<Foo>(Foo::<!NONE_APPLICABLE!>x3<!>)
bar9(Foo::<!NONE_APPLICABLE!>x3<!>)
}
}
@@ -6,5 +6,5 @@ fun foo(i: Long) {}
fun bar(f: (Boolean) -> Unit) {}
fun test() {
bar(::<!UNRESOLVED_REFERENCE!>foo<!>)
bar(::<!NONE_APPLICABLE!>foo<!>)
}
@@ -5,5 +5,5 @@ fun foo(x: Float) = 10f
fun foo(x: String) = ""
fun main() {
bar(::<!UNRESOLVED_REFERENCE!>foo<!>) // no report about unresolved callable reference for `foo`
bar(::<!NONE_APPLICABLE!>foo<!>) // no report about unresolved callable reference for `foo`
}
@@ -25,7 +25,7 @@ class Case1() {
}
fun case() {
Companion(::<!UNRESOLVED_REFERENCE!>x<!>)
Companion(::<!NONE_APPLICABLE!>x<!>)
}
val x = ""
@@ -41,7 +41,7 @@ class Case2() {
}
fun case() {
Companion(::<!UNRESOLVED_REFERENCE!>x<!>)
Companion(::<!NONE_APPLICABLE!>x<!>)
}
val x = C()