@@ -1858,24 +1858,98 @@ static bool shouldSkipDisjunctionChoice(ConstraintSystem &cs,
1858
1858
return false ;
1859
1859
}
1860
1860
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
+
1861
1940
Constraint *ConstraintSystem::selectDisjunction () {
1862
1941
SmallVector<Constraint *, 4 > disjunctions;
1863
1942
1864
1943
collectDisjunctions (disjunctions);
1944
+ if (auto *disjunction = selectBestBindingDisjunction (*this , disjunctions))
1945
+ return disjunction;
1865
1946
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.
1869
1948
auto minDisjunction =
1870
1949
std::min_element (disjunctions.begin (), disjunctions.end (),
1871
1950
[&](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 ();
1879
1953
});
1880
1954
1881
1955
if (minDisjunction != disjunctions.end ())
0 commit comments