[FIR] Keep all failed resolution candidates and fully resolve them
Previously, when a candidate was found with an applicability that is better than the current best applicability, all previous candidates were thrown away. Now we keep them, unless the new applicability is successful. If no successful candidates are found, we fully resolve all the unsuccessful ones and select the ones with the least bad applicability. This improves diagnostics for unresolved calls. #KT-57844 Fixed
This commit is contained in:
committed by
Space Team
parent
451daaa7c5
commit
b2fa104081
@@ -1,5 +1,5 @@
|
||||
object A1<!CONSTRUCTOR_IN_OBJECT!>()<!> {
|
||||
<!CONSTRUCTOR_IN_OBJECT!>constructor(x: Int = "", y: Int)<!> : <!NONE_APPLICABLE!>this<!>() {
|
||||
<!CONSTRUCTOR_IN_OBJECT!>constructor(x: Int = "", y: Int)<!> : <!UNRESOLVED_REFERENCE!>this<!>() {
|
||||
x + y
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,6 +11,6 @@ fun test() {
|
||||
<!NONE_APPLICABLE!>foo<!>(1, 2)
|
||||
foo(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
|
||||
<!NONE_APPLICABLE!>bar<!>(1, 2)
|
||||
bar(1, <!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
<!NONE_APPLICABLE!>bar<!>()
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -94,7 +94,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x == null) {
|
||||
x<!UNSAFE_CALL!>.<!>toString("")
|
||||
x.<!NONE_APPLICABLE!>toString<!>("")
|
||||
}
|
||||
|
||||
""
|
||||
@@ -134,7 +134,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING!>x === null<!>) {
|
||||
x<!UNSAFE_CALL!>.<!>toString("")
|
||||
x.<!NONE_APPLICABLE!>toString<!>("")
|
||||
}
|
||||
|
||||
""
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ fun <T: Any> joinT(x: Comparable<*>, y: T): T? {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val x2 = <!NONE_APPLICABLE!>joinT<!>(Unit, "2")
|
||||
val x2 = joinT(<!ARGUMENT_TYPE_MISMATCH!>Unit<!>, "2")
|
||||
checkSubtype<String?>(x2)
|
||||
}
|
||||
|
||||
+5
-5
@@ -274,8 +274,8 @@ fun poll76() {
|
||||
}
|
||||
|
||||
fun poll8() {
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar<!> <!NONE_APPLICABLE!>in<!> <!NONE_APPLICABLE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo<!>)
|
||||
<!NO_VALUE_FOR_PARAMETER!>inv()<!>
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar<!> <!INAPPLICABLE_CANDIDATE!>in<!> <!INAPPLICABLE_CANDIDATE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo<!>)
|
||||
<!UNRESOLVED_REFERENCE!>inv<!>()
|
||||
}
|
||||
|
||||
fun poll81() {
|
||||
@@ -284,8 +284,8 @@ fun poll81() {
|
||||
}
|
||||
|
||||
fun poll82() {
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar3<!> <!NONE_APPLICABLE!>in<!> <!NONE_APPLICABLE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo3<!>)
|
||||
<!NO_VALUE_FOR_PARAMETER!>inv()<!>
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar3<!> <!INAPPLICABLE_CANDIDATE!>in<!> <!INAPPLICABLE_CANDIDATE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo3<!>)
|
||||
<!UNRESOLVED_REFERENCE!>inv<!>()
|
||||
}
|
||||
|
||||
fun poll83() {
|
||||
@@ -294,7 +294,7 @@ fun poll83() {
|
||||
}
|
||||
|
||||
fun poll84() {
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar5<!> <!NONE_APPLICABLE!>in<!> <!NONE_APPLICABLE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo5<!>)
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar5<!> <!INAPPLICABLE_CANDIDATE!>in<!> <!INAPPLICABLE_CANDIDATE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo5<!>)
|
||||
inv
|
||||
}
|
||||
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
fun f(s: String, t: String) = s + t
|
||||
|
||||
// MODULE: m2
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
fun f(s: String, t: String) = t + s
|
||||
|
||||
// MODULE: m3(m1, m2)
|
||||
// FILE: c.kt
|
||||
import p.f
|
||||
|
||||
fun test() {
|
||||
// There should be no "none applicable" error here
|
||||
<!NONE_APPLICABLE!>f<!>(
|
||||
<!SYNTAX!><!>}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ fun <T : Bar, T1> foo(x : Int) {}
|
||||
fun <T1, T : Foo> foo(x : Long) {}
|
||||
|
||||
fun f(): Unit {
|
||||
<!NONE_APPLICABLE!>foo<!><Int, Int>(1)
|
||||
foo<<!UPPER_BOUND_VIOLATED!>Int<!>, Int>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// SKIP_TXT
|
||||
|
||||
// FILE: MyJClass.java
|
||||
|
||||
public class MyJClass {
|
||||
public void meth(int pathname) {}
|
||||
private void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: MyJClass2.java
|
||||
|
||||
public class MyJClass2 {
|
||||
public void meth(int pathname) {}
|
||||
public void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun test1(myJClass: MyJClass) {
|
||||
myJClass.meth(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
|
||||
fun test2(myJClass: MyJClass2) {
|
||||
myJClass.meth(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// SKIP_TXT
|
||||
|
||||
// FILE: MyJClass.java
|
||||
|
||||
public class MyJClass {
|
||||
public void meth(int pathname) {}
|
||||
private void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: MyJClass2.java
|
||||
|
||||
public class MyJClass2 {
|
||||
public void meth(int pathname) {}
|
||||
public void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun test1(myJClass: MyJClass) {
|
||||
myJClass.meth(<!TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
|
||||
fun test2(myJClass: MyJClass2) {
|
||||
myJClass.meth(<!TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
Vendored
+1
-1
@@ -7,7 +7,7 @@ class SomeClass
|
||||
|
||||
fun test(identifier: SomeClass, fn: String.() -> Unit) {
|
||||
<!NONE_APPLICABLE!>identifier<!>()
|
||||
identifier(<!NO_VALUE_FOR_PARAMETER!>123)<!>
|
||||
<!NONE_APPLICABLE!>identifier<!>(123)
|
||||
identifier(1, <!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
<!ARGUMENT_TYPE_MISMATCH!>1<!>.fn()
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ fun overloadedFun(arg: String, vararg args: String) = X1
|
||||
fun overloadedFun(arg: String, vararg args: String, flag: Boolean = true) = X2
|
||||
|
||||
val test1a: X1 = overloadedFun("", "")
|
||||
val test1b: X1 = <!NONE_APPLICABLE!>overloadedFun<!>("", args = "")
|
||||
val test1b: X1 = overloadedFun("", args = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>)
|
||||
val test1c: X2 = overloadedFun("", "", "", flag = true)
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ val y2: B<Int> = B("")
|
||||
val y3: B<Int> = B<Int>(1)
|
||||
val y4: B<Int> = B<Int>("")
|
||||
|
||||
val y5: B<String> = <!NONE_APPLICABLE!>B<!><String>(1)
|
||||
val y5: B<String> = B<String>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
val y6: B<String> = B<String>("")
|
||||
val y7: B<String> = <!TYPE_MISMATCH, TYPE_MISMATCH!>B(1)<!>
|
||||
val y8: B<String> = B("")
|
||||
|
||||
@@ -6,9 +6,9 @@ class A0<T1, T2> {
|
||||
|
||||
constructor(x: T1, y: T2, z: T2): this(x, 1) // ok, delegates to constructor(x: T1, y: Int)
|
||||
|
||||
constructor(x: T1, y: Int): <!NONE_APPLICABLE!>this<!>(x, "")
|
||||
constructor(x: T1, y: Int): this(x, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
constructor(x: T1): this(x, 1)
|
||||
constructor(x: T1, y: T2, z: String): <!NONE_APPLICABLE!>this<!>(y, x)
|
||||
constructor(x: T1, y: T2, z: String): this(<!ARGUMENT_TYPE_MISMATCH!>y<!>, <!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
||||
}
|
||||
|
||||
class A1<T1, T2> : B<T1, T2> {
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ fun bar(arg: Long?): Long {
|
||||
return i<!UNSAFE_CALL!>--<!> <!UNSAFE_OPERATOR_CALL!>+<!> i
|
||||
}
|
||||
if (i++ == 7L) {
|
||||
return i++ <!UNSAFE_OPERATOR_CALL!>+<!> i
|
||||
return i++ <!NONE_APPLICABLE!>+<!> i
|
||||
}
|
||||
return 0L
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ fun testLong(@ImplicitIntegerCoercion x: ULong) = x
|
||||
|
||||
fun box(): String = when {
|
||||
test(5) != 5.toUInt() -> "Fail: test(5)"
|
||||
<!NONE_APPLICABLE!>test<!>(5L) != 5L.toULong() -> "Fail: test(5L)"
|
||||
<!EQUALITY_NOT_APPLICABLE!>test(<!ARGUMENT_TYPE_MISMATCH!>5L<!>) != 5L.toULong()<!> -> "Fail: test(5L)"
|
||||
testLong(5) != 5L.toULong() -> "Fail: test(5L)"
|
||||
testLong(<!ARGUMENT_TYPE_MISMATCH!>5L<!>) != 5L.toULong() -> "Fail: test(5L)"
|
||||
else -> "OK"
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ fun foo() {
|
||||
<!NEW_INFERENCE_ERROR!>select(1, 1u)<!> checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Comparable<*>>() }
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>id(1)<!>)
|
||||
|
||||
1 <!NONE_APPLICABLE!>+<!> 1u
|
||||
(1u <!NONE_APPLICABLE!>+<!> 1) <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { _<UInt>() }
|
||||
1 + <!ARGUMENT_TYPE_MISMATCH!>1u<!>
|
||||
(1u + <!ARGUMENT_TYPE_MISMATCH!>1<!>) checkType { _<UInt>() }
|
||||
|
||||
id<UInt>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,6 +9,6 @@ fun test() {
|
||||
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>fUShort<!>()
|
||||
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>fULong<!>()
|
||||
|
||||
3000000000 <!NONE_APPLICABLE!>until<!> 3000000004UL
|
||||
0 <!NONE_APPLICABLE!>until<!> 10u
|
||||
3000000000 until <!ARGUMENT_TYPE_MISMATCH!>3000000004UL<!>
|
||||
0 until <!ARGUMENT_TYPE_MISMATCH!>10u<!>
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ fun test() {
|
||||
foo(1) checkType { _<Int>() }
|
||||
foo(1u) checkType { _<String>() }
|
||||
|
||||
<!NONE_APPLICABLE!>foo<!>(2147483648) <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { _<String>() }
|
||||
foo(<!ARGUMENT_TYPE_MISMATCH!>2147483648<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
|
||||
foo(2147483647 + 1) checkType { _<Int>() }
|
||||
|
||||
fooByte(1) checkType { _<Int>() }
|
||||
|
||||
Reference in New Issue
Block a user