diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 92506851fb9..4de1da8dc51 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetTypeInferrer; import org.jetbrains.jet.lexer.JetTokens; @@ -727,7 +728,7 @@ public class TopDownAnalyzer { JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(declaration, bodyExpression); JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, flowInformationProvider); - typeInferrer.getType(functionInnerScope, bodyExpression, true, null); + typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, descriptor, JetStandardClasses.getUnitType()); } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index e12584ab8ca..384e1c455a1 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -308,9 +308,44 @@ public class JetTypeInferrer { public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) { final JetType expectedReturnType = functionDescriptor.getUnsubstitutedReturnType(); + JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); + checkFunctionReturnType(functionInnerScope, function, functionDescriptor, expectedReturnType); +// Map typeMap = collectReturnedExpressionsWithTypes(outerScope, function, functionDescriptor, expectedReturnType); +// if (typeMap.isEmpty()) { +// return; // The function returns Nothing +// } +// for (Map.Entry entry : typeMap.entrySet()) { +// JetType actualType = entry.getValue(); +// JetElement element = entry.getKey(); +// JetTypeChecker typeChecker = semanticServices.getTypeChecker(); +// if (!typeChecker.isSubtypeOf(actualType, expectedReturnType)) { +// if (typeChecker.isConvertibleBySpecialConversion(actualType, expectedReturnType)) { +// if (expectedReturnType.getConstructor().equals(JetStandardClasses.getUnitType().getConstructor()) +// && element.getParent() instanceof JetReturnExpression) { +// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type Unit"); +// } +// } +// else { +// if (element == function) { +// JetExpression bodyExpression = function.getBodyExpression(); +// assert bodyExpression != null; +// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType); +// } +// else if (element instanceof JetExpression) { +// JetExpression expression = (JetExpression) element; +// trace.getErrorHandler().typeMismatch(expression, expectedReturnType, actualType); +// } +// else { +// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type " + expectedReturnType); +// } +// } +// } +// } + } + + public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @Nullable final JetType expectedReturnType) { JetExpression bodyExpression = function.getBodyExpression(); assert bodyExpression != null; - JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); new TypeInferrerVisitor(functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), null, expectedReturnType).getType(bodyExpression); List unreachableElements = Lists.newArrayList(); @@ -356,37 +391,6 @@ public class JetTypeInferrer { } }); } -// Map typeMap = collectReturnedExpressionsWithTypes(outerScope, function, functionDescriptor, expectedReturnType); -// if (typeMap.isEmpty()) { -// return; // The function returns Nothing -// } -// for (Map.Entry entry : typeMap.entrySet()) { -// JetType actualType = entry.getValue(); -// JetElement element = entry.getKey(); -// JetTypeChecker typeChecker = semanticServices.getTypeChecker(); -// if (!typeChecker.isSubtypeOf(actualType, expectedReturnType)) { -// if (typeChecker.isConvertibleBySpecialConversion(actualType, expectedReturnType)) { -// if (expectedReturnType.getConstructor().equals(JetStandardClasses.getUnitType().getConstructor()) -// && element.getParent() instanceof JetReturnExpression) { -// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type Unit"); -// } -// } -// else { -// if (element == function) { -// JetExpression bodyExpression = function.getBodyExpression(); -// assert bodyExpression != null; -// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType); -// } -// else if (element instanceof JetExpression) { -// JetExpression expression = (JetExpression) element; -// trace.getErrorHandler().typeMismatch(expression, expectedReturnType, actualType); -// } -// else { -// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type " + expectedReturnType); -// } -// } -// } -// } } @NotNull diff --git a/idea/testData/checker/FunctionReturnTypes.jet b/idea/testData/checker/FunctionReturnTypes.jet index 2aa8c2f68da..e3413d2ce59 100644 --- a/idea/testData/checker/FunctionReturnTypes.jet +++ b/idea/testData/checker/FunctionReturnTypes.jet @@ -110,4 +110,13 @@ fun blockReturnValueTypeMatch() : Int { else return 1.0 } -val a = return 1 \ No newline at end of file +val a = return 1 + +class A() { + this(a : Int) : this() { + if (a == 1) + return + return 1 + } + +} \ No newline at end of file