We infer requirements from types appearing in parameter and result types,
like this:
func foo<T>(_: Set<T>) // 'T : Hashable' inferred from 'Set<T>'
Normally we muffle the warning if the requirement is re-stated redundantly:
func foo<T>(_: Set<T>) where T : Hashable // no warning
However, in some cases we failed to do this if the requirement was inferred
from a type appearing in a 'where' clause, like this:
struct G<A, B> {}
extension G where B : Hashable, A == Set<B> {}
This is because in this case the redundancy was detected by
RewriteSystem::addRule() returning false.
The simplest fix here is to change InferredGenericSignatureRequest
to re-order requirements so that inferred requirements appear last.
This way, if any are redundant, we won't diagnose them since it is
the inferred requirement that is redundant and not the user-written
one.
Fixes rdar://problem/92092635.
It's possible for the requirement machine to fail to pick up a source location for its computed errors to attach to when
1) The declaration has no where clause
2) Nor does it have a generic parameter list
This is possible because of the magic of desugaring opaque types in input position to generic parameters a la
func foo(_ : some P<T, U>)
Try to use the first valid user-written inference source to derive a location.
rdar://92105516
warning.
These diagnostics are stricter in the RequirementMachine than in the GSB,
and there's code that relies on the more relaxed diagnostics in the source
compatibility suite. Downgrade these diagnostics to a warning using
warnUntilSwiftVersion(6).
We want to allow this for all conformance requirements written in protocols
or the `where` clause of protocol extensions.
Fixes rdar://problem/91304291.
I don't have a reduced test case. It was possible for computing the requirement
signatures of a connected component to have finished, and yet for the
ProtocolDecl::hasComputedRequirementSignature() method to return false, if
we had evaluated a RequirementSignatureRequestRQM but not the top-level
RequirementSignatureRequest.
Instead, track whether we've computed the signatures for a component directly.
I don't have a reduced test case. It would arise with associated type inference,
which uses this predicate to break nasty cycles.
Note that this changes the behavior of a test slightly when the
-disable-concrete-contraction flag is used. This is because we're
not using the Requirement Machine that minimized the signature
and not the Requirement Machine built from the minimized
signature; the former includes a concrete conformance rule.
The isConcreteType() query returns true on the former when
given the generic parameter τ_0_0.
Since -disable-concrete-contraction is only meant for debugging,
I'm just removing that line from the test.
Instead of kicking off an AbstractGenericSignatureRequest recursively,
handle the rebuilding in a loop in {Abstract,Inferred}GenericSignatureRequest.
This also avoids an unnecessary call to verify() when rebuilding.
I'll clean this up, comment it and generalize it to work with protocol requirement
signatures soon. Landing this now to unblock the Linux corelibs-foundation build.
Fixes rdar://problem/89791117.
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.
initialization of the rewrite system.
Instead, the rewrite system can determine trivially redundant requirements
by finding structural requirements with no associated rewrite rules.
Previously only the GenericSignatureBuilder would call this; to ensure
we get the same test coverage when the Requirement Machine is 'on' as
'verify', also call this from the Requirement Machine.
For now, we can't call this from RequirementSignatureRequestRQM due
to circularity issues; that will have to wait until this request is
folded into RequirementSignatureRequest.
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.
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 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.
These come up in SIL and in the experimental named opaque result types
implementation. Pass the correct DeclContext here, instead of using
the ModuleDecl.
In the long run it doesn't really matter if we leave them in there, but for now
matching the GenericSignatureBuilder's behavior makes the tests pass with
-requirement-machine-inferred-signatures=verify.
- 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()