@@ -436,7 +436,8 @@ ElementInfo makeJoinElement(ConstraintSystem &cs, TypeJoinExpr *join,
436
436
437
437
struct SyntacticElementContext
438
438
: public llvm::PointerUnion<AbstractFunctionDecl *, AbstractClosureExpr *,
439
- SingleValueStmtExpr *, ExprPattern *, TapExpr *> {
439
+ SingleValueStmtExpr *, ExprPattern *, TapExpr *,
440
+ CaptureListExpr *> {
440
441
// Inherit the constructors from PointerUnion.
441
442
using PointerUnion::PointerUnion;
442
443
@@ -461,6 +462,10 @@ struct SyntacticElementContext
461
462
return {func};
462
463
}
463
464
465
+ static SyntacticElementContext forCaptureList (CaptureListExpr *CLE) {
466
+ return {CLE};
467
+ }
468
+
464
469
static SyntacticElementContext
465
470
forSingleValueStmtExpr (SingleValueStmtExpr *SVE,
466
471
TypeJoinExpr *Join = nullptr ) {
@@ -484,6 +489,9 @@ struct SyntacticElementContext
484
489
return EP->getDeclContext ();
485
490
} else if (auto *tap = this ->dyn_cast <TapExpr *>()) {
486
491
return tap->getVar ()->getDeclContext ();
492
+ } else if (auto *CLE = this ->dyn_cast <CaptureListExpr *>()) {
493
+ // The capture list is part of the closure's parent context.
494
+ return CLE->getClosureBody ()->getParent ();
487
495
} else {
488
496
llvm_unreachable (" unsupported kind" );
489
497
}
@@ -552,6 +560,8 @@ class SyntacticElementConstraintGenerator
552
560
SyntacticElementContext context;
553
561
ConstraintLocator *locator;
554
562
563
+ std::optional<llvm::SaveAndRestore<DeclContext *>> DCScope;
564
+
555
565
// / Whether a conjunction was generated.
556
566
bool generatedConjunction = false ;
557
567
@@ -562,7 +572,17 @@ class SyntacticElementConstraintGenerator
562
572
SyntacticElementConstraintGenerator (ConstraintSystem &cs,
563
573
SyntacticElementContext context,
564
574
ConstraintLocator *locator)
565
- : cs(cs), context(context), locator(locator) {}
575
+ : cs(cs), context(context), locator(locator) {
576
+ // Capture list bindings in multi-statement closures get solved as part of
577
+ // the closure's conjunction, which has the DeclContext set to the closure.
578
+ // This is wrong for captures though, which are semantically bound outside
579
+ // of the closure body. So we need to re-adjust their DeclContext here for
580
+ // constraint generation. The constraint system's DeclContext will be wrong
581
+ // for solving, but CSGen should ensure that constraints carry the correct
582
+ // DeclContext.
583
+ if (context.is <CaptureListExpr *>())
584
+ DCScope.emplace (cs.DC , context.getAsDeclContext ());
585
+ }
566
586
567
587
void createConjunction (ArrayRef<ElementInfo> elements,
568
588
ConstraintLocator *locator, bool isIsolated = false ,
@@ -1616,26 +1636,40 @@ bool isConditionOfStmt(ConstraintLocatorBuilder locator) {
1616
1636
return false ;
1617
1637
}
1618
1638
1639
+ static std::optional<SyntacticElementContext>
1640
+ getSyntacticElementContext (ASTNode element, ConstraintLocatorBuilder locator) {
1641
+ // / Capture list bindings are part of the capture list, which is semantically
1642
+ // / outside the closure it's part of. As such, it needs its own context.
1643
+ if (auto *PBD = getAsDecl<PatternBindingDecl>(element)) {
1644
+ if (auto *VD = PBD->getSingleVar ()) {
1645
+ if (auto *CLE = VD->getParentCaptureList ())
1646
+ return SyntacticElementContext::forCaptureList (CLE);
1647
+ }
1648
+ }
1649
+
1650
+ auto anchor = locator.getAnchor ();
1651
+ if (auto *closure = getAsExpr<ClosureExpr>(anchor))
1652
+ return SyntacticElementContext::forClosure (closure);
1653
+ if (auto *fn = getAsDecl<AbstractFunctionDecl>(anchor))
1654
+ return SyntacticElementContext::forFunction (fn);
1655
+ if (auto *SVE = getAsExpr<SingleValueStmtExpr>(anchor))
1656
+ return SyntacticElementContext::forSingleValueStmtExpr (SVE);
1657
+ if (auto *EP = getAsPattern<ExprPattern>(anchor))
1658
+ return SyntacticElementContext::forExprPattern (EP);
1659
+ if (auto *tap = getAsExpr<TapExpr>(anchor))
1660
+ return SyntacticElementContext::forTapExpr (tap);
1661
+
1662
+ return std::nullopt;
1663
+ }
1664
+
1619
1665
ConstraintSystem::SolutionKind
1620
1666
ConstraintSystem::simplifySyntacticElementConstraint (
1621
1667
ASTNode element, ContextualTypeInfo contextInfo, bool isDiscarded,
1622
1668
TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
1623
- auto anchor = locator.getAnchor ();
1624
1669
1625
- std::optional<SyntacticElementContext> context;
1626
- if (auto *closure = getAsExpr<ClosureExpr>(anchor)) {
1627
- context = SyntacticElementContext::forClosure (closure);
1628
- } else if (auto *fn = getAsDecl<AbstractFunctionDecl>(anchor)) {
1629
- context = SyntacticElementContext::forFunction (fn);
1630
- } else if (auto *SVE = getAsExpr<SingleValueStmtExpr>(anchor)) {
1631
- context = SyntacticElementContext::forSingleValueStmtExpr (SVE);
1632
- } else if (auto *EP = getAsPattern<ExprPattern>(anchor)) {
1633
- context = SyntacticElementContext::forExprPattern (EP);
1634
- } else if (auto *tap = getAsExpr<TapExpr>(anchor)) {
1635
- context = SyntacticElementContext::forTapExpr (tap);
1636
- } else {
1670
+ auto context = getSyntacticElementContext (element, locator);
1671
+ if (!context)
1637
1672
return SolutionKind::Error;
1638
- }
1639
1673
1640
1674
SyntacticElementConstraintGenerator generator (*this , *context,
1641
1675
getConstraintLocator (locator));
0 commit comments