Skip to content

Commit bea5b52

Browse files
authored
Merge pull request #70681 from rjmccall/variadic-generic-tuple-reabstraction
Support variadic generic tuple arguments in reabstraction thunks
2 parents f15ed1e + c66ccbc commit bea5b52

9 files changed

+1332
-746
lines changed

lib/SILGen/ResultPlan.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,13 @@ class PackTransformResultPlan final : public ResultPlan {
529529
auto eltPatternTy =
530530
PackAddr->getType().castTo<SILPackType>()
531531
->getSILElementType(ComponentIndex);
532-
auto result = SGF.createOpenedElementValueEnvironment(eltPatternTy);
533-
auto openedEnv = result.first;
534-
auto eltAddrTy = result.second;
532+
auto substPatternType = FormalPackType.getElementType(ComponentIndex);
533+
534+
SILType eltAddrTy;
535+
CanType substEltType;
536+
auto openedEnv =
537+
SGF.createOpenedElementValueEnvironment({eltPatternTy}, {&eltAddrTy},
538+
{substPatternType}, {&substEltType});
535539

536540
// Loop over the pack, initializing each value with the appropriate
537541
// element.
@@ -560,18 +564,10 @@ class PackTransformResultPlan final : public ResultPlan {
560564
return eltMV;
561565
}();
562566

563-
// Map the formal type into the generic environment.
564-
auto substType = FormalPackType.getElementType(ComponentIndex);
565-
substType = cast<PackExpansionType>(substType).getPatternType();
566-
if (openedEnv) {
567-
substType = openedEnv->mapContextualPackTypeIntoElementContext(
568-
substType);
569-
}
570-
571567
// Finish in the normal way for scalar results.
572568
RValue rvalue =
573569
ScalarResultPlan::finish(SGF, loc, eltMV, OrigPatternType,
574-
substType, eltInit, Rep);
570+
substEltType, eltInit, Rep);
575571
assert(rvalue.isInContext()); (void) rvalue;
576572
});
577573
});

lib/SILGen/SILGenFunction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,6 +2697,11 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
26972697
GenericEnvironment *
26982698
createOpenedElementValueEnvironment(ArrayRef<SILType> packExpansionTys,
26992699
ArrayRef<SILType*> eltTys);
2700+
GenericEnvironment *
2701+
createOpenedElementValueEnvironment(ArrayRef<SILType> packExpansionTys,
2702+
ArrayRef<SILType*> eltTys,
2703+
ArrayRef<CanType> formalPackExpansionTys,
2704+
ArrayRef<CanType*> formalEltTys);
27002705

27012706
/// Emit a dynamic loop over a single pack-expansion component of a pack.
27022707
///

lib/SILGen/SILGenPack.cpp

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -452,44 +452,63 @@ GenericEnvironment *
452452
SILGenFunction::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

Comments
 (0)