@@ -2641,7 +2641,60 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
2641
2641
}
2642
2642
2643
2643
BraceStmt *
2644
- TypeCheckFunctionBodyRequest::evaluate (Evaluator &evaluator,
2644
+ PreCheckFunctionBodyRequest::evaluate (Evaluator &evaluator,
2645
+ AbstractFunctionDecl *AFD) const {
2646
+ auto &ctx = AFD->getASTContext ();
2647
+ auto *body = AFD->getBody ();
2648
+ assert (body && " Expected body" );
2649
+ assert (!AFD->isBodyTypeChecked () && " Body already type-checked?" );
2650
+
2651
+ if (auto *func = dyn_cast<FuncDecl>(AFD)) {
2652
+ // Don't apply this pre-checking to functions with result builders.
2653
+ if (getResultBuilderType (func))
2654
+ return body;
2655
+
2656
+ if (func->hasSingleExpressionBody () &&
2657
+ func->getResultInterfaceType ()->isVoid ()) {
2658
+ // The function returns void. We don't need an explicit return, no
2659
+ // matter what the type of the expression is. Take the inserted return
2660
+ // back out.
2661
+ body->setLastElement (func->getSingleExpressionBody ());
2662
+ }
2663
+ // If there is a single statement in the body that can be turned into a
2664
+ // single expression return, do so now.
2665
+ if (!func->getResultInterfaceType ()->isVoid ()) {
2666
+ if (auto *S = body->getSingleActiveStatement ()) {
2667
+ if (S->mayProduceSingleValue (evaluator)) {
2668
+ auto *SVE = SingleValueStmtExpr::createWithWrappedBranches (
2669
+ ctx, S, /* DC*/ func, /* mustBeExpr*/ false );
2670
+ auto *RS = new (ctx) ReturnStmt (SourceLoc (), SVE);
2671
+ body->setLastElement (RS);
2672
+ func->setHasSingleExpressionBody ();
2673
+ func->setSingleExpressionBody (SVE);
2674
+ }
2675
+ }
2676
+ }
2677
+ }
2678
+
2679
+ if (auto *ctor = dyn_cast<ConstructorDecl>(AFD)) {
2680
+ if (body->empty () || !isKnownEndOfConstructor (body->getLastElement ())) {
2681
+ // For constructors, we make sure that the body ends with a "return"
2682
+ // stmt, which we either implicitly synthesize, or the user can write.
2683
+ // This simplifies SILGen.
2684
+ SmallVector<ASTNode, 8 > Elts (body->getElements ().begin (),
2685
+ body->getElements ().end ());
2686
+ Elts.push_back (new (ctx) ReturnStmt (body->getRBraceLoc (),
2687
+ /* value*/ nullptr ,
2688
+ /* implicit*/ true ));
2689
+ body = BraceStmt::create (ctx, body->getLBraceLoc (), Elts,
2690
+ body->getRBraceLoc (), body->isImplicit ());
2691
+ }
2692
+ }
2693
+ return body;
2694
+ }
2695
+
2696
+ BraceStmt *
2697
+ TypeCheckFunctionBodyRequest::evaluate (Evaluator &eval,
2645
2698
AbstractFunctionDecl *AFD) const {
2646
2699
ASTContext &ctx = AFD->getASTContext ();
2647
2700
@@ -2672,6 +2725,12 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
2672
2725
range.End );
2673
2726
};
2674
2727
2728
+ // First do a pre-check of the body.
2729
+ body = evaluateOrDefault (eval, PreCheckFunctionBodyRequest{AFD}, nullptr );
2730
+ assert (body);
2731
+
2732
+ // Then apply a result builder if we have one, which if successful will
2733
+ // produce a type-checked body.
2675
2734
bool alreadyTypeChecked = false ;
2676
2735
if (auto *func = dyn_cast<FuncDecl>(AFD)) {
2677
2736
if (Type builderType = getResultBuilderType (func)) {
@@ -2686,42 +2745,6 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &evaluator,
2686
2745
2687
2746
body->walk (ContextualizeClosuresAndMacros (AFD));
2688
2747
}
2689
- } else {
2690
- if (func->hasSingleExpressionBody () &&
2691
- func->getResultInterfaceType ()->isVoid ()) {
2692
- // The function returns void. We don't need an explicit return, no
2693
- // matter what the type of the expression is. Take the inserted return
2694
- // back out.
2695
- body->setLastElement (func->getSingleExpressionBody ());
2696
- }
2697
- // If there is a single statement in the body that can be turned into a
2698
- // single expression return, do so now.
2699
- if (!func->getResultInterfaceType ()->isVoid ()) {
2700
- if (auto *S = body->getSingleActiveStatement ()) {
2701
- if (S->mayProduceSingleValue (evaluator)) {
2702
- auto *SVE = SingleValueStmtExpr::createWithWrappedBranches (
2703
- ctx, S, /* DC*/ func, /* mustBeExpr*/ false );
2704
- auto *RS = new (ctx) ReturnStmt (SourceLoc (), SVE);
2705
- body->setLastElement (RS);
2706
- func->setHasSingleExpressionBody ();
2707
- func->setSingleExpressionBody (SVE);
2708
- }
2709
- }
2710
- }
2711
- }
2712
- } else if (auto *ctor = dyn_cast<ConstructorDecl>(AFD)) {
2713
- if (body->empty () ||
2714
- !isKnownEndOfConstructor (body->getLastElement ())) {
2715
- // For constructors, we make sure that the body ends with a "return" stmt,
2716
- // which we either implicitly synthesize, or the user can write. This
2717
- // simplifies SILGen.
2718
- SmallVector<ASTNode, 8 > Elts (body->getElements ().begin (),
2719
- body->getElements ().end ());
2720
- Elts.push_back (new (ctx) ReturnStmt (body->getRBraceLoc (),
2721
- /* value*/ nullptr ,
2722
- /* implicit*/ true ));
2723
- body = BraceStmt::create (ctx, body->getLBraceLoc (), Elts,
2724
- body->getRBraceLoc (), body->isImplicit ());
2725
2748
}
2726
2749
}
2727
2750
0 commit comments