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 50edcb51b7e..b5a73de7b3b 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 @@ -390,6 +390,7 @@ public class CallResolver { if (!results.isSingleResult()) { argumentTypeResolver.checkTypesForFunctionArgumentsWithNoCallee(context); candidateResolver.completeNestedCallsForNotResolvedInvocation(context); + candidateResolver.completeTypeInferenceForAllCandidates(context, results); return results; } @@ -405,6 +406,8 @@ public class CallResolver { candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false); resolvedCall.markCallAsCompleted(); + candidateResolver.completeTypeInferenceForAllCandidates(context, results); + if (callToCompleteInference.getStatus().isSuccess()) { return OverloadResolutionResultsImpl.success(resolvedCall); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 440dee89806..b0eba8c7826 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -34,10 +34,12 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory; import org.jetbrains.jet.lang.resolve.calls.context.*; import org.jetbrains.jet.lang.resolve.calls.inference.*; import org.jetbrains.jet.lang.resolve.calls.model.*; +import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask; import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer; +import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.*; @@ -265,6 +267,47 @@ public class CandidateResolver { return returnType; } + private void completeTypeInferenceForAllCandidates( + @NotNull CallCandidateResolutionContext context, + @Nullable JetExpression expression + ) { + if (expression == null) return; + + CallKey callKey = CallKey.create(expression); + OverloadResolutionResultsImpl resolutionResults = context.resolutionResultsCache.getResolutionResults(callKey); + if (resolutionResults == null) return; + + completeTypeInferenceForAllCandidates(context.toBasic(), resolutionResults); + } + + public void completeTypeInferenceForAllCandidates( + @NotNull BasicCallResolutionContext context, + @NotNull OverloadResolutionResultsImpl results + ) { + Collection> candidates; + if (context.collectAllCandidates) { + candidates = results.getAllCandidates(); + assert candidates != null : "Should be guaranteed by collectAllCandidates == true"; + } + else { + candidates = results.getResultingCalls(); + } + for (ResolvedCall resolvedCall : candidates) { + ResolvedCallWithTrace resolvedCallWithTrace = (ResolvedCallWithTrace) resolvedCall; + if (resolvedCallWithTrace.isCompleted()) continue; + + TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create( + context.trace, "Trace to complete a candidate that is not a resulting call"); + ResolvedCallImpl callToCompleteInference = resolvedCallWithTrace.getCallToCompleteTypeArgumentInference(); + + CallCandidateResolutionContext callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( + callToCompleteInference, context.replaceBindingTrace(temporaryBindingTrace), TracingStrategy.EMPTY); + + completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false); + resolvedCallWithTrace.markCallAsCompleted(); + } + } + private static void updateSystemWithConstraintSystemCompleter( @NotNull CallCandidateResolutionContext context, @NotNull ResolvedCallImpl resolvedCall @@ -364,6 +407,7 @@ public class CandidateResolver { if (storedContextForArgument == null) { JetType type = ArgumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression); checkResultArgumentType(type, argument, context); + completeTypeInferenceForAllCandidates(context, keyExpression); return; } @@ -389,6 +433,7 @@ public class CandidateResolver { type, expression, context.trace, isFairSafeCallExpression(expression, context.trace)); markResultingCallAsCompleted(context, keyExpression); + completeTypeInferenceForAllCandidates(context, keyExpression); DataFlowUtils.checkType(result, expression, contextForArgument); }