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> {
6453
6453
// /
6454
6454
// / This includes:
6455
6455
// / - Not yet resolved outer VarDecls (including closure parameters)
6456
+ // / - Outer pack expansions that are not yet fully resolved
6456
6457
// / - Return statements with a contextual type that has not yet been resolved
6457
6458
// /
6458
6459
// / This is required because isolated conjunctions, just like single-expression
@@ -6474,6 +6475,7 @@ class TypeVarRefCollector : public ASTWalker {
6474
6475
6475
6476
// / Infer the referenced type variables from a given decl.
6476
6477
void inferTypeVars (Decl *D);
6478
+ void inferTypeVars (PackExpansionExpr *);
6477
6479
6478
6480
MacroWalking getMacroWalkingBehavior () const override {
6479
6481
return MacroWalking::Arguments;
Original file line number Diff line number Diff line change @@ -870,6 +870,14 @@ void TypeVarRefCollector::inferTypeVars(Decl *D) {
870
870
TypeVars.insert (typeVars.begin (), typeVars.end ());
871
871
}
872
872
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
+
873
881
ASTWalker::PreWalkResult<Expr *>
874
882
TypeVarRefCollector::walkToExprPre (Expr *expr) {
875
883
if (isa<ClosureExpr>(expr))
@@ -891,6 +899,14 @@ TypeVarRefCollector::walkToExprPre(Expr *expr) {
891
899
inferTypeVars (D);
892
900
}
893
901
}
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
+
894
910
return Action::Continue (expr);
895
911
}
896
912
Original file line number Diff line number Diff line change @@ -153,6 +153,17 @@ class TypeVariableRefFinder : public ASTWalker {
153
153
}
154
154
}
155
155
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
+
156
167
return Action::Continue (expr);
157
168
}
158
169
Original file line number Diff line number Diff line change @@ -739,3 +739,25 @@ do {
739
739
// expected-warning@-2 {{immutable value 'y' was never used; consider replacing with '_' or removing it}}
740
740
}
741
741
}
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