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,
|
OverloadResolutionResultsImpl<F> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates,
|
||||||
failedCandidates);
|
failedCandidates);
|
||||||
if (!results.isSingleResult() && results.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
|
if (!results.isSingleResult() && !results.isIncomplete()) {
|
||||||
checkTypesWithNoCallee(task.toBasic());
|
checkTypesWithNoCallee(task.toBasic());
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
@@ -1033,7 +1033,7 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
if (!thisLevel.isEmpty()) {
|
if (!thisLevel.isEmpty()) {
|
||||||
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
|
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
|
||||||
if (results.isSuccess()) {
|
if (results.isSingleResult()) {
|
||||||
results.getResultingCall().getTrace().commit();
|
results.getResultingCall().getTrace().commit();
|
||||||
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
|
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
|
||||||
}
|
}
|
||||||
@@ -1058,9 +1058,6 @@ public class CallResolver {
|
|||||||
|
|
||||||
ResolvedCallWithTrace<D> failed = failedCandidates.iterator().next();
|
ResolvedCallWithTrace<D> failed = failedCandidates.iterator().next();
|
||||||
failed.getTrace().commit();
|
failed.getTrace().commit();
|
||||||
if (failed.getStatus() != ResolutionStatus.STRONG_ERROR && failed.hasUnknownTypeParameters()) {
|
|
||||||
return OverloadResolutionResultsImpl.incompleteTypeInference(failed);
|
|
||||||
}
|
|
||||||
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1078,13 +1075,9 @@ public class CallResolver {
|
|||||||
|
|
||||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallWithTrace<D>> candidates, boolean discriminateGenerics) {
|
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallWithTrace<D>> candidates, boolean discriminateGenerics) {
|
||||||
if (candidates.size() != 1) {
|
if (candidates.size() != 1) {
|
||||||
boolean dirty = false;
|
|
||||||
Set<ResolvedCallWithTrace<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
Set<ResolvedCallWithTrace<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
||||||
for (Iterator<ResolvedCallWithTrace<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
for (Iterator<ResolvedCallWithTrace<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
||||||
ResolvedCallWithTrace<D> candidate = iterator.next();
|
ResolvedCallWithTrace<D> candidate = iterator.next();
|
||||||
if (candidate.hasUnknownTypeParameters()) {
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
if (candidate.isDirty()) {
|
if (candidate.isDirty()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
@@ -1107,10 +1100,6 @@ public class CallResolver {
|
|||||||
|
|
||||||
Set<ResolvedCallWithTrace<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
Set<ResolvedCallWithTrace<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
||||||
|
|
||||||
if (dirty) {
|
|
||||||
return OverloadResolutionResultsImpl.incompleteTypeInference(candidates);
|
|
||||||
}
|
|
||||||
|
|
||||||
return OverloadResolutionResultsImpl.ambiguity(noOverrides);
|
return OverloadResolutionResultsImpl.ambiguity(noOverrides);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1118,9 +1107,6 @@ public class CallResolver {
|
|||||||
|
|
||||||
TemporaryBindingTrace temporaryTrace = result.getTrace();
|
TemporaryBindingTrace temporaryTrace = result.getTrace();
|
||||||
temporaryTrace.commit();
|
temporaryTrace.commit();
|
||||||
if (result.hasUnknownTypeParameters()) {
|
|
||||||
return OverloadResolutionResultsImpl.incompleteTypeInference(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return OverloadResolutionResultsImpl.success(result);
|
return OverloadResolutionResultsImpl.success(result);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -63,4 +63,6 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
|
|||||||
boolean isNothing();
|
boolean isNothing();
|
||||||
|
|
||||||
boolean isAmbiguity();
|
boolean isAmbiguity();
|
||||||
|
|
||||||
|
boolean isIncomplete();
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-10
@@ -28,8 +28,11 @@ import java.util.Collections;
|
|||||||
*/
|
*/
|
||||||
/*package*/ class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
|
/*package*/ class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
|
||||||
|
|
||||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallWithTrace<D> descriptor) {
|
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallWithTrace<D> candidate) {
|
||||||
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(descriptor));
|
if (candidate.hasUnknownTypeParameters()) {
|
||||||
|
return incompleteTypeInference(candidate);
|
||||||
|
}
|
||||||
|
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(candidate));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> nameNotFound() {
|
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) {
|
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));
|
return new OverloadResolutionResultsImpl<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
|
||||||
}
|
}
|
||||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> manyFailedCandidates(Collection<ResolvedCallWithTrace<D>> failedCandidates) {
|
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> manyFailedCandidates(Collection<ResolvedCallWithTrace<D>> failedCandidates) {
|
||||||
return new OverloadResolutionResultsImpl<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
|
return new OverloadResolutionResultsImpl<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> descriptors) {
|
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||||
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, descriptors);
|
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) {
|
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||||
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, descriptors);
|
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> descriptor) {
|
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> candidate) {
|
||||||
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, Collections.singleton(descriptor));
|
return incompleteTypeInference(Collections.singleton(candidate));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Collection<ResolvedCallWithTrace<D>> results;
|
private final Collection<ResolvedCallWithTrace<D>> results;
|
||||||
@@ -96,7 +107,7 @@ import java.util.Collections;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSingleResult() {
|
public boolean isSingleResult() {
|
||||||
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
|
return results.size() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,7 +119,13 @@ import java.util.Collections;
|
|||||||
public boolean isAmbiguity() {
|
public boolean isAmbiguity() {
|
||||||
return resultCode == Code.AMBIGUITY;
|
return resultCode == Code.AMBIGUITY;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
@Override
|
||||||
|
public boolean isIncomplete() {
|
||||||
|
return resultCode == Code.INCOMPLETE_TYPE_INFERENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// public OverloadResolutionResultsImpl<D> newContents(@NotNull Collection<D> functionDescriptors) {
|
// public OverloadResolutionResultsImpl<D> newContents(@NotNull Collection<D> functionDescriptors) {
|
||||||
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
|
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
|
||||||
// }
|
// }
|
||||||
|
|||||||
+2
-7
@@ -611,13 +611,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
if (!results.isNothing()) {
|
if (!results.isNothing()) {
|
||||||
checkSuper(receiver, results, context.trace, callExpression);
|
checkSuper(receiver, results, context.trace, callExpression);
|
||||||
result[0] = true;
|
result[0] = true;
|
||||||
if (results.isSingleResult()) {
|
if (results.isIncomplete()) {
|
||||||
ResolvedCall<FunctionDescriptor> resultingCall = results.getResultingCall();
|
return null;
|
||||||
if (resultingCall instanceof ResolvedCallWithTrace) {
|
|
||||||
if (((ResolvedCallWithTrace)resultingCall).getStatus() == ResolutionStatus.TYPE_INFERENCE_ERROR) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return results.isSingleResult() ? results.getResultingDescriptor() : 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");
|
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")
|
@TestMetadata("conflictingSubstitutions.kt")
|
||||||
public void testConflictingSubstitutions() throws Exception {
|
public void testConflictingSubstitutions() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/inference/conflictingSubstitutions.kt");
|
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");
|
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")
|
@TestMetadata("typeConstructorMismatch.kt")
|
||||||
public void testTypeConstructorMismatch() throws Exception {
|
public void testTypeConstructorMismatch() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/inference/typeConstructorMismatch.kt");
|
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");
|
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")
|
@TestMetadata("kt2514.kt")
|
||||||
public void testKt2514() throws Exception {
|
public void testKt2514() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt");
|
doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user