Commit Graph

859 Commits

Author SHA1 Message Date
Slava Pestov
c08601bee9 RequirementMachine: Implement RewriteSystem::getLocalRules() 2022-03-16 00:58:30 -04:00
Slava Pestov
327e7e580b RequirementMachine: Add importedRules parameter to RewriteSystem::initialize() 2022-03-16 00:58:30 -04:00
Slava Pestov
af443bee0a RequirementMachine: Implement RewriteContext::getRequirementMachine(ProtocolDecl *) 2022-03-16 00:58:30 -04:00
Holly Borla
6b64ac26f4 [RequirementMachine] Suppress redundant requirement warnings for inferred
requirements.
2022-03-15 21:14:43 -07:00
Slava Pestov
aaf84ac6c2 RequirementMachine: Implement RequirementMachine::initWithProtocolSignatureRequirements() 2022-03-15 18:34:54 -04:00
Slava Pestov
f3bcc52e6c RequirementMachine: Rename RequirementMachine::initWithProtocols() 2022-03-15 18:34:54 -04:00
Slava Pestov
564f626f62 RequirementMachine: Rename some RuleBuilder methods for clarity 2022-03-15 18:34:54 -04:00
Slava Pestov
1d8dd94501 RequirementMachine: Refactor RuleBuilder in preparation for rule sharing 2022-03-15 18:34:54 -04:00
Slava Pestov
1f125c3b5b RequirementMachine: Make some methods on RuleBuilder private 2022-03-15 18:34:54 -04:00
Slava Pestov
2a634ba468 RequirementMachine: Optimize RewriteSystem::normalizeRedundantRules() 2022-03-15 13:35:34 -04:00
Slava Pestov
afafede086 RequirementMachine: Support for RewriteStep::Relation in computeNormalForm() 2022-03-15 13:35:34 -04:00
Slava Pestov
86561b8865 RequirementMachine: Generalize RewritePath::replaceRuleWithPath() to replaceRulesWithPaths() 2022-03-15 13:35:34 -04:00
Slava Pestov
f810d3f388 RequirementMachine: Optimize Rewrite{Path,Loop}::computeNormalForm() 2022-03-15 13:35:34 -04:00
Slava Pestov
4df7bf91c5 RequirementMachine: Pack RewriteStep more tightly 2022-03-15 13:35:34 -04:00
Slava Pestov
d4732f5a19 RequirementMachine: Move RewritePath and RewriteLoop methods from HomotopyReduction.cpp to RewriteLoop.cpp 2022-03-15 13:35:34 -04:00
Slava Pestov
755941c21f RequirementMachine: Split off Rule.cpp from RewriteSystem.cpp 2022-03-15 13:35:34 -04:00
Slava Pestov
2ee5aeefee RequirementMachine: InferredGenericSignatureRequest returns parent generic signature if completion fails 2022-03-14 12:33:18 -04:00
Slava Pestov
6a74ad7065 RequirementMachine: Drop GSB compatibility hack involving ErrorTypes
Another hack we can remove now that 'verify' mode skips checking if
there was a conflict.
2022-03-14 12:33:18 -04:00
Slava Pestov
7b01ff60f0 RequirementMachine: Simplify RewriteSystem::processConflicts()
Remove the logic which incorrectly attempted to simulate the
GenericSignatureBuilder's minimization behavior in the presence
of conflicts, since it doesn't matter anymore.
2022-03-14 12:33:18 -04:00
Slava Pestov
13c6611ee8 RequirementMachine: Use recordConflict() in concretizeNestedTypesFromConcreteParent()
Instead of calling markConflicting() directly, use the existing
recordConflict() utility.
2022-03-14 12:33:18 -04:00
Slava Pestov
a8a281d637 RequirementMachine: Use recordConflict() for superclass conflicts
Instead of calling markConflicting() directly, use the existing
recordConflict() utility.
2022-03-14 12:33:18 -04:00
Slava Pestov
f5b3d19703 RequirementMachine: Replace hadError() with getErrors() returning an OptionSet
This gives us more fine-grained information which will be plumbed
through the various requests.
2022-03-14 12:33:18 -04:00
Slava Pestov
1578ab578a RequirementMachine: Refactor requests to not be downstream of the GenericSignatureBuilder
This will make it easier to remove the GenericSignatureBuilder (which
still won't happen for a little while).
2022-03-14 12:33:18 -04:00
Slava Pestov
05aeeff386 RequirementMachine: Reconstitute sugar in trivial cases
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.
2022-03-14 12:33:18 -04:00
Slava Pestov
e0c10d412e RequirementMachine: Tweak debug output 2022-03-14 12:33:18 -04:00
Slava Pestov
762bf1e7d0 RequirementMachine: Refine 'derived via protocol typealias' criterion
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).
2022-03-14 12:33:18 -04:00
Slava Pestov
3576318fc7 RequirementMachine: Refactor construction of requirements from rules
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.
2022-03-14 12:33:18 -04:00
Slava Pestov
a61f67a0e8 RequirementMachine: Hack to allow protocol typealiases to appear in associated type inheritance clauses
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.
2022-03-14 12:33:18 -04:00
Slava Pestov
1f83cd0b49 RequirementMachine: Don't eliminate a rule via a path involving a protocol typealias rule
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.
2022-03-11 17:28:01 -05:00
Slava Pestov
a259844803 RequirementMachine: Record those rewrite loops involving protocol typealiases 2022-03-11 17:28:01 -05:00
Slava Pestov
5cfee4e9ab RequirementMachine: Stricter invariants in verifyRewriteRules() 2022-03-11 17:28:01 -05:00
Slava Pestov
3641b77c21 RequirementMachine: Split up first pass of homotopy reduction into two
Add a separate pass to consider rules with unresolved names which are
not simplified.
2022-03-11 17:28:01 -05:00
Slava Pestov
f082c02e42 RequirementMachine: Plumb through the loop candidate to isRedundantRuleFn 2022-03-11 17:28:01 -05:00
Slava Pestov
f59ffbb94d RequirementMachine: Remove unused field from RewriteContext 2022-03-11 17:28:01 -05:00
Slava Pestov
54c83ead9e RequirementMachine: Make some low-cost assertions unconditional 2022-03-11 17:28:01 -05:00
Slava Pestov
e717330d3b RequirementMachine: Minor optimization 2022-03-11 17:28:01 -05:00
Holly Borla
7ce6504b93 [RequirementMachine] Avoid passing the requirement error vector through
initialization of the rewrite system.

