@@ -2486,52 +2486,6 @@ FunctionType::ExtInfo ConstraintSystem::closureEffects(ClosureExpr *expr) {
2486
2486
bool foundThrow () { return FoundThrow; }
2487
2487
};
2488
2488
2489
- // A walker that looks for 'async' and 'await' expressions
2490
- // that aren't nested within closures or nested declarations.
2491
- class FindInnerAsync : public ASTWalker {
2492
- bool FoundAsync = false ;
2493
-
2494
- std::pair<bool , Expr *> walkToExprPre (Expr *expr) override {
2495
- // If we've found an 'await', record it and terminate the traversal.
2496
- if (isa<AwaitExpr>(expr)) {
2497
- FoundAsync = true ;
2498
- return { false , nullptr };
2499
- }
2500
-
2501
- // Do not recurse into other closures.
2502
- if (isa<ClosureExpr>(expr))
2503
- return { false , expr };
2504
-
2505
- return { true , expr };
2506
- }
2507
-
2508
- bool walkToDeclPre (Decl *decl) override {
2509
- // Do not walk into function or type declarations.
2510
- if (auto *patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
2511
- if (patternBinding->isSpawnLet ())
2512
- FoundAsync = true ;
2513
-
2514
- return true ;
2515
- }
2516
-
2517
- return false ;
2518
- }
2519
-
2520
- std::pair<bool , Stmt *> walkToStmtPre (Stmt *stmt) override {
2521
- if (auto forEach = dyn_cast<ForEachStmt>(stmt)) {
2522
- if (forEach->getAwaitLoc ().isValid ()) {
2523
- FoundAsync = true ;
2524
- return { false , nullptr };
2525
- }
2526
- }
2527
-
2528
- return { true , stmt };
2529
- }
2530
-
2531
- public:
2532
- bool foundAsync () { return FoundAsync; }
2533
- };
2534
-
2535
2489
// If either 'throws' or 'async' was explicitly specified, use that
2536
2490
// set of effects.
2537
2491
bool throws = expr->getThrowsLoc ().isValid ();
@@ -2552,13 +2506,11 @@ FunctionType::ExtInfo ConstraintSystem::closureEffects(ClosureExpr *expr) {
2552
2506
2553
2507
auto throwFinder = FindInnerThrows (*this , expr);
2554
2508
body->walk (throwFinder);
2555
- auto asyncFinder = FindInnerAsync ();
2556
- body->walk (asyncFinder);
2557
2509
auto result = ASTExtInfoBuilder ()
2558
- .withThrows (throwFinder.foundThrow ())
2559
- .withAsync (asyncFinder. foundAsync ( ))
2560
- .withConcurrent (concurrent)
2561
- .build ();
2510
+ .withThrows (throwFinder.foundThrow ())
2511
+ .withAsync (bool ( findAsyncNode (expr) ))
2512
+ .withConcurrent (concurrent)
2513
+ .build ();
2562
2514
closureEffectsCache[expr] = result;
2563
2515
return result;
2564
2516
}
@@ -5708,3 +5660,60 @@ bool constraints::isOperatorDisjunction(Constraint *disjunction) {
5708
5660
auto *decl = getOverloadChoiceDecl (choices.front ());
5709
5661
return decl ? decl->isOperator () : false ;
5710
5662
}
5663
+
5664
+ ASTNode constraints::findAsyncNode (ClosureExpr *closure) {
5665
+ auto *body = closure->getBody ();
5666
+ if (!body)
5667
+ return ASTNode ();
5668
+
5669
+ // A walker that looks for 'async' and 'await' expressions
5670
+ // that aren't nested within closures or nested declarations.
5671
+ class FindInnerAsync : public ASTWalker {
5672
+ ASTNode AsyncNode;
5673
+
5674
+ std::pair<bool , Expr *> walkToExprPre (Expr *expr) override {
5675
+ // If we've found an 'await', record it and terminate the traversal.
5676
+ if (isa<AwaitExpr>(expr)) {
5677
+ AsyncNode = expr;
5678
+ return {false , nullptr };
5679
+ }
5680
+
5681
+ // Do not recurse into other closures.
5682
+ if (isa<ClosureExpr>(expr))
5683
+ return {false , expr};
5684
+
5685
+ return {true , expr};
5686
+ }
5687
+
5688
+ bool walkToDeclPre (Decl *decl) override {
5689
+ // Do not walk into function or type declarations.
5690
+ if (auto *patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
5691
+ if (patternBinding->isSpawnLet ())
5692
+ AsyncNode = patternBinding;
5693
+
5694
+ return true ;
5695
+ }
5696
+
5697
+ return false ;
5698
+ }
5699
+
5700
+ std::pair<bool , Stmt *> walkToStmtPre (Stmt *stmt) override {
5701
+ if (auto forEach = dyn_cast<ForEachStmt>(stmt)) {
5702
+ if (forEach->getAwaitLoc ().isValid ()) {
5703
+ AsyncNode = forEach;
5704
+ return {false , nullptr };
5705
+ }
5706
+ }
5707
+
5708
+ return {true , stmt};
5709
+ }
5710
+
5711
+ public:
5712
+ ASTNode getAsyncNode () { return AsyncNode; }
5713
+ };
5714
+
5715
+ FindInnerAsync asyncFinder;
5716
+ body->walk (asyncFinder);
5717
+
5718
+ return asyncFinder.getAsyncNode ();
5719
+ }
0 commit comments