`emitThrow` previously asserted that the only legal mismatch between the
in-flight error type and the throw destination was `any Error`, then
existential-erased to `Error`. Anything else Sema accepted — `do
throws(any P) where P: Error`, or a class subtype of the destination —
crashed the assertion (or, before that was tightened, miscompiled at
runtime).
Dispatch on the destination type:
- existential: erase, looking up conformance to each protocol in the
destination's existential layout (so `any P` works, not just `any
Error`);
- class: emit an `upcast`.
Anything else still hits an `unreachable` — Sema rejects those today, so
hitting it would indicate a Sema regression rather than a missing SILGen
path.
Fixes https://github.com/swiftlang/swift/issues/83826.
Since SILFunctionType doesn't support a full range of isolation
kinds not setting the isolation of the thunk that reabstracts
a function value into a `nonisolated(nonsending)` one, results
in `OptimizeHopToExecutor` incorrectly removing hops from the thunk.
In turn, at the call site, synchronous code that follows a call to
`nonisolated(nonseding)` function value through a reabstraction thunk,
would be executed on the isolation of the function value called by the
thunk instead of returning to the caller's context.
Resolves: rdar://176709091
Resolves: https://github.com/swiftlang/swift/issues/88993
The native `__deallocating_deinit` for an isolated destructor already
hops to the expected executor via `swift_task_deinitOnExecutor`. The
@objc thunk is invoked by ObjC `release`, which can run from any thread,
so asserting the current executor in the thunk crashes
`_dispatch_assert_queue_fail` whenever the last reference is dropped
from a non-isolated context.
Skip the precondition (and the async hop, which can't apply here since
deinits aren't async) when the thunked decl is an isolating destructor.
Non-deinit @objc methods still get the check.
Apply the expected isolation before attempting to reabstraction.
This is the same as `@isolated(any)` and the common logic has
been factored in a closure.
Such closures have a specialized direct conversion to actual `nonisolated(nonsending)`
type. They gain an implicit isolation parameter that isn't marked as "isolated"
and gets ignored in the prolog.
In `applyBorrowMutateAccessor()`, the self value was not being passed
to `getFnValue()` for class method dispatch. Fix this by correctly passing
the self value when it is required for dispatch similar to the call emission
of other accessors.
- `SILGenModule::getFunction` uses `constant` isolation in `getOrCreateFunction`
so there is no need to set it again afterwards.
- `preEmitFunction` is only used from `emitFunctionDefinition` which is always
called with `getFunction` (from the point above) as an argument that already
gets isolation from `constant`.
In the pattern-match emission for do-catch, we had been emitting SIL
such as this:
```
bb4: %11 = struct_extract %0, #Bool._value
cond_br %11, bb5, bb6
bb5:
dealloc_stack %15 : $*any Error
br bb2
bb6:
%15 = alloc_stack $any Error
...
dealloc_stack %15
throw %20
```
This is invalid SIL and it wasn't getting caught. My guess is that
the old version of StackNesting cleaned up the obviously-invalid
undominated dealloc_stack before the verifier saw it.
The new StackNesting pass doesn't do that; instead it will crash.
This patch avoids emitting the invalid SIL in this case.
https://github.com/swiftlang/swift/issues/88220
rdar://173812126
We cannot use spare bits or other overlapping storage layout tricks with fundamentally
address-only enums, and we can take advantage of this to do borrowing switches or other
in-place projections without copying the value. However, for resilient enums, the
implementation may use spare bit packing, but the type must be handled address-only
outside of its defining module, and we didn't have a way to express that with
borrowing switch. Optimization passes have also been running into problems with the
complexity that we were using `unchecked_take_enum_data_addr` sometimes as a pure
operation. This patch splits the instruction into three:
- `unchecked_inplace_enum_data_addr` represents a nondestructive in-place enum
projection. It is only allowed for enums whose projection operation is
nondestructive.
- `unchecked_take_enum_data_addr` represents a destructive enum projection,
invalidating the enum and leaving the payload to be further consumed.
This matches the current instruction's semantics.
- `unchecked_borrow_enum_data_addr` represents a borrowing enum projection.
The instruction takes a second operand for "scratch" space, which the
enum representation may be copied into in order to avoid invalidating the
enum value, so the result is dependent on the lifetime of both the
original enum and the scratch buffer. This allows for borrowing switches
over resilient enums.
`unchecked_borrow_enum_data_addr` is implemented by taking advantage of the
"address-only enums can't do spare bit optimization" property at runtime.
We inspect the operand type's bitwise-borrowability from its metadata. If
the type is bitwise-borrowable, then we are allowed to bitwise-copy the
enum to the scratch space and apply the projection to the scratch space,
preserving the original value. If the type is not bitwise-borrowable, then
we cannot use spare bit optimization in its layout, so we apply the
projection in-place.
Fixes rdar://174952822.
Now that we have generalized existentials in Embedded Swift, we also
have all of the infrastructure for metatypes. They're lazily
constructed on an as-needed basis, but otherwise work the same way as
in non-Embedded Swift.
Fixes rdar://145706221.
This eliminates the need for unsafe addressors. It will replace unsafeAddress in
the UnsafePointer subscript and the Span subscript.
This is needed to support Span<~E>.
rdar://175382153 (Add Builtin.borrowAt: allows borrowing in-memory values)
Prevents situations when actor isolation ends up not being set
un-intentionally i.e. when cloning, specializating, or creating
thunks.
The thunks get `unspecified` isolation at the moment.
The `@export(interface)` and `@export(implementation)` attributes
SE-0497 are queried directly on AST nodes in several places within the
SIL pipeline. However, they don't persist when SIL functions are
serialized, meaning that clients of the original module might make
different assumptions about the availability of a given function's
definition.
Represent these attributes in a SIL function (as an optional
CodeGenerationModel), (de-)serialize them into the module, and add a
textual representation as SIL function attributes `[export_interface]`
and `[export_implementation]`.
Apply-like instructions aren't expected to be created with
a SubstitutionMap if the callee has no invocation GenericSignature [1].
After upgrading the assertion checking for that [2], it became
apparent there were a few situations where the created apply
is still including them.
This patch fixes one of places, which is when we create partial applies.
It also fixes a small issue in TypeLowering for property wrapped field init
accessors, where the type for Self within a constrained extension had a type
parameter that was fixed to a concrete type and would trigger a different
assertion failure.
[1] https://github.com/swiftlang/swift/pull/74266
[2] https://github.com/swiftlang/swift/pull/88160
related to rdar://174669500
The backdeployment thunk is calling into a method within a
constrained extension, but it's constrained the generic
parameter to a fixed type.
So, there is no invocation generic signature, thus no
substitution map is expected by the assertion added in
https://github.com/swiftlang/swift/pull/88160
resolves rdar://174437884