|
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 |
|
@@ -1814,6 +1815,9 @@ static bool shouldSkipDisjunctionChoice(ConstraintSystem &cs,
|
1814 | 1815 | static Constraint *selectBestBindingDisjunction(
|
1815 | 1816 | ConstraintSystem &cs, SmallVectorImpl<Constraint *> &disjunctions) {
|
1816 | 1817 |
|
| 1818 | + if (disjunctions.empty()) |
| 1819 | + return nullptr; |
| 1820 | + |
1817 | 1821 | // Collect any disjunctions that simply attempt bindings for a
|
1818 | 1822 | // type variable.
|
1819 | 1823 | SmallVector<Constraint *, 8> bindingDisjunctions;
|
@@ -1884,44 +1888,28 @@ Constraint *ConstraintSystem::selectDisjunction() {
|
1884 | 1888 | SmallVector<Constraint *, 4> disjunctions;
|
1885 | 1889 |
|
1886 | 1890 | collectDisjunctions(disjunctions);
|
1887 |
| - |
1888 |
| - if (disjunctions.empty()) |
1889 |
| - return nullptr; |
1890 |
| - |
1891 |
| - auto *disjunction = |
1892 |
| - selectBestBindingDisjunction(*this, disjunctions); |
1893 |
| - |
1894 |
| - if (disjunction) |
| 1891 | + if (auto *disjunction = selectBestBindingDisjunction(*this, disjunctions)) |
1895 | 1892 | return disjunction;
|
1896 | 1893 |
|
1897 | 1894 | // Pick the disjunction with the lowest disjunction number in order
|
1898 | 1895 | // to solve them in the order they were created (which should be
|
1899 | 1896 | // stable within an expression).
|
1900 |
| - disjunction = disjunctions[0]; |
1901 |
| - auto found = DisjunctionNumber.find(disjunction); |
1902 |
| - assert(found != DisjunctionNumber.end()); |
1903 |
| - auto lowestNumber = found->second; |
1904 |
| - if (lowestNumber > 0) { |
1905 |
| - for (auto contender : llvm::makeArrayRef(disjunctions).slice(1)) { |
1906 |
| - auto found = DisjunctionNumber.find(contender); |
1907 |
| - assert(found != DisjunctionNumber.end()); |
1908 |
| - unsigned newNumber = found->second; |
1909 |
| - if (newNumber < lowestNumber) { |
1910 |
| - lowestNumber = newNumber; |
1911 |
| - disjunction = contender; |
1912 |
| - |
1913 |
| - if (lowestNumber == 0) |
1914 |
| - break; |
1915 |
| - } |
1916 |
| - } |
1917 |
| - } |
| 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); |
| 1902 | + |
| 1903 | + assert(firstFound != DisjunctionNumber.end() && |
| 1904 | + secondFound != DisjunctionNumber.end()); |
1918 | 1905 |
|
1919 |
| - // If there are no active constraints in the disjunction, there is |
1920 |
| - // no solution. |
1921 |
| - // if (bestSize == 0) |
1922 |
| - // return nullptr; |
| 1906 | + return firstFound->second < secondFound->second; |
| 1907 | + }); |
1923 | 1908 |
|
1924 |
| - return disjunction; |
| 1909 | + if (minDisjunction != disjunctions.end()) |
| 1910 | + return *minDisjunction; |
| 1911 | + |
| 1912 | + return nullptr; |
1925 | 1913 | }
|
1926 | 1914 |
|
1927 | 1915 | bool ConstraintSystem::solveSimplified(
|
|
0 commit comments