Skip to content

Commit 9eccfbd

Browse files
committed
[CSGen] Use a ShapeOf constraint when generating constraints for a pack
expansion expression.
1 parent 5218a0d commit 9eccfbd

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

lib/AST/ParameterPack.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,36 @@ CanPackType PackType::getReducedShape() {
314314
}
315315

316316
CanType TypeBase::getReducedShape() {
317-
if (auto *packArchetype = getAs<PackArchetypeType>())
318-
return packArchetype->getReducedShape();
319-
320317
if (auto *packType = getAs<PackType>())
321318
return packType->getReducedShape();
322319

323320
if (auto *expansionType = getAs<PackExpansionType>())
324321
return expansionType->getReducedShape();
325322

323+
struct PatternTypeWalker : public TypeWalker {
324+
CanType shapeType;
325+
326+
Action walkToTypePre(Type type) override {
327+
// Don't consider pack references inside nested pack
328+
// expansion types.
329+
if (type->is<PackExpansionType>()) {
330+
return Action::Stop;
331+
}
332+
333+
if (auto *archetype = type->getAs<PackArchetypeType>()) {
334+
shapeType = archetype->getReducedShape();
335+
return Action::Stop;
336+
}
337+
338+
return Action::Continue;
339+
}
340+
} patternTypeWalker;
341+
342+
Type(this).walk(patternTypeWalker);
343+
344+
if (patternTypeWalker.shapeType)
345+
return patternTypeWalker.shapeType;
346+
326347
assert(!isTypeVariableOrMember());
327348
assert(!hasTypeParameter());
328349

lib/Sema/CSGen.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2925,20 +2925,15 @@ namespace {
29252925
CS.addConstraint(ConstraintKind::PackElementOf, elementResultType,
29262926
patternTy, CS.getConstraintLocator(expr));
29272927

2928-
// FIXME: Use a ShapeOf constraint here.
2929-
Type shapeType;
2930-
auto *binding = expr->getBindings().front();
2931-
auto type = CS.simplifyType(CS.getType(binding));
2932-
type.visit([&](Type type) {
2933-
if (shapeType)
2934-
return;
2935-
2936-
if (auto archetype = type->getAs<PackArchetypeType>()) {
2937-
shapeType = archetype->getReducedShape();
2938-
}
2939-
});
2928+
auto *shapeLoc =
2929+
CS.getConstraintLocator(expr, ConstraintLocator::PackShape);
2930+
auto *shapeTypeVar = CS.createTypeVariable(shapeLoc,
2931+
TVO_CanBindToPack |
2932+
TVO_CanBindToHole);
2933+
CS.addConstraint(ConstraintKind::ShapeOf, patternTy, shapeTypeVar,
2934+
CS.getConstraintLocator(expr));
29402935

2941-
return PackExpansionType::get(patternTy, shapeType);
2936+
return PackExpansionType::get(patternTy, shapeTypeVar);
29422937
}
29432938

29442939
Type visitDynamicTypeExpr(DynamicTypeExpr *expr) {

0 commit comments

Comments
 (0)