We would bail out early if there was no property map entry for this key.
But this means if a term without properties was non-canonical, this
method would still return false.
On the other hand, it is possible for a DependentMemberType to be
canonical, even if its parent is not, in the case where the parent
is fixed to a concrete type.
To handle this properly, change the type walk to use a TypeWalker
directly instead of findIf(); this allows us to return
Action::SkipChildren upon encountering a DependentMemberType.
The primary use of isCanonicalTypeInContext() was from inside
GenericSignature::verify(). So the assertion there will become
stricter.
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.
We assert when building a rewrite system for an existing generic
signature, or in AbstractGenericSignatureRequest, where there is no
source location.
In RequirementSignatureRequest and InferredGenericSignatureRequest
we now produce a diagnostic.
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.
When a rule is replaced by a rewrite path, if the rule is in context
then every step of the replacement step is necessarily always in context.
The only way new rules in empty context can be introduced by a
replacement is if the original rewrite step being replaced had no
context.
Therefore, loops that do not contain rules in empty context will
never provide any additional information during homotopy reduction.
This is a source-level error, not an invariant violation. Instead, plumb
a new hadError() flag, which in the future will assert if no diagnostic
was produced.