diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java index 4311134c7e8..0cdfa3a2f1a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java @@ -75,7 +75,7 @@ public class ControlStructureTypingUtils { ) { SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( constructionName.toUpperCase(), argumentNames, isArgumentNullable); - TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName); + TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName, context); ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(call, function); CallResolver callResolver = expressionTypingServices.getCallResolver(); OverloadResolutionResults results = callResolver.resolveCallWithKnownCandidate( @@ -248,7 +248,8 @@ public class ControlStructureTypingUtils { @NotNull /*package*/ static TracingStrategy createTracingForSpecialConstruction( final @NotNull Call call, - final @NotNull String constructionName + final @NotNull String constructionName, + final @NotNull ExpressionTypingContext context ) { class CheckTypeContext { public BindingTrace trace; @@ -272,7 +273,15 @@ public class ControlStructureTypingUtils { if (typeInfo == null) return false; Ref hasError = Ref.create(); - DataFlowUtils.checkType(typeInfo.getType(), expression, c.expectedType, typeInfo.getDataFlowInfo(), c.trace, hasError); + DataFlowUtils.checkType( + typeInfo.getType(), + expression, + context + .replaceExpectedType(c.expectedType) + .replaceDataFlowInfo(typeInfo.getDataFlowInfo()) + .replaceBindingTrace(c.trace), + hasError + ); return hasError.get(); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowUtils.java index 89eb531b454..525b87c060b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowUtils.java @@ -156,49 +156,41 @@ public class DataFlowUtils { @Nullable public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context) { - return checkType(expressionType, expression, context.expectedType, context.dataFlowInfo, context.trace); + return checkType(expressionType, expression, context, (Ref) null); } @Nullable public static JetType checkType( - @Nullable JetType expressionType, @NotNull JetExpression expressionToCheck, - @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace - ) { - return checkType(expressionType, expressionToCheck, expectedType, dataFlowInfo, trace, null); - } - - @Nullable - public static JetType checkType( - @Nullable final JetType expressionType, @NotNull JetExpression expressionToCheck, - @NotNull JetType expectedType, @NotNull final DataFlowInfo dataFlowInfo, @NotNull final BindingTrace trace, + @Nullable final JetType expressionType, + @NotNull JetExpression expressionToCheck, + @NotNull final ResolutionContext c, @Nullable Ref hasError ) { if (hasError != null) hasError.set(false); final JetExpression expression = JetPsiUtil.safeDeparenthesize(expressionToCheck, false); - recordExpectedType(trace, expression, expectedType); + recordExpectedType(c.trace, expression, c.expectedType); if (expressionType == null) return null; - if (noExpectedType(expectedType) || !expectedType.getConstructor().isDenotable() || - JetTypeChecker.DEFAULT.isSubtypeOf(expressionType, expectedType)) { + if (noExpectedType(c.expectedType) || !c.expectedType.getConstructor().isDenotable() || + JetTypeChecker.DEFAULT.isSubtypeOf(expressionType, c.expectedType)) { - if (!noExpectedType(expectedType)) { - Approximation.Info approximationInfo = TypesPackage.getApproximationTo(expressionType, expectedType, + if (!noExpectedType(c.expectedType)) { + Approximation.Info approximationInfo = TypesPackage.getApproximationTo(expressionType, c.expectedType, new Approximation.DataFlowExtras() { private DataFlowValue getDataFlowValue() { - return DataFlowValueFactory.createDataFlowValue(expression, expressionType, trace.getBindingContext()); + return DataFlowValueFactory.createDataFlowValue(expression, expressionType, c.trace.getBindingContext()); } @Override public boolean getCanBeNull() { - return dataFlowInfo.getNullability(getDataFlowValue()).canBeNull(); + return c.dataFlowInfo.getNullability(getDataFlowValue()).canBeNull(); } - @NotNull @Override public Set getPossibleTypes() { - return dataFlowInfo.getPossibleTypes(getDataFlowValue()); + return c.dataFlowInfo.getPossibleTypes(getDataFlowValue()); } @NotNull @@ -209,7 +201,7 @@ public class DataFlowUtils { } ); if (approximationInfo != null) { - trace.record(BindingContext.EXPRESSION_RESULT_APPROXIMATION, expression, approximationInfo); + c.trace.record(BindingContext.EXPRESSION_RESULT_APPROXIMATION, expression, approximationInfo); } } @@ -217,25 +209,25 @@ public class DataFlowUtils { } if (expression instanceof JetConstantExpression) { - CompileTimeConstant value = ConstantExpressionEvaluator.OBJECT$.evaluate(expression, trace, expectedType); + CompileTimeConstant value = ConstantExpressionEvaluator.OBJECT$.evaluate(expression, c.trace, c.expectedType); if (value instanceof IntegerValueTypeConstant) { - value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, expectedType); + value = EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) value, c.expectedType); } - boolean error = new CompileTimeConstantChecker(trace, true) - .checkConstantExpressionType(value, (JetConstantExpression) expression, expectedType); + boolean error = new CompileTimeConstantChecker(c.trace, true) + .checkConstantExpressionType(value, (JetConstantExpression) expression, c.expectedType); if (hasError != null) hasError.set(error); return expressionType; } - DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, expressionType, trace.getBindingContext()); + DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, expressionType, c.trace.getBindingContext()); - for (JetType possibleType : dataFlowInfo.getPossibleTypes(dataFlowValue)) { - if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType)) { - SmartCastUtils.recordCastOrError(expression, possibleType, trace, dataFlowValue.isStableIdentifier(), false); + for (JetType possibleType : c.dataFlowInfo.getPossibleTypes(dataFlowValue)) { + if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, c.expectedType)) { + SmartCastUtils.recordCastOrError(expression, possibleType, c.trace, dataFlowValue.isStableIdentifier(), false); return possibleType; } } - trace.report(TYPE_MISMATCH.on(expression, expectedType, expressionType)); + c.trace.report(TYPE_MISMATCH.on(expression, c.expectedType, expressionType)); if (hasError != null) hasError.set(true); return expressionType; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java index 7210dc19bb4..cca21423485 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorForStatements.java @@ -307,7 +307,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace); } dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo(); - DataFlowUtils.checkType(binaryOperationType, expression, leftType, dataFlowInfo, context.trace); + DataFlowUtils.checkType(binaryOperationType, expression, context.replaceExpectedType(leftType).replaceDataFlowInfo(dataFlowInfo)); BasicExpressionTypingVisitor.checkLValue(context.trace, leftOperand); } temporary.commit();