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.
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.
The RequirementSignature generalizes the old ArrayRef<Requirement>
which stores the minimal requirements that a conforming type's
witnesses must satisfy, to also record the protocol typealiases
defined in the protocol.
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.
- 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()
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.
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.
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.
We would skip recording a conformance access path if the subject
type canonicalized to a concrete type, but this was incorrect.
The correct formulation is to use the _canonical anchor_ and not
the canonical type as the caching key; that is, we always want it
to be a type parameter, even if it is fixed to a concrete type,
because type parameters fixed to concrete types can appear in
the middle of conformance access paths, as the example in the
radar demonstrates.
Fixes rdar://problem/83687967.
This was manifesting as module interfaces printing generic parameters
as `τ_0_0` in some cases.
Note that the GSB has the same bug, so this test case will fail with
-requirement-machine=off. I don't plan on fixing the bug in the GSB
unless we need to.
Fixes rdar://problem/78977127.