This basically undoes 3da6fe9c0d, which in hindsight was wrong.
There were no other usages of TypeArrayView anywhere else except for
GenericSignature::getGenericParams(), and it was almost never what
you want, so callers had to convert back and forth to an ArrayRef.
Remove it.
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
`InferredGenericSignatureRequest` creates `StructuralRequirement`s for
the requirements of the generic signature that is passed to it (if one
is).
Previously, it used invalid `SourceLoc`s for these requirements. The
result was that when errors that were emitted as a result of those
`StructuralRequirement`s (during concrete type contraction), they would
also have invalid `SourceLoc`s. The effect was that those errors were
ignored during `diagnoseRequirementErrors`.
Here, use the available loc for those requirements.
rdar://108963047
This fixes an edge case where we start with the following requirements:
- U : P
- T : P
- T.[P]A == C
- T == G<T.[P]A>
- U.[P]A == T.[P]A
and end up with the following set of minimal rules (where the type
witness for [P]A in the conformance G<C> : P is C):
- U.[P] => U
- U.[P:A] => T.[P:A]
- T.[concrete: G<C>] => T
- T.[concrete: G<C> : P] => T
Since U.[P]A and T.[P]A are concrete, we split the abstract same-type
requirement into two requirements, and re-run minimization:
- U : P
- T.[P]A == C
- U.[P]A == C
- T == G<C>
The concrete conformance rule T.[concrete: G<C> : P] => T does not
correspond to a requirement, so it was simply dropped, and the above
rules violate post-contraction invariants; T.[P]A is not a valid
type parameter because there is no conformance requirement T : P in
the minimized signature.
We can fix this by re-running concrete contraction after splitting
concrete equivalence classes. After contraction, the above requirements
turn into
- U : P
- C == C
- U.[P]A == C
- T == G<C>
Which correctly minimizes to
- U : P
- U.[P]A == C
- T == G<C>
Both concrete contraction and concrete equivalence classes are hacks,
and we should think of a way to directly express the transformations
they perform with the rewrite system.
Fixes https://github.com/apple/swift/issues/61192.
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.
Rename the second one to a 'reduced type'.
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.