data flow info for arg may affect next argument's type for type argument inference case

This commit is contained in:
Svetlana Isakova
2013-07-30 16:17:24 +04:00
parent 9ccd1e5ddd
commit 99bb6f13b5
3 changed files with 27 additions and 12 deletions
@@ -420,10 +420,7 @@ public class CandidateResolver {
return; return;
} }
DataFlowInfo dataFlowInfoForValueArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(argument); DataFlowInfo dataFlowInfoForValueArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(argument);
ResolutionContext<?> newContext = context.replaceExpectedType(context.expectedType); ResolutionContext<?> newContext = context.replaceExpectedType(context.expectedType).replaceDataFlowInfo(dataFlowInfoForValueArgument);
if (dataFlowInfoForValueArgument != null) {
newContext = newContext.replaceDataFlowInfo(dataFlowInfoForValueArgument);
}
DataFlowUtils.checkType(type, expression, newContext); DataFlowUtils.checkType(type, expression, newContext);
} }
@@ -573,13 +570,19 @@ public class CandidateResolver {
JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument); JetType effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument);
JetExpression argumentExpression = valueArgument.getArgumentExpression(); JetExpression argumentExpression = valueArgument.getArgumentExpression();
TemporaryBindingTrace traceToResolveArgument = TemporaryBindingTrace.create( TemporaryBindingTrace traceToResolveArgument = TemporaryBindingTrace.create(
context.trace, "transient trace to resolve argument", argumentExpression); context.trace, "transient trace to resolve argument", argumentExpression);
JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT); JetType expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT);
CallResolutionContext<?> newContext = context.replaceBindingTrace(traceToResolveArgument).replaceExpectedType(expectedType); DataFlowInfo dataFlowInfoForArgument = context.candidateCall.getDataFlowInfoForArguments().getInfo(valueArgument);
JetTypeInfo typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, CallResolutionContext<?> newContext = context.replaceBindingTrace(traceToResolveArgument)
resolveFunctionArgumentBodies, traceToResolveArgument); .replaceExpectedType(expectedType).replaceDataFlowInfo(dataFlowInfoForArgument);
JetType type = updateResultTypeForSmartCasts(typeInfoForCall.getType(), argumentExpression, context);
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( constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, ConstraintPosition.getValueParameterPosition(
valueParameterDescriptor.getIndex())); valueParameterDescriptor.getIndex()));
if (isErrorType != null) { if (isErrorType != null) {
@@ -591,13 +594,13 @@ public class CandidateResolver {
private static JetType updateResultTypeForSmartCasts( private static JetType updateResultTypeForSmartCasts(
@Nullable JetType type, @Nullable JetType type,
@Nullable JetExpression argumentExpression, @Nullable JetExpression argumentExpression,
@NotNull CallCandidateResolutionContext<?> context @NotNull DataFlowInfo dataFlowInfoForArgument,
@NotNull BindingTrace trace
) { ) {
if (argumentExpression == null || type == null) return type; if (argumentExpression == null || type == null) return type;
DataFlowValue dataFlowValue = DataFlowValue dataFlowValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(argumentExpression, type, trace.getBindingContext());
DataFlowValueFactory.INSTANCE.createDataFlowValue(argumentExpression, type, context.trace.getBindingContext()); Set<JetType> possibleTypes = dataFlowInfoForArgument.getPossibleTypes(dataFlowValue);
Set<JetType> possibleTypes = context.dataFlowInfo.getPossibleTypes(dataFlowValue);
if (possibleTypes.isEmpty()) return type; if (possibleTypes.isEmpty()) return type;
return TypeUtils.intersect(JetTypeChecker.INSTANCE, possibleTypes); return TypeUtils.intersect(JetTypeChecker.INSTANCE, possibleTypes);
@@ -0,0 +1,7 @@
package a
fun <T> foo(u: T, <!UNUSED_PARAMETER!>v<!>: T): T = u
fun test(s: String?) {
val <!UNUSED_VARIABLE!>r<!>: String = foo(s!!, s)
}
@@ -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); 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") @TestMetadata("intersectionTypes.kt")
public void testIntersectionTypes() throws Exception { public void testIntersectionTypes() throws Exception {
doTest("compiler/testData/diagnostics/tests/smartCasts/inference/intersectionTypes.kt"); doTest("compiler/testData/diagnostics/tests/smartCasts/inference/intersectionTypes.kt");