Invertible protocols are currently always mangled with `Ri`, followed by
a single letter for each invertible protocol (e.g., `c` and `e` for
`Copyable` and `Escapable`, respectively), followed by the generic
parameter index. However, this requires that we extend the mangling
for any future invertible protocols, which mean they won't be
backward compatible.
Replace this mangling with one that mangles the bit # for the
invertible protocol, e.g., `Ri_` (followed by the generic parameter
index) is bit 0, which is `Copyable`. `Ri0_` (then generic parameter
index) is bit 1, which is `Escapable`. This allows us to round-trip
through mangled names for any invertible protocol, without any
knowledge of what the invertible protocol is, providing forward
compatibility. The same forward compatibility is present in all
metadata and the runtime, allowing us to add more invertible
protocols in the future without updating any of them, and also
allowing backward compatibility.
Only the demangling to human-readable strings maps the bit numbers
back to their names, and there's a fallback printing with just the bit
number when appropriate.
Also generalize the mangling a bit to allow for mangling of invertible
requirements on associated types, e.g., `S.Sequence: ~Copyable`. This
is currently unsupported by the compiler or runtime, but that may
change, and it was easy enough to finish off the mangling work for it.
* Allow normal function results of @yield_once coroutines
* Address review comments
* Workaround LLVM coroutine codegen problem: it assumes that unwind path never returns.
This is not true to Swift coroutines as unwind path should end with error result.
Introduce metadata and runtime support for describing conformances to
"suppressible" protocols such as `Copyable`. The metadata changes occur
in several different places:
* Context descriptors gain a flag bit to indicate when the type itself has
suppressed one or more suppressible protocols (e.g., it is `~Copyable`).
When the bit is set, the context will have a trailing
`SuppressibleProtocolSet`, a 16-bit bitfield that records one bit for
each suppressed protocol. Types with no suppressed conformances will
leave the bit unset (so the metadata is unchanged), and older runtimes
don't look at the bit, so they will ignore the extra data.
* Generic context descriptors gain a flag bit to indicate when the type
has conditional conformances to suppressible protocols. When set,
there will be trailing metadata containing another
`SuppressibleProtocolSet` (a subset of the one in the main context
descriptor) indicating which suppressible protocols have conditional
conformances, followed by the actual lists of generic requirements
for each of the conditional conformances. Again, if there are no
conditional conformances to suppressible protocols, the bit won't be
set. Old runtimes ignore the bit and any trailing metadata.
* Generic requirements get a new "kind", which provides an ignored
protocol set (another `SuppressibleProtocolSet`) stating which
suppressible protocols should *not* be checked for the subject type
of the generic requirement. For example, this encodes a requirement
like `T: ~Copyable`. These generic requirements can occur anywhere
that there is a generic requirement list, e.g., conditional
conformances and extended existentials. Older runtimes handle unknown
generic requirement kinds by stating that the requirement isn't
satisfied.
Extend the runtime to perform checking of the suppressible
conformances on generic arguments as part of checking generic
requirements. This checking follows the defaults of the language, which
is that every generic argument must conform to each of the suppressible
protocols unless there is an explicit generic requirement that states
which suppressible protocols to ignore. Thus, a generic parameter list
`<T, Y where T: ~Escapable>` will check that `T` is `Copyable` but
not that it is `Escapable`, and check that `U` is both `Copyable` and
`Escapable`. To implement this, we collect the ignored protocol sets
from these suppressed requirements while processing the generic
requirements, then check all of the generic arguments against any
conformances not suppressed.
Answering the actual question "does `X` conform to `Copyable`?" (for
any suppressible protocol) looks at the context descriptor metadata to
answer the question, e.g.,
1. If there is no "suppressed protocol set", then the type conforms.
This covers types that haven't suppressed any conformances, including
all types that predate noncopyable generics.
2. If the suppressed protocol set doesn't contain `Copyable`, then the
type conforms.
3. If the type is generic and has a conditional conformance to
`Copyable`, evaluate the generic requirements for that conditional
conformance to answer whether it conforms.
The procedure above handles the bits of a `SuppressibleProtocolSet`
opaquely, with no mapping down to specific protocols. Therefore, the
same implementation will work even with future suppressible protocols,
including back deployment.
The end result of this is that we can dynamically evaluate conditional
conformances to protocols that depend on conformances to suppressible
protocols.
Implements rdar://123466649.
In top-level code, we were incorrectly pulling closure discriminators
from TopLevelCodeDecls, not from the enclosing source file, which could
lead to the same discriminators being assigned to different closures that
come from macro expansions at the top level. Hilarity ensures, yet I am
not amused.
Adjust the DeclContext appropriately when computing discriminators.
Fixes rdar://123836908.
The `ABI` headers had accidentally grown an `#include` into compiler headers,
allowing the enum constant values of the `ValueOwnership` enum to leak into
the runtime ABI. Sever this inappropriate relationship by declaring a separate
`ParameterOwnership` enum with ABI-stable values in the ABI headers, and
explicitly converting between the AST and ABI representation where needed.
Fixes rdar://122435628.
By populating the memory cache before loading the module, we can avoid a cycle
where a module is imported that is an overlay, which then triggers
ClangImporter, which then (redundantly) triggers the import of the overlay
module, which would reimport the module again, since it's import is still
underway and it hasn't been entered into the cache yet.
rdar://118846313
This adds SIL-level support and LLVM codegen for normal results of a coroutine.
The main user of this will be autodiff as VJP of a coroutine must be a coroutine itself (in order to produce the yielded result) and return a pullback closure as a normal result.
For now only direct results are supported, but this seems to be enough for autodiff purposes.
When the Swift module is not available, we'll synthesize the
Copyable/Escapable decls into the Builtin module.
In the future, it might be nice to just do this always, and define
typealiases for those types in the stdlib to refer to the ones in the
builtin module.
Allow the use of typed throws for the main functions of `@main` types,
and thread the thrown error through to a new entry point in the library,
`_errorInMainTyped`, which is generic in the thrown error type.
Fixes rdar://121603043.
Not quite NFC because apparently the representation bleeds into what's
accepted in some situations where we're supposed to be warning about
conflicts and then making an arbitrary choice. But what we're doing
is nonsense, so we definitely need to break behavior here.
This is setting up for isolated(any) and isolated(caller). I tried
to keep that out of the patch as much as possible, though.
Use an optional isolated parameter to this new `next(_:)` overload to
keep it on the same actor as the caller, and pass `#isolation` when
desugaring the async for..in loop. This keeps async iteration loops on
the same actor, allowing non-Sendable values to be used with many
async sequences.
This couples together several changes to move entirely from
`@rethrows` over to typed throws:
* Use the `Failure` type to determine whether an async for-each loop
will throw, rather than depending on rethrows checking
* Introduce a special carve-out for `rethrows` functions that have a
generic requirement on an `AsyncSequence` or `AsyncIteratorProtocol`,
which uses that requirement's `Failure` type as potentially being part
of the thrown error type. This allows existing generic functions like
the following to continue to work:
func f<S: AsyncSequence>(_: S) rethrows
* Switch SIL generation for the async for-each loop from the prior
`next()` over to the typed-throws version `_nextElement`.
* Remove `@rethrows` from `AsyncSequence` and `AsyncIteratorProtocol`
entirely. We are now fully dependent on typed throws.
Instead of passing a unique_ptr of an opaque type back and forth,
let's just push elements onto an std::vector. For now this change
is completely NFC, but further simplifications will become
possible shortly.