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.
The previous implementation assumes `UnsafePointer` has no requirements
on its generic parameter. This fix handles any requirements that may be
present on the parameter. With NoncopyableGenerics, the generic
parameter actually does gain a requirement.
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.
Generate the full debug info for generic structs. The strategy is to
emit one full entry for the generic type with archetypes, and one
forward declaration per instantiation of the generic type.
For example, given:
```
struct Pair<T, U> {
let t: T
let u: U
}
let p1 = Pair<Int, Double>(t: 1, u: 4.2)
let p2 = Pair<String, Bool>(t: "Hello", u: true)
```
DebugInfo will have one entry for Pair<T, U> which includes descriptions
of its fields, one forward declaration of Pair<Int, Double> and one
forward declaration of Pair<String, Bool>. This information is enough
for the algorithms of RemoteMirrors to reconstruct type information for
the fully instantiated types.
It's not clear that its worth keeping this as a
base class for SerializedAbstractClosure and
SerializedTopLevelCodeDecl, most clients are
interested in the concrete kinds, not only whether
the context is serialized.
Pattern:
%f = function_ref @invocationClosure : $@convention(thin) (BigStruct) -> ()
%s = struct $InvocationWrapper (%f : $@convention(thin) (BigStruct) -> ())
Error:
Unhandled use of FunctionRefInst
UNREACHABLE executed at /swift/lib/IRGen/LoadableByAddress.cpp:3057!
This fix simply adds the unrecognized case. Rewriting a function_ref
does not change its value, so I'm not sure why the assert exists in
the first place.
This allows calling a C++ function with default arguments from Swift without having to explicitly specify the values of all arguments.
rdar://103975014
Optionally, the dependency to the initialization of the global can be specified with a dependency token `depends_on <token>`.
This is usually a `builtin "once"` which calls the initializer for the global variable.
Currently only arrays can be put into a read-only data section.
"Regular" classes have dynamically initialized metadata, which needs to be stored into the isa field at runtime.
Concurrency runtime expects discarding task operation entrypoint
function not to have result type, but the current SILGen
implementation generates reabstraction thunk to convert `() -> Void`
to `() -> T` for the operation function.
Since the `T` is always `Void` for DiscardingTG, the mismatch of result
type expectation does not cause any problem on most platforms, but the
signature mismatch causes a problem on WebAssembly.
This patch introduces new builtin operations for creating discarding
task, which always takes `() -> Void` as the operation function type.
The dependent 'value' may be marked 'nonescaping', which guarantees that the
lifetime dependence is statically enforceable. In this case, the compiler
must be able to follow all values forwarded from the dependent 'value', and
recognize all final (non-forwarded, non-escaping) use points. This implies
that `findPointerEscape` is false. A diagnostic pass checks that the
incoming SIL to verify that these use points are all initially within the
'base' lifetime. Regular 'mark_dependence' semantics ensure that
optimizations cannot violate the lifetime dependence after diagnostics.
Previously, mayRequirePackMetadata only considered whether a type
involved a pack. That failed to account for the case of outlined value
functions that require pack metadata when the type involves a pack in
its layout. Here, mayRequirePackMetadata now considers also whether the
layout corresponding to a type involves a pack.
rdar://119829826
I am doing this in preparation for adding options to SILParameterInfo/
SILResultInfo that state that a parameter/result is transferring. Even though I
could have just introduced a new bit here, I instead streamlined the interface
of SILParameterInfo/SILResultInfo to use an OptionSet instead of individual bits
to make it easier to add new flags here. The reason why it is easier is that
along API (e.x.: function argument) boundaries one does not have to marshal each
field or pass each field. Instead one can just pass the whole OptionSet as an
opaque thing. Using this I was able to change serialization/deserialization of
SILParameterInfo/SILResultInfo so that one does not need to update them if one
adds new fields!
The reason why I am doing this for both SILParameterInfo/SILResultInfo in the
same commit is because they share code in the demangler that I did not want to
have to duplicate in an intervening commit. By changing them both at the same
type, I didn't have to change anything without an actual need to.
I am doing this in a separate commit from adding transferring support so I can
validate correctness using the tests for the options already supported
(currently only differentiability).
rdar://119792426
There are a few issues with wrong assumptions around extra inhabitants that cause tags to not be identified properly in some cases. Until a proper fix is identified, we emit tag functions instead.