See the comment at the top of ConcreteContraction.cpp for a detailed explanation.
This can be turned off with the -disable-requirement-machine-concrete-contraction
pass, mostly meant for testing. A few tests now run with this pass both enabled
and disabled, to exercise code paths which are otherwise trivially avoided by
concrete contraction.
Fixes rdar://problem/88135912.
The conflicting rule here is the permanent 'identity conformance'
([P].[P] => [P]). Permanent rules cannot be marked as conflicting,
so just check for this condition first.
If you have something like this:
protocol P {
associatedtype A : Q where Self == Self.A.B
}
protocol Q {
associatedtype B
}
class C : P {
typealias A = D
}
class D : P {
typealias B = C
}
The GSB would minimize the generic signature <T where T : P, T : C>
to <T where T == C>, because of the same-type requirement in
protocol P.
However in reality, the conformance 'C : P' is unsound, because it
is no longer covariant. I added a warning in commit d831eff74879cb.
Because the upcoming 'concrete contraction' pass eliminates 'T : P'
before homotopy reduction gets a chance to run, I'm changing the
Requirement Machine to produce a different minimization from the
GSB. This is technically an ABI break, but it should not impact any
real code in practice. If it does, I'll need to come up with a
different workaround in concrete contraction.
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.
This ensures we produce the same minimal signature as the GSB
in a couple of really silly examples where a superclass requirement
and a concrete type requirement imply each other.
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.
Types cannot contain Terms, so the Symbol representation uses
GenericTypeParameterTypes whose index refers to an array of
"substitution" Terms.
We can (ab)use the PrintOptions.AlternateTypeNames mechanism
to print those GenericTypeParamTypes as if they were Terms.
macine flags to callers.
Callers gate this decision on different flags; InferredGenericSignatureRequestRQM
needs RequirementMachineInferredSignatures to be enabled, and the other
callsites need RequirementMachineProtocolSignatures to be enabled.
The inverted form no longer has to replace substitutions; we use
the inverted form of DecomposeConcrete for that. So just assert
that the substitutions are equal.
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.
When building a rewrite system for a generic signature or protocol,
we would add requirements from the requirement signature of every
protocol dependency. Now, also add protocol typealias rules as well.