@@ -436,7 +436,8 @@ ElementInfo makeJoinElement(ConstraintSystem &cs, TypeJoinExpr *join,
436436
437437struct SyntacticElementContext
438438 : public llvm::PointerUnion<AbstractFunctionDecl *, AbstractClosureExpr *,
439- SingleValueStmtExpr *, ExprPattern *, TapExpr *> {
439+ SingleValueStmtExpr *, ExprPattern *, TapExpr *,
440+ CaptureListExpr *> {
440441 // Inherit the constructors from PointerUnion.
441442 using PointerUnion::PointerUnion;
442443
@@ -461,6 +462,10 @@ struct SyntacticElementContext
461462 return {func};
462463 }
463464
465+ static SyntacticElementContext forCaptureList (CaptureListExpr *CLE) {
466+ return {CLE};
467+ }
468+
464469 static SyntacticElementContext
465470 forSingleValueStmtExpr (SingleValueStmtExpr *SVE,
466471 TypeJoinExpr *Join = nullptr ) {
@@ -484,6 +489,9 @@ struct SyntacticElementContext
484489 return EP->getDeclContext ();
485490 } else if (auto *tap = this ->dyn_cast <TapExpr *>()) {
486491 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 ();
487495 } else {
488496 llvm_unreachable (" unsupported kind" );
489497 }
@@ -552,6 +560,8 @@ class SyntacticElementConstraintGenerator
552560 SyntacticElementContext context;
553561 ConstraintLocator *locator;
554562
563+ std::optional<llvm::SaveAndRestore<DeclContext *>> DCScope;
564+
555565 // / Whether a conjunction was generated.
556566 bool generatedConjunction = false ;
557567
@@ -562,7 +572,17 @@ class SyntacticElementConstraintGenerator
562572 SyntacticElementConstraintGenerator (ConstraintSystem &cs,
563573 SyntacticElementContext context,
564574 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+ }
566586
567587 void createConjunction (ArrayRef<ElementInfo> elements,
568588 ConstraintLocator *locator, bool isIsolated = false ,
@@ -1616,26 +1636,40 @@ bool isConditionOfStmt(ConstraintLocatorBuilder locator) {
16161636 return false ;
16171637}
16181638
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+
16191665ConstraintSystem::SolutionKind
16201666ConstraintSystem::simplifySyntacticElementConstraint (
16211667 ASTNode element, ContextualTypeInfo contextInfo, bool isDiscarded,
16221668 TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
1623- auto anchor = locator.getAnchor ();
16241669
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)
16371672 return SolutionKind::Error;
1638- }
16391673
16401674 SyntacticElementConstraintGenerator generator (*this , *context,
16411675 getConstraintLocator (locator));
0 commit comments