@@ -1065,30 +1065,6 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1065
1065
return RS;
1066
1066
}
1067
1067
1068
- // If the body consisted of a single return without a result
1069
- //
1070
- // func foo() -> Int {
1071
- // return
1072
- // }
1073
- //
1074
- // in parseAbstractFunctionBody the return is given an empty, implicit tuple
1075
- // as its result
1076
- //
1077
- // func foo() -> Int {
1078
- // return ()
1079
- // }
1080
- //
1081
- // Look for that case and diagnose it as missing return expression.
1082
- if (!ResultTy->isVoid() && TheFunc->hasSingleExpressionBody()) {
1083
- auto expr = TheFunc->getSingleExpressionBody();
1084
- if (expr->isImplicit() && isa<TupleExpr>(expr) &&
1085
- cast<TupleExpr>(expr)->getNumElements() == 0) {
1086
- getASTContext().Diags.diagnose(RS->getReturnLoc(),
1087
- diag::return_expr_missing);
1088
- return RS;
1089
- }
1090
- }
1091
-
1092
1068
Expr *E = RS->getResult();
1093
1069
TypeCheckExprOptions options = {};
1094
1070
@@ -2677,6 +2653,83 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2677
2653
return false;
2678
2654
}
2679
2655
2656
+ /// Insert an implicit return for a single expression body function if needed,
2657
+ /// returning \c true if the implicit return was added, \c false otherwise.
2658
+ static bool addSingleExprReturnIfNeeded(BraceStmt *body, DeclContext *dc) {
2659
+ // Must have a single active element.
2660
+ auto node = body->getSingleActiveElement();
2661
+ if (!node)
2662
+ return false;
2663
+
2664
+ auto &ctx = dc->getASTContext();
2665
+ auto makeResult = [&](Expr *E) -> bool {
2666
+ body->setLastElement(ReturnStmt::createImplicit(ctx, E));
2667
+ return true;
2668
+ };
2669
+
2670
+ // For a constructor, we only support nil literals as the implicit result.
2671
+ if (auto *ctor = dyn_cast<ConstructorDecl>(dc)) {
2672
+ if (auto *E = node.dyn_cast<Expr *>()) {
2673
+ if (ctor->isFailable() && isa<NilLiteralExpr>(E))
2674
+ return makeResult(E);
2675
+ }
2676
+ return false;
2677
+ }
2678
+
2679
+ // Otherwise, we only support implicit results for FuncDecls and ClosureExprs.
2680
+ if (!isa<FuncDecl>(dc) && !isa<ClosureExpr>(dc))
2681
+ return false;
2682
+
2683
+ if (auto *fd = dyn_cast<FuncDecl>(dc)) {
2684
+ // Don't apply if we have a result builder, or a Void return type.
2685
+ if (getResultBuilderType(fd) || fd->getResultInterfaceType()->isVoid())
2686
+ return false;
2687
+ }
2688
+
2689
+ // A statement can potentially become an expression.
2690
+ if (auto *S = node.dyn_cast<Stmt *>()) {
2691
+ if (S->mayProduceSingleValue(ctx)) {
2692
+ auto *SVE = SingleValueStmtExpr::createWithWrappedBranches(
2693
+ ctx, S, dc, /*mustBeExpr*/ false);
2694
+ return makeResult(SVE);
2695
+ }
2696
+ // If we have a single statement 'return' in a closure, treat it as a
2697
+ // single expression body. If we don't have a return value, synthesize
2698
+ // 'return ()'. Don't do this in a FuncDecl since we know we have a
2699
+ // non-Void return.
2700
+ if (isa<ClosureExpr>(dc)) {
2701
+ if (auto *returnStmt = dyn_cast<ReturnStmt>(S)) {
2702
+ // Treat the existing result as a single expression return.
2703
+ if (returnStmt->hasResult())
2704
+ return true;
2705
+
2706
+ auto *returnExpr = TupleExpr::createEmpty(ctx, SourceLoc(), SourceLoc(),
2707
+ /*implicit*/ true);
2708
+ returnStmt->setResult(returnExpr);
2709
+ return true;
2710
+ }
2711
+ }
2712
+ }
2713
+
2714
+ if (auto *E = node.dyn_cast<Expr *>()) {
2715
+ // Take any expression, except for assignments. This helps improves
2716
+ // diagnostics.
2717
+ // TODO: We probably ought to apply this to closures too, but that currently
2718
+ // regresses a couple of diagnostics.
2719
+ if (!isa<ClosureExpr>(dc)) {
2720
+ auto *SemanticExpr = E->getSemanticsProvidingExpr();
2721
+ if (auto *SE = dyn_cast<SequenceExpr>(SemanticExpr)) {
2722
+ if (SE->getNumElements() > 1 && isa<AssignExpr>(SE->getElement(1)))
2723
+ return false;
2724
+ }
2725
+ if (isa<AssignExpr>(SemanticExpr))
2726
+ return false;
2727
+ }
2728
+ return makeResult(E);
2729
+ }
2730
+ return false;
2731
+ }
2732
+
2680
2733
BraceStmt *
2681
2734
PreCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
2682
2735
AbstractFunctionDecl *AFD) const {
@@ -2687,38 +2740,15 @@ PreCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
2687
2740
assert(body && "Expected body");
2688
2741
assert(!AFD->isBodyTypeChecked() && "Body already type-checked?");
2689
2742
2690
- if (auto *func = dyn_cast<FuncDecl>(AFD)) {
2691
- // Don't apply this pre-checking to functions with result builders.
2692
- if (getResultBuilderType(func))
2693
- return body;
2694
-
2695
- if (func->hasSingleExpressionBody() &&
2696
- func->getResultInterfaceType()->isVoid()) {
2697
- // The function returns void. We don't need an explicit return, no
2698
- // matter what the type of the expression is. Take the inserted return
2699
- // back out.
2700
- body->setLastElement(func->getSingleExpressionBody());
2701
- }
2702
- // If there is a single statement in the body that can be turned into a
2703
- // single expression return, do so now.
2704
- if (!func->getResultInterfaceType()->isVoid()) {
2705
- if (auto *S = body->getSingleActiveStatement()) {
2706
- if (S->mayProduceSingleValue(ctx)) {
2707
- auto *SVE = SingleValueStmtExpr::createWithWrappedBranches(
2708
- ctx, S, /*DC*/ func, /*mustBeExpr*/ false);
2709
- body->setLastElement(ReturnStmt::createImplicit(ctx, SVE));
2710
- func->setHasSingleExpressionBody();
2711
- func->setSingleExpressionBody(SVE);
2712
- }
2713
- }
2714
- }
2715
- }
2743
+ // Insert an implicit return for a single expression body.
2744
+ if (addSingleExprReturnIfNeeded(body, AFD))
2745
+ AFD->setHasSingleExpressionBody();
2716
2746
2747
+ // For constructors, we make sure that the body ends with a "return"
2748
+ // stmt, which we either implicitly synthesize, or the user can write.
2749
+ // This simplifies SILGen.
2717
2750
if (auto *ctor = dyn_cast<ConstructorDecl>(AFD)) {
2718
2751
if (body->empty() || !isKnownEndOfConstructor(body->getLastElement())) {
2719
- // For constructors, we make sure that the body ends with a "return"
2720
- // stmt, which we either implicitly synthesize, or the user can write.
2721
- // This simplifies SILGen.
2722
2752
SmallVector<ASTNode, 8> Elts(body->getElements().begin(),
2723
2753
body->getElements().end());
2724
2754
Elts.push_back(ReturnStmt::createImplicit(ctx, body->getRBraceLoc(),
@@ -2730,6 +2760,17 @@ PreCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
2730
2760
return body;
2731
2761
}
2732
2762
2763
+ BraceStmt *PreCheckClosureBodyRequest::evaluate(Evaluator &evaluator,
2764
+ ClosureExpr *closure) const {
2765
+ auto *body = closure->getBody();
2766
+
2767
+ // Insert an implicit return for a single expression body.
2768
+ if (addSingleExprReturnIfNeeded(body, closure))
2769
+ closure->setBody(body, /*isSingleExpression*/ true);
2770
+
2771
+ return body;
2772
+ }
2773
+
2733
2774
/// Determine whether the given declaration requires a definition.
2734
2775
///
2735
2776
/// Only valid for declarations that can have definitions, i.e.,
0 commit comments