The GenericSignatureBuilder did not actually allow this, but it's conflict
detection was imperfect so it did not flag the example in the radar;
variations on this code were rejected by the GenericSignatureBuilder.
Since the Requirement Machine finds all conflicts correctly, relax the
logic here to make this example work.
Fixes rdar://problem/91637621.
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.
Instead of keeping track of the best one so far, and unifying subsequent rules
against it.
This allows us to record more identities, fixing a regression from an earlier
change where we were unable to eliminate an obviously-redundant rule.
We can't actually rely on concretelySimplifyLeftHandSideSubstitutions()
to do this for us, because the less-simplified rule (the LHS rule)
might only apply to a suffix of the base term.
This doesn't record rewrite loops from most concrete unifications just yet,
only handling a case where two concrete types were identical except for an
adjustment.
If a type parameter is subject to both a conformance requirement
and a concrete type requirement, the concrete type might conform
conditionally.
In this case, introduce new requirements to satisfy the conditional
conformance.
Since this can add new hitherto-unseen protocols to the rewrite
system, restrict this feature to top-level generic signatures, and
not protocol requirement signatures. Allowing this to occur in
protocol requirement signatures would change the connectivity of
the protocol dependency graph (and hence the connected components)
during completion, which would be a major complication in the
design. The GSB already enforces this restriction.
I changed the existing conditional_requirement_inference.swift test
to run with -requirement-machine-inferred-signatures=verify. Since
one of the test cases there triggers an unrelated bug in the
Requirement Machine, I split it off into a new file named
conditional_requirement_inference_2.swift which still runs with
the GSB. Once the bug is fixed I'll merge the files again.
A type parameter subject to an AnyObject requirement might also be subject
to a concrete type requirement. There are two cases to handle here:
- If the concrete type is a class, the layout requirement is redundant.
- If the concrete type is not a class, we have a conflict.
There is an existing test that's good enough; I just changed it to
run with -requirement-machine-inferred-signatures=verify.
This will replace the 'concrete type in domain' hack. Instead of
finding some other type parameter with the same concrete type and a
compatible starting symbol, this finds a prefix of the original
term. This allows the induced same-type requirement to be described
with a rewrite path.
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.