Skip to content

Commit d09ea98

Browse files
committed
[GenericEnvironment] Add helper methods to map pack interface types to
element archetypes, and element interface types to pack archetypes.
1 parent 1ab9f8f commit d09ea98

File tree

5 files changed

+63
-48
lines changed

5 files changed

+63
-48
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
239239
/// Map a generic parameter type to a contextual type.
240240
Type mapTypeIntoContext(GenericTypeParamType *type) const;
241241

242+
/// Map a type containing parameter packs to a contextual type
243+
/// in the opened element generic context.
244+
Type mapPackTypeIntoElementContext(Type type) const;
245+
246+
/// Map a type containing pack element type parameters to a contextual
247+
/// type in the pack generic context.
248+
Type mapElementTypeIntoPackContext(Type type) const;
249+
242250
/// Map the given SIL interface type to a contextual type.
243251
///
244252
/// This operation will also reabstract dependent types according to the

lib/AST/GenericEnvironment.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,48 @@ Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const {
494494
return result;
495495
}
496496

497+
Type
498+
GenericEnvironment::mapPackTypeIntoElementContext(Type type) const {
499+
assert(getKind() == Kind::OpenedElement);
500+
assert(!type->hasArchetype());
501+
502+
auto sig = getGenericSignature();
503+
ASTContext &ctx = sig->getASTContext();
504+
QueryInterfaceTypeSubstitutions substitutions(this);
505+
506+
// Map the interface type to the element type by stripping
507+
// away the isParameterPack bit before mapping type parameters
508+
// to archetypes.
509+
return type.subst([&](SubstitutableType *type) {
510+
auto *genericParam = type->getAs<GenericTypeParamType>();
511+
if (!genericParam)
512+
return Type();
513+
514+
return substitutions(genericParam->asScalar(ctx));
515+
}, LookUpConformanceInSignature(sig.getPointer()));
516+
}
517+
518+
Type
519+
GenericEnvironment::mapElementTypeIntoPackContext(Type type) const {
520+
assert(getKind() == Kind::Primary);
521+
assert(!type->hasArchetype());
522+
523+
auto sig = getGenericSignature();
524+
ASTContext &ctx = sig->getASTContext();
525+
QueryInterfaceTypeSubstitutions substitutions(this);
526+
527+
// Map element archetypes to the pack archetypes by converting
528+
// element types to interface types and adding the isParameterPack
529+
// bit. Then, map type parameters to archetypes.
530+
return type.subst([&](SubstitutableType *type) {
531+
auto *genericParam = type->getAs<GenericTypeParamType>();
532+
if (!genericParam)
533+
return Type();
534+
535+
return substitutions(genericParam->asParameterPack(ctx));
536+
}, LookUpConformanceInSignature(sig.getPointer()));
537+
}
538+
497539
SubstitutionMap GenericEnvironment::getForwardingSubstitutionMap() const {
498540
auto genericSig = getGenericSignature();
499541
return SubstitutionMap::get(genericSig,

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7095,32 +7095,15 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
70957095
auto toExpansionType = toType->getAs<PackExpansionType>();
70967096
auto *expansion = dyn_cast<PackExpansionExpr>(expr);
70977097

7098-
// FIXME: Duplicated code from `PackReferenceFinder` in PreCheckExpr.
7099-
auto toElementType = toExpansionType->getPatternType();
7100-
toElementType =
7101-
toElementType->mapTypeOutOfContext().transform([&](Type type) -> Type {
7102-
auto *genericParam = type->getAs<GenericTypeParamType>();
7103-
if (!genericParam || !genericParam->isParameterPack())
7104-
return type;
7105-
7106-
auto param = genericParam->asScalar(ctx);
7107-
return expansion->getGenericEnvironment()->mapTypeIntoContext(param);
7108-
});
7098+
auto *elementEnv = expansion->getGenericEnvironment();
7099+
auto toElementType = elementEnv->mapPackTypeIntoElementContext(
7100+
toExpansionType->getPatternType()->mapTypeOutOfContext());
71097101

71107102
auto *pattern = coerceToType(expansion->getPatternExpr(),
71117103
toElementType, locator);
7112-
7113-
// FIXME: Duplicated code from `visitPackExpansionExpr` in CSGen.
7114-
auto patternType =
7115-
cs.getType(pattern).transform([&](Type type) -> Type {
7116-
auto *element = type->getAs<ElementArchetypeType>();
7117-
if (!element)
7118-
return type;
7119-
7120-
auto *elementParam = element->mapTypeOutOfContext()->getAs<GenericTypeParamType>();
7121-
auto *pack = elementParam->asParameterPack(ctx);;
7122-
return cs.DC->mapTypeIntoContext(pack);
7123-
});
7104+
auto *packEnv = cs.DC->getGenericEnvironmentOfContext();
7105+
auto patternType = packEnv->mapElementTypeIntoPackContext(
7106+
toElementType->mapTypeOutOfContext());
71247107
auto shapeType = toExpansionType->getCountType();
71257108
auto expansionTy = PackExpansionType::get(patternType, shapeType);
71267109

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8432,7 +8432,6 @@ ConstraintSystem::SolutionKind
84328432
ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
84338433
TypeMatchOptions flags,
84348434
ConstraintLocatorBuilder locator) {
8435-
ASTContext &ctx = getASTContext();
84368435
auto elementType = simplifyType(first, flags);
84378436
auto *loc = getConstraintLocator(locator);
84388437

@@ -8449,17 +8448,11 @@ ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
84498448

84508449
// Replace opened element archetypes with pack archetypes
84518450
// for the resulting type of the pack expansion.
8452-
auto patternType = elementType.transform([&](Type type) -> Type {
8453-
auto *element = type->getAs<ElementArchetypeType>();
8454-
if (!element)
8455-
return type;
8456-
8457-
auto *elementParam = element->mapTypeOutOfContext()->getAs<GenericTypeParamType>();
8458-
auto *pack = elementParam->asParameterPack(ctx);
8459-
return this->DC->mapTypeIntoContext(pack);
8460-
});
8461-
8451+
auto *environment = DC->getGenericEnvironmentOfContext();
8452+
auto patternType = environment->mapElementTypeIntoPackContext(
8453+
elementType->mapTypeOutOfContext());
84628454
addConstraint(ConstraintKind::Bind, second, patternType, locator);
8455+
84638456
return SolutionKind::Solved;
84648457
}
84658458

lib/Sema/PreCheckExpr.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -436,26 +436,15 @@ static Expr *getPackExpansion(DeclContext *dc, Expr *expr, SourceLoc opLoc) {
436436
if (auto expansionType = decl->getType()->getAs<PackExpansionType>()) {
437437
auto sourceRange = declRef->getSourceRange();
438438

439-
// Map the pattern interface type to the element interface type
440-
// by making all type parameter packs scalar type parameters.
441-
auto patternType = expansionType->getPatternType();
442-
auto elementInterfaceType =
443-
patternType->mapTypeOutOfContext().transform([&](Type type) -> Type {
444-
auto *genericParam = type->getAs<GenericTypeParamType>();
445-
if (!genericParam || !genericParam->isParameterPack())
446-
return type;
447-
448-
return genericParam->asScalar(ctx);
449-
});
450-
451-
// Map the element interface type into the context of the opened
439+
// Map the pattern interface type into the context of the opened
452440
// element signature.
453441
if (!environment) {
454442
auto sig = ctx.getOpenedElementSignature(
455443
dc->getGenericSignatureOfContext().getCanonicalSignature());
456444
environment = GenericEnvironment::forOpenedElement(sig, UUID::fromTime());
457445
}
458-
auto elementType = environment->mapTypeIntoContext(elementInterfaceType);
446+
auto elementType = environment->mapPackTypeIntoElementContext(
447+
expansionType->getPatternType()->mapTypeOutOfContext());
459448

460449
auto *opaqueValue = new (ctx) OpaqueValueExpr(sourceRange, elementType);
461450
opaqueValues.push_back(opaqueValue);

0 commit comments

Comments
 (0)