|
16 | 16 | using namespace swift; |
17 | 17 | using namespace rewriting; |
18 | 18 |
|
19 | | -/// Simplify terms appearing in the substitutions of the last symbol of \p term, |
20 | | -/// which must be a superclass or concrete type symbol. |
21 | | -bool RewriteSystem::simplifySubstitutions(Symbol &symbol, |
22 | | - RewritePath *path) const { |
23 | | - assert(symbol.hasSubstitutions()); |
24 | | - |
25 | | - // Fast path if the type is fully concrete. |
26 | | - auto substitutions = symbol.getSubstitutions(); |
27 | | - if (substitutions.empty()) |
28 | | - return false; |
29 | | - |
30 | | - // Save the original rewrite path length so that we can reset if if we don't |
31 | | - // find anything to simplify. |
32 | | - unsigned oldSize = (path ? path->size() : 0); |
33 | | - |
34 | | - if (path) { |
35 | | - // The term is at the top of the primary stack. Push all substitutions onto |
36 | | - // the primary stack. |
37 | | - path->add(RewriteStep::forDecompose(substitutions.size(), |
38 | | - /*inverse=*/false)); |
39 | | - |
40 | | - // Move all substitutions but the first one to the secondary stack. |
41 | | - for (unsigned i = 1; i < substitutions.size(); ++i) |
42 | | - path->add(RewriteStep::forShift(/*inverse=*/false)); |
43 | | - } |
44 | | - |
45 | | - // Simplify and collect substitutions. |
46 | | - SmallVector<Term, 2> newSubstitutions; |
47 | | - newSubstitutions.reserve(substitutions.size()); |
48 | | - |
49 | | - bool first = true; |
50 | | - bool anyChanged = false; |
51 | | - for (auto substitution : substitutions) { |
52 | | - // Move the next substitution from the secondary stack to the primary stack. |
53 | | - if (!first && path) |
54 | | - path->add(RewriteStep::forShift(/*inverse=*/true)); |
55 | | - first = false; |
56 | | - |
57 | | - // The current substitution is at the top of the primary stack; simplify it. |
58 | | - MutableTerm mutTerm(substitution); |
59 | | - anyChanged |= simplify(mutTerm, path); |
60 | | - |
61 | | - // Record the new substitution. |
62 | | - newSubstitutions.push_back(Term::get(mutTerm, Context)); |
63 | | - } |
64 | | - |
65 | | - // All simplified substitutions are now on the primary stack. Collect them to |
66 | | - // produce the new term. |
67 | | - if (path) { |
68 | | - path->add(RewriteStep::forDecompose(substitutions.size(), |
69 | | - /*inverse=*/true)); |
70 | | - } |
71 | | - |
72 | | - // If nothing changed, we don't have to rebuild the symbol. |
73 | | - if (!anyChanged) { |
74 | | - if (path) { |
75 | | - // The rewrite path should consist of a Decompose, followed by a number |
76 | | - // of Shifts, followed by a Compose. |
77 | | - #ifndef NDEBUG |
78 | | - for (auto iter = path->begin() + oldSize; iter < path->end(); ++iter) { |
79 | | - assert(iter->Kind == RewriteStep::Shift || |
80 | | - iter->Kind == RewriteStep::Decompose); |
81 | | - } |
82 | | - #endif |
83 | | - |
84 | | - path->resize(oldSize); |
85 | | - } |
86 | | - return false; |
87 | | - } |
88 | | - |
89 | | - // Build the new symbol with simplified substitutions. |
90 | | - symbol = symbol.withConcreteSubstitutions(newSubstitutions, Context); |
91 | | - return true; |
92 | | -} |
93 | | - |
94 | 19 | /// Simplify terms appearing in the substitutions of the last symbol of \p term, |
95 | 20 | /// which must be a superclass or concrete type symbol. |
96 | 21 | /// |
|
0 commit comments