[FIR] Fixes for call conflict resolution
Let ConeCompositeConflictResolver pass the results of the previous resolver to the next one. Otherwise, we get false positive conflicts when a set of candidates can't be fully reduced by one resolver but could be resolved by the subsequent application of multiple ones. This change makes ConeCompositeConflictResolver order-dependent and thus, ConeOverloadConflictResolver must be invoked last, because it must work on a pre-filtered list. Also, let ConeEquivalentCallConflictResolver use FirStandardOverrideChecker instead of compareCallsByUsedArguments because it's stricter. This all fixes a false positive overload resolution ambiguity in common metadata compilation that is caused by stdlib using the new KMP format. Now stdlib metadata is in the classpath, and so declarations from the stdlib are returned from both MetadataSymbolProvider and KlibBasedSymbolProvider. This isn't a problem per se because duplicate candidates are filtered out by ConeEquivalentCallConflictResolver (K1 works analogously), but in the case of top-level functions with generic receivers like Collection<T>.toTypedArray, the check failed because of the direct comparison of receiver types. #KT-60943 Fixed
This commit is contained in:
committed by
Space Team
parent
86ef313233
commit
724d527fd8
+3
-3
@@ -36,7 +36,7 @@ fun case1() {
|
||||
val a: Boolean? = false
|
||||
checkSubtype<Boolean?>(a)
|
||||
val x4 = <!CONDITION_TYPE_MISMATCH!>a<!> && true
|
||||
x4 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>() }
|
||||
x4 checkType { check<Boolean>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 2
|
||||
@@ -44,7 +44,7 @@ fun case2() {
|
||||
val a: Any = false
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>a<!>
|
||||
val x4 = <!CONDITION_TYPE_MISMATCH!>a<!> && true
|
||||
x4 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>() }
|
||||
x4 checkType { check<Boolean>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
@@ -56,7 +56,7 @@ fun case3() {
|
||||
val x3 = a1 && <!CONDITION_TYPE_MISMATCH!>a2<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean")!>x3<!>
|
||||
|
||||
x3 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>() }
|
||||
x3 checkType { check<Boolean>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 4
|
||||
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-313
|
||||
* MAIN LINK: expressions, logical-conjunction-expression -> paragraph 2 -> sentence 1
|
||||
* PRIMARY LINKS: expressions, logical-conjunction-expression -> paragraph 2 -> sentence 2
|
||||
* NUMBER: 1
|
||||
* DESCRIPTION: Both operands of a logical conjunction expression must have a type which is a subtype of kotlin.Boolean
|
||||
* HELPERS: checkType
|
||||
*/
|
||||
|
||||
// MODULE: libModule
|
||||
// FILE: libModule/JavaClass.java
|
||||
package libModule;
|
||||
|
||||
public class JavaClass {
|
||||
public static boolean VALUE;
|
||||
|
||||
public static Object VALUE_OBJ = true;
|
||||
|
||||
public Boolean getValue ()
|
||||
{ return new Boolean ("true"); }
|
||||
}
|
||||
|
||||
// MODULE: mainModule(libModule)
|
||||
// FILE: KotlinClass.kt
|
||||
package mainModule
|
||||
import libModule.*
|
||||
import checkSubtype
|
||||
import checkType
|
||||
import check
|
||||
|
||||
fun foo() = run { false && JavaClass.VALUE && throw Exception() }
|
||||
|
||||
|
||||
// TESTCASE NUMBER: 1
|
||||
fun case1() {
|
||||
val a1 = false
|
||||
val a2 = JavaClass.VALUE
|
||||
val a3 = foo()
|
||||
val a4 = JavaClass().getValue()
|
||||
val a5 = JavaClass.VALUE_OBJ
|
||||
|
||||
checkSubtype<Boolean>(a1)
|
||||
checkSubtype<Boolean>(a2)
|
||||
checkSubtype<Boolean>(a3)
|
||||
checkSubtype<Boolean>(a4)
|
||||
|
||||
val x3 = a1 && a2 && a3 && a4 && a5 as Boolean
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean")!>x3<!>
|
||||
|
||||
x3 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>()}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
|
||||
|
||||
+3
-3
@@ -36,7 +36,7 @@ fun case1() {
|
||||
val a: Boolean? = false
|
||||
checkSubtype<Boolean?>(a)
|
||||
val x4 = <!CONDITION_TYPE_MISMATCH!>a<!> || true
|
||||
x4 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>() }
|
||||
x4 checkType { check<Boolean>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 2
|
||||
@@ -44,7 +44,7 @@ fun case2() {
|
||||
val a: Any = false
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>a<!>
|
||||
val x4 = <!CONDITION_TYPE_MISMATCH!>a<!> || true
|
||||
x4 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>() }
|
||||
x4 checkType { check<Boolean>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
@@ -56,7 +56,7 @@ fun case3() {
|
||||
val x3 = a1 || <!CONDITION_TYPE_MISMATCH!>a2<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean")!>x3<!>
|
||||
|
||||
x3 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>() }
|
||||
x3 checkType { check<Boolean>() }
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 4
|
||||
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-313
|
||||
* MAIN LINK: expressions, logical-disjunction-expression -> paragraph 2 -> sentence 1
|
||||
* PRIMARY LINKS: expressions, logical-disjunction-expression -> paragraph 2 -> sentence 2
|
||||
* NUMBER: 1
|
||||
* DESCRIPTION:Both operands of a logical disjunction expression must have a type which is a subtype of kotlin.Boolean
|
||||
* HELPERS: checkType
|
||||
*/
|
||||
|
||||
// MODULE: libModule
|
||||
// FILE: libModule/JavaClass.java
|
||||
package libModule;
|
||||
|
||||
public class JavaClass {
|
||||
public static boolean VALUE;
|
||||
|
||||
public static Object VALUE_OBJ = true;
|
||||
|
||||
public Boolean getValue ()
|
||||
{ return new Boolean ("true"); }
|
||||
}
|
||||
|
||||
// MODULE: mainModule(libModule)
|
||||
// FILE: KotlinClass.kt
|
||||
package mainModule
|
||||
import libModule.*
|
||||
import checkSubtype
|
||||
import checkType
|
||||
import check
|
||||
|
||||
fun foo() = run { false || JavaClass.VALUE || throw Exception() }
|
||||
|
||||
|
||||
// TESTCASE NUMBER: 1
|
||||
fun case1() {
|
||||
val a1 = false
|
||||
val a2 = JavaClass.VALUE
|
||||
val a3 = foo()
|
||||
val a4 = JavaClass().getValue()
|
||||
val a5 = JavaClass.VALUE_OBJ
|
||||
|
||||
checkSubtype<Boolean>(a1)
|
||||
checkSubtype<Boolean>(a2)
|
||||
checkSubtype<Boolean>(a3)
|
||||
checkSubtype<Boolean>(a4)
|
||||
|
||||
val x3 = a1 || a2 || a3 || a4 || a5 as Boolean
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Boolean")!>x3<!>
|
||||
|
||||
x3 <!OVERLOAD_RESOLUTION_AMBIGUITY!>checkType<!> { <!NONE_APPLICABLE!>check<!><Boolean>()}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
|
||||
|
||||
Reference in New Issue
Block a user