Key paths can't reference non-escapable or non-copyable storage declarations,
so we don't need to refer to them resiliently, and can elide their property
descriptors.
However, declarations may still be conditionally Copyable and Escapable, and
if so, then they still need a property descriptor for resilient key path
references. When a property or subscript can be used in a context where it
is fully Copyable and Escapable, emit the property descriptor in a generic
environment constrained by the necessary conditional constraints.
Fixes rdar://151628396.
Suppose protocol P has a primary associated type A, and we have
a `any P<S>` value. We form the generalization signature <T>
with substitution map {T := S}, and the existential signature
<T, Self where T == Self.A>.
Now, if we call a protocol requirement that takes Self.A.A.A,
we see this is fixed concrete type, because the reduced type of
Self.A.A.A is T.A.A in the existential signature.
However, this type parameter is not formed from the
conformance requirements of the generalization signature
(there aren't any), so we cannot directly apply the outer
substitution map.
Instead, change the outer substitution conformance lookup
callback to check if the reduced type parameter is valid
in the generalization signature, and not just rooted in a
generic parameter of the generalization signature.
If it isn't, fall back to global conformance lookup.
A better fix would introduce new requirements into the
generalization signature to handle this, or store them
separately in the generic environment itself. But this is fine
for now.
- Fixes https://github.com/swiftlang/swift/issues/79763.
- Fixes rdar://problem/146111083.
We don't really want to support this, at least not yet, but there
are ways to sneak it past the diagnostic that are hard to close.
Fixes rdar://problem/135348472.
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)
We don't need to build a DenseMap here. More importantly, this
changes the logic to avoid calling mapTypeOutOfContext() on
element archetypes, instead doing the mapping directly.
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.
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
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.
type.subst in mapTypeIntoContext.
The outer context substitutions are already applied when invoking
QueryInterfaceTypeSubstitutions. Applying the context substitutions
before subst also causes problems because QueryInterfaceTypeSubstitutions
will return a null type if given an archetype, which manifested with
opened pack element environments.
First, we need this to work on both lowered and unlowered types,
so Type::subst is problematic: it'll assert if it sees a type
like SILFunctionType. In this case, the substitution is simple
enough that that's never a problem, but Type::subst doesn't know
that, and the assertion is generally a good one.
Second, we need this to not recurse into nested pack expansions.
Third, we need this to not mess around with any existing element
archetypes we might see in the type, so mapping in and out of
context is not really okay.
Fortunately, because we're mapping between structures (pack and
element archetypes) that are guaranteed to have the same
constraints, this transformation is really easy and we can just
do it with transformRec.
opened generic environments
Finding these is very hot for these environments, so doing it once
is a pretty nice win in both speed and code complexity.
I'm not actually using this yet.
I'm not really convinced that the existing implementation here is
correct in general; it might work for the type checker's use cases,
but I don't think we can rely on not seeing opened element archetypes
from other expansions in the type we're processing here. But we can
at least tread water while offering a more convenient API.
This simplifies the representation and allows clients to handle fewer
cases. It also removes an ambiguity in the representation which could
lead us to have two canonical types for the same type.
This is definitely not working yet, but I'm not making progress on
it quickly enough to unblock what we need to unblock; it'll have to
be fixed in parallel.
The function `forEachPackElementBinding` found "interesting"
GenericTypeParamTypes, transformed each, and called back. Here the work
of finding such "interesting" types is pulled out into a separate
function `forEachPackElementGenericTypeParam` through which
`forEachPackElementBinding` now factors.
getOrCreateArchetypeFromInterfaceType.
Instead of special casing parameter packs for primary generic environments,
handle parameter packs in each kind of environment. For opened element
environments, a pack archetype can be produced from the outer substitutions.