Commit Graph

118 Commits

Author SHA1 Message Date
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
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
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
Slava Pestov
5281426569 RequirementMachine: Fix minimization when protocol is constrained to a class that conforms to the protocol
Consider this example:

    protocol P : C {}
    class C : P {}

    <T where T : P>

The GenericSignatureBuilder thinks the minimized signature is
<T where T : P>. The RequirementMachine would minimize it down to
<T where T : C>. The latter is more correct, since the conformance
here is concrete and no witness table needs to be passed in at
runtime, however for strict binary compatibility we need to produce
the same signature as the GenericSignatureBuilder.

Accomplish this by changing the minimal conformances algorithm to
detect "circular concrete conformance rules", which take the form

    [P].[concrete: C : Q]

Where Q : P. These rules are given special handling. Ordinarily a
protocol conformance rule is eliminated before a concrete conformance
rule; however concrete conformances derived from circular
conformances are considered to be redundant from the get-go,
preventing protocol conformances that can be written in terms of
such concrete conformances from themselves becoming redundant.

Fixes rdar://problem/89633532.
2022-03-02 03:13:41 -05:00
Slava Pestov
a69ac78482 RequirementMachine: Rework PropertyMap::recordConflict() for GSB compatibility
We want to prefer explicit rules when an explicit rule and non-explicit
rule conflict. Since the explicit bit hasn't been computed yet when
building the property map, save conflicting rule pairs in a side table,
and then process them later in homotopy reduction.

The side table will also be useful for diagnostics later.
2022-02-17 19:40:58 -05:00
Slava Pestov
86d47d951d RequirementMachine: Re-visit substitution-simplified rules for concrete unification 2022-02-17 19:40:58 -05:00
Slava Pestov
991fe1dbd8 RequirementMachine: Preserve replacement paths for redundant rules 2022-02-16 16:28:08 -05:00
Slava Pestov
57d89a6f11 RequirementMachine: Use processTypeDifference() in simplifyLeftHandSideSubstitutions() 2022-02-15 04:02:46 -05:00
Slava Pestov
12ba9bf1ab RequirementMachine: Move processTypeDifference() method and friends from PropertyMap to RewriteSystem 2022-02-15 04:02:46 -05:00
Slava Pestov
41a6f9e118 RequirementMachine: Remove old implementation of simplifySubstitutions() 2022-02-15 04:02:46 -05:00
Slava Pestov
5e54a52c0e RequirementMachine: Remove old implementation of simplifyLeftHandSideSubstitutions()
Now that the PropertyMap to the concrete simplification version is optional,
we can just pass nullptr here to get the old behavior where type terms are
simplified to canonical anchors and no concrete simplification is performed.
2022-02-15 04:02:46 -05:00
Slava Pestov
2e3cb17666 RequirementMachine: Refactor concrete substitution pass 2022-02-15 04:02:46 -05:00
Slava Pestov
fa65fd0e05 RequirementMachine: Plumb protocol typealiases through minimization
Now that we can detect protocol typealias rules, collect and keep
track of them so that they can be recorded in protocol requirement
signatures.

For now, this is all NFC since nothing introduces such rules into
the rewrite system, except for invalid requirements which are
diagnosed anyway.
2022-02-13 00:24:23 -05:00
Slava Pestov
f9c2d9fd7c RequirementMachine: Introduce Rule::isProtocolTypeAliasRule()
There are two kinds of protocol typealiases:

1) The underlying type is a type parameter. These rules look like
   [P].A => X where X is the underlying type.

2) The underlying type is a concrete type. These rules look like
   [P].A.[concrete: C] => [P].A.

