Filter out equivalent calls before reporting "none applicable"
If a module is configured in such a way that the same function appears multiple times via different dependencies, it's not helpful to report "none of the following functions can be called", listing the same function multiple times
This commit is contained in:
+4
-1
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.*;
|
||||
@@ -147,7 +148,9 @@ public class ResolutionResultsHandler {
|
||||
}
|
||||
if (!thisLevel.isEmpty()) {
|
||||
if (severityLevel.contains(ARGUMENTS_MAPPING_ERROR)) {
|
||||
return recordFailedInfo(tracing, trace, thisLevel);
|
||||
@SuppressWarnings("unchecked")
|
||||
OverloadingConflictResolver<MutableResolvedCall<D>> myResolver = (OverloadingConflictResolver) overloadingConflictResolver;
|
||||
return recordFailedInfo(tracing, trace, myResolver.filterOutEquivalentCalls(new LinkedHashSet<MutableResolvedCall<D>>(thisLevel)));
|
||||
}
|
||||
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false, false, checkArgumentsMode);
|
||||
return recordFailedInfo(tracing, trace, results.getResultingCalls());
|
||||
|
||||
+1
-3
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.varargParameterPosition
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.lang.AssertionError
|
||||
import java.util.*
|
||||
|
||||
class OverloadingConflictResolver<C : Any>(
|
||||
@@ -94,8 +93,7 @@ class OverloadingConflictResolver<C : Any>(
|
||||
// Sometimes we should compare "copies" from sources and from binary files.
|
||||
// But we cannot compare return types for such copies, because it may lead us to recursive problem (see KT-11995).
|
||||
// Because of this we compare them without return type and choose descriptor from source if we found duplicate.
|
||||
private fun filterOutEquivalentCalls(
|
||||
candidates: Set<C>): Set<C> {
|
||||
fun filterOutEquivalentCalls(candidates: Set<C>): Set<C> {
|
||||
if (candidates.size <= 1) return candidates
|
||||
|
||||
val fromSourcesGoesFirst = candidates.sortedBy { if (isFromSources(it.resultingDescriptor)) 0 else 1 }
|
||||
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
// 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
|
||||
f(
|
||||
<!SYNTAX!><!>}
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
// -- Module: <m1> --
|
||||
package
|
||||
|
||||
package p {
|
||||
public fun f(/*0*/ s: kotlin.String, /*1*/ t: kotlin.String): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
// -- Module: <m2> --
|
||||
package
|
||||
|
||||
package p {
|
||||
public fun f(/*0*/ s: kotlin.String, /*1*/ t: kotlin.String): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
// -- Module: <m3> --
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
package p {
|
||||
public fun f(/*0*/ s: kotlin.String, /*1*/ t: kotlin.String): kotlin.String
|
||||
public fun f(/*0*/ s: kotlin.String, /*1*/ t: kotlin.String): kotlin.String
|
||||
}
|
||||
@@ -12311,6 +12311,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("incompleteCodeNoNoneApplicable.kt")
|
||||
public void testIncompleteCodeNoNoneApplicable() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/incompleteCodeNoNoneApplicable.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noGenericsInParams.kt")
|
||||
public void testNoGenericsInParams() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/noGenericsInParams.kt");
|
||||
|
||||
Reference in New Issue
Block a user