File tree Expand file tree Collapse file tree 4 files changed +51
-0
lines changed Expand file tree Collapse file tree 4 files changed +51
-0
lines changed Original file line number Diff line number Diff line change @@ -6453,6 +6453,7 @@ class ConjunctionElementProducer : public BindingProducer<ConjunctionElement> {
64536453// /
64546454// / This includes:
64556455// / - Not yet resolved outer VarDecls (including closure parameters)
6456+ // / - Outer pack expansions that are not yet fully resolved
64566457// / - Return statements with a contextual type that has not yet been resolved
64576458// /
64586459// / This is required because isolated conjunctions, just like single-expression
@@ -6474,6 +6475,7 @@ class TypeVarRefCollector : public ASTWalker {
64746475
64756476 // / Infer the referenced type variables from a given decl.
64766477 void inferTypeVars (Decl *D);
6478+ void inferTypeVars (PackExpansionExpr *);
64776479
64786480 MacroWalking getMacroWalkingBehavior () const override {
64796481 return MacroWalking::Arguments;
Original file line number Diff line number Diff line change @@ -870,6 +870,14 @@ void TypeVarRefCollector::inferTypeVars(Decl *D) {
870870 TypeVars.insert (typeVars.begin (), typeVars.end ());
871871}
872872
873+ void TypeVarRefCollector::inferTypeVars (PackExpansionExpr *E) {
874+ auto expansionType = CS.getType (E)->castTo <PackExpansionType>();
875+
876+ SmallPtrSet<TypeVariableType *, 4 > referencedVars;
877+ expansionType->getTypeVariables (referencedVars);
878+ TypeVars.insert (referencedVars.begin (), referencedVars.end ());
879+ }
880+
873881ASTWalker::PreWalkResult<Expr *>
874882TypeVarRefCollector::walkToExprPre (Expr *expr) {
875883 if (isa<ClosureExpr>(expr))
@@ -891,6 +899,14 @@ TypeVarRefCollector::walkToExprPre(Expr *expr) {
891899 inferTypeVars (D);
892900 }
893901 }
902+
903+ if (auto *packElement = getAsExpr<PackElementExpr>(expr)) {
904+ // If environment hasn't been established yet, it means that pack expansion
905+ // appears inside of this closure.
906+ if (auto *outerEnvironment = CS.getPackEnvironment (packElement))
907+ inferTypeVars (outerEnvironment);
908+ }
909+
894910 return Action::Continue (expr);
895911}
896912
Original file line number Diff line number Diff line change @@ -153,6 +153,17 @@ class TypeVariableRefFinder : public ASTWalker {
153153 }
154154 }
155155
156+ // If closure appears inside of a pack expansion, the elements
157+ // that reference pack elements have to bring expansion's shape
158+ // type in scope to make sure that the shapes match.
159+ if (auto *packElement = getAsExpr<PackElementExpr>(expr)) {
160+ if (auto *outerEnvironment = CS.getPackEnvironment (packElement)) {
161+ auto *expansionTy = CS.simplifyType (CS.getType (outerEnvironment))
162+ ->castTo <PackExpansionType>();
163+ expansionTy->getCountType ()->getTypeVariables (ReferencedVars);
164+ }
165+ }
166+
156167 return Action::Continue (expr);
157168 }
158169
Original file line number Diff line number Diff line change @@ -739,3 +739,25 @@ do {
739739 // expected-warning@-2 {{immutable value 'y' was never used; consider replacing with '_' or removing it}}
740740 }
741741}
742+
743+ // Closures wrapped in a pack expansion
744+ do {
745+ func takesClosure< T> ( _ fn: ( ) -> T ) -> T { return fn ( ) }
746+
747+ func testClosure< each T > ( _ t: repeat each T ) -> ( repeat each T ) {
748+ ( repeat takesClosure { each t } ) // Ok
749+ }
750+
751+ func testMultiStmtClosure< each T > ( _ t: repeat each T ) -> ( repeat each T ) {
752+ ( repeat takesClosure {
753+ let v = each t
754+ return v
755+ } ) // Ok
756+ }
757+
758+ func takesAutoclosure< T> ( _ fn: @autoclosure ( ) -> T ) -> T { return fn ( ) }
759+
760+ func f2< each T > ( _ t: repeat each T ) -> ( repeat each T ) {
761+ ( repeat takesAutoclosure( each t) ) // Ok
762+ }
763+ }
You can’t perform that action at this time.
0 commit comments