KT-2505 Type mismatch: inferred type is T but T was expected
#KT-2505
This commit is contained in:
@@ -591,7 +591,7 @@ public class CallResolver {
|
||||
|
||||
OverloadResolutionResultsImpl<F> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates,
|
||||
failedCandidates);
|
||||
if (!results.isSingleResult() && results.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
|
||||
if (!results.isSingleResult() && !results.isIncomplete()) {
|
||||
checkTypesWithNoCallee(task.toBasic());
|
||||
}
|
||||
return results;
|
||||
@@ -1033,7 +1033,7 @@ public class CallResolver {
|
||||
}
|
||||
if (!thisLevel.isEmpty()) {
|
||||
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
|
||||
if (results.isSuccess()) {
|
||||
if (results.isSingleResult()) {
|
||||
results.getResultingCall().getTrace().commit();
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
|
||||
}
|
||||
@@ -1058,9 +1058,6 @@ public class CallResolver {
|
||||
|
||||
ResolvedCallWithTrace<D> failed = failedCandidates.iterator().next();
|
||||
failed.getTrace().commit();
|
||||
if (failed.getStatus() != ResolutionStatus.STRONG_ERROR && failed.hasUnknownTypeParameters()) {
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(failed);
|
||||
}
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
||||
}
|
||||
else {
|
||||
@@ -1078,13 +1075,9 @@ public class CallResolver {
|
||||
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallWithTrace<D>> candidates, boolean discriminateGenerics) {
|
||||
if (candidates.size() != 1) {
|
||||
boolean dirty = false;
|
||||
Set<ResolvedCallWithTrace<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
||||
for (Iterator<ResolvedCallWithTrace<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
||||
ResolvedCallWithTrace<D> candidate = iterator.next();
|
||||
if (candidate.hasUnknownTypeParameters()) {
|
||||
dirty = true;
|
||||
}
|
||||
if (candidate.isDirty()) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -1107,10 +1100,6 @@ public class CallResolver {
|
||||
|
||||
Set<ResolvedCallWithTrace<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
||||
|
||||
if (dirty) {
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(candidates);
|
||||
}
|
||||
|
||||
return OverloadResolutionResultsImpl.ambiguity(noOverrides);
|
||||
}
|
||||
else {
|
||||
@@ -1118,9 +1107,6 @@ public class CallResolver {
|
||||
|
||||
TemporaryBindingTrace temporaryTrace = result.getTrace();
|
||||
temporaryTrace.commit();
|
||||
if (result.hasUnknownTypeParameters()) {
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(result);
|
||||
}
|
||||
|
||||
return OverloadResolutionResultsImpl.success(result);
|
||||
}
|
||||
|
||||
+2
@@ -63,4 +63,6 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
|
||||
boolean isNothing();
|
||||
|
||||
boolean isAmbiguity();
|
||||
|
||||
boolean isIncomplete();
|
||||
}
|
||||
|
||||
+27
-10
@@ -28,8 +28,11 @@ import java.util.Collections;
|
||||
*/
|
||||
/*package*/ class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallWithTrace<D> descriptor) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(descriptor));
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallWithTrace<D> candidate) {
|
||||
if (candidate.hasUnknownTypeParameters()) {
|
||||
return incompleteTypeInference(candidate);
|
||||
}
|
||||
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(candidate));
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> nameNotFound() {
|
||||
@@ -37,22 +40,30 @@ import java.util.Collections;
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> singleFailedCandidate(ResolvedCallWithTrace<D> candidate) {
|
||||
if (candidate.getStatus() != ResolutionStatus.STRONG_ERROR && candidate.hasUnknownTypeParameters()) {
|
||||
return incompleteTypeInference(candidate);
|
||||
}
|
||||
return new OverloadResolutionResultsImpl<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
|
||||
}
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> manyFailedCandidates(Collection<ResolvedCallWithTrace<D>> failedCandidates) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> descriptors) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, descriptors);
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||
for (ResolvedCallWithTrace<D> candidate : candidates) {
|
||||
if (candidate.hasUnknownTypeParameters()) {
|
||||
return incompleteTypeInference(candidates);
|
||||
}
|
||||
}
|
||||
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, candidates);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(Collection<ResolvedCallWithTrace<D>> descriptors) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, descriptors);
|
||||
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, candidates);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> descriptor) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, Collections.singleton(descriptor));
|
||||
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> candidate) {
|
||||
return incompleteTypeInference(Collections.singleton(candidate));
|
||||
}
|
||||
|
||||
private final Collection<ResolvedCallWithTrace<D>> results;
|
||||
@@ -96,7 +107,7 @@ import java.util.Collections;
|
||||
|
||||
@Override
|
||||
public boolean isSingleResult() {
|
||||
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
|
||||
return results.size() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,7 +119,13 @@ import java.util.Collections;
|
||||
public boolean isAmbiguity() {
|
||||
return resultCode == Code.AMBIGUITY;
|
||||
}
|
||||
//
|
||||
|
||||
@Override
|
||||
public boolean isIncomplete() {
|
||||
return resultCode == Code.INCOMPLETE_TYPE_INFERENCE;
|
||||
}
|
||||
|
||||
//
|
||||
// public OverloadResolutionResultsImpl<D> newContents(@NotNull Collection<D> functionDescriptors) {
|
||||
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
|
||||
// }
|
||||
|
||||
+2
-7
@@ -611,13 +611,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
if (!results.isNothing()) {
|
||||
checkSuper(receiver, results, context.trace, callExpression);
|
||||
result[0] = true;
|
||||
if (results.isSingleResult()) {
|
||||
ResolvedCall<FunctionDescriptor> resultingCall = results.getResultingCall();
|
||||
if (resultingCall instanceof ResolvedCallWithTrace) {
|
||||
if (((ResolvedCallWithTrace)resultingCall).getStatus() == ResolutionStatus.TYPE_INFERENCE_ERROR) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (results.isIncomplete()) {
|
||||
return null;
|
||||
}
|
||||
return results.isSingleResult() ? results.getResultingDescriptor() : null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package d
|
||||
|
||||
fun <T> joinT(<!UNUSED_PARAMETER!>x<!>: Int, vararg <!UNUSED_PARAMETER!>a<!>: T): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun <T> joinT(<!UNUSED_PARAMETER!>x<!>: Any, <!UNUSED_PARAMETER!>y<!>: T): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val x2 = joinT(<!NON_VARARG_SPREAD!>*<!>1, "2")
|
||||
x2 : String?
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
//KT-2505 Type mismatch: inferred type is T but T was expected
|
||||
|
||||
package a
|
||||
|
||||
trait MyType {}
|
||||
class MyClass<T> : MyType {}
|
||||
|
||||
public open class HttpResponse() {
|
||||
public open fun parseAs<T>(dataClass : MyClass<T>) : T? {
|
||||
return null
|
||||
}
|
||||
public open fun parseAs(dataType : MyType) : Any? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun test<R> (httpResponse: HttpResponse, rtype: MyClass<R>) {
|
||||
val res = httpResponse.parseAs( rtype )
|
||||
res : R? //type mismatch: required R?, found T?
|
||||
}
|
||||
@@ -1259,6 +1259,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/inference/arrayConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("completeInferenceIfManyFailed.kt")
|
||||
public void testCompleteInferenceIfManyFailed() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/completeInferenceIfManyFailed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("conflictingSubstitutions.kt")
|
||||
public void testConflictingSubstitutions() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/conflictingSubstitutions.kt");
|
||||
@@ -1324,6 +1329,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("possibleCycleOnConstraints.kt")
|
||||
public void testPossibleCycleOnConstraints() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/possibleCycleOnConstraints.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeConstructorMismatch.kt")
|
||||
public void testTypeConstructorMismatch() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/typeConstructorMismatch.kt");
|
||||
@@ -1405,6 +1415,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2484.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt2505.kt")
|
||||
public void testKt2505() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2505.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt2514.kt")
|
||||
public void testKt2514() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt");
|
||||
|
||||
Reference in New Issue
Block a user