Instead, the rewrite system can determine trivially redundant requirements
by finding structural requirements with no associated rewrite rules.
2022-03-10 13:13:50 -08:00
Holly Borla
0085eb0dfe [RequirementMachine] Separate setting the explicit bit and the requirement
ID for a rewrite rule.
2022-03-09 21:22:53 -08:00
Holly Borla
4b55c30fad [RequirementMachine] Instead of recording redundant requirements and other
diagnostics in the rewrite system, pass down the 'errors' vector from the
top-level requests.
2022-03-09 18:18:43 -08:00
Holly Borla
b5d7a0152b [RequirementMachine] Factor the 'rules once in empty context' computation out
into a method on RewritePath.
2022-03-09 16:17:55 -08:00
Holly Borla
2f7018b605 [RequirementMachine] Don't suppress redundancy diagnostics when the
non-explicit, non-redundant replacement rule is not in the rewrite
system's minimization domain.
2022-03-09 12:14:58 -08:00
Holly Borla
397684909b [RequirementMachine] Suppress redundancy warnings when an explicit, redundant
rule has a non-explicit, non-redundant rule in its rewrite path.

This fixes bogus redundancy diagnostics in cases where the canonical form
of a redundant rule is not explicit in source, e.g.

protocol Swappable2 {
  associatedtype A
  associatedtype B
  associatedtype Swapped : Swappable2
    where Swapped.B == A,
          Swapped.Swapped == Self
}

in the above case, the canonical rule for `Swapped.B == A` is the rule
[Swappable2:Swapped].[Swappable2:A] => [Swappable2:B], which is not
explicit.
2022-03-09 12:14:58 -08:00
Holly Borla
a154641288 [RequirementMachine] Propagate explicit requirement IDs from redundant
rules in a separate pass after homotopy reduction.

RewriteSystem::propagateExplicitBits was too eager in propagating
IDs from explicit rules within rewrite loops, which resulted in bogus
redundancy warnings when the canonical form of an explicit rule was
given a different requirement ID. Instead, propagate requirement IDs
after homotopy reduction when redundant rules are computed and rewrite
loops are simplified.
2022-03-09 12:14:58 -08:00
Holly Borla
be30d76732 [RequirementMachine] Diagnose redundant requirements found during minimization
of the rewrite system.
2022-03-09 12:14:58 -08:00
Holly Borla
3c95cac5e8 [RequirementMachine] Store a requirement ID for explicit rules in the
rewrite system.

This ID can be used to index into the WrittenRequirements array in the
rewrite system to retrieve the structural requirement, e.g. for the
purpose of diagnostics.
2022-03-09 12:14:58 -08:00
Holly Borla
b18e815436 [RequirementMachine] Preserve structural requirements during rule construction,
and diagnose trivially redundant rules in the rewrite system.
2022-03-09 12:14:58 -08:00
Slava Pestov
b6a641bc07 RequirementMachine: New way of introducing concrete conformance rules
Define the relation as

    [concrete: C].[P] =>> [concrete: C].[concrete: C : P]

instead of

    [concrete: C].[P] =>> [concrete: C : P]

This changes the rewrite loop recorded for a rule T.[concrete: C : P]
to have (T.[concrete: C] => T) appearing twice in context instead of
just once.

We don't ever want a concrete conformance rule to be able to imply a
concrete type rule. This became possible with loop normalization
because the single occurrence of (T.[concrete: C] => T).[P] could
cancel with a subsequent step (T => T.[concrete: C]).[P] in another
rewrite loop after substitution.
2022-03-08 23:21:58 -05:00
Slava Pestov
95f122f105 RequirementMachine: Add -enable-requirement-machine-loop-normalization flag 2022-03-08 22:47:22 -05:00
Slava Pestov
a0c3045709 RequirementMachine: Relax criterion for deleting a useless loop
Distinguish a loop with elimination candidates, which are rules
appearing in empty context and exactly once, from a useful loop,
which contains at least one rule in empty context (but the same
rule might appear more than once).

Normalizing a useful loop might produce a loop with elimination
candidates, but normalizing a useless loop never does.
2022-03-08 22:47:22 -05:00
Slava Pestov
713e0a4a6d RequirementMachine: Reduce replacement paths for redundant rules to left-canonical normal form
This brings back the code I deleted in 1bf6102f1e
but repurposes it to simplify the replacement paths recorded for
redundant rewrite rules only.
2022-03-08 22:47:22 -05:00