@@ -510,21 +510,23 @@ TypeChecker::applyFunctionBuilderBodyTransform(FuncDecl *FD,
510
510
body->getRBraceLoc ());
511
511
}
512
512
513
- ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder (
514
- ClosureExpr *closure , Type builderType, ConstraintLocator *calleeLocator ,
515
- ConstraintLocatorBuilder locator) {
513
+ ConstraintSystem::TypeMatchResult ConstraintSystem::matchFunctionBuilder (
514
+ AnyFunctionRef fn , Type builderType, Type bodyResultType ,
515
+ ConstraintLocator *calleeLocator, ConstraintLocatorBuilder locator) {
516
516
auto builder = builderType->getAnyNominal ();
517
517
assert (builder && " Bad function builder type" );
518
518
assert (builder->getAttrs ().hasAttribute <FunctionBuilderAttr>());
519
519
520
520
// FIXME: Right now, single-expression closures suppress the function
521
521
// builder translation.
522
- if (closure->hasSingleExpressionBody ())
523
- return getTypeMatchSuccess ();
522
+ if (auto closure = fn.getAbstractClosureExpr ()) {
523
+ if (closure->hasSingleExpressionBody ())
524
+ return getTypeMatchSuccess ();
525
+ }
524
526
525
527
// Pre-check the closure body: pre-check any expressions in it and look
526
528
// for return statements.
527
- auto request = PreCheckFunctionBuilderRequest{closure };
529
+ auto request = PreCheckFunctionBuilderRequest{fn };
528
530
switch (evaluateOrDefault (getASTContext ().evaluator , request,
529
531
FunctionBuilderClosurePreCheck::Error)) {
530
532
case FunctionBuilderClosurePreCheck::Okay:
@@ -547,7 +549,7 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder(
547
549
// Check whether we can apply this specific function builder.
548
550
BuilderClosureVisitor visitor (getASTContext (), this ,
549
551
/* wantExpr=*/ false , builderType);
550
- (void )visitor.visit (closure-> getBody ());
552
+ (void )visitor.visit (fn. getBody ());
551
553
552
554
// If we saw a control-flow statement or declaration that the builder
553
555
// cannot handle, we don't have a well-formed function builder application.
@@ -585,17 +587,18 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder(
585
587
586
588
BuilderClosureVisitor visitor (getASTContext (), this ,
587
589
/* wantExpr=*/ true , builderType);
588
- Expr *singleExpr = visitor.visit (closure-> getBody ());
590
+ Expr *singleExpr = visitor.visit (fn. getBody ());
589
591
590
592
// We've already pre-checked all the original expressions, but do the
591
593
// pre-check to the generated expression just to set up any preconditions
592
594
// that CSGen might have.
593
595
//
594
596
// TODO: just build the AST the way we want it in the first place.
595
- if (ConstraintSystem::preCheckExpression (singleExpr, closure))
597
+ auto dc = fn.getAsDeclContext ();
598
+ if (ConstraintSystem::preCheckExpression (singleExpr, dc))
596
599
return getTypeMatchFailure (locator);
597
600
598
- singleExpr = generateConstraints (singleExpr, closure );
601
+ singleExpr = generateConstraints (singleExpr, dc );
599
602
if (!singleExpr)
600
603
return getTypeMatchFailure (locator);
601
604
@@ -607,41 +610,37 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder(
607
610
functionBuilderTransformed.begin (),
608
611
functionBuilderTransformed.end (),
609
612
[&](const std::pair<AnyFunctionRef, AppliedBuilderTransform> &elt) {
610
- return elt.first == closure ;
613
+ return elt.first == fn ;
611
614
}) == functionBuilderTransformed.end () &&
612
615
" already transformed this closure along this path!?!" );
613
616
functionBuilderTransformed.push_back (
614
- std::make_pair (closure ,
617
+ std::make_pair (fn ,
615
618
AppliedBuilderTransform{builderType, singleExpr}));
616
619
617
- // Bind the result type of the closure to the type of the transformed
618
- // expression.
619
- Type closureType = getType (closure);
620
- auto fnType = closureType->castTo <FunctionType>();
621
- addConstraint (ConstraintKind::Equal, fnType->getResult (), transformedType,
620
+ // Bind the body result type to the type of the transformed expression.
621
+ addConstraint (ConstraintKind::Equal, bodyResultType, transformedType,
622
622
locator);
623
623
return getTypeMatchSuccess ();
624
624
}
625
625
626
626
namespace {
627
627
628
628
// / Pre-check all the expressions in the closure body.
629
- class PreCheckFunctionBuilderClosure : public ASTWalker {
630
- ClosureExpr *Closure ;
629
+ class PreCheckFunctionBuilderApplication : public ASTWalker {
630
+ AnyFunctionRef Fn ;
631
631
bool HasReturnStmt = false ;
632
632
bool HasError = false ;
633
633
public:
634
- PreCheckFunctionBuilderClosure (ClosureExpr *closure)
635
- : Closure(closure) {}
634
+ PreCheckFunctionBuilderApplication (AnyFunctionRef fn) : Fn(fn) {}
636
635
637
636
FunctionBuilderClosurePreCheck run () {
638
- Stmt *oldBody = Closure-> getBody ();
637
+ Stmt *oldBody = Fn. getBody ();
639
638
640
639
Stmt *newBody = oldBody->walk (*this );
641
640
642
641
// If the walk was aborted, it was because we had a problem of some kind.
643
642
assert ((newBody == nullptr ) == (HasError || HasReturnStmt) &&
644
- " unexpected short-circuit while walking closure body" );
643
+ " unexpected short-circuit while walking body" );
645
644
if (!newBody) {
646
645
if (HasError)
647
646
return FunctionBuilderClosurePreCheck::Error;
@@ -658,7 +657,7 @@ class PreCheckFunctionBuilderClosure : public ASTWalker {
658
657
// Pre-check the expression. If this fails, abort the walk immediately.
659
658
// Otherwise, replace the expression with the result of pre-checking.
660
659
// In either case, don't recurse into the expression.
661
- if (ConstraintSystem::preCheckExpression (E, /* DC*/ Closure )) {
660
+ if (ConstraintSystem::preCheckExpression (E, /* DC*/ Fn. getAsDeclContext () )) {
662
661
HasError = true ;
663
662
return std::make_pair (false , nullptr );
664
663
}
@@ -682,10 +681,12 @@ class PreCheckFunctionBuilderClosure : public ASTWalker {
682
681
683
682
llvm::Expected<FunctionBuilderClosurePreCheck>
684
683
PreCheckFunctionBuilderRequest::evaluate (Evaluator &eval,
685
- ClosureExpr *closure ) const {
684
+ AnyFunctionRef fn ) const {
686
685
// Single-expression closures should already have been pre-checked.
687
- if (closure->hasSingleExpressionBody ())
688
- return FunctionBuilderClosurePreCheck::Okay;
686
+ if (auto closure = fn.getAbstractClosureExpr ()) {
687
+ if (closure->hasSingleExpressionBody ())
688
+ return FunctionBuilderClosurePreCheck::Okay;
689
+ }
689
690
690
- return PreCheckFunctionBuilderClosure (closure ).run ();
691
+ return PreCheckFunctionBuilderApplication (fn ).run ();
691
692
}
0 commit comments