Skip to content

Commit fc47edc

Browse files
committed
[ConstraintSystem] Hoist code for creating partitions for designated types.
Move this into a separate function.
1 parent f66a852 commit fc47edc

File tree

2 files changed

+93
-65
lines changed

2 files changed

+93
-65
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,69 @@ getOperatorDesignatedNominalTypes(Constraint *bindOverload) {
16831683
return operatorDecl->getDesignatedNominalTypes();
16841684
}
16851685

1686+
void ConstraintSystem::partitionForDesignatedTypes(
1687+
ArrayRef<Constraint *> Choices, ConstraintMatchLoop forEachChoice,
1688+
PartitionAppendCallback appendPartition,
1689+
SmallVectorImpl<SmallVector<unsigned, 4>> &definedInDesignatedType,
1690+
SmallVectorImpl<SmallVector<unsigned, 4>>
1691+
&definedInExtensionOfDesignatedType) {
1692+
1693+
auto designatedNominalTypes = getOperatorDesignatedNominalTypes(Choices[0]);
1694+
if (designatedNominalTypes.empty())
1695+
return;
1696+
1697+
forEachChoice(
1698+
Choices, [&](unsigned constraintIndex, Constraint *constraint) -> bool {
1699+
auto *decl = constraint->getOverloadChoice().getDecl();
1700+
auto *funcDecl = cast<FuncDecl>(decl);
1701+
1702+
auto *parentDecl = funcDecl->getParent()->getAsDecl();
1703+
for (auto designatedTypeIndex : indices(designatedNominalTypes)) {
1704+
auto *designatedNominal =
1705+
designatedNominalTypes[designatedTypeIndex];
1706+
if (parentDecl == designatedNominal) {
1707+
if (designatedTypeIndex >= definedInDesignatedType.size())
1708+
definedInDesignatedType.resize(designatedTypeIndex + 1);
1709+
auto &constraints = definedInDesignatedType[designatedTypeIndex];
1710+
constraints.push_back(constraintIndex);
1711+
return true;
1712+
}
1713+
1714+
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(parentDecl)) {
1715+
parentDecl = extensionDecl->getExtendedNominal();
1716+
if (parentDecl == designatedNominal) {
1717+
if (designatedTypeIndex >=
1718+
definedInExtensionOfDesignatedType.size())
1719+
definedInExtensionOfDesignatedType.resize(
1720+
designatedTypeIndex + 1);
1721+
1722+
auto &constraints =
1723+
definedInExtensionOfDesignatedType[designatedTypeIndex];
1724+
constraints.push_back(constraintIndex);
1725+
return true;
1726+
}
1727+
}
1728+
}
1729+
1730+
return false;
1731+
});
1732+
1733+
// Now collect the overload choices that are defined within the type
1734+
// that was designated in the operator declaration.
1735+
// Add partitions for each of the overloads we found in types that
1736+
// were designated as part of the operator declaration.
1737+
for (auto designatedTypeIndex : indices(designatedNominalTypes)) {
1738+
if (designatedTypeIndex < definedInDesignatedType.size()) {
1739+
auto &primary = definedInDesignatedType[designatedTypeIndex];
1740+
appendPartition(primary);
1741+
}
1742+
if (designatedTypeIndex < definedInExtensionOfDesignatedType.size()) {
1743+
auto &secondary = definedInExtensionOfDesignatedType[designatedTypeIndex];
1744+
appendPartition(secondary);
1745+
}
1746+
}
1747+
}
1748+
16861749
void ConstraintSystem::partitionDisjunction(
16871750
ArrayRef<Constraint *> Choices, SmallVectorImpl<unsigned> &Ordering,
16881751
SmallVectorImpl<unsigned> &PartitionBeginning) {
@@ -1707,9 +1770,9 @@ void ConstraintSystem::partitionDisjunction(
17071770
// Local function used to iterate over the untaken choices from the
17081771
// disjunction and use a higher-order function to determine if they
17091772
// should be part of a partition.
1710-
auto forEachChoice =
1773+
ConstraintMatchLoop forEachChoice =
17111774
[&](ArrayRef<Constraint *>,
1712-
llvm::function_ref<bool(unsigned index, Constraint *)> fn) {
1775+
std::function<bool(unsigned index, Constraint *)> fn) {
17131776
for (auto index : indices(Choices)) {
17141777
auto *constraint = Choices[index];
17151778
if (taken.count(constraint))
@@ -1723,7 +1786,6 @@ void ConstraintSystem::partitionDisjunction(
17231786
}
17241787
};
17251788

1726-
17271789
// First collect some things that we'll generally put near the end
17281790
// of the partitioning.
17291791

@@ -1769,80 +1831,30 @@ void ConstraintSystem::partitionDisjunction(
17691831

17701832
// Local function to create the next partition based on the options
17711833
// passed in.
1772-
auto appendPartition = [&](SmallVectorImpl<unsigned> &options) {
1773-
if (options.size()) {
1774-
PartitionBeginning.push_back(Ordering.size());
1775-
Ordering.insert(Ordering.end(), options.begin(), options.end());
1776-
}
1777-
};
1834+
PartitionAppendCallback appendPartition =
1835+
[&](SmallVectorImpl<unsigned> &options) {
1836+
if (options.size()) {
1837+
PartitionBeginning.push_back(Ordering.size());
1838+
Ordering.insert(Ordering.end(), options.begin(), options.end());
1839+
}
1840+
};
17781841

17791842
SmallVector<SmallVector<unsigned, 4>, 4> definedInDesignatedType;
17801843
SmallVector<SmallVector<unsigned, 4>, 4> definedInExtensionOfDesignatedType;
1781-
SmallVector<unsigned, 4> everythingElse;
1782-
1783-
// Now collect the overload choices that are defined within the type
1784-
// that was designated in the operator declaration.
1785-
auto designatedNominalTypes = getOperatorDesignatedNominalTypes(Choices[0]);
1786-
if (!designatedNominalTypes.empty()) {
1787-
forEachChoice(
1788-
Choices, [&](unsigned constraintIndex, Constraint *constraint) -> bool {
1789-
auto *decl = constraint->getOverloadChoice().getDecl();
1790-
auto *funcDecl = cast<FuncDecl>(decl);
1791-
1792-
auto *parentDecl = funcDecl->getParent()->getAsDecl();
1793-
for (auto designatedTypeIndex : indices(designatedNominalTypes)) {
1794-
auto *designatedNominal =
1795-
designatedNominalTypes[designatedTypeIndex];
1796-
if (parentDecl == designatedNominal) {
1797-
if (designatedTypeIndex >= definedInDesignatedType.size())
1798-
definedInDesignatedType.resize(designatedTypeIndex + 1);
1799-
auto &constraints = definedInDesignatedType[designatedTypeIndex];
1800-
constraints.push_back(constraintIndex);
1801-
return true;
1802-
}
1803-
1804-
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(parentDecl)) {
1805-
parentDecl = extensionDecl->getExtendedNominal();
1806-
if (parentDecl == designatedNominal) {
1807-
if (designatedTypeIndex >=
1808-
definedInExtensionOfDesignatedType.size())
1809-
definedInExtensionOfDesignatedType.resize(
1810-
designatedTypeIndex + 1);
1811-
1812-
auto &constraints =
1813-
definedInExtensionOfDesignatedType[designatedTypeIndex];
1814-
constraints.push_back(constraintIndex);
1815-
return true;
1816-
}
1817-
}
1818-
}
1819-
1820-
return false;
1821-
});
1822-
}
18231844

1824-
// Add partitions for each of the overloads we found in types that
1825-
// were designated as part of the operator declaration.
1826-
for (auto designatedTypeIndex : indices(designatedNominalTypes)) {
1827-
if (designatedTypeIndex < definedInDesignatedType.size()) {
1828-
auto &primary = definedInDesignatedType[designatedTypeIndex];
1829-
appendPartition(primary);
1830-
}
1831-
if (designatedTypeIndex < definedInExtensionOfDesignatedType.size()) {
1832-
auto &secondary = definedInExtensionOfDesignatedType[designatedTypeIndex];
1833-
appendPartition(secondary);
1834-
}
1835-
}
1845+
partitionForDesignatedTypes(Choices, forEachChoice, appendPartition,
1846+
definedInDesignatedType,
1847+
definedInExtensionOfDesignatedType);
18361848

1849+
SmallVector<unsigned, 4> everythingElse;
18371850
// Gather the remaining options.
18381851
forEachChoice(Choices, [&](unsigned index, Constraint *constraint) -> bool {
18391852
everythingElse.push_back(index);
18401853
return true;
18411854
});
1855+
appendPartition(everythingElse);
18421856

18431857
// Now create the remaining partitions from what we previously collected.
1844-
1845-
appendPartition(everythingElse);
18461858
appendPartition(globalScope);
18471859
appendPartition(unavailable);
18481860
appendPartition(disabled);

lib/Sema/ConstraintSystem.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3221,6 +3221,22 @@ class ConstraintSystem {
32213221

32223222
bool haveTypeInformationForAllArguments(FunctionType *fnType);
32233223

3224+
typedef std::function<bool(unsigned index, Constraint *)> ConstraintMatcher;
3225+
typedef std::function<void(ArrayRef<Constraint *>, ConstraintMatcher)>
3226+
ConstraintMatchLoop;
3227+
typedef std::function<void(SmallVectorImpl<unsigned> &options)>
3228+
PartitionAppendCallback;
3229+
3230+
// Partition the choices in a disjunction based on those that match
3231+
// the designated types for the operator that the disjunction was
3232+
// formed for.
3233+
void partitionForDesignatedTypes(
3234+
ArrayRef<Constraint *> Choices, ConstraintMatchLoop forEachChoice,
3235+
PartitionAppendCallback appendPartition,
3236+
SmallVectorImpl<SmallVector<unsigned, 4>> &definedInDesignatedType,
3237+
SmallVectorImpl<SmallVector<unsigned, 4>>
3238+
&definedInExtensionOfDesignatedType);
3239+
32243240
// Partition the choices in the disjunction into groups that we will
32253241
// iterate over in an order appropriate to attempt to stop before we
32263242
// have to visit all of the options.

0 commit comments

Comments
 (0)