Skip to content

Commit 39c2bbb

Browse files
committed
[ConstraintSystem] Implement pack expansion type opening
Models `PackExpansionType` as a type variable that can only bind to `PackExpansionType` and `expansion of` constraint that connects expansion variable to its pattern, shape types.
1 parent 6437531 commit 39c2bbb

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

Diff for: include/swift/Sema/ConstraintSystem.h

+15
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,9 @@ class Solution {
14671467
llvm::DenseMap<ConstraintLocator *, OpenedArchetypeType *>
14681468
OpenedExistentialTypes;
14691469

1470+
llvm::DenseMap<PackExpansionType *, TypeVariableType *>
1471+
OpenedPackExpansionTypes;
1472+
14701473
/// The pack expansion environment that can open pack elements for
14711474
/// a given locator.
14721475
llvm::DenseMap<ConstraintLocator *, std::pair<UUID, Type>>
@@ -2219,6 +2222,9 @@ class ConstraintSystem {
22192222
llvm::SmallMapVector<ConstraintLocator *, OpenedArchetypeType *, 4>
22202223
OpenedExistentialTypes;
22212224

2225+
llvm::SmallMapVector<PackExpansionType *, TypeVariableType *, 4>
2226+
OpenedPackExpansionTypes;
2227+
22222228
llvm::SmallMapVector<ConstraintLocator *, std::pair<UUID, Type>, 4>
22232229
PackExpansionEnvironments;
22242230

@@ -2702,6 +2708,9 @@ class ConstraintSystem {
27022708
/// The length of \c OpenedExistentialTypes.
27032709
unsigned numOpenedExistentialTypes;
27042710

2711+
/// The length of \c OpenedPackExpansionsTypes.
2712+
unsigned numOpenedPackExpansionTypes;
2713+
27052714
/// The length of \c PackExpansionEnvironments.
27062715
unsigned numPackExpansionEnvironments;
27072716

@@ -3973,6 +3982,12 @@ class ConstraintSystem {
39733982
Type openOpaqueType(OpaqueTypeArchetypeType *type,
39743983
ConstraintLocatorBuilder locator);
39753984

3985+
/// "Open" a pack expansion type by replacing it with a type variable,
3986+
/// opening its pattern and shape types and connecting them to the
3987+
/// aforementioned variable via special constraints.
3988+
Type openPackExpansionType(PackExpansionType *expansion,
3989+
OpenedTypeMap &replacements);
3990+
39763991
public:
39773992
/// Recurse over the given type and open any opaque archetype types.
39783993
Type openOpaqueType(Type type, ContextualTypePurpose context,

Diff for: lib/Sema/CSSolver.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ Solution ConstraintSystem::finalize() {
169169
solution.OpenedExistentialTypes.insert(openedExistential);
170170
}
171171

172+
for (const auto &expansion : OpenedPackExpansionTypes) {
173+
assert(solution.OpenedPackExpansionTypes.count(expansion.first) == 0 ||
174+
solution.OpenedPackExpansionTypes[expansion.first] ==
175+
expansion.second &&
176+
"Already recorded");
177+
solution.OpenedPackExpansionTypes.insert(expansion);
178+
}
179+
172180
// Remember the defaulted type variables.
173181
solution.DefaultedConstraints.insert(DefaultedConstraints.begin(),
174182
DefaultedConstraints.end());
@@ -271,6 +279,11 @@ void ConstraintSystem::applySolution(const Solution &solution) {
271279
OpenedExistentialTypes.insert(openedExistential);
272280
}
273281

282+
// Register the solution's opened pack expansion types.
283+
for (const auto &expansion : solution.OpenedPackExpansionTypes) {
284+
OpenedPackExpansionTypes.insert(expansion);
285+
}
286+
274287
// Register the solutions's pack expansion environments.
275288
for (const auto &expansion : solution.PackExpansionEnvironments) {
276289
PackExpansionEnvironments.insert(expansion);
@@ -594,6 +607,7 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
594607
numArgumentMatchingChoices = cs.argumentMatchingChoices.size();
595608
numOpenedTypes = cs.OpenedTypes.size();
596609
numOpenedExistentialTypes = cs.OpenedExistentialTypes.size();
610+
numOpenedPackExpansionTypes = cs.OpenedPackExpansionTypes.size();
597611
numPackExpansionEnvironments = cs.PackExpansionEnvironments.size();
598612
numDefaultedConstraints = cs.DefaultedConstraints.size();
599613
numAddedNodeTypes = cs.addedNodeTypes.size();
@@ -672,6 +686,9 @@ ConstraintSystem::SolverScope::~SolverScope() {
672686
// Remove any opened existential types.
673687
truncate(cs.OpenedExistentialTypes, numOpenedExistentialTypes);
674688

689+
// Remove any opened pack expansion types.
690+
truncate(cs.OpenedPackExpansionTypes, numOpenedPackExpansionTypes);
691+
675692
// Remove any pack expansion environments.
676693
truncate(cs.PackExpansionEnvironments, numPackExpansionEnvironments);
677694

Diff for: lib/Sema/ConstraintSystem.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,32 @@ Type ConstraintSystem::openType(Type type, OpenedTypeMap &replacements) {
984984
});
985985
}
986986

987+
Type ConstraintSystem::openPackExpansionType(PackExpansionType *expansion,
988+
OpenedTypeMap &replacements) {
989+
auto patternType = openType(expansion->getPatternType(), replacements);
990+
auto shapeType = openType(expansion->getCountType(), replacements);
991+
992+
auto openedPackExpansion = PackExpansionType::get(patternType, shapeType);
993+
994+
auto known = OpenedPackExpansionTypes.find(openedPackExpansion);
995+
if (known != OpenedPackExpansionTypes.end())
996+
return known->second;
997+
998+
auto *expansionVar = createTypeVariable(
999+
getConstraintLocator({}, ConstraintLocator::PackExpansionType),
1000+
TVO_PackExpansion);
1001+
1002+
// This constraint is important to make sure that pack expansion always
1003+
// has a binding and connect pack expansion var to any type variables
1004+
// that appear in pattern and shape types.
1005+
addUnsolvedConstraint(Constraint::create(
1006+
*this, ConstraintKind::Defaultable, expansionVar, openedPackExpansion,
1007+
getConstraintLocator({}, ConstraintLocator::PackExpansionType)));
1008+
1009+
OpenedPackExpansionTypes[openedPackExpansion] = expansionVar;
1010+
return expansionVar;
1011+
}
1012+
9871013
Type ConstraintSystem::openOpaqueType(OpaqueTypeArchetypeType *opaque,
9881014
ConstraintLocatorBuilder locator) {
9891015
auto opaqueDecl = opaque->getDecl();

Diff for: lib/Sema/TypeCheckConstraints.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,16 @@ void ConstraintSystem::print(raw_ostream &out) const {
15901590
}
15911591
}
15921592

1593+
if (!OpenedPackExpansionTypes.empty()) {
1594+
out.indent(indent) << "Opened pack expansion types:\n";
1595+
for (const auto &expansion : OpenedPackExpansionTypes) {
1596+
out.indent(indent + 2);
1597+
out << expansion.first->getString(PO);
1598+
out << " opens to " << expansion.second->getString(PO);
1599+
out << "\n";
1600+
}
1601+
}
1602+
15931603
if (!DefaultedConstraints.empty()) {
15941604
out.indent(indent) << "Defaulted constraints:\n";
15951605
interleave(DefaultedConstraints, [&](ConstraintLocator *locator) {

0 commit comments

Comments
 (0)