Previously we did this when adding new concrete type rules,
but we don't have a complete rewrite system at that point yet,
so there was no guarantee concrete substitution terms would
be canonical.
Now, perform simplification in a post-pass after completion,
at the same time as simplifying rule right hand sides.
Rewrite loops are recorded relating the original rule with the
simplified substitutions.
Filter out trivial overlaps where a rule overlaps entirely with
itself before looking at CheckedOverlaps. Otherwise, we'll miss
overlaps where a rule overlaps with itself at a non-zero
position.
When a rewrite rule is replaced with a path containing ::Adjust, ::Decompose,
::ConcreteConformance or ::SuperclassConformance rewrite steps, the steps
will get a non-zero EndOffset if the original rule appears in a step with a
non-zero EndOffset.
For this reason, these steps must work with a non-zero EndOffset, which
primarily means computing correct offsets into the term being manipulated.