Skip to content

Commit 5828a98

Browse files
authored
Merge pull request #18032 from rudkx/restore-order
Return to the old disjunction ordering until some test regressions are addressed.
2 parents 074dc43 + 8b62b13 commit 5828a98

File tree

2 files changed

+85
-12
lines changed

2 files changed

+85
-12
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,24 +1858,98 @@ static bool shouldSkipDisjunctionChoice(ConstraintSystem &cs,
18581858
return false;
18591859
}
18601860

1861+
// Attempt to find a disjunction of bind constraints where all options
1862+
// in the disjunction are binding the same type variable.
1863+
//
1864+
// Prefer disjunctions where the bound type variable is also the
1865+
// right-hand side of a conversion constraint, since having a concrete
1866+
// type that we're converting to can make it possible to split the
1867+
// constraint system into multiple ones.
1868+
static Constraint *selectBestBindingDisjunction(
1869+
ConstraintSystem &cs, SmallVectorImpl<Constraint *> &disjunctions) {
1870+
1871+
if (disjunctions.empty())
1872+
return nullptr;
1873+
1874+
// Collect any disjunctions that simply attempt bindings for a
1875+
// type variable.
1876+
SmallVector<Constraint *, 8> bindingDisjunctions;
1877+
for (auto *disjunction : disjunctions) {
1878+
llvm::Optional<TypeVariableType *> commonTypeVariable;
1879+
if (llvm::all_of(
1880+
disjunction->getNestedConstraints(),
1881+
[&](Constraint *bindingConstraint) {
1882+
if (bindingConstraint->getKind() != ConstraintKind::Bind)
1883+
return false;
1884+
1885+
auto *tv =
1886+
bindingConstraint->getFirstType()->getAs<TypeVariableType>();
1887+
// Only do this for simple type variable bindings, not for
1888+
// bindings like: ($T1) -> $T2 bind String -> Int
1889+
if (!tv)
1890+
return false;
1891+
1892+
if (!commonTypeVariable.hasValue())
1893+
commonTypeVariable = tv;
1894+
1895+
if (commonTypeVariable.getValue() != tv)
1896+
return false;
1897+
1898+
return true;
1899+
})) {
1900+
bindingDisjunctions.push_back(disjunction);
1901+
}
1902+
}
1903+
1904+
for (auto *disjunction : bindingDisjunctions) {
1905+
auto nested = disjunction->getNestedConstraints();
1906+
assert(!nested.empty());
1907+
auto *tv = cs.simplifyType(nested[0]->getFirstType())
1908+
->getRValueType()
1909+
->getAs<TypeVariableType>();
1910+
assert(tv);
1911+
1912+
SmallVector<Constraint *, 8> constraints;
1913+
cs.getConstraintGraph().gatherConstraints(
1914+
tv, constraints, ConstraintGraph::GatheringKind::EquivalenceClass);
1915+
1916+
for (auto *constraint : constraints) {
1917+
if (constraint->getKind() != ConstraintKind::Conversion)
1918+
continue;
1919+
1920+
auto toType =
1921+
cs.simplifyType(constraint->getSecondType())->getRValueType();
1922+
auto *toTV = toType->getAs<TypeVariableType>();
1923+
if (tv != toTV)
1924+
continue;
1925+
1926+
return disjunction;
1927+
}
1928+
}
1929+
1930+
// If we had any binding disjunctions, return the first of
1931+
// those. These ensure that we attempt to bind types earlier than
1932+
// trying the elements of other disjunctions, which can often mean
1933+
// we fail faster.
1934+
if (!bindingDisjunctions.empty())
1935+
return bindingDisjunctions[0];
1936+
1937+
return nullptr;
1938+
}
1939+
18611940
Constraint *ConstraintSystem::selectDisjunction() {
18621941
SmallVector<Constraint *, 4> disjunctions;
18631942

18641943
collectDisjunctions(disjunctions);
1944+
if (auto *disjunction = selectBestBindingDisjunction(*this, disjunctions))
1945+
return disjunction;
18651946

1866-
// Pick the disjunction with the lowest disjunction number in order
1867-
// to solve them in the order they were created (which should be
1868-
// stable within an expression).
1947+
// Pick the disjunction with the smallest number of active choices.
18691948
auto minDisjunction =
18701949
std::min_element(disjunctions.begin(), disjunctions.end(),
18711950
[&](Constraint *first, Constraint *second) -> bool {
1872-
auto firstFound = DisjunctionNumber.find(first);
1873-
auto secondFound = DisjunctionNumber.find(second);
1874-
1875-
assert(firstFound != DisjunctionNumber.end() &&
1876-
secondFound != DisjunctionNumber.end());
1877-
1878-
return firstFound->second < secondFound->second;
1951+
return first->countActiveNestedConstraints() <
1952+
second->countActiveNestedConstraints();
18791953
});
18801954

18811955
if (minDisjunction != disjunctions.end())

validation-test/stdlib/AnyHashable.swift.gyb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -757,9 +757,8 @@ AnyHashableTests.test("AnyHashable(MinimalHashableRCSwiftError)/Hashable") {
757757
xs,
758758
equalityOracle: { $0 / 2 == $1 / 2 },
759759
hashEqualityOracle: { $0 / 4 == $1 / 4 })
760-
let mapped = xs.map(AnyHashable.init)
761760
checkHashable(
762-
mapped,
761+
xs.map(AnyHashable.init),
763762
equalityOracle: { $0 / 2 == $1 / 2 },
764763
hashEqualityOracle: { $0 / 4 == $1 / 4 })
765764
}

0 commit comments

Comments
 (0)