`swift_willThrow` is called with an error right before it is thrown.
This existing entrypoint requires an already-boxed error existential;
with typed errors, we don't have the error existential on hand, so we
would need to allocate the box to throw a typed error. That's not okay.
Introduce a new `swift_willThrowTypedImpl` entry point into the runtime
that will first check for the presence of an error handler and, if one
is present, box the error to provide to the error handler. This
maintains the no-allocations path for typed errors while still
allowing existing error handlers to work.
This new entrypoint isn't available on older Swift runtimes, so create
a back-deployable shim called by the compiler. On new-enough platforms,
this will call through to `swift_willThrowTypedImpl`. On older
platforms, we drop the error and don't call the registered will-throw
handler at all. This is a compromise that avoids boxing when throwing
typed errors, at the cost of a slightly different experience for this
new feature on older runtimes.
Fixes rdar://119828459.
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.
The thunk is a reabstraction thunk with a custom prolog that
has a runtime precondition check that makes sure that concurrent
environment where the thunk is run matches that of a global
actor associated with the thunked type.
To be used in situations when a global actor isolation is stripped
from a function type in argument positions and could be extended in
the future to cover more if needed.
When the deployment target is Swift 5.9 aligned or higher, we should not need
to call `_diagnoseUnavailableCodeReached()` via a back-deployment thunk since
the function will always be available in the standard library.
Resolves rdar://121878128
This models the conversion from an uninhabited
value to any type, and allows us to get rid of
a couple of places where we'd attempt to drop
the return statement instead.
We don't want the dispatch phase of a pattern match to invalidate the subject,
because we don't define the order in which patterns are evaluated, and if a
particular match attempt fails, we need to still have an intact subject value
on hand to try a potentially arbitrary other pattern against it. For
noncopyable types, this means we have to always emit the match phase as a
borrow, including the variable bindings for a guard expression if any.
For a consuming pattern match, end the borrow scope and reproject the variable
bindings by using consuming destructuring operations on the subject in the
match block.
For now, this new code path only handles single-case-label-per-block switches
without fallthroughs.
Don't delete the OS declaration of `exit` because the concurrency shims aren't always imported, and so the shim declaration might not always be available.
Don't override the OS declaration of `exit` in the concurrency shims since we can't just delete the OS one. Instead, set up internal shims just for building Concurrency that forward declares `exit`.
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.
When SILGen was emitting the stored initializer function, it updated the location to a new autogenerated location tied to the initialization expression. That in turn reset the function's parent module to null, as the initialization expression is not a decl, and thus it didn't produce a decl context SIL could use when looking for the parent module. That lead to a this function having no parent module when it was serialized, and thus a user that used this function from code in another Swift module thought that this function should use 'dllimport' on Windows, even when the parent module was built with as the static library (i.e. using the -static flag). This lead to spurious LNK4217 diagnostics when building the Swift package manager using CMake on windows. This change fixes that by preserving the parent module for such function.
It's better to ask SILType if it is MoveOnly than go to the AST type and
ask if it is noncopyable, because some types in SIL do not have a
well-defined notion of conformance in the AST.
First, "can have an absence of Copyable" is a rather confusing notion,
so the query is flipped to "can be Copyable". Next, it's more robust to
ask if a conformance exists for the TypeDecl to answer that question,
rather than trying to replicate what happens within that conformance
lookup.
Also renames `TypeDecl::isEscapable` to match.
A baked-in assumption was that the generic parameters of the KeyPath
family of types have no conformance requirements. That's no longer the
case with NoncopyableGenerics, so we need to dig up conformances when
forming the substitution map, as-needed.
The distributed-actor-as-actor conformance is synthesized by the
frontend, so make sure that when we access the API that exposes it
(asLocalActor), we be sure to mark the conformance as "used".
This is a very specific workaround for general problem with
compiler-synthesized conformances. SIL deserialization can bring in a
reference to a conformance late in the SIL pipeline, after the point at
which SILGen can create the conformance. We should be able to address
this systemically to remove the hack.
access level for optimization: `public`. It requires an extra check for
the actual access level that was declared when determining serialization
since the behavior should be different.
This PR sets its effective access level to `package` as originally defined,
updates call sites to make appropriate acces level comparisons, and removes
`package` specific checks.
When an actual instance of a distributed actor is on the local node, it is
has the capabilities of `Actor`. This isn't expressible directly in the type
system, because not all `DistributedActor`s are `Actor`s, nor is the
opposite true.
Instead, provide an API `DistributedActor.asLocalActor` that can only
be executed when the distributed actor is known to be local (because
this API is not itself `distributed`), and produces an existential
`any Actor` referencing that actor. The resulting existential value
carries with it a special witness table that adapts any type
conforming to the DistributedActor protocol into a type that conforms
to the Actor protocol. It is "as if" one had written something like this:
extension DistributedActor: Actor { }
which, of course, is not permitted in the language. Nonetheless, we
lovingly craft such a witness table:
* The "type" being extended is represented as an extension context,
rather than as a type context. This hasn't been done before, all Swift
runtimes support it uniformly.
* A special witness is provided in the Distributed library to implement
the `Actor.unownedExecutor` operation. This witness back-deploys to the
Swift version were distributed actors were introduced (5.7). On Swift
5.9 runtimes (and newer), it will use
`DistributedActor.unownedExecutor` to support custom executors.
* The conformance of `Self: DistributedActor` is represented as a
conditional requirement, which gets satisfied by the witness table
that makes the type a `DistributedActor`. This makes the special
witness work.
* The witness table is *not* visible via any of the normal runtime
lookup tables, because doing so would allow any
`DistributedActor`-conforming type to conform to `Actor`, which would
break the safety model.
* The witness table is emitted on demand in any client that needs it.
In back-deployment configurations, there may be several witness tables
for the same concrete distributed actor conforming to `Actor`.
However, this duplication can only be observed under fairly extreme
circumstances (where one is opening the returned existential and
instantiating generic types with the distributed actor type as an
`Actor`, then performing dynamic type equivalence checks), and will
not be present with a new Swift runtime.
All of these tricks together mean that we need no runtime changes, and
`asLocalActor` back-deploys as far as distributed actors, allowing it's
use in `#isolation` and the async for...in loop.