@@ -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);
@@ -2268,7 +2311,7 @@ class SubstFunctionTypePatternVisitor
2268
2311
// Recursively visit the pattern type.
2269
2312
auto patternTy = visit (substPatternType, origPatternType);
2270
2313
2271
- // Find a pack parameter from the pattern to expand over .
2314
+ // If the pattern contains a pack parameter, use that as the count type .
2272
2315
CanType countParam;
2273
2316
patternTy->walkPackReferences ([&](Type t) {
2274
2317
if (t->isTypeParameter ()) {
@@ -2282,10 +2325,22 @@ class SubstFunctionTypePatternVisitor
2282
2325
return false ;
2283
2326
});
2284
2327
2285
- // If that didn't work, we should be able to find an expansion
2286
- // to use from either the substituted type or the subs. At worst,
2287
- // we can make one.
2288
- assert (countParam && " implementable but lazy" );
2328
+ // If the pattern was fully substituted, substitute the original
2329
+ // count type and use that instead.
2330
+ if (!countParam) {
2331
+ auto origCountType = origExpansion.getPackExpansionCountType ();
2332
+ CanType substCountType;
2333
+ if (origExpansion.getGenericSubstitutions ()) {
2334
+ substCountType = cast<PackExpansionType>(origExpansion.getType ())
2335
+ .getCountType ();
2336
+ } else {
2337
+ assert (candidateSubstType);
2338
+ substCountType =
2339
+ cast<PackExpansionType>(candidateSubstType).getCountType ();
2340
+ }
2341
+
2342
+ countParam = visit (substCountType, origCountType);
2343
+ }
2289
2344
2290
2345
return CanPackExpansionType::get (patternTy, countParam);
2291
2346
}
0 commit comments