The isProtocolTypeAliasRule() predicate detects both cases and
returns the type alias name ('A', in the above examples). For now
it's not used anywhere, since we don't actually introduce these
rules for any reason.
2022-02-13 00:24:23 -05:00
Slava Pestov
0d0bcb2ff1 RequirementMachine: Simplify the Symbol API for removal of merged associated types 2022-02-07 18:57:45 -05:00
Slava Pestov
e2e088e082 RequirementMachine: Remove merged associated types from completion 2022-02-07 18:57:45 -05:00
Slava Pestov
00d226fd2f RequirementMachine: Store the base term in the TypeDifference 2022-02-07 08:20:59 -05:00
Slava Pestov
06d4770adb RequirementMachine: Teach homotopy reduction to better deal with incomparable rules 2022-02-07 08:20:59 -05:00
Slava Pestov
037dc98845 RequirementMachine: Generalize compare() methods to return None instead of asserting on incomparable symbols 2022-02-07 08:20:59 -05:00
Slava Pestov
37be2d5dd7 RequirementMachine: Emit a diagnostic note with the offending rewrite rule if completion failed
This surfaces an implementation detail, but it might be better
than nothing.
2022-02-07 08:20:59 -05:00
Slava Pestov
0060592b85 RequirementMachine: Add concrete nesting depth check
Configured with -requirement-machine-max-concrete-nesting= frontend flag.
2022-02-07 08:20:59 -05:00
Slava Pestov
634ca55764 RequirementMachine: Rework completion limits a bit
- Rename StepLimit to MaxRuleCount, DepthLimit to MaxRuleLength
- Rename command line flags to -requirement-machine-max-rule-{count,length}=
- Check limits outside of PropertyMap::buildPropertyMap()
- Simplify the logic in RequirementMachine::computeCompletion()
2022-02-07 08:20:59 -05:00
Slava Pestov
7464a5f139 RequirementMachine: Make recordTypeDifference() and buildTypeDifference() public 2022-02-07 08:20:58 -05:00
Slava Pestov
8eb8e8d86d RequirementMachine: Make RewriteSystem::recordRewriteLoop() public for use by the property map 2022-02-07 08:20:58 -05:00
Slava Pestov
b28d35fa22 RequirementMachine: Introduce RewriteSystem::computeTypeDifference() 2022-02-07 08:20:58 -05:00
Slava Pestov
106896228e RequirementMachine: Split up Rule::isSimplified() into three predicates
We have three simplification passes, give each one its own predicate:
- Left hand side simplification
- Right hand side simplification
- Substitution simplification

This is for debugging output and will also allow me to tighten up
some invariants.
2022-01-27 18:54:03 -05:00
Slava Pestov
75dfc8b3a8 RequirementMachine: Minimal conformances algorithm ignores conformance rules not in our minimization domain 2022-01-27 18:54:03 -05:00
Slava Pestov
1c1b0e6cfc RequirementMachine: Clean up computeCriticalPair() a bit 2022-01-27 18:54:03 -05:00
Slava Pestov
10e4ffdfbd RequirementMachine: Track known protocols in the rewrite system
Conditional requirement inference needs to be able to add rewrite rules
from the requirement signatures of hitherto-unseen protocols, so to
help with that, extract out the RuleBuilder's ProtocolMap and move it
into the RewriteSystem.
2022-01-25 00:35:03 -05:00
Slava Pestov
da30258f49 RequirementMachine: Remove RewriteSystem::TypeWitness 2022-01-13 19:14:52 -05:00
Slava Pestov
bdbf50e1e3 RequirementMachine: Replace RewriteStep::SameTypeWitness with a relation 2022-01-13 19:14:52 -05:00
Slava Pestov
6064671abd RequirementMachine: Replace RewriteStep::ConcreteTypeWitness with relations 2022-01-13 18:01:15 -05:00
Slava Pestov
abb85fb3ca RequirementMachine: Replace RewriteStep::{Superclass,Concrete}Conformance with relations 2022-01-13 00:02:31 -05:00
Slava Pestov
f06f59a18a RequirementMachine: Generalize relations so they look more like rules 2022-01-13 00:02:31 -05:00
Slava Pestov
746f4a5a8f RequirementMachine: Throw out rewrite loops not part of the minimization domain
When minimizing a generic signature, we only care about loops
where the basepoint is a generic parameter symbol.

