Improved error reporting for candidates with wrong parameter count
This commit is contained in:
@@ -160,7 +160,7 @@ public class CandidateResolver(
|
||||
val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
|
||||
call, tracing, candidateCall, Sets.newLinkedHashSet<ValueArgument>())
|
||||
if (!argumentMappingStatus.isSuccess()) {
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
candidateCall.addStatus(ARGUMENTS_MAPPING_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-18
@@ -136,33 +136,36 @@ public class ResolutionResultsHandler {
|
||||
}
|
||||
}
|
||||
if (!thisLevel.isEmpty()) {
|
||||
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
|
||||
if (results.isSingleResult()) {
|
||||
results.getResultingCall().getTrace().moveAllMyDataTo(task.trace);
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
|
||||
if (severityLevel.contains(ARGUMENTS_MAPPING_ERROR)) {
|
||||
return recordFailedInfo(task, thisLevel);
|
||||
}
|
||||
|
||||
task.tracing.noneApplicable(task.trace, results.getResultingCalls());
|
||||
task.tracing.recordAmbiguity(task.trace, results.getResultingCalls());
|
||||
return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls());
|
||||
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
|
||||
return recordFailedInfo(task, results.getResultingCalls());
|
||||
}
|
||||
}
|
||||
|
||||
assert false : "Should not be reachable, cause every status must belong to some level";
|
||||
|
||||
Set<MutableResolvedCall<D>> noOverrides = OverrideResolver.filterOutOverridden(failedCandidates, MAP_TO_CANDIDATE);
|
||||
if (noOverrides.size() != 1) {
|
||||
task.tracing.noneApplicable(task.trace, noOverrides);
|
||||
task.tracing.recordAmbiguity(task.trace, noOverrides);
|
||||
return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides);
|
||||
}
|
||||
|
||||
failedCandidates = noOverrides;
|
||||
return recordFailedInfo(task, noOverrides);
|
||||
}
|
||||
|
||||
MutableResolvedCall<D> failed = failedCandidates.iterator().next();
|
||||
failed.getTrace().moveAllMyDataTo(task.trace);
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
||||
return recordFailedInfo(task, failedCandidates);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> recordFailedInfo(
|
||||
@NotNull ResolutionTask task,
|
||||
@NotNull Collection<MutableResolvedCall<D>> candidates
|
||||
) {
|
||||
if (candidates.size() == 1) {
|
||||
MutableResolvedCall<D> failed = candidates.iterator().next();
|
||||
failed.getTrace().moveAllMyDataTo(task.trace);
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
||||
}
|
||||
task.tracing.noneApplicable(task.trace, candidates);
|
||||
task.tracing.recordAmbiguity(task.trace, candidates);
|
||||
return OverloadResolutionResultsImpl.manyFailedCandidates(candidates);
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> boolean allIncomplete(@NotNull Collection<MutableResolvedCall<D>> results) {
|
||||
|
||||
@@ -31,6 +31,7 @@ public enum ResolutionStatus {
|
||||
// 'a.foo()' shouldn't be resolved to package level non-extension 'fun foo()'
|
||||
// candidates with such error are thrown away completely
|
||||
RECEIVER_PRESENCE_ERROR,
|
||||
ARGUMENTS_MAPPING_ERROR,
|
||||
INCOMPLETE_TYPE_INFERENCE,
|
||||
SUCCESS(true);
|
||||
|
||||
@@ -38,6 +39,7 @@ public enum ResolutionStatus {
|
||||
public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] {
|
||||
EnumSet.of(UNSAFE_CALL_ERROR), // weakest
|
||||
EnumSet.of(OTHER_ERROR),
|
||||
EnumSet.of(ARGUMENTS_MAPPING_ERROR),
|
||||
EnumSet.of(RECEIVER_TYPE_ERROR),
|
||||
EnumSet.of(RECEIVER_PRESENCE_ERROR), // most severe
|
||||
};
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
fun foo() {}
|
||||
fun foo(s: Int) {}
|
||||
|
||||
|
||||
fun bar(a: Any) {}
|
||||
fun bar(a: Int) {}
|
||||
|
||||
fun test() {
|
||||
<!NONE_APPLICABLE!>foo<!>(1, 2)
|
||||
foo(<!TYPE_MISMATCH!>""<!>)
|
||||
|
||||
<!NONE_APPLICABLE!>bar<!>(1, 2)
|
||||
<!NONE_APPLICABLE!>bar<!>()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package
|
||||
|
||||
internal fun bar(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
internal fun bar(/*0*/ a: kotlin.Int): kotlin.Unit
|
||||
internal fun foo(): kotlin.Unit
|
||||
internal fun foo(/*0*/ s: kotlin.Int): kotlin.Unit
|
||||
internal fun test(): kotlin.Unit
|
||||
+3
-4
@@ -6,12 +6,11 @@ fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Int, vararg <!UNUSED_PARAMETER!>a<!
|
||||
return null
|
||||
}
|
||||
|
||||
fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Any, <!UNUSED_PARAMETER!>y<!>: T): T? {
|
||||
fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Comparable<*>, <!UNUSED_PARAMETER!>y<!>: T): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val x2 = joinT(<!NON_VARARG_SPREAD!>*<!>1, "2")
|
||||
val x2 = <!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>joinT<!>(<!TYPE_MISMATCH!>Unit<!>, "2")
|
||||
checkSubtype<String?>(x2)
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package
|
||||
|
||||
package d {
|
||||
internal fun </*0*/ T : kotlin.Any> joinT(/*0*/ x: kotlin.Any, /*1*/ y: T): T?
|
||||
internal fun </*0*/ T : kotlin.Any> joinT(/*0*/ x: kotlin.Comparable<*>, /*1*/ y: T): T?
|
||||
internal fun </*0*/ T : kotlin.Any> joinT(/*0*/ x: kotlin.Int, /*1*/ vararg a: T /*kotlin.Array<out T>*/): T?
|
||||
internal fun test(): kotlin.Unit
|
||||
}
|
||||
|
||||
+2
-2
@@ -83,7 +83,7 @@ fun test(n: J?, nn: J) {
|
||||
|
||||
J(nn, nn, nn)
|
||||
J(platformNN, platformNN, platformNN)
|
||||
<!NONE_APPLICABLE!>J<!>(n, n, n)
|
||||
<!NONE_APPLICABLE!>J<!>(platformN, platformN, platformN)
|
||||
J(<!TYPE_MISMATCH!>n<!>, n, n)
|
||||
J(<!TYPE_MISMATCH!>platformN<!>, platformN, platformN)
|
||||
J(platformJ, platformJ, platformJ)
|
||||
}
|
||||
+2
-3
@@ -11,7 +11,6 @@ public class ResolutionTaskHolder<F, G : F> {
|
||||
|
||||
//todo the problem is the type of ResolutionTask is inferred as ResolutionTask<F, F> too early
|
||||
tasks.<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>bar<!>(ResolutionTask(candidate))
|
||||
tasks.<!NONE_APPLICABLE!>add<!>(ResolutionTask(candidate))
|
||||
tasks.add(ResolutionTask(candidate))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class X<T>(val t: T) {
|
||||
constructor(t: T, i: Int) : <!NONE_APPLICABLE!>this<!>(i)
|
||||
}
|
||||
constructor(t: T, i: Int) : this(<!TYPE_MISMATCH!>i<!>)
|
||||
}
|
||||
+3
-3
@@ -5,8 +5,8 @@ fun bar(): String? = null
|
||||
|
||||
fun foo() {
|
||||
var x = ArrayList<String>()
|
||||
x.<!NONE_APPLICABLE!>add<!>(null)
|
||||
x.<!NONE_APPLICABLE!>add<!>(bar())
|
||||
x.add(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
x.add(<!TYPE_MISMATCH!>bar()<!>)
|
||||
x.add("")
|
||||
|
||||
x[0] = <!NULL_FOR_NONNULL_TYPE!>null<!>
|
||||
@@ -19,4 +19,4 @@ fun foo() {
|
||||
|
||||
val b4: Collection<String?> = x
|
||||
val b6: MutableCollection<String?> = <!TYPE_MISMATCH!>x<!>
|
||||
}
|
||||
}
|
||||
Vendored
+3
-3
@@ -22,8 +22,8 @@ fun bar(): String? = null
|
||||
|
||||
fun foo() {
|
||||
var x = A<String>()
|
||||
x.<!NONE_APPLICABLE!>add<!>(null)
|
||||
x.<!NONE_APPLICABLE!>add<!>(bar())
|
||||
x.add(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
x.add(<!TYPE_MISMATCH!>bar()<!>)
|
||||
x.add("")
|
||||
|
||||
x[0] = <!NULL_FOR_NONNULL_TYPE!>null<!>
|
||||
@@ -36,4 +36,4 @@ fun foo() {
|
||||
|
||||
val b4: Collection<String?> = x
|
||||
val b6: MutableCollection<String?> = <!TYPE_MISMATCH!>x<!>
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ fun <T> tt(t : T) : T {
|
||||
val x : ArrayList<Int> = 0
|
||||
x`java::java.util.ArrayList.get()`[1]
|
||||
val foo = `Bar`Bar()
|
||||
foo`!!`[null, 1]
|
||||
foo`get2`[null, 1]
|
||||
foo`get2`[1, 1]
|
||||
foo`get1`[1]
|
||||
foo`set1`[1] = ""
|
||||
|
||||
@@ -2370,6 +2370,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("overloadedFunction.kt")
|
||||
public void testOverloadedFunction() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/checkArguments/overloadedFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SpreadVarargs.kt")
|
||||
public void testSpreadVarargs() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.kt");
|
||||
|
||||
+2
-2
@@ -11,10 +11,10 @@ fun other() {
|
||||
}
|
||||
|
||||
// EXIST: { lookupString:"nFirst", itemText:"nFirst =" }
|
||||
// EXIST: { lookupString:"nSecond", itemText:"nSecond =" }
|
||||
// EXIST: { lookupString:"nThird", itemText:"nThird =" }
|
||||
// EXIST: nLocal
|
||||
|
||||
// todo - should exist
|
||||
// ABSENT: nClassParam
|
||||
// ABSENT: nSecond
|
||||
// ABSENT: nThird
|
||||
// ABSENT: nClassField
|
||||
@@ -3,6 +3,7 @@
|
||||
// !MESSAGE_TYPE: HTML
|
||||
|
||||
fun foo(i: Int, s: String, b: Boolean) {}
|
||||
fun foo(i: Int, s: Int) {}
|
||||
fun foo(b: Boolean, s: String) {}
|
||||
fun foo(i: Int) {}
|
||||
|
||||
|
||||
+1
-2
@@ -3,7 +3,6 @@
|
||||
None of the following functions can be called with the arguments supplied.
|
||||
<ul>
|
||||
<li>foo(<font color=red><b>Boolean</b></font>, String) <i>defined in</i> root package</li>
|
||||
<li>foo(Int<font color=red><b>)</b></font> <i>defined in</i> root package</li>
|
||||
<li>foo(Int, String, <font color=red><b>Boolean</b></font>) <i>defined in</i> root package</li>
|
||||
<li>foo(Int, <font color=red><b>Int</b></font>) <i>defined in</i> root package</li>
|
||||
</ul>
|
||||
</html>
|
||||
@@ -8,8 +8,5 @@ None of the following functions can be called with the arguments supplied.
|
||||
<li>foo(Int, <font color=red><b>R</b></font>, MutableList<`Int>, MutableList<`<font color=red><b>R</b></font>>)<br/>
|
||||
<i>where</i> <font color=red><b>R</b></font><i> cannot be inferred</i>; T = Int<i> for </i><br/>
|
||||
<b>fun</b> <`T, R> foo(t: T, r: R, lt: MutableList<`T>, lr: MutableList<`R>): Int <i>defined in</i> p</li>
|
||||
<li>foo(Int, Any, List<`Int><font color=red><b>)</b></font><br/>
|
||||
<i>where</i> T = Int<i> for </i><br/>
|
||||
<b>fun</b> <`T> foo(t: T, a: Any, l: List<`T>): Int <i>defined in</i> p</li>
|
||||
</ul>
|
||||
</html>
|
||||
@@ -1,6 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
// WITH_RUNTIME
|
||||
// ERROR: No value passed for parameter value
|
||||
// ERROR: <html>None of the following functions can be called with the arguments supplied. <ul><li>assert(<font color=red><b>Boolean</b></font>, () → Any) <i>defined in</i> kotlin</li><li>assert(<font color=red><b>Boolean</b></font>, Any = ...) <i>defined in</i> kotlin</li></ul></html>
|
||||
|
||||
fun foo() {
|
||||
<caret>assert { "text" }
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public open fun valueOf(p0: kotlin.Short): kotlin.Short! defined in java.lang.Short public open fun valueOf(p0: kotlin.String!): kotlin.Short! defined in java.lang.Short public open fun valueOf(p0: kotlin.String!, p1: kotlin.Int): kotlin.Short! defined in java.lang.Short
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public open fun valueOf(p0: kotlin.Short): kotlin.Short! defined in java.lang.Short public open fun valueOf(p0: kotlin.String!): kotlin.Short! defined in java.lang.Short
|
||||
package demo
|
||||
|
||||
class Test {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public constructor FileInputStream(p0: [ERROR : Unresolved java classifier: FileDescriptor]!) defined in java.io.FileInputStream public constructor FileInputStream(p0: java.io.File!) defined in java.io.FileInputStream public constructor FileInputStream(p0: kotlin.String!) defined in java.io.FileInputStream
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public constructor InputStreamReader(p0: java.io.InputStream!) defined in java.io.InputStreamReader public constructor InputStreamReader(p0: java.io.InputStream!, p1: [ERROR : Unresolved java classifier: CharsetDecoder]!) defined in java.io.InputStreamReader public constructor InputStreamReader(p0: java.io.InputStream!, p1: java.nio.charset.Charset!) defined in java.io.InputStreamReader public constructor InputStreamReader(p0: java.io.InputStream!, p1: kotlin.String!) defined in java.io.InputStreamReader
|
||||
// ERROR: Type mismatch: inferred type is java.io.DataInputStream but java.io.InputStream! was expected
|
||||
// ERROR: Assignments are not expressions, and only expressions are allowed in this context
|
||||
// ERROR: Unresolved reference: close
|
||||
import java.io.*
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
// ERROR: Unresolved reference: LinkedList
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public open fun add(e: kotlin.Any): kotlin.Boolean defined in java.util.ArrayList public open fun add(index: kotlin.Int, element: kotlin.Any): kotlin.Unit defined in java.util.ArrayList
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public open fun add(e: kotlin.Any): kotlin.Boolean defined in java.util.ArrayList public open fun add(index: kotlin.Int, element: kotlin.Any): kotlin.Unit defined in java.util.ArrayList
|
||||
// ERROR: Null can not be a value of a non-null type kotlin.Any
|
||||
// ERROR: Null can not be a value of a non-null type kotlin.Any
|
||||
import java.util.*
|
||||
|
||||
public class Lists {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public fun <T> listOf(): kotlin.List<kotlin.String> defined in kotlin public fun <T> listOf(vararg values: kotlin.String): kotlin.List<kotlin.String> defined in kotlin public fun <T> listOf(value: kotlin.String): kotlin.List<kotlin.String> defined in kotlin
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: public fun <T> setOf(): kotlin.Set<kotlin.String> defined in kotlin public fun <T> setOf(vararg values: kotlin.String): kotlin.Set<kotlin.String> defined in kotlin public fun <T> setOf(value: kotlin.String): kotlin.Set<kotlin.String> defined in kotlin
|
||||
// ERROR: Null can not be a value of a non-null type kotlin.String
|
||||
// ERROR: Null can not be a value of a non-null type kotlin.String
|
||||
import java.util.*
|
||||
|
||||
class A {
|
||||
|
||||
Reference in New Issue
Block a user