@@ -452,44 +452,63 @@ GenericEnvironment *
452452SILGenFunction::createOpenedElementValueEnvironment (
453453 ArrayRef<SILType> expansionTys,
454454 ArrayRef<SILType*> eltTys) {
455- // The element-types output array should be the same size as the
456- // expansion-types input array. We don't currently have a reason
457- // to allow them to be empty --- we never do this with a dynamic
458- // set of types --- but maybe it's justifiable.
455+ return createOpenedElementValueEnvironment (expansionTys, eltTys, {}, {});
456+ }
457+
458+
459+ GenericEnvironment *
460+ SILGenFunction::createOpenedElementValueEnvironment (
461+ ArrayRef<SILType> expansionTys,
462+ ArrayRef<SILType*> eltTys,
463+ ArrayRef<CanType> formalExpansionTypes,
464+ ArrayRef<CanType*> formalEltTypes) {
465+ // The element-types output arrays should be the same size as their
466+ // corresponding expansion-types input arrays.
459467 assert (expansionTys.size () == eltTys.size ());
460- assert (!expansionTys.empty ());
461- if (expansionTys.empty ()) return nullptr ;
468+ assert (formalExpansionTypes.size () == formalEltTypes.size ());
462469
463- auto countArchetype = cast<PackArchetypeType>(
464- expansionTys[0 ].castTo <PackExpansionType>().getCountType ());
470+ assert (!expansionTys.empty () || !formalExpansionTypes.empty ());
471+ auto countArchetype =
472+ cast<PackArchetypeType>(
473+ (expansionTys.empty ()
474+ ? cast<PackExpansionType>(formalExpansionTypes[0 ])
475+ : expansionTys[0 ].castTo <PackExpansionType>()).getCountType ());
465476
466477 GenericEnvironment *env = nullptr ;
467- for (auto i : indices (expansionTys)) {
468- auto exp = expansionTys[i].castTo <PackExpansionType>();
469- assert ((i == 0 ||
470- countArchetype->getReducedShape () ==
471- cast<PackArchetypeType>(exp.getCountType ())->getReducedShape ())
478+ auto processExpansion = [&](CanPackExpansionType expansion) -> CanType {
479+ assert (countArchetype->getReducedShape () ==
480+ cast<PackArchetypeType>(expansion.getCountType ())->getReducedShape ()
472481 && " expansions are over packs with different shapes" );
473482
474- // The lowered element type is the lowered pattern type, if that's
475- // invariant to expansion, or else the expansion mapping of that in
476- // the opened-element environment.
477- auto loweredPatternTy = exp.getPatternType ();
478- auto loweredEltTy = loweredPatternTy;
479- if (!isPatternInvariantToExpansion (loweredPatternTy, countArchetype)) {
480- // Lazily create the opened-element environment if we find a
481- // pattern type that's not invariant to expansion.
482- if (!env) {
483- auto context = OpenedElementContext::
484- createForContextualExpansion (SGM.getASTContext (), exp);
485- env = context.environment ;
486- }
487- loweredEltTy =
488- env->mapContextualPackTypeIntoElementContext (loweredPatternTy);
483+ // The element type is the pattern type, if that's invariant to
484+ // expansion, or else the expansion mapping of that in the
485+ // opened-element environment.
486+ auto patternType = expansion.getPatternType ();
487+ if (isPatternInvariantToExpansion (patternType, countArchetype))
488+ return patternType;
489+
490+ // Lazily create the opened-element environment if we find a
491+ // pattern type that's not invariant to expansion.
492+ if (!env) {
493+ auto context = OpenedElementContext::
494+ createForContextualExpansion (SGM.getASTContext (), expansion);
495+ env = context.environment ;
489496 }
497+ return env->mapContextualPackTypeIntoElementContext (patternType);
498+ };
499+
500+ for (auto i : indices (expansionTys)) {
501+ auto exp = expansionTys[i].castTo <PackExpansionType>();
502+ auto loweredEltTy = processExpansion (exp);
490503 *eltTys[i] = SILType::getPrimitiveAddressType (loweredEltTy);
491504 }
492505
506+ for (auto i : indices (formalExpansionTypes)) {
507+ auto exp = cast<PackExpansionType>(formalExpansionTypes[i]);
508+ auto eltType = processExpansion (exp);
509+ *formalEltTypes[i] = eltType;
510+ }
511+
493512 return env;
494513}
495514
0 commit comments