When minimizing protocol requirement signatures in a connected
component, we only care about loops where the basepoint is a
protocol symbol or associated type symbol whose protocol is
part of the connected component.

All other loops can be discarded since they do not encode
redundancies that are relevant to us.
2022-01-05 23:59:46 -05:00
Slava Pestov
66cf913d68 RequirementMachine: Minimization understands 'relations' among layout requirements
A superclass requirement 'T : C' implies a layout requirement
'T : AnyObject' (if the class is @objc) or 'T : _NativeObject'
(if the class is not @objc).

In the latter case, there might already be a 'T : AnyObject'
requirement, in which case the type parameter 'T' is subject
to two layout requirements:

    T : AnyObject
    T : _NativeObject

The second requirement implies the first however. To encode this
in the world of rewrite loops, we the notion of a 'relation'
between property symbols, and a 'Relation' rewrite step.

Here, the relation is that _NativeObject < AnyObject. Once this
relation is recorded, the Relation rewrite step will transform

    T.[layout: _NativeObject].[layout: AnyObject]

into

    T.[layout: _NativeObject]

and vice versa.

This rewrite step allows us to construct a rewrite loop which
makes the first rewrite rule redundant via the second.
2022-01-04 22:35:58 -05:00
Slava Pestov
82a494e31b RequirementMachine: Go back to doing three passes in homotopy reduction
First pass:
- Eliminate rules with unresolved name symbols in LHS
- Eliminate simplified non-conformance rules

Second pass:
- Eliminate non-minimal conformance rules

Third pass:
- Eliminate all other non-conformance rules

If you have a concrete requirement with a non-canonical substitution, like

    A : P, A == G<B.T>

We add an induced rule for the abstract type witness,

    A.T == B.T

This rule has a rewrite path in terms of the previous two rules, but we
want to try to eliminate the other two rules first.

This new ordering ensures we eliminate the simplified rule A == G<B.T> and
compute minimal conformances before we get around to considering A.T == B.T,
which can no longer be eliminated by that point.

If we eliminate A.T == B.T first, we end up with simplified concrete
type and concrete conformance rules which cannot be eliminated:

    A.[concrete: G<B.T>] => A
    A.[concrete: G<B.T> : P] => A

This changes the minimized signature in an incompatible way in two test cases.

In Generics/rdar83308672.swift, the signature becomes equivalent to what the
GSB used to output.

In Generics/sr10532.swift, the GSB would output an invalid signature anyway,
so it doesn't matter.
2021-12-17 10:04:52 -05:00
Slava Pestov
3c9344cc80 RequirementMachine: Improved verifyMinimizedRules() 2021-12-17 10:04:52 -05:00
Slava Pestov
4c83fe851d RequirementMachine: Generalize ConcreteTypeWitness to TypeWitness 2021-12-17 10:04:52 -05:00
Slava Pestov
317743a487 RequirementMachine: Rename GeneratingConformances => MinimalConformances 2021-12-17 10:04:52 -05:00
Slava Pestov
8e3f35075f RequirementMachine: Make the rewrite path optional with RewriteSystem::simplifySubstitution() 2021-12-14 02:16:46 -05:00
Slava Pestov
c6441c0d89 RequirementMachine: Add machinery for recording concrete type witnesses 2021-12-14 02:16:46 -05:00
Slava Pestov
7a56ab8c18 RequirementMachine: Mark conflicting rules
This isn't quite right, because we really want the longer (more
specific) of the two rules to be conflicting, not the most-recently
added rule.
2021-12-13 18:48:23 -05:00
Slava Pestov
5ac43b14d2 RequirementMachine: Fully canonicalize substitutions in concrete type rules
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.
2021-12-13 18:48:23 -05:00
Slava Pestov
96bdef9f50 RequirementMachine: Move generating conformances algorithm into its own class 2021-12-08 00:53:35 -05:00