13
13
// This file implements the constraint solver used in the type checker.
14
14
//
15
15
// ===----------------------------------------------------------------------===//
16
- #include " ConstraintSystem.h"
17
16
#include " ConstraintGraph.h"
17
+ #include " ConstraintSystem.h"
18
18
#include " swift/AST/ParameterList.h"
19
19
#include " swift/AST/TypeWalker.h"
20
20
#include " llvm/ADT/Statistic.h"
21
21
#include " llvm/Support/Compiler.h"
22
- #include " llvm/Support/raw_ostream.h"
23
22
#include " llvm/Support/SaveAndRestore.h"
23
+ #include " llvm/Support/raw_ostream.h"
24
+ #include < algorithm>
24
25
#include < memory>
25
26
#include < tuple>
26
27
@@ -1492,13 +1493,8 @@ bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions,
1492
1493
1493
1494
// If we don't have more than one component, just solve the whole
1494
1495
// system.
1495
- if (numComponents < 2 ) {
1496
- SmallVector<Constraint *, 8 > disjunctions;
1497
- collectDisjunctions (disjunctions);
1498
-
1499
- return solveSimplified (selectDisjunction (disjunctions), solutions,
1500
- allowFreeTypeVariables);
1501
- }
1496
+ if (numComponents < 2 )
1497
+ return solveSimplified (solutions, allowFreeTypeVariables);
1502
1498
1503
1499
if (TC.Context .LangOpts .DebugConstraintSolver ) {
1504
1500
auto &log = getASTContext ().TypeCheckerDebug ->getStream ();
@@ -1819,6 +1815,9 @@ static bool shouldSkipDisjunctionChoice(ConstraintSystem &cs,
1819
1815
static Constraint *selectBestBindingDisjunction (
1820
1816
ConstraintSystem &cs, SmallVectorImpl<Constraint *> &disjunctions) {
1821
1817
1818
+ if (disjunctions.empty ())
1819
+ return nullptr ;
1820
+
1822
1821
// Collect any disjunctions that simply attempt bindings for a
1823
1822
// type variable.
1824
1823
SmallVector<Constraint *, 8 > bindingDisjunctions;
@@ -1885,46 +1884,40 @@ static Constraint *selectBestBindingDisjunction(
1885
1884
return nullptr ;
1886
1885
}
1887
1886
1888
- Constraint *ConstraintSystem::selectDisjunction (
1889
- SmallVectorImpl<Constraint *> &disjunctions) {
1890
- if (disjunctions.empty ())
1891
- return nullptr ;
1887
+ Constraint *ConstraintSystem::selectDisjunction () {
1888
+ SmallVector<Constraint *, 4 > disjunctions;
1892
1889
1893
- auto *disjunction =
1894
- selectBestBindingDisjunction (*this , disjunctions);
1895
- if (disjunction)
1890
+ collectDisjunctions (disjunctions);
1891
+ if (auto *disjunction = selectBestBindingDisjunction (*this , disjunctions))
1896
1892
return disjunction;
1897
1893
1898
- // Pick the smallest disjunction.
1899
- // FIXME: This heuristic isn't great, but it helped somewhat for
1900
- // overload sets.
1901
- disjunction = disjunctions[0 ];
1902
- auto bestSize = disjunction->countActiveNestedConstraints ();
1903
- if (bestSize > 2 ) {
1904
- for (auto contender : llvm::makeArrayRef (disjunctions).slice (1 )) {
1905
- unsigned newSize = contender->countActiveNestedConstraints ();
1906
- if (newSize < bestSize) {
1907
- bestSize = newSize;
1908
- disjunction = contender;
1909
-
1910
- if (bestSize == 2 )
1911
- break ;
1912
- }
1913
- }
1914
- }
1894
+ // Pick the disjunction with the lowest disjunction number in order
1895
+ // to solve them in the order they were created (which should be
1896
+ // stable within an expression).
1897
+ auto minDisjunction =
1898
+ std::min_element (disjunctions.begin (), disjunctions.end (),
1899
+ [&](Constraint *first, Constraint *second) -> bool {
1900
+ auto firstFound = DisjunctionNumber.find (first);
1901
+ auto secondFound = DisjunctionNumber.find (second);
1915
1902
1916
- // If there are no active constraints in the disjunction, there is
1917
- // no solution.
1918
- if (bestSize == 0 )
1919
- return nullptr ;
1903
+ assert (firstFound != DisjunctionNumber.end () &&
1904
+ secondFound != DisjunctionNumber.end ());
1905
+
1906
+ return firstFound->second < secondFound->second ;
1907
+ });
1920
1908
1921
- return disjunction;
1909
+ if (minDisjunction != disjunctions.end ())
1910
+ return *minDisjunction;
1911
+
1912
+ return nullptr ;
1922
1913
}
1923
1914
1924
1915
bool ConstraintSystem::solveSimplified (
1925
- Constraint *disjunction, SmallVectorImpl<Solution> &solutions,
1916
+ SmallVectorImpl<Solution> &solutions,
1926
1917
FreeTypeVariableBinding allowFreeTypeVariables) {
1927
1918
1919
+ auto *disjunction = selectDisjunction ();
1920
+
1928
1921
auto bestBindings = determineBestBindings ();
1929
1922
1930
1923
// If we have a binding that does not involve type variables, and is
@@ -1937,6 +1930,8 @@ bool ConstraintSystem::solveSimplified(
1937
1930
allowFreeTypeVariables);
1938
1931
}
1939
1932
1933
+
1934
+
1940
1935
// If there are no disjunctions we can't solve this system unless we have
1941
1936
// free type variables and are allowing them in the solution.
1942
1937
if (!disjunction) {
0 commit comments