Skip to content

Commit 72e296e

Browse files
authored
Merge pull request #62140 from hborla/variadic-generics-locators
[ConstraintSystem] Add locator path elements for pack expansion patterns and pack shapes.
2 parents 1a9a15f + 6de85ee commit 72e296e

File tree

7 files changed

+69
-40
lines changed

7 files changed

+69
-40
lines changed

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ CUSTOM_LOCATOR_PATH_ELT(PackType)
195195
/// An element of a pack type - the T in <T, U, V, ...>
196196
CUSTOM_LOCATOR_PATH_ELT(PackElement)
197197

198+
/// The shape of a parameter pack.
199+
SIMPLE_LOCATOR_PATH_ELT(PackShape)
200+
201+
/// The pattern of a pack expansion.
202+
SIMPLE_LOCATOR_PATH_ELT(PackExpansionPattern)
203+
198204
/// An unresolved member.
199205
SIMPLE_LOCATOR_PATH_ELT(UnresolvedMember)
200206

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6411,8 +6411,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
64116411
void visitElementArchetypeType(ElementArchetypeType *T) {
64126412
if (Options.PrintForSIL) {
64136413
Printer << "@element(\"" << T->getOpenedElementID() << ") ";
6414-
visit(T->getGenericEnvironment()->getOpenedExistentialType());
6415-
Printer << ") ";
64166414

64176415
auto interfaceTy = T->getInterfaceType();
64186416
visit(interfaceTy);

lib/AST/ParameterPack.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ struct PackTypeParameterCollector: TypeWalker {
3939
if (paramTy->isParameterPack())
4040
typeParams.insert(paramTy);
4141
} else if (auto *archetypeTy = t->getAs<PackArchetypeType>()) {
42-
if (archetypeTy->isRoot())
43-
typeParams.insert(paramTy);
42+
typeParams.insert(archetypeTy->getRoot());
4443
}
4544

4645
return Action::Continue;
@@ -315,14 +314,20 @@ CanPackType PackType::getReducedShape() {
315314

316315
CanType TypeBase::getReducedShape() {
317316
if (auto *packArchetype = getAs<PackArchetypeType>())
318-
return packArchetype->getReducedShape();
317+
return packArchetype->getReducedShape();
319318

320319
if (auto *packType = getAs<PackType>())
321320
return packType->getReducedShape();
322321

323322
if (auto *expansionType = getAs<PackExpansionType>())
324323
return expansionType->getReducedShape();
325324

325+
SmallVector<Type, 2> rootParameterPacks;
326+
getTypeParameterPacks(rootParameterPacks);
327+
328+
if (!rootParameterPacks.empty())
329+
return rootParameterPacks.front()->getReducedShape();
330+
326331
assert(!isTypeVariableOrMember());
327332
assert(!hasTypeParameter());
328333

lib/Sema/CSGen.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,27 +2918,24 @@ namespace {
29182918
CS.setType(binding, type);
29192919
}
29202920

2921-
auto elementResultType = CS.getType(expr->getPatternExpr());
2922-
auto patternTy = CS.createTypeVariable(CS.getConstraintLocator(expr),
2921+
auto *patternLoc =
2922+
CS.getConstraintLocator(expr, ConstraintLocator::PackExpansionPattern);
2923+
auto patternTy = CS.createTypeVariable(patternLoc,
29232924
TVO_CanBindToPack |
29242925
TVO_CanBindToHole);
2926+
auto elementResultType = CS.getType(expr->getPatternExpr());
29252927
CS.addConstraint(ConstraintKind::PackElementOf, elementResultType,
29262928
patternTy, CS.getConstraintLocator(expr));
29272929

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-
});
2930+
auto *shapeLoc =
2931+
CS.getConstraintLocator(expr, ConstraintLocator::PackShape);
2932+
auto *shapeTypeVar = CS.createTypeVariable(shapeLoc,
2933+
TVO_CanBindToPack |
2934+
TVO_CanBindToHole);
2935+
CS.addConstraint(ConstraintKind::ShapeOf, patternTy, shapeTypeVar,
2936+
CS.getConstraintLocator(expr));
29402937

2941-
return PackExpansionType::get(patternTy, shapeType);
2938+
return PackExpansionType::get(patternTy, shapeTypeVar);
29422939
}
29432940

29442941
Type visitDynamicTypeExpr(DynamicTypeExpr *expr) {

lib/Sema/CSSimplify.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,14 +2423,17 @@ static PackType *replaceTypeVariablesWithFreshPacks(ConstraintSystem &cs,
24232423
// wrapping a pack type variable. Otherwise, create a new scalar
24242424
// type variable.
24252425
//
2426-
// FIXME: Locator for diagnostics
24272426
// FIXME: Other TVO_* flags for type variables?
2427+
auto elementLoc = cs.getConstraintLocator(loc,
2428+
LocatorPathElt::PackElement(freshTypeVars.size()));
24282429
if (packExpansionElt != nullptr) {
2429-
auto *freshTypeVar = cs.createTypeVariable(loc, TVO_CanBindToPack);
2430+
auto *freshTypeVar =
2431+
cs.createTypeVariable(elementLoc, TVO_CanBindToPack);
24302432
freshTypeVars.push_back(PackExpansionType::get(
24312433
freshTypeVar, packExpansionElt->getCountType()));
24322434
} else {
2433-
freshTypeVars.push_back(cs.createTypeVariable(loc, /*options=*/0));
2435+
freshTypeVars.push_back(
2436+
cs.createTypeVariable(elementLoc, /*options=*/0));
24342437
}
24352438
}
24362439
}
@@ -2483,7 +2486,6 @@ static PackType *replaceTypeVariablesWithFreshPacks(ConstraintSystem &cs,
24832486
// Bind each pack type variable occurring in the pattern type to its
24842487
// binding pack that was constructed above.
24852488
for (const auto &pair : typeVars) {
2486-
// FIXME: Locator for diagnostics
24872489
cs.addConstraint(ConstraintKind::Bind,
24882490
pair.first, PackType::get(ctx, pair.second), locator);
24892491
}
@@ -2498,10 +2500,9 @@ ConstraintSystem::matchPackExpansionTypes(PackExpansionType *expansion1,
24982500
ConstraintKind kind, TypeMatchOptions flags,
24992501
ConstraintLocatorBuilder locator) {
25002502
// The count types of two pack expansion types must have the same shape.
2501-
//
2502-
// FIXME: Locator for diagnostics.
2503-
auto *loc = getConstraintLocator(locator);
2504-
auto *shapeTypeVar = createTypeVariable(loc, TVO_CanBindToPack);
2503+
auto *shapeLoc = getConstraintLocator(
2504+
locator.withPathElement(ConstraintLocator::PackShape));
2505+
auto *shapeTypeVar = createTypeVariable(shapeLoc, TVO_CanBindToPack);
25052506
addConstraint(ConstraintKind::ShapeOf,
25062507
expansion1->getCountType(), shapeTypeVar, locator);
25072508
addConstraint(ConstraintKind::ShapeOf,
@@ -2522,7 +2523,6 @@ ConstraintSystem::matchPackExpansionTypes(PackExpansionType *expansion1,
25222523
if (auto *pack2 = pattern2->getAs<PackType>()) {
25232524
if (auto *pack1 = replaceTypeVariablesWithFreshPacks(
25242525
*this, pattern1, pack2, locator)) {
2525-
// FIXME: Locator for diagnostics.
25262526
addConstraint(kind, pack1, pack2, locator);
25272527
return getTypeMatchSuccess();
25282528
}
@@ -2538,7 +2538,6 @@ ConstraintSystem::matchPackExpansionTypes(PackExpansionType *expansion1,
25382538
if (auto *pack1 = pattern1->getAs<PackType>()) {
25392539
if (auto *pack2 = replaceTypeVariablesWithFreshPacks(
25402540
*this, pattern2, pack1, locator)) {
2541-
// FIXME: Locator for diagnostics.
25422541
addConstraint(kind, pack1, pack2, locator);
25432542
return getTypeMatchSuccess();
25442543
}
@@ -6852,8 +6851,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
68526851
kind, subflags, packLoc);
68536852
}
68546853
case TypeKind::PackExpansion: {
6855-
// FIXME: Need a new locator element
6856-
68576854
auto expansion1 = cast<PackExpansionType>(desugar1);
68586855
auto expansion2 = cast<PackExpansionType>(desugar2);
68596856

@@ -7562,9 +7559,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifySubclassOfConstraint(
75627559
for (unsigned i = 0, e = packType->getNumElements(); i < e; ++i) {
75637560
auto eltType = packType->getElementType(i);
75647561
if (auto *packExpansionType = eltType->getAs<PackExpansionType>()) {
7565-
// FIXME: Locator element for pack expansion pattern
7562+
auto patternLoc =
7563+
locator.withPathElement(ConstraintLocator::PackExpansionPattern);
75667564
addConstraint(ConstraintKind::SubclassOf, packExpansionType->getPatternType(),
7567-
classType, locator.withPathElement(LocatorPathElt::PackElement(i)));
7565+
classType, patternLoc);
75687566
} else {
75697567
addConstraint(ConstraintKind::SubclassOf, eltType,
75707568
classType, locator.withPathElement(LocatorPathElt::PackElement(i)));
@@ -7680,11 +7678,12 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
76807678
for (unsigned i = 0, e = packType->getNumElements(); i < e; ++i) {
76817679
auto eltType = packType->getElementType(i);
76827680
if (auto *packExpansionType = eltType->getAs<PackExpansionType>()) {
7683-
// FIXME: Locator element for pack expansion pattern
7681+
auto patternLoc =
7682+
locator.withPathElement(ConstraintLocator::PackExpansionPattern);
76847683
addConstraint(ConstraintKind::ConformsTo,
76857684
packExpansionType->getPatternType(),
76867685
protocol->getDeclaredInterfaceType(),
7687-
locator.withPathElement(LocatorPathElt::PackElement(i)));
7686+
patternLoc);
76887687
} else {
76897688
addConstraint(ConstraintKind::ConformsTo, eltType,
76907689
protocol->getDeclaredInterfaceType(),
@@ -14158,8 +14157,9 @@ void ConstraintSystem::addConstraint(Requirement req,
1415814157
auto type1 = req.getFirstType();
1415914158
auto type2 = req.getSecondType();
1416014159

14161-
// FIXME: Locator for diagnostics
14162-
auto typeVar = createTypeVariable(getConstraintLocator(locator),
14160+
auto *shapeLoc = getConstraintLocator(
14161+
locator.withPathElement(ConstraintLocator::PackShape));
14162+
auto typeVar = createTypeVariable(shapeLoc,
1416314163
TVO_CanBindToPack);
1416414164

1416514165
addConstraint(ConstraintKind::ShapeOf, type1, typeVar, locator);

lib/Sema/ConstraintLocator.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ unsigned LocatorPathElt::getNewSummaryFlags() const {
9797
case ConstraintLocator::SyntacticElement:
9898
case ConstraintLocator::PackType:
9999
case ConstraintLocator::PackElement:
100+
case ConstraintLocator::PackShape:
101+
case ConstraintLocator::PackExpansionPattern:
100102
case ConstraintLocator::PatternBindingElement:
101103
case ConstraintLocator::NamedPatternDecl:
102104
case ConstraintLocator::AnyPatternDecl:
@@ -434,16 +436,28 @@ void LocatorPathElt::dump(raw_ostream &out) const {
434436
break;
435437
}
436438

437-
case ConstraintLocator::ConstraintLocator::PackType:
438-
out << "pack type";
439+
case ConstraintLocator::ConstraintLocator::PackType: {
440+
auto packElt = elt.castTo<LocatorPathElt::PackType>();
441+
out << "pack type '" << packElt.getType()->getString(PO) << "'";
439442
break;
443+
}
440444

441445
case ConstraintLocator::PackElement: {
442446
auto packElt = elt.castTo<LocatorPathElt::PackElement>();
443447
out << "pack element #" << llvm::utostr(packElt.getIndex());
444448
break;
445449
}
446450

451+
case ConstraintLocator::PackShape: {
452+
out << "pack shape";
453+
break;
454+
}
455+
456+
case ConstraintLocator::PackExpansionPattern: {
457+
out << "pack expansion pattern";
458+
break;
459+
}
460+
447461
case ConstraintLocator::PatternBindingElement: {
448462
auto patternBindingElt =
449463
elt.castTo<LocatorPathElt::PatternBindingElement>();

lib/Sema/ConstraintSystem.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5327,8 +5327,17 @@ void constraints::simplifyLocator(ASTNode &anchor,
53275327
break;
53285328

53295329
case ConstraintLocator::PackElement:
5330+
case ConstraintLocator::PackShape:
53305331
break;
53315332

5333+
case ConstraintLocator::PackExpansionPattern: {
5334+
if (auto *expansion = getAsExpr<PackExpansionExpr>(anchor))
5335+
anchor = expansion->getPatternExpr();
5336+
5337+
path = path.slice(1);
5338+
break;
5339+
}
5340+
53325341
case ConstraintLocator::PatternBindingElement: {
53335342
auto pattern = path[0].castTo<LocatorPathElt::PatternBindingElement>();
53345343
auto *patternBinding = cast<PatternBindingDecl>(anchor.get<Decl *>());

0 commit comments

Comments
 (0)