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.
Swift methods can be called from Objective-C without a vtable
load, and more importantly without emitting an `llvm.type.checked.load`
instruction. These are effectively virtual callsites that are not
visible to the VFE logic in GlobalDCE.
To to safely enable swift-vfe we must prevent vtables whose functions
are callable from Objective-C from being eliminated.
To do this we ensure such vtables have public vcall_visibility, which
indirectly prevents GlobalDCE from stripping them.
Merge conflict while removing `nocapture` from
`s21move_function_dbginfo20addressOnlyValueTestyyxAA1PRzlF`. Resolution
was to remove nocapture from the expected output in both cases:
```
// CHECK-LABEL: define swiftcc void @"$s21move_function_dbginfo20addressOnlyValueTestyyxAA1PRzlF"(ptr noalias[-nocapture-] %0, ptr %T, ptr %T.P)
```
Conflict cause: 4858cb6225
This is the same as the original change to this file. The conflict seems
to be due to the next line changing, when moving from llvm.dbg.addr to
llvm.dbg.value.
Conflicts:
test/DebugInfo/move_function_dbginfo.swift
C++ `operator bool()` is currently imported into Swift as `__convertToBool()`, which shouldn't be used by clients directly.
This adds a new protocol into the C++ stdlib overlay: `CxxConvertibleToBool`, along with an intitializer for `Swift.Bool` taking an instance of `CxxConvertibleToBool`.
rdar://115074954
- VTableSpecializer, a new pass that synthesizes a new vtable per each observed concrete type used
- Don't use full type metadata refs in embedded Swift
- Lazily emit specialized class metadata (LazySpecializedClassMetadata) in IRGen
- Don't emit regular class metadata for a class decl if it's generic (only emit the specialized metadata)
- In embedded Swift, classes get a simplified metadata: Basically just a vtable + destructor + superclass pointer.
- Only non-resilient (intended as permanent restriction), non-generic classes (for now) supported.
- Relax the check that prohibits metadata emission and usage to allow classes.
This will be used to provide a safe overload of `std::vector::erase` in Swift.
`std::vector::erase` is not currently imported into Swift because it returns a C++ iterator.
rdar://113704853
This makes it possible to initialize `std::vector` from a Swift Sequence. This also conforms C++ vectors to `ExpressibleByArrayLiteral`, making it possible, for instance, to pass a Swift array to a C++ function that takes a vector of strings as a parameter.
rdar://104826995
`ReadOnly`/`ArgMemOnly` were mostly moved over, but a few were missed.
Update them all. Also default to `unknown` for no memory effects rather
than none (ie. we should be conservative).
This is an inheritor of the existing `UnsafeCxxInputIterator` protocol, with the only difference being the ability to mutate `var pointee` via a non-const `operator*()`.
This is needed to support mutable subscripts for `std::map` via `CxxDictionary`.
rdar://105399019
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.
`std::set::insert` isn't exposed into Swift, because it returns an instance of an unsafe type.
This change adds a Swift overload of `insert` for `std::set` and `std::unordered_set` that has the return type identical to `Swift.Set.insert`: a tuple of `(inserted: Bool, memberAfterInsert: Element)`.
rdar://111036912