An "abstract" ProtocolConformanceRef is a conformance of a type
parameter or archetype to a given protocol. Previously, we would only
store the protocol requirement itself---but not track the actual
conforming type, requiring clients of ProtocolConformanceRef to keep
track of this information separately.
Record the conforming type as part of an abstract ProtocolConformanceRef,
so that clients will be able to recover it later. This is handled by a uniqued
AbstractConformance structure, so that ProtocolConformanceRef itself stays one
pointer.
There remain a small number of places where we create an abstract
ProtocolConformanceRef with a null type. We'll want to chip away at
those and establish some stronger invariants on the abstract conformance
in the future.
If any of the get*() methods are called on the wrong kind of
ProtocolConformanceRef, we immediately cast a pointer to an
incorrect type, which will most likely cause a crash.
Put AvailabilityRange into its own header with very few dependencies so that it
can be included freely in other headers that need to use it as a complete type.
NFC.
If a protocol does not inherit Sendable, we still say that the
existential type is Sendable in Swift 5 mode. Make sure this
doesn't crash the SIL specializer.
Fixes https://github.com/swiftlang/swift/issues/75728
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
Workaround for rdar://119950540 when dealing with invertible protocols.
This should be sound because "its an invariant that subst() on a
conformance returns the same thing as a global lookup with subst() of
the conforming type, assuming you don't have overlapping conformances."
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.
There are a lot of problems caused by our highly-abstract substitution
subsystem. Most of them would be solved by a more semantic / holistic
understanding of the active transformation, but that's difficult to do
because we just pass around function_refs. The first step in fixing
that is to pass around a better currency type. For now, it can just
hold the function_refs (and the SubstOptions).
I've set it up so that the places that just apply SubstitutionMaps
are constructing the IFS in a standard way; that should make it easy
to change those places in the future.