property for IsolatedDefaultValues.
For property wrappers and init accesors, skip property initializers that are
subsumed, e.g. by an init accessor or a backing property wrapper initializer,
and always consider the subsuming initializer to determine whether compiler
synthesized initializers should have `nonisolated` applied.
This change also lessens the source break of SE-0411 by still emitting
member initializers in implicit constructors when the initializer violates
actor isolation to preserve the behavior of existing code when concurrency
diagnostics are downgraded to warnings in Swift 5 mode.
Even if the final pattern ends up consuming the value, the match itself
must be nondestructive, because any match condition could fail and cause
us to have to go back to the original aggregate. For copyable values,
we can always copy our way out of consuming operations, but we don't
have that luxury for noncopyable types, so the entire match operation
has to be done as a borrow.
For address-only enums, this requires codifying part of our tag layout
algorithm in SIL, namely that an address-only enum will never use
spare bits or other overlapping storage for the enum tag. This allows
us to assume that `unchecked_take_enum_data_addr` is safely non-side-
effecting and match an address-only noncopyable enum as a borrow.
I put TODOs to remove defensive copies from various parts of our
copyable enum codegen, as well as to have the instruction report
its memory behavior as `None` when the projection is nondestructive,
but this disturbs SILGen for existing code in ways SIL passes aren't
yet ready for, so I'll leave those as is for now.
This patch is enough to get simple examples of noncopyable enum switches
to SILGen correctly. Additional work is necessary to stage in the binding
step of the pattern match; for a consuming switch, we'll need to end
the borrow(s) and then reproject the matched components so we can
consume them moving them into the owned bindings. The move-only checker
also needs to be updated because it currently always tries to convert
a switch into a consuming operation.
Introduce a new expression macro that produces an value of type
`(any AnyActor)?` that describes the current actor isolation. This
isolation will be `nil` in non-isolated code, and refer to either the
actor instance of shared global actor in other cases.
This is currently behind the experimental feature flag
OptionalIsolatedParameters.
When `PreconcurrencyConformances` feature is enabled, emit a
precondition into every synchronous isolated @objc thunk to
make sure that it's always called on the right executor.
For `@preconcurrency` conformance witness thunks replace hop to
executor with a precondition to make sure that the thunk is always
called in the expected context.
Obsolete the `-enable-swift3-objc-inference` option and related options by
removing support for inferring `@objc` attributes using Swift 3 rules.
Automated migration from Swift 3 has not been supported by the compiler for
many years.
Type-checking and SILGen for non-inlinable functions is skipped in the
presence of `-experimental-skip-non-inlinable-function-bodies` and
`-experimental-skip-non-inlinable-function-bodies-without-types` flags.
Such functions may be top-level and may contain captures (if they appear
after a `guard` statement), for which we were setting the type expansion
context during SILGen. Setting type expansion context however, relied on
the capture info being computed -- which was never happening because of
the abovementioned flags.
Changes in this commit make setting type expansion context, for
captures, conditional on a flag that ensures that the function has already
been typechecked.
Fixes#57646
The SILGen emission for `Builtin.createAsyncTask` performs an
existential erasure and assumed that `any Any.Type` has no protocols in
its ExistentialLayout, but it's now possible to have some there with
NoncopyableGenerics.
There are a bunch of static `collectExistentialConformances` copied
around Sema and SILGen that are almost the same, save for whether they
want to permit missing conformances and/or check conditional
conformances.
This commit requestifies and combines all but one of these functions
into a `ModuleDecl::collectExistentialConformances`. The motivation for
this clean-up is another place that will need this procedure.
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.
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.
We need the self metatype parameter to correctly lower
DynamicSelfType in IRGen, so plumb this through to all
calls of init accessors, and inside the prolog of an
init accessor definition.
This does not break the public ABI, because init
accessors are never public. Also for value types, the
metatype is thin, so it should not change generated
code.
For classes we need the metatype in the general case
because of `Self`, but hopefully in most cases the
init accessor can be inlined away and the value_metatype
instruction subject to dead code elimination.
Fixes rdar://problem/119822466.
In address-lowered mode, to initialize tuple-typed memory in a single
step, tuple_addr_constructor must generally be used because it's not
possible to construct a tuple any of whose fields are address-only. In
opaque values mode, there is no problem constructing such a tuple. So
construct the tuple and then assign it into the tuple-typed memory; the
single instruction that initializes the memory will be the assign.
Fix a leak when emitting the native to foreign thunk for an async
function which fulfills an Objective-C protocol requirement which can be
fulfilled with either a value or an error via a nullable completion.
Previously, the SIL in question used to look like this:
```sil
%maybe_completion = ...
try_apply %impl..., normal success, ...
success(%value):
switch_enum %maybe_completion...
case some!enumelt: invoke
case none!enumelt: ignore
ignore:
br join
invoke(%completion):
%some_value = enum Optional, some!enumelt, %value // consumes %value
%guaranteed_some_value = begin_borrow %some_value
%none_error = enum Optional, none!enumelt
apply %completion(%guaranteed_some_value, %none_error)
end_borrow %guaranteed_some_value
destroy_value %some_value
br join
join:
destroy_value %maybe_completion
...
```
which leaks %value on the codepath through `ignore`.
Note that `%value` is consumed by the `enum` instruction, but
`%completion` is invoked with `%guaranteed_some_value`, a guaranteed
value. So there is no need to consume %value in `invoke`.
Here, `%value` itself is borrowed and forwarded into an enum instruction
whose result is passed to `%completion`:
```sil
%maybe_completion = ...
try_apply %impl..., normal success, ...
success(%value):
switch_enum %maybe_completion...
case some!enumelt: invoke
case none!enumelt: ignore
ignore:
br join
invoke(%completion):
%guaranteed_value = begin_borrow %value
%guaranteed_some_value = enum Optional, some!enumelt, %guaranteed_value
%none_error = enum Optional, none!enumelt
apply %completion(%guaranteed_some_value, %none_error)
end_borrow %guaranteed_some_value
br join
join:
destroy_value %maybe_completion
destroy_value %value
...
```
Because an argument scope was already being created and a cleanup was
already being pushed for `%value`, nothing more is required to fix the
issue than to reorder the enum and the borrow.
rdar://119732084
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.
patterns) in argument positions in reabstraction thunks.
Most of the difficulty in this work continues to center around
(1) trying to reuse as much code as possible between the parameter
and result paths and (2) propagating ownership information as
necessary throughout the code. I did my best to assert the preconditions
and postconditions here, but undoubtedly I'm missing cases. Some
simplicity here is still eluding me here.
This patch necessarily changes quite a bit of the code used in
non-variadic paths. I tried to avoid doing things that I knew would
be risky, like optimizing copies. I did fail in a few places: e.g.
we should now generate significantly better code when erasing to
Optional<Any>, just because the code was oddly poorly-factored before.
You can see the effect on the function_conversion test case.