Forward the owning cleanup for the temporary buffer (if needed) instead of
creating a new cleanup, to avoid a double-free when both the initialization
cleanup and the value cleanup execute. Fixes rdar://147961840.
When a generic function has potentially Escapable outputs, those outputs
declare lifetime dependencies, which have no effect when substitution
leads to those types becoming `Escapable` in a concrete context.
This means that type substitution should canonically eliminate lifetime
dependencies targeting Escapable parameters or returns, and that
type checking should allow a function value with potentially-Escapable
lifetime dependencies to bind to a function type without those dependencies
when the target of the dependencies is Escapable.
Fixes rdar://147533059.
Rather than representing a missing availability range on `PoundAvailableInfo`
with a default-constructed `AvailabilityRange` (empty), store the ranges as
optionals instead. This allows an empty range to represent an availability
condition which is known to be false at compile time, which will be necessary
when generating SIL for `if #available` queries that check custom availability
domains.
Specifically:
1. I made it so that thunks from caller -> concurrent properly ignore the
isolated parameter of the thunk when calling the concurrent function.
rdar://148112362
2. I made it so that thunks from concurrent -> caller properly create a
Optional<any Actor>.none and pass that into the caller function.
rdar://148112384
3. I made it so that in cases where we are assigning an @Sendable caller to a
non-sendable caller variable, we allow for the conversion as long as the
parameters/results are sendable as well.
rdar://148112532
4. I made it so that when we generate a thunk from @execution(caller) ->
@GlobalActor, we mangle in @GlobalActor into the thunk.
rdar://148112569
5. I discovered that due to the way we handle function conversion expr/decl ref
expr, we were emitted two thunks when we assigned a global @caller function to a
local @caller variable. The result is that we would first cast from @caller ->
@concurrent and then back to @caller. The result of this would be that the
@caller function would always be called on the global queue.
rdar://148112646
I also added a bunch of basic tests as well that showed that this behavior was
broken.
This removes the IsolatedConformances feature gate from SILGen for
dynamic casts, such that all dynamic casts that will not work with
isolated conformances are marked as such. Isolated conformances can
still only come into a program when part of it enables the feature
flag.
Tweaked diagnostic to use a string instead of a type. Renamed the
feature in `FeatureAvailability.def` (and added the `TaskExecutor`
feature to 6.2). Also fixed the `swift_getActiveExecutor()`
function to return the main executor only when on the main thread.
rdar://141348916
When performing a dynamic cast to an existential type that satisfies
(Metatype)Sendable, it is unsafe to allow isolated conformances of any
kind to satisfy protocol requirements for the existential. Identify
these cases and mark the corresponding cast instructions with a new flag,
`[prohibit_isolated_conformances]` that will be used to indicate to the
runtime that isolated conformances need to be rejected.
Adds assertions in various places where properties that can vary between ABI-only decls and their counterparts—particularly function and parameter attributes—are handled in SILGen, ensuring that we don’t accidentally end up processing ABI-only decls there.
I am doing this in preparation for adding the ability to represent in the SIL
type system that a function is global actor isolated. Since we have isolated
parameters in SIL, we do not need to represent parameter, nonisolated, or
nonisolated caller in the type system. So this should be sufficient for our
purposes.
I am adding this since I need to ensure that we mangle into thunks that convert
execution(caller) functions to `global actor` functions what the global actor
is. Otherwise, we cannot tell the difference in between such a thunk and a thunk
that converts execution(caller) to execution(concurrent).
This just ensures that all thunks are verified right when they are created. This
is necessary since some thunks do not go through function post processing.
This is a value operation that can work just fine on lowered types,
so there's no need to carry along a formal type. Make the value/address
duality clearer, and enforce it in the verifier.
PR #79084 adjusted the projection logic for addressor accessors to avoid
a temporary materialization in cases where the base value is already in
memory; however, many LValue physical components were still unconditionally
using `ManagedValue::forLValue` and causing unnecessary materializations
from already-read-accessed memory locations. Fixes rdar://147705667.
As part of the criteria to determine whether a method override requires a new
vtable entry in addition to overriding the base class's vtable entry for the
method, we compare the visibility of the base class to that of the derived
class, since if further subclasses of the derived class cannot see the original
base class's method descriptor, they would not be able to directly override its
vtable entry.
However, there was a subtle inconsistency in our checks in two different
places: `NeedsNewVTableEntryRequest::evaluate` compared the visibility of the
derived method to its immediate override method, whereas
`SILGenModule::emitVTableMethod` compared visibility with the ultimate base
method that originated the vtable entry in question. Internal imports create
a situation where this leads to inconsistent answers, causing us to emit
a vtable thunk but without a corresponding new vtable entry, causing the thunk
to become self-recursive (rdar://147360093). If the base class is in a separate
module:
```
// Module1
open class Base {
public required init() {}
}
```
and an intermediate class inherits that base class, it must `public import`
the module in the file defining the class to do so:
```
// Module2
public import Module1
open class MidDerived: Base { }
```
However, another file in the same module can further inherit that class, but
with only an `internal import` of the base module:
```
// Also Module2
import Module1
open class MostDerived: MidDerived { }
```
The implicit `init()` is `public` in each class, but from the perspective of
`MostDerived.init`, `Base.init` is `internal` because of the import. However,
the fact that its immediate parent is `public` should be sufficient evidence
that its original definition had visibility to `Base`, so no thunk should
be necessary.