diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 1da95d1cae6..d744e2fe381 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -25,10 +25,10 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; -import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -89,8 +89,8 @@ public interface BindingContext { WritableSlice> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice>(DO_NOTHING); - WritableSlice> RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice(); - WritableSlice> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice(); + WritableSlice> RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice(); + WritableSlice> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice(); WritableSlice TRACE_DELTAS_CACHE = Slices.createSimpleSlice(); WritableSlice> LOOP_RANGE_ITERATOR_RESOLVED_CALL = Slices.createSimpleSlice(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index f459b957426..8548c135138 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -28,9 +28,11 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.context.*; import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.constants.ConstantUtils; import org.jetbrains.jet.lang.resolve.name.Name; @@ -148,18 +150,18 @@ public class CallExpressionResolver { } @Nullable - private ResolvedCall getResolvedCallForFunction( + private ResolvedCallWithTrace getResolvedCallForFunction( @NotNull Call call, @NotNull JetExpression callExpression, @NotNull ReceiverValue receiver, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, @NotNull boolean[] result ) { CallResolver callResolver = expressionTypingServices.getCallResolver(); - OverloadResolutionResults results = callResolver.resolveFunctionCall( + OverloadResolutionResultsImpl results = callResolver.resolveFunctionCall( BasicCallResolutionContext.create(context, call, resolveMode)); if (!results.isNothing()) { checkSuper(receiver, results, context.trace, callExpression); result[0] = true; if (results.isSingleResult() && resolveMode == ResolveMode.TOP_LEVEL_CALL) { - ResolvedCallImpl callToComplete = results.getResultingCall().getResolvedCallToComplete(); + ResolvedCallImpl callToComplete = results.getResultingCall().getCallToCompleteTypeArgumentInference(); if (CallResolverUtil.hasReturnTypeDependentOnNotInferredParams(callToComplete)) return null; // Expected type mismatch was reported before as 'TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH' @@ -271,7 +273,7 @@ public class CallExpressionResolver { Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create(context.trace, "trace to resolve as function call", callExpression); - ResolvedCall resolvedCall = getResolvedCallForFunction( + ResolvedCallWithTrace resolvedCall = getResolvedCallForFunction( call, callExpression, receiver, context.replaceBindingTrace(traceForFunction), resolveMode, result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; 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 ef8755cc60c..58a33a34d1e 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 @@ -133,7 +133,7 @@ public class CallResolver { } @NotNull - public OverloadResolutionResults resolveFunctionCall(@NotNull BasicCallResolutionContext context) { + /*package*/ OverloadResolutionResultsImpl resolveFunctionCall(@NotNull BasicCallResolutionContext context) { ProgressIndicatorProvider.checkCanceled(); @@ -260,19 +260,19 @@ public class CallResolver { CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); } - private OverloadResolutionResults doResolveCallOrGetCachedResults( - @NotNull WritableSlice> resolutionResultsSlice, + private OverloadResolutionResultsImpl doResolveCallOrGetCachedResults( + @NotNull WritableSlice> resolutionResultsSlice, @NotNull final BasicCallResolutionContext context, @NotNull final List> prioritizedTasks, @NotNull CallTransformer callTransformer, @NotNull final JetReferenceExpression reference ) { PsiElement element = context.call.getCallElement(); - OverloadResolutionResults results = null; + OverloadResolutionResultsImpl results = null; TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call); if (element instanceof JetExpression) { CallKey key = CallKey.create(context.call.getCallType(), (JetExpression) element); - OverloadResolutionResults cachedResults = context.trace.get(resolutionResultsSlice, key); + OverloadResolutionResultsImpl cachedResults = context.trace.get(resolutionResultsSlice, key); if (cachedResults != null) { DelegatingBindingTrace deltasTraceForResolve = context.trace.get(TRACE_DELTAS_CACHE, (JetExpression) element); assert deltasTraceForResolve != null; @@ -283,7 +283,6 @@ public class CallResolver { if (results == null) { BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall); results = doResolveCall(newContext, prioritizedTasks, callTransformer, reference); - assert results instanceof OverloadResolutionResultsImpl; DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace(); if (deltasTraceForTypeInference != null) { deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall); @@ -304,7 +303,7 @@ public class CallResolver { private void completeTypeInferenceDependentOnFunctionLiterals( @NotNull BasicCallResolutionContext context, - @NotNull OverloadResolutionResults results, + @NotNull OverloadResolutionResultsImpl results, @NotNull TracingStrategy tracing ) { if (!results.isSingleResult()) { @@ -314,13 +313,13 @@ public class CallResolver { return; } CallCandidateResolutionContext candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( - (ResolvedCallImpl) results.getResultingCall(), context, tracing); + results.getResultingCall().getCallToCompleteTypeArgumentInference(), context, tracing); candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(candidateContext); } - private OverloadResolutionResults completeTypeInferenceDependentOnExpectedType( + private OverloadResolutionResultsImpl completeTypeInferenceDependentOnExpectedType( @NotNull BasicCallResolutionContext context, - @NotNull OverloadResolutionResults results, + @NotNull OverloadResolutionResultsImpl results, @NotNull TracingStrategy tracing ) { if (results.isSingleResult()) { @@ -332,16 +331,15 @@ public class CallResolver { if (!results.isSingleResult()) return results; - ResolvedCallWithTrace resolvedCall = (ResolvedCallWithTrace) results.getResultingCall(); - //todo[ResolvedCallImpl] - if (!(resolvedCall instanceof ResolvedCallImpl)) return results; + ResolvedCallImpl resolvedCall = results.getResultingCall().getCallToCompleteTypeArgumentInference(); + if (!resolvedCall.hasIncompleteTypeParameters()) { CallCandidateResolutionContext callCandidateResolutionContext = - CallCandidateResolutionContext.createForCallBeingAnalyzed((ResolvedCallImpl) resolvedCall, context, tracing); + CallCandidateResolutionContext.createForCallBeingAnalyzed(resolvedCall, context, tracing); candidateResolver.completeNestedCallsInference(callCandidateResolutionContext); return results; } - ResolvedCallImpl copy = CallResolverUtil.copy((ResolvedCallImpl) resolvedCall, context); + ResolvedCallImpl copy = CallResolverUtil.copy(resolvedCall, context); CallCandidateResolutionContext callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(copy, context, tracing); candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(callCandidateResolutionContext, false); @@ -352,8 +350,8 @@ public class CallResolver { return OverloadResolutionResultsImpl.incompleteTypeInference(copy); } - private void cacheResults(@NotNull WritableSlice> resolutionResultsSlice, - @NotNull BasicCallResolutionContext context, @NotNull OverloadResolutionResults results, + private void cacheResults(@NotNull WritableSlice> resolutionResultsSlice, + @NotNull BasicCallResolutionContext context, @NotNull OverloadResolutionResultsImpl results, @NotNull DelegatingBindingTrace traceToResolveCall) { //boolean canBeCached = true; //for (ResolvedCall call : results.getResultingCalls()) { @@ -370,17 +368,17 @@ public class CallResolver { traceToResolveCall.addAllMyDataTo(deltasTraceToCacheResolve); - context.trace.record(resolutionResultsSlice, CallKey.create(context.call.getCallType(), (JetExpression)callElement), results); + context.trace.record(resolutionResultsSlice, CallKey.create(context.call.getCallType(), (JetExpression) callElement), results); context.trace.record(TRACE_DELTAS_CACHE, (JetExpression) callElement, deltasTraceToCacheResolve); } - private OverloadResolutionResults checkArgumentTypesAndFail(BasicCallResolutionContext context) { + private OverloadResolutionResultsImpl checkArgumentTypesAndFail(BasicCallResolutionContext context) { argumentTypeResolver.checkTypesWithNoCallee(context); return OverloadResolutionResultsImpl.nameNotFound(); } @NotNull - private OverloadResolutionResults doResolveCall( + private OverloadResolutionResultsImpl doResolveCall( @NotNull final BasicCallResolutionContext context, @NotNull final List> prioritizedTasks, // high to low priority @NotNull CallTransformer callTransformer, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index 853d51aac49..0bb1a6e66ea 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -107,15 +107,12 @@ public class CallResolverUtil { } public static boolean hasReturnTypeDependentOnNotInferredParams( - @NotNull ResolvedCallImpl resolvedCall + @NotNull ResolvedCallImpl callToComplete ) { - //todo[ResolvedCallImpl] - if (!(resolvedCall instanceof ResolvedCallImpl)) return false; - ResolvedCallImpl call = (ResolvedCallImpl) resolvedCall; - ConstraintSystem constraintSystem = call.getConstraintSystem(); + ConstraintSystem constraintSystem = callToComplete.getConstraintSystem(); if (constraintSystem == null) return false; - CallableDescriptor candidateDescriptor = call.getCandidateDescriptor(); + CallableDescriptor candidateDescriptor = callToComplete.getCandidateDescriptor(); JetType returnType = candidateDescriptor.getReturnType(); if (returnType == null) return false; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java index c71ea864c9c..7e2e4cb0444 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TypeInfoForCall.java @@ -22,11 +22,13 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.resolve.TraceUtil; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetTypeInfo; +import static org.jetbrains.jet.lang.resolve.calls.context.CallCandidateResolutionContext.createForCallBeingAnalyzed; + public class TypeInfoForCall { private final JetTypeInfo typeInfo; @@ -43,22 +45,16 @@ public class TypeInfoForCall { public static TypeInfoForCall create( @Nullable JetType type, @NotNull DataFlowInfo dataFlowInfo, - @NotNull ResolvedCall resolvedCall, + @NotNull ResolvedCallWithTrace resolvedCall, @NotNull Call call, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode ) { JetTypeInfo typeInfo = JetTypeInfo.create(type, dataFlowInfo); - CallCandidateResolutionContext callCandidateResolutionContext; - if (resolvedCall instanceof ResolvedCallImpl) { - //todo[ResolvedCallImpl] - callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( - (ResolvedCallImpl) resolvedCall, context.replaceBindingTrace(TraceUtil.TRACE_STUB), - call, resolveMode, ((ResolvedCallImpl) resolvedCall).getTracing()); - } - else { - callCandidateResolutionContext = null; - } + ResolvedCallImpl resolvedCallToComplete = resolvedCall.getCallToCompleteTypeArgumentInference(); + CallCandidateResolutionContext callCandidateResolutionContext = createForCallBeingAnalyzed( + resolvedCallToComplete, context.replaceBindingTrace(TraceUtil.TRACE_STUB), + call, resolveMode, resolvedCallToComplete.getTracing()); return new TypeInfoForCall(typeInfo, callCandidateResolutionContext); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java index 2ae822d470e..5ad4e201d5b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java @@ -269,4 +269,10 @@ public class ResolvedCallImpl implements ResolvedC assert dataFlowInfo != null; dataFlowInfo = dataFlowInfo.and(info); } + + @NotNull + @Override + public ResolvedCallImpl getCallToCompleteTypeArgumentInference() { + return this; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallWithTrace.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallWithTrace.java index 12da5beeb09..3639226ccd7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallWithTrace.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallWithTrace.java @@ -37,4 +37,12 @@ public interface ResolvedCallWithTrace extends Res boolean isDirty(); DelegatingBindingTrace getTrace(); + + /** + * //todo get rid of Impl class in the interface + * If the call has incomplete type parameters, it should be completed after resolution process is finished. + * Returns this for normal call and function call for VariableAsFunctionCall. + */ + @NotNull + ResolvedCallImpl getCallToCompleteTypeArgumentInference(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java index 7604892244d..46156889da8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java @@ -132,4 +132,10 @@ public class VariableAsFunctionResolvedCall implements ResolvedCallWithTrace getCallToCompleteTypeArgumentInference() { + return functionCall.getCallToCompleteTypeArgumentInference(); + } } diff --git a/compiler/testData/diagnostics/tests/inference/complicated/completeNestedCallsInference.kt b/compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedCallsInference.kt similarity index 100% rename from compiler/testData/diagnostics/tests/inference/complicated/completeNestedCallsInference.kt rename to compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedCallsInference.kt diff --git a/compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedForVariableAsFunctionCall.kt b/compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedForVariableAsFunctionCall.kt new file mode 100644 index 00000000000..9525f5ec59f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedForVariableAsFunctionCall.kt @@ -0,0 +1,16 @@ +package j + +trait MyFunc {} + +class A(val b: B) { +} + +class B { + fun invoke(f: (T) -> T): MyFunc = throw Exception() +} + +fun id(r: R) = r + +fun foo(a: A) { + val r : MyFunc = id (a.b { x -> x + 14 }) +} \ 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 460b02de3f1..a14a3da8af2 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2028,7 +2028,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } @TestMetadata("compiler/testData/diagnostics/tests/inference") - @InnerTestClasses({Inference.Complicated.class, Inference.Regressions.class, Inference.ReportingImprovements.class, Inference.UpperBounds.class, Inference.Varargs.class}) + @InnerTestClasses({Inference.NestedCalls.class, Inference.Regressions.class, Inference.ReportingImprovements.class, Inference.UpperBounds.class, Inference.Varargs.class}) public static class Inference extends AbstractDiagnosticsTestWithEagerResolve { public void testAllFilesPresentInInference() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inference"), Pattern.compile("^(.+)\\.kt$"), true); @@ -2154,15 +2154,20 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt"); } - @TestMetadata("compiler/testData/diagnostics/tests/inference/complicated") - public static class Complicated extends AbstractDiagnosticsTestWithEagerResolve { - public void testAllFilesPresentInComplicated() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inference/complicated"), Pattern.compile("^(.+)\\.kt$"), true); + @TestMetadata("compiler/testData/diagnostics/tests/inference/nestedCalls") + public static class NestedCalls extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInNestedCalls() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inference/nestedCalls"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("completeNestedCallsInference.kt") public void testCompleteNestedCallsInference() throws Exception { - doTest("compiler/testData/diagnostics/tests/inference/complicated/completeNestedCallsInference.kt"); + doTest("compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedCallsInference.kt"); + } + + @TestMetadata("completeNestedForVariableAsFunctionCall.kt") + public void testCompleteNestedForVariableAsFunctionCall() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/nestedCalls/completeNestedForVariableAsFunctionCall.kt"); } } @@ -2457,7 +2462,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage public static Test innerSuite() { TestSuite suite = new TestSuite("Inference"); suite.addTestSuite(Inference.class); - suite.addTestSuite(Complicated.class); + suite.addTestSuite(NestedCalls.class); suite.addTestSuite(Regressions.class); suite.addTestSuite(ReportingImprovements.class); suite.addTestSuite(UpperBounds.class);