Local returns are only allowed with explicitly specified return types
This is a temporary limitation: otherwise type inference is having trouble to account for all the returned expressions. We will fix the inference and remove the limitation
This commit is contained in:
@@ -535,6 +535,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<JetSimpleNameExpression> EXPRESSION_EXPECTED_NAMESPACE_FOUND = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<JetReturnExpression> RETURN_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<JetReturnExpression> RETURN_NOT_ALLOWED_EXPLICIT_RETURN_TYPE_REQUIRED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<JetReturnExpression> RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<JetDeclarationWithBody>
|
||||
NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY = DiagnosticFactory0.create(ERROR, DECLARATION_WITH_BODY);
|
||||
|
||||
+1
@@ -83,6 +83,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM,
|
||||
"Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly"); // TODO: message
|
||||
MAP.put(RETURN_NOT_ALLOWED, "'return' is not allowed here");
|
||||
MAP.put(RETURN_NOT_ALLOWED_EXPLICIT_RETURN_TYPE_REQUIRED, "'return' is only allowed in function literals that have return types specified explicitly");
|
||||
MAP.put(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE, "Projections are not allowed for immediate arguments of a supertype");
|
||||
MAP.put(LABEL_NAME_CLASH, "There is more than one label with such a name in this scope");
|
||||
MAP.put(EXPRESSION_EXPECTED_NAMESPACE_FOUND, "Expression expected, but a namespace name found");
|
||||
|
||||
+2
@@ -282,6 +282,8 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetType declaredReturnType = null;
|
||||
if (returnTypeRef != null) {
|
||||
declaredReturnType = context.expressionTypingServices.getTypeResolver().resolveType(context.scope, returnTypeRef, context.trace, true);
|
||||
// This is needed for ControlStructureTypingVisitor#visitReturnExpression() to properly type-check returned expressions
|
||||
functionDescriptor.setReturnType(declaredReturnType);
|
||||
if (expectedReturnType != null) {
|
||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(declaredReturnType, expectedReturnType)) {
|
||||
temporaryTrace.report(EXPECTED_RETURN_TYPE_MISMATCH.on(returnTypeRef, expectedReturnType));
|
||||
|
||||
+13
-4
@@ -58,6 +58,8 @@ import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*;
|
||||
|
||||
public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
public static final String RETURN_NOT_ALLOWED_MESSAGE = "Return not allowed";
|
||||
|
||||
protected ControlStructureTypingVisitor(@NotNull ExpressionTypingInternals facade) {
|
||||
super(facade);
|
||||
}
|
||||
@@ -504,7 +506,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
} while (containingFunction instanceof JetFunctionLiteral);
|
||||
// Unqualified, in a function literal
|
||||
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
|
||||
resultType = ErrorUtils.createErrorType("Return not allowed");
|
||||
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
|
||||
}
|
||||
if (containingFunctionDescriptor != null) {
|
||||
expectedType = DescriptorUtils.getFunctionExpectedReturnType(containingFunctionDescriptor, (JetElement) containingFunction);
|
||||
@@ -513,17 +515,24 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
else {
|
||||
// Outside a function
|
||||
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
|
||||
resultType = ErrorUtils.createErrorType("Return not allowed");
|
||||
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
|
||||
}
|
||||
}
|
||||
else if (labelTargetElement != null) {
|
||||
SimpleFunctionDescriptor functionDescriptor = context.trace.get(FUNCTION, labelTargetElement);
|
||||
if (functionDescriptor != null) {
|
||||
expectedType = DescriptorUtils.getFunctionExpectedReturnType(functionDescriptor, labelTargetElement);
|
||||
if (functionDescriptor != containingFunctionDescriptor) {
|
||||
boolean inLambdaWithNoExplicitType = expectedType == TypeUtils.NO_EXPECTED_TYPE;
|
||||
if (inLambdaWithNoExplicitType) {
|
||||
// expectedType is NO_EXPECTED_TYPE iff the return type of the corresponding function descriptor is not computed yet
|
||||
// our temporary policy is to prohibit returns in this case. It mostly applies to local returns in lambdas
|
||||
context.trace.report(RETURN_NOT_ALLOWED_EXPLICIT_RETURN_TYPE_REQUIRED.on(expression));
|
||||
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
|
||||
}
|
||||
else if (functionDescriptor != containingFunctionDescriptor) {
|
||||
// Qualified, non-local
|
||||
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
|
||||
resultType = ErrorUtils.createErrorType("Return not allowed");
|
||||
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user