Every protocol gets an 'identity conformance' rule [P].[P] => [P].
A trivially-stated circularity is always redundant because of this
rule, and we diagnose circular inheritance elsewhere as a hard
error, so just add a special case to skip adding such a rule here
to avoid the useless warning on top of the existing error.
We want to allow this for all conformance requirements written in protocols
or the `where` clause of protocol extensions.
Fixes rdar://problem/91304291.
When computing an overlap between a property-like rule (T.[p] => T for some
property symbol [p]) and another rule, try harder to ensure that the new
rule is a property-like rule.
In a conformance-valid rewrite system, all rules that are not LHS- or RHS-
simplified will eventually either be property-like or same-type rules, but
we need to maintain this invariant for that rules that become simplified
as well, to ensure that rewrite loops have a certain structure that is
important for the minimal conformances algorithm.
I don't quite understand why to be honest, but I'm close to figuring it
out.
Fixes rdar://problem/91232987.
computing a concrete same-type or superclass for conflict diagnostics.
Otherwise, diagnostics will show fresh type parameters when the concrete
type is generic.
initializing a RequirementMachine for a written protocol signature.
These generic parameters are used for re-sugaring when computing a
type from a term, so if the recorded 'Self' parameter is canonicalized,
it shows up in diagnostics as 'tau_0_0'.
A protocol typealias 'typealias T = X' introduces a same-type requirement
'Self.T == Self.X'. However the right hand side of the requirement was
wrapped in a sugared TypeAliasType.
This meant if the requirement surfaced in a redundancy diagnostic, it
would print as 'Self.T == Self.T'. It could also trigger a request cycle
via isInterestingTypealias() in DiagnosticEngine.cpp.
A requirement machine built from existing protocol requirement signatures only
exists to cache those rules and allow them to be inherited by other machines.
Recording loops is unnecessary in this case, since no minimization will be
performed.
Property map construction is still not incremental, and considers
all rules. Skipping subst-simplified rules here violates invariants
checked by the next commit.
For efficiency I want to keep replacement paths for redundant rules
unsubstituted, so that earlier replacement paths can reference
redundant rules that appear later in the RedundantRules array.
Right now we expand replacement paths so that their RewriteSteps
only mention non-redundant rules.
This patch refactors the computeRedundantRequirementDiagnostics()
method a bit:
The impliedRequirements set is now named nonExplicitNonRedundantRules,
and in addition to storing these rules themselves, the set also
stores any _redundant_ rules that reference these rules via their
replacement paths.
Since this is computing a transitive closure, we walk the
RedundantRules array in reverse. A replacement path can only
reference a redundant rule if that redundant rule appears later
in the array.