@@ -128,17 +128,21 @@ void RewriteSystem::simplifyLeftHandSideSubstitutions() {
128128 }
129129}
130130
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.
134137// /
135138// / Returns None if the concrete type symbol cannot be simplified further.
136139// /
137140// / Otherwise returns an index which can be passed to
138141// / RewriteSystem::getTypeDifference().
139142Optional<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) {
142146 assert (symbol.hasSubstitutions ());
143147
144148 // Fast path if the type is fully concrete.
@@ -181,39 +185,19 @@ PropertyMap::concretelySimplifySubstitutions(Term baseTerm, Symbol symbol,
181185 // has to iterate until fixed point anyway.
182186 //
183187 // This should be rare in practice.
184- if (System. simplify (mutTerm, path)) {
188+ if (simplify (mutTerm, path)) {
185189 // Record a mapping from this substitution to the simplified term.
186190 sameTypes.emplace_back (index, Term::get (mutTerm, Context));
187- } else {
188- auto *props = lookUpProperties (mutTerm);
189191
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);
197198
198199 // Record a mapping from this substitution to the concrete type.
199200 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- }
217201 }
218202 }
219203 }
@@ -240,7 +224,7 @@ PropertyMap::concretelySimplifySubstitutions(Term baseTerm, Symbol symbol,
240224 Context);
241225 assert (difference.LHS != difference.RHS );
242226
243- unsigned differenceID = System. recordTypeDifference (difference);
227+ unsigned differenceID = recordTypeDifference (difference);
244228
245229 // All simplified substitutions are now on the primary stack. Collect them to
246230 // produce the new term.
@@ -252,9 +236,15 @@ PropertyMap::concretelySimplifySubstitutions(Term baseTerm, Symbol symbol,
252236 return differenceID;
253237}
254238
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);
258248 if (rule.isLHSSimplified () ||
259249 rule.isRHSSimplified () ||
260250 rule.isSubstitutionSimplified ())
@@ -268,14 +258,13 @@ void PropertyMap::concretelySimplifyLeftHandSideSubstitutions() const {
268258
269259 RewritePath path;
270260
271- auto differenceID = concretelySimplifySubstitutions (
272- rule.getRHS (), symbol, &path);
261+ auto differenceID = simplifySubstitutions (rule.getRHS (), symbol, map, &path);
273262 if (!differenceID)
274263 continue ;
275264
276265 rule.markSubstitutionSimplified ();
277266
278- auto difference = System. getTypeDifference (*differenceID);
267+ auto difference = getTypeDifference (*differenceID);
279268 assert (difference.LHS == symbol);
280269
281270 // If the original rule is (T.[concrete: C] => T) and [concrete: C'] is
@@ -295,6 +284,6 @@ void PropertyMap::concretelySimplifyLeftHandSideSubstitutions() const {
295284 MutableTerm lhs (rhs);
296285 lhs.add (difference.RHS );
297286
298- System. addRule (lhs, rhs, &path);
287+ addRule (lhs, rhs, &path);
299288 }
300289}
0 commit comments