diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index fa6e828d16f..ae22f2db0b3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -305,13 +305,13 @@ public class CallResolver { private OverloadResolutionResults completeTypeInferenceDependentOnExpectedType( @NotNull BasicResolutionContext context, - @NotNull OverloadResolutionResults results, + @NotNull OverloadResolutionResults resultsWithIncompleteTypeInference, @NotNull TracingStrategy tracing ) { - if (results.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) return results; + if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) return resultsWithIncompleteTypeInference; Set> successful = Sets.newLinkedHashSet(); Set> failed = Sets.newLinkedHashSet(); - for (ResolvedCall call : results.getResultingCalls()) { + for (ResolvedCall call : resultsWithIncompleteTypeInference.getResultingCalls()) { if (!(call instanceof ResolvedCallImpl)) continue; ResolvedCallImpl resolvedCall = (ResolvedCallImpl) call; if (!resolvedCall.hasUnknownTypeParameters()) { @@ -325,16 +325,20 @@ public class CallResolver { } completeTypeInferenceDependentOnExpectedTypeForCall(resolvedCall, context, tracing, successful, failed); } - if (results.getResultingCalls().size() > 1) { + if (resultsWithIncompleteTypeInference.getResultingCalls().size() > 1) { for (ResolvedCallWithTrace call : successful) { if (call instanceof ResolvedCallImpl) { - ((ResolvedCallImpl)call).addStatus(ResolutionStatus.OTHER_ERROR); + ((ResolvedCallImpl)call).addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR); failed.add(call); } } successful.clear(); } - return computeResultAndReportErrors(context.trace, tracing, successful, failed); + OverloadResolutionResultsImpl results = computeResultAndReportErrors(context.trace, tracing, successful, failed); + if (!results.isSingleResult()) { + checkTypesWithNoCallee(context); + } + return results; } private void completeTypeInferenceDependentOnExpectedTypeForCall(ResolvedCallImpl resolvedCall, @@ -381,9 +385,9 @@ public class CallResolver { if (constraintSystemWithoutExpectedTypeConstraint.isSuccessful()) { resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor()); } - List argumentTypes = checkValueArgumentTypes(context, resolvedCall, context.trace).argumentTypes; + List argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes; JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null; - tracing.typeInferenceFailed(context.trace, + tracing.typeInferenceFailed(resolvedCall.getTrace(), InferenceErrorData .create(descriptor, constraintSystem, argumentTypes, receiverType, context.expectedType), constraintSystemWithoutExpectedTypeConstraint); @@ -394,9 +398,9 @@ public class CallResolver { resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor()); // Here we type check the arguments with inferred types expected - checkValueArgumentTypes(context, resolvedCall, context.trace); + checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()); - checkBounds(resolvedCall, constraintSystem, context.trace, tracing); + checkBounds(resolvedCall, constraintSystem, resolvedCall.getTrace(), tracing); resolvedCall.setHasUnknownTypeParameters(false); if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) { resolvedCall.addStatus(ResolutionStatus.SUCCESS); @@ -768,20 +772,25 @@ public class CallResolver { // Solution - if (!constraintsSystem.hasContradiction()) { + boolean hasContradiction = constraintsSystem.hasContradiction(); + boolean boundsAreSatisfied = ConstraintsUtil.checkBoundsAreSatisfied(constraintsSystem); + if (!hasContradiction && boundsAreSatisfied) { candidateCall.setHasUnknownTypeParameters(true); return SUCCESS; } - else { - ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context); - ResolutionStatus argumentsStatus = checkingResult.status; - List argumentTypes = checkingResult.argumentTypes; - JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null; - context.tracing.typeInferenceFailed(context.trace, - InferenceErrorData.create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType, context.expectedType), - constraintSystemWithRightTypeParameters); - return TYPE_INFERENCE_ERROR.combine(argumentsStatus); + ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context); + ResolutionStatus argumentsStatus = checkingResult.status; + List argumentTypes = checkingResult.argumentTypes; + JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null; + InferenceErrorData inferenceErrorData = InferenceErrorData + .create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType, context.expectedType); + if (hasContradiction) { + context.tracing.typeInferenceFailed(candidateCall.getTrace(), inferenceErrorData, constraintSystemWithRightTypeParameters); } + else { + context.tracing.upperBoundViolated(candidateCall.getTrace(), inferenceErrorData); + } + return TYPE_INFERENCE_ERROR.combine(argumentsStatus); } private boolean addConstraintForValueArgument(ValueArgument valueArgument, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java index 060299446ea..7def2ca8beb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java @@ -32,8 +32,8 @@ public enum ResolutionStatus { @SuppressWarnings("unchecked") public static final EnumSet[] SEVERITY_LEVELS = new EnumSet[] { EnumSet.of(UNSAFE_CALL_ERROR), // weakest - EnumSet.of(OTHER_ERROR), EnumSet.of(TYPE_INFERENCE_ERROR), + EnumSet.of(OTHER_ERROR), EnumSet.of(STRONG_ERROR), // most severe }; diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt new file mode 100644 index 00000000000..09b136ad5e6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt @@ -0,0 +1,16 @@ +//KT-2514 Type inference fails when using extension function literal +package kt2514 + +//+JDK +import java.io.Closeable + +fun Thread.use(block: Thread.() -> T): T = block() + +fun T.use(block: (T)-> R) : R = block(this) + +fun main(args: Array) { + Thread().use { } // compilation error: Type inference failed + Thread().use { 5 + 5 } // compilation error: Type inference failed + Thread().use { } // compiles okay + Thread().use { 5 + 5 } // compiles okay +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 279fa0fd393..ab021b6176a 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1375,6 +1375,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2324.kt"); } + @TestMetadata("kt2514.kt") + public void testKt2514() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt"); + } + @TestMetadata("kt702.kt") public void testKt702() throws Exception { doTest("compiler/testData/diagnostics/tests/inference/regressions/kt702.kt");