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 62f7d6f7f27..e8d301adac1 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 @@ -420,10 +420,7 @@ public class CandidateResolver { return; } DataFlowInfo dataFlowInfoForValueArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(argument); - ResolutionContext newContext = context.replaceExpectedType(context.expectedType); - if (dataFlowInfoForValueArgument != null) { - newContext = newContext.replaceDataFlowInfo(dataFlowInfoForValueArgument); - } + ResolutionContext newContext = context.replaceExpectedType(context.expectedType).replaceDataFlowInfo(dataFlowInfoForValueArgument); DataFlowUtils.checkType(type, expression, newContext); } @@ -573,13 +570,19 @@ public class CandidateResolver { JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); JetExpression argumentExpression = valueArgument.getArgumentExpression(); + TemporaryBindingTrace traceToResolveArgument = TemporaryBindingTrace.create( context.trace, "transient trace to resolve argument", argumentExpression); JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT); - CallResolutionContext newContext = context.replaceBindingTrace(traceToResolveArgument).replaceExpectedType(expectedType); - JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, - resolveFunctionArgumentBodies, traceToResolveArgument); - JetType type = updateResultTypeForSmartCasts(typeInfoForCall.getType(), argumentExpression, context); + DataFlowInfo dataFlowInfoForArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(valueArgument); + CallResolutionContext newContext = context.replaceBindingTrace(traceToResolveArgument) + .replaceExpectedType(expectedType).replaceDataFlowInfo(dataFlowInfoForArgument); + + JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( + argumentExpression, newContext, resolveFunctionArgumentBodies, traceToResolveArgument); + context.candidateCall.getDataFlowInfoForArguments().updateInfo(valueArgument, typeInfoForCall.getDataFlowInfo()); + + JetType type = updateResultTypeForSmartCasts(typeInfoForCall.getType(), argumentExpression, dataFlowInfoForArgument, context.trace); constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition( valueParameterDescriptor.getIndex())); if (isErrorType != null) { @@ -591,13 +594,13 @@ public class CandidateResolver { private static JetType updateResultTypeForSmartCasts( @Nullable JetType type, @Nullable JetExpression argumentExpression, - @NotNull CallCandidateResolutionContext context + @NotNull DataFlowInfo dataFlowInfoForArgument, + @NotNull BindingTrace trace ) { if (argumentExpression == null || type == null) return type; - DataFlowValue dataFlowValue = - DataFlowValueFactory.INSTANCE.createDataFlowValue(argumentExpression, type, context.trace.getBindingContext()); - Set possibleTypes = context.dataFlowInfo.getPossibleTypes(dataFlowValue); + DataFlowValue dataFlowValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(argumentExpression, type, trace.getBindingContext()); + Set possibleTypes = dataFlowInfoForArgument.getPossibleTypes(dataFlowValue); if (possibleTypes.isEmpty()) return type; return TypeUtils.intersect(JetTypeChecker.INSTANCE, possibleTypes); diff --git a/compiler/testData/diagnostics/tests/smartCasts/inference/dependentOnPrevArg.kt b/compiler/testData/diagnostics/tests/smartCasts/inference/dependentOnPrevArg.kt new file mode 100644 index 00000000000..6a101411a7a --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/inference/dependentOnPrevArg.kt @@ -0,0 +1,7 @@ +package a + +fun foo(u: T, v: T): T = u + +fun test(s: String?) { + val r: String = foo(s!!, s) +} \ 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 cd4c849cd16..2bb83ac4d22 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -5122,6 +5122,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/smartCasts/inference"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("dependentOnPrevArg.kt") + public void testDependentOnPrevArg() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/inference/dependentOnPrevArg.kt"); + } + @TestMetadata("intersectionTypes.kt") public void testIntersectionTypes() throws Exception { doTest("compiler/testData/diagnostics/tests/smartCasts/inference/intersectionTypes.kt");