diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowInfo.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowInfo.java index d2e390c93c7..6079c1183fc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowInfo.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowInfo.java @@ -39,7 +39,7 @@ public interface DataFlowInfo { DataFlowInfo disequate(@NotNull DataFlowValue a, @NotNull DataFlowValue b); @NotNull - DataFlowInfo establishSubtyping(@NotNull DataFlowValue[] values, @NotNull JetType type); + DataFlowInfo establishSubtyping(@NotNull DataFlowValue value, @NotNull JetType type); @NotNull DataFlowInfo and(@NotNull DataFlowInfo other); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java index 76f10f90c80..7b496f3b6de 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java @@ -23,10 +23,7 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.util.CommonSuppliers; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability.NOT_NULL; @@ -41,6 +38,8 @@ import static org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability.NOT_NUL @NotNull private final ListMultimap typeInfo; + private static final ImmutableMap EMPTY_NULLABILITY_INFO = + ImmutableMap.copyOf(Collections.emptyMap()); private static final ListMultimap EMPTY_TYPE_INFO = newTypeInfo(); /* package */ DelegatingDataFlowInfo( @@ -133,18 +132,13 @@ import static org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability.NOT_NUL @Override @NotNull - public DataFlowInfo establishSubtyping(@NotNull DataFlowValue[] values, @NotNull JetType type) { - if (values.length == 0) return this; - - ListMultimap newTypeInfo = newTypeInfo(); - Map newNullabilityInfo = Maps.newHashMap(); - for (DataFlowValue value : values) { - newTypeInfo.put(value, type); - if (!type.isNullable()) { - putNullability(newNullabilityInfo, value, NOT_NULL); - } - } - return new DelegatingDataFlowInfo(this, ImmutableMap.copyOf(newNullabilityInfo), newTypeInfo); + public DataFlowInfo establishSubtyping(@NotNull DataFlowValue value, @NotNull JetType type) { + if (value.getType().equals(type)) return this; + if (getPossibleTypes(value).contains(type)) return this; + ImmutableMap newNullabilityInfo = + type.isNullable() ? EMPTY_NULLABILITY_INFO : ImmutableMap.of(value, NOT_NULL); + ListMultimap newTypeInfo = ImmutableListMultimap.of(value, type); + return new DelegatingDataFlowInfo(this, newNullabilityInfo, newTypeInfo); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 023e18fa7aa..8b51a08ba97 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -222,7 +222,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { dataFlowInfo = typeInfo.getDataFlowInfo(); if (operationType == JetTokens.AS_KEYWORD) { DataFlowValue value = DataFlowValueFactory.INSTANCE.createDataFlowValue(left, typeInfo.getType(), context.trace.getBindingContext()); - dataFlowInfo = dataFlowInfo.establishSubtyping(new DataFlowValue[]{value}, targetType); + dataFlowInfo = dataFlowInfo.establishSubtyping(value, targetType); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java index fcf94abeb89..b56529d2ab6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java @@ -80,7 +80,9 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { subjectType = typeInfo.getType(); context = context.replaceDataFlowInfo(typeInfo.getDataFlowInfo()); } - final DataFlowValue variableDescriptor = subjectExpression != null ? DataFlowValueFactory.INSTANCE.createDataFlowValue(subjectExpression, subjectType, context.trace.getBindingContext()) : DataFlowValue.NULL; + final DataFlowValue subjectDataFlowValue = subjectExpression != null + ? DataFlowValueFactory.INSTANCE.createDataFlowValue(subjectExpression, subjectType, context.trace.getBindingContext()) + : DataFlowValue.NULL; // TODO : exhaustive patterns @@ -103,7 +105,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { DataFlowInfos infos = checkWhenCondition( subjectExpression, subjectExpression == null, subjectType, condition, - context, variableDescriptor); + context, subjectDataFlowValue); newDataFlowInfo = infos.thenInfo; elseDataFlowInfo = elseDataFlowInfo.and(infos.elseInfo); } @@ -113,7 +115,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { newDataFlowInfo = null; for (JetWhenCondition condition : conditions) { DataFlowInfos infos = checkWhenCondition(subjectExpression, subjectExpression == null, subjectType, condition, - context, variableDescriptor); + context, subjectDataFlowValue); if (newDataFlowInfo == null) { newDataFlowInfo = infos.thenInfo; } @@ -160,7 +162,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { final JetType subjectType, JetWhenCondition condition, final ExpressionTypingContext context, - final DataFlowValue... subjectVariables + final DataFlowValue subjectDataFlowValue ) { final Ref newDataFlowInfo = new Ref(noChange(context)); condition.accept(new JetVisitorVoid() { @@ -189,7 +191,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { context.trace.report(EXPECTED_CONDITION.on(condition)); } if (condition.getTypeRef() != null) { - DataFlowInfos result = checkTypeForIs(context, subjectType, condition.getTypeRef(), subjectVariables); + DataFlowInfos result = checkTypeForIs(context, subjectType, condition.getTypeRef(), subjectDataFlowValue); if (condition.isNegated()) { newDataFlowInfo.set(new DataFlowInfos(result.elseInfo, result.thenInfo)); } @@ -204,7 +206,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { JetExpression expression = condition.getExpression(); if (expression != null) { newDataFlowInfo.set(checkTypeForExpressionCondition(context, expression, subjectType, subjectExpression == null, - subjectVariables)); + subjectDataFlowValue)); } } @@ -231,7 +233,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { JetExpression expression, JetType subjectType, boolean conditionExpected, - DataFlowValue... subjectVariables + DataFlowValue subjectDataFlowValue ) { if (expression == null) { return noChange(context); @@ -258,12 +260,10 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { DataFlowValue expressionDataFlowValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(expression, type, context.trace.getBindingContext()); DataFlowInfos result = noChange(context); - for (DataFlowValue subjectVariable : subjectVariables) { - result = new DataFlowInfos( - result.thenInfo.equate(subjectVariable, expressionDataFlowValue), - result.elseInfo.disequate(subjectVariable, expressionDataFlowValue) - ); - } + result = new DataFlowInfos( + result.thenInfo.equate(subjectDataFlowValue, expressionDataFlowValue), + result.elseInfo.disequate(subjectDataFlowValue, expressionDataFlowValue) + ); return result; } @@ -271,7 +271,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { ExpressionTypingContext context, JetType subjectType, JetTypeReference typeReferenceAfterIs, - DataFlowValue... subjectVariables + DataFlowValue subjectDataFlowValue ) { if (typeReferenceAfterIs == null) { return noChange(context); @@ -281,7 +281,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { if (BasicExpressionTypingVisitor.isCastErased(subjectType, type, JetTypeChecker.INSTANCE)) { context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(typeReferenceAfterIs, type)); } - return new DataFlowInfos(context.dataFlowInfo.establishSubtyping(subjectVariables, type), context.dataFlowInfo); + return new DataFlowInfos(context.dataFlowInfo.establishSubtyping(subjectDataFlowValue, type), context.dataFlowInfo); } private static DataFlowInfos noChange(ExpressionTypingContext context) {