@@ -382,22 +382,49 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
382
382
}
383
383
384
384
Pattern *convertBindingsToOptionalSome (Expr *E) {
385
- auto *Bind = dyn_cast<BindOptionalExpr>(E->getSemanticsProvidingExpr ());
386
- if (!Bind) return getSubExprPattern (E);
385
+ auto *expr = E->getSemanticsProvidingExpr ();
386
+ auto *bindExpr = dyn_cast<BindOptionalExpr>(expr);
387
+ if (!bindExpr) {
388
+ // Let's see if this expression prefixed with any number of '?'
389
+ // has any other disjoint 'BindOptionalExpr' inside of it, if so,
390
+ // we need to wrap such sub-expression into `OptionalEvaluationExpr`.
391
+ bool hasDisjointChaining = false ;
392
+ expr->forEachChildExpr ([&](Expr *subExpr) -> Expr * {
393
+ // If there is `OptionalEvaluationExpr` in the AST
394
+ // it means that all of possible `BindOptionalExpr`
395
+ // which follow are covered by it.
396
+ if (isa<OptionalEvaluationExpr>(subExpr))
397
+ return nullptr ;
398
+
399
+ if (isa<BindOptionalExpr>(subExpr)) {
400
+ hasDisjointChaining = true ;
401
+ return nullptr ;
402
+ }
403
+
404
+ return subExpr;
405
+ });
406
+
407
+ if (hasDisjointChaining)
408
+ E = new (TC.Context ) OptionalEvaluationExpr (E);
409
+
410
+ return getSubExprPattern (E);
411
+ }
387
412
388
- auto sub = convertBindingsToOptionalSome (Bind->getSubExpr ());
389
- return new (TC.Context ) OptionalSomePattern (sub, Bind->getQuestionLoc ());
413
+ auto *subExpr = convertBindingsToOptionalSome (bindExpr->getSubExpr ());
414
+ return new (TC.Context ) OptionalSomePattern (subExpr,
415
+ bindExpr->getQuestionLoc ());
390
416
}
391
417
392
418
// Convert a x? to OptionalSome pattern. In the AST form, this will look like
393
419
// an OptionalEvaluationExpr with an immediate BindOptionalExpr inside of it.
394
420
Pattern *visitOptionalEvaluationExpr (OptionalEvaluationExpr *E) {
421
+ auto *subExpr = E->getSubExpr ();
395
422
// We only handle the case where one or more bind expressions are subexprs
396
423
// of the optional evaluation. Other cases are not simple postfix ?'s.
397
- if (!isa<BindOptionalExpr>(E-> getSubExpr () ->getSemanticsProvidingExpr ()))
424
+ if (!isa<BindOptionalExpr>(subExpr ->getSemanticsProvidingExpr ()))
398
425
return nullptr ;
399
426
400
- return convertBindingsToOptionalSome (E-> getSubExpr () );
427
+ return convertBindingsToOptionalSome (subExpr );
401
428
}
402
429
403
430
0 commit comments