Without this, we only considered a protocol refinement rule redundant if
it was derived by directly-stated protocol refinements. But this broke
when completion introduced a 'transitive' refinement [P].[R] => [P]
from two directly-stated refinements [P].[Q] => [P] and [Q].[R] => [Q].
Fixes rdar://problem/90402503.
Completion has a maximum rule limit since the Knuth-Bendix algorithm
is a semi-decision procedure that does not terminate on all inputs.
However, this means that generic signatures which import a large
number of complex protocols can hit the limit even if they are
convergent.
Since imported rules are essentially free, ignore them here, to
avoid having to increase the limit by hand.
Now the default limit is 4000 local rules per requirement machine;
it seems implausible that you would exceed this, but if anyone has
an example we can bump the limit again.
This fixes a regression from the rule sharing implementation; I forgot
to handle the imported rules in builder.ImportedRules here.
This makes the usage of RuleBuilder in conditional requirement
inference look like the other usages of RuleBuilder, except
that the results are passed to RewriteSystem::addRules() instead
of RewriteSystem::initialize().
All the pieces are now in place so that the RuleBuilder can assemble
a confluent rewrite system for downstream protocol dependencies,
instead of building rules from protocol requirement signatures.
Remove the logic which incorrectly attempted to simulate the
GenericSignatureBuilder's minimization behavior in the presence
of conflicts, since it doesn't matter anymore.
The Requirement Machine operates on canonical types internally and erases
sugared types appearing in generic requirements as a result.
For trivial cases like Array<T> vs [T], we can use the existing
TypeBase::reconstituteSugar() utility to produce a more aesthetically-pleasing
generic signature.
Preserves concrete type rules on associated types that were derived
from rules indirectly formed from protocol typealias rules.
That is, if you have a pair of rules in another minimization domain:
[P].A.[concrete: C] => [P].A
[Q:T].[P] => [Q:T]
Then completion will introduce a new rule:
[Q:T].A.[concrete: C] => [Q:T].A
Since this rule is outside of our minimization domain, we don't record
a rewrite loop for it, and it will never become redundant.
Now if we have a rule in our own minimization domain:
T.[Q:T].A => T.[Q:U]
Then we get a new rule:
T.[Q:U].[concrete: C] => T.[Q:U]
Make sure we keep this rule around on account of it being derived from
([Q:T].A.[concrete: C] => [Q:T].A).
The final step in minimization is building Requirements and
ProtocolTypeAliases from the minimal Rules in the RewriteSystem.
Move this to a new file and refactor it a bit to handle
Requirements and ProtocolTypeAliases more consistently.
If you have something like
protocol P {
typealias A = C
associatedtype T : A
}
class C {}
Then ::Structural resolution of 'A' in the inheritance clause will
produce a DependentMemberType 'Self.A'. Check for this case and
attempt ::Interface resolution to get the correct underlying type.
Fixes rdar://problem/90219229.
If a rule is not a protocol typealias rule, and does not contain any unresolved
symbols, do not attempt to eliminate it via a protocol typealias rule.
This fixes a bunch of cases where the RequirementMachine was overly-eager to
remove rules.