@@ -128,17 +128,21 @@ void RewriteSystem::simplifyLeftHandSideSubstitutions() {
128
128
}
129
129
}
130
130
131
- // / Similar to RewriteSystem::simplifySubstitutions(), but also replaces type
132
- // / parameters with concrete types and builds a type difference describing
133
- // / the transformation.
131
+ // / Simplify terms appearing in the substitutions of the last symbol of \p term,
132
+ // / which must be a superclass or concrete type symbol.
133
+ // /
134
+ // / Additionally, if \p map is non-null, any terms which become concrete types
135
+ // / will cause the corresponding generic parameter in the concrete type symbol
136
+ // / to be replaced.
134
137
// /
135
138
// / Returns None if the concrete type symbol cannot be simplified further.
136
139
// /
137
140
// / Otherwise returns an index which can be passed to
138
141
// / RewriteSystem::getTypeDifference().
139
142
Optional<unsigned >
140
- PropertyMap::concretelySimplifySubstitutions (Term baseTerm, Symbol symbol,
141
- RewritePath *path) const {
143
+ RewriteSystem::simplifySubstitutions (Term baseTerm, Symbol symbol,
144
+ const PropertyMap *map,
145
+ RewritePath *path) {
142
146
assert (symbol.hasSubstitutions ());
143
147
144
148
// Fast path if the type is fully concrete.
@@ -181,39 +185,19 @@ PropertyMap::concretelySimplifySubstitutions(Term baseTerm, Symbol symbol,
181
185
// has to iterate until fixed point anyway.
182
186
//
183
187
// This should be rare in practice.
184
- if (System. simplify (mutTerm, path)) {
188
+ if (simplify (mutTerm, path)) {
185
189
// Record a mapping from this substitution to the simplified term.
186
190
sameTypes.emplace_back (index, Term::get (mutTerm, Context));
187
- } else {
188
- auto *props = lookUpProperties (mutTerm);
189
191
190
- if (props && props->ConcreteType ) {
191
- // The property map entry might apply to a suffix of the substitution
192
- // term, so prepend the appropriate prefix to its own substitutions.
193
- auto prefix = props->getPrefixAfterStrippingKey (mutTerm);
194
- auto concreteSymbol =
195
- props->ConcreteType ->prependPrefixToConcreteSubstitutions (
196
- prefix, Context);
192
+ } else if (map) {
193
+ auto *props = map->lookUpProperties (mutTerm);
194
+
195
+ if (props && props->isConcreteType ()) {
196
+ auto concreteSymbol = props->concretelySimplifySubstitution (
197
+ mutTerm, Context, path);
197
198
198
199
// Record a mapping from this substitution to the concrete type.
199
200
concreteTypes.emplace_back (index, concreteSymbol);
200
-
201
- // If U.V is the substitution term and V is the property map key,
202
- // apply the rewrite step U.(V => V.[concrete: C]) followed by
203
- // prepending the prefix U to each substitution in the concrete type
204
- // symbol if |U| > 0.
205
- if (path) {
206
- path->add (RewriteStep::forRewriteRule (/* startOffset=*/ prefix.size (),
207
- /* endOffset=*/ 0 ,
208
- /* ruleID=*/ *props->ConcreteTypeRule ,
209
- /* inverse=*/ true ));
210
-
211
- if (!prefix.empty ()) {
212
- path->add (RewriteStep::forPrefixSubstitutions (/* length=*/ prefix.size (),
213
- /* endOffset=*/ 0 ,
214
- /* inverse=*/ false ));
215
- }
216
- }
217
201
}
218
202
}
219
203
}
@@ -240,7 +224,7 @@ PropertyMap::concretelySimplifySubstitutions(Term baseTerm, Symbol symbol,
240
224
Context);
241
225
assert (difference.LHS != difference.RHS );
242
226
243
- unsigned differenceID = System. recordTypeDifference (difference);
227
+ unsigned differenceID = recordTypeDifference (difference);
244
228
245
229
// All simplified substitutions are now on the primary stack. Collect them to
246
230
// produce the new term.
@@ -252,9 +236,15 @@ PropertyMap::concretelySimplifySubstitutions(Term baseTerm, Symbol symbol,
252
236
return differenceID;
253
237
}
254
238
255
- void PropertyMap::concretelySimplifyLeftHandSideSubstitutions () const {
256
- for (unsigned ruleID = 0 , e = System.getRules ().size (); ruleID < e; ++ruleID) {
257
- auto &rule = System.getRule (ruleID);
239
+ // / Simplify substitution terms in superclass, concrete type and concrete
240
+ // / conformance symbols.
241
+ // /
242
+ // / During completion, \p map will be null. After completion, the property map
243
+ // / is built, and a final simplification pass is performed with \p map set to
244
+ // / the new property map.
245
+ void RewriteSystem::simplifyLeftHandSideSubstitutions (const PropertyMap *map) {
246
+ for (unsigned ruleID = 0 , e = Rules.size (); ruleID < e; ++ruleID) {
247
+ auto &rule = getRule (ruleID);
258
248
if (rule.isLHSSimplified () ||
259
249
rule.isRHSSimplified () ||
260
250
rule.isSubstitutionSimplified ())
@@ -268,14 +258,13 @@ void PropertyMap::concretelySimplifyLeftHandSideSubstitutions() const {
268
258
269
259
RewritePath path;
270
260
271
- auto differenceID = concretelySimplifySubstitutions (
272
- rule.getRHS (), symbol, &path);
261
+ auto differenceID = simplifySubstitutions (rule.getRHS (), symbol, map, &path);
273
262
if (!differenceID)
274
263
continue ;
275
264
276
265
rule.markSubstitutionSimplified ();
277
266
278
- auto difference = System. getTypeDifference (*differenceID);
267
+ auto difference = getTypeDifference (*differenceID);
279
268
assert (difference.LHS == symbol);
280
269
281
270
// If the original rule is (T.[concrete: C] => T) and [concrete: C'] is
@@ -295,6 +284,6 @@ void PropertyMap::concretelySimplifyLeftHandSideSubstitutions() const {
295
284
MutableTerm lhs (rhs);
296
285
lhs.add (difference.RHS );
297
286
298
- System. addRule (lhs, rhs, &path);
287
+ addRule (lhs, rhs, &path);
299
288
}
300
289
}
0 commit comments