@@ -795,6 +795,49 @@ AbstractionPattern AbstractionPattern::getPackExpansionPatternType() const {
795
795
llvm_unreachable (" bad kind" );
796
796
}
797
797
798
+ static CanType getPackExpansionCountType (CanType type) {
799
+ return cast<PackExpansionType>(type).getCountType ();
800
+ }
801
+
802
+ AbstractionPattern AbstractionPattern::getPackExpansionCountType () const {
803
+ switch (getKind ()) {
804
+ case Kind::Invalid:
805
+ llvm_unreachable (" querying invalid abstraction pattern!" );
806
+ case Kind::ObjCMethodType:
807
+ case Kind::CurriedObjCMethodType:
808
+ case Kind::PartialCurriedObjCMethodType:
809
+ case Kind::CFunctionAsMethodType:
810
+ case Kind::CurriedCFunctionAsMethodType:
811
+ case Kind::PartialCurriedCFunctionAsMethodType:
812
+ case Kind::CXXMethodType:
813
+ case Kind::CurriedCXXMethodType:
814
+ case Kind::PartialCurriedCXXMethodType:
815
+ case Kind::Tuple:
816
+ case Kind::OpaqueFunction:
817
+ case Kind::OpaqueDerivativeFunction:
818
+ case Kind::ObjCCompletionHandlerArgumentsType:
819
+ case Kind::ClangType:
820
+ llvm_unreachable (" pattern for function or tuple cannot be for "
821
+ " pack expansion type" );
822
+
823
+ case Kind::Opaque:
824
+ return *this ;
825
+
826
+ case Kind::Type:
827
+ if (isTypeParameterOrOpaqueArchetype ())
828
+ return AbstractionPattern::getOpaque ();
829
+ return AbstractionPattern (getGenericSubstitutions (),
830
+ getGenericSignature (),
831
+ ::getPackExpansionCountType (getType()));
832
+
833
+ case Kind::Discard:
834
+ return AbstractionPattern::getDiscard (
835
+ getGenericSubstitutions (), getGenericSignature (),
836
+ ::getPackExpansionCountType (getType()));
837
+ }
838
+ llvm_unreachable (" bad kind" );
839
+ }
840
+
798
841
size_t AbstractionPattern::getNumPackExpandedComponents () const {
799
842
assert (isPackExpansion ());
800
843
assert (getKind () == Kind::Type || getKind () == Kind::Discard);
@@ -2267,7 +2310,7 @@ class SubstFunctionTypePatternVisitor
2267
2310
// Recursively visit the pattern type.
2268
2311
auto patternTy = visit (substPatternType, origPatternType);
2269
2312
2270
- // Find a pack parameter from the pattern to expand over .
2313
+ // If the pattern contains a pack parameter, use that as the count type .
2271
2314
CanType countParam;
2272
2315
patternTy->walkPackReferences ([&](Type t) {
2273
2316
if (t->isTypeParameter ()) {
@@ -2281,10 +2324,22 @@ class SubstFunctionTypePatternVisitor
2281
2324
return false ;
2282
2325
});
2283
2326
2284
- // If that didn't work, we should be able to find an expansion
2285
- // to use from either the substituted type or the subs. At worst,
2286
- // we can make one.
2287
- assert (countParam && " implementable but lazy" );
2327
+ // If the pattern was fully substituted, substitute the original
2328
+ // count type and use that instead.
2329
+ if (!countParam) {
2330
+ auto origCountType = origExpansion.getPackExpansionCountType ();
2331
+ CanType substCountType;
2332
+ if (origExpansion.getGenericSubstitutions ()) {
2333
+ substCountType = cast<PackExpansionType>(origExpansion.getType ())
2334
+ .getCountType ();
2335
+ } else {
2336
+ assert (candidateSubstType);
2337
+ substCountType =
2338
+ cast<PackExpansionType>(candidateSubstType).getCountType ();
2339
+ }
2340
+
2341
+ countParam = visit (substCountType, origCountType);
2342
+ }
2288
2343
2289
2344
return CanPackExpansionType::get (patternTy, countParam);
2290
2345
}
0 commit comments