Commit Graph

54 Commits

Author SHA1 Message Date
Michael Gottesman
81885a67d0 [silgen] Change two places we used Builtin.Executor to instead use Optional<any Actor> as an expected executor.
We want SILGen to have a simplified view of its executor and know that whenever
one sees an Actor, it is an actual actor instead of a Builtin.Executor. This
just simplifies code. Also, we should eventually have an invariant that
Builtin.Executor should only be allowed in LoweredSIL after LowerHopToExecutor
has run. But that is a change for another day.
2025-10-16 10:51:13 -07:00
Pavel Yaskevich
30f0fa8d75 [Concurrency] SE-0463: Sendable inference on sync and async variants of imported APIs should match
This is a follow-up to https://github.com/swiftlang/swift/pull/82085
which made it so async variant doesn't get `@Sendable` inferred because
the proposal specified that inference should happen only on completion
handler parameter type of a synchronous variant of an imported API.

This runs into implementation issues related to thunking in some
cases were async convention expects the type of a completion handler
to match exactly for both variants of the imported API.

Resolves: rdar://154695053
2025-07-01 00:05:20 -07:00
Pavel Yaskevich
74471e858b [ClangImporter] Use DefaultsToSendable with completion handler parameter
This lifts the check for the feature flag up into the `importParameterType`
from `importType` and means that completion handler type for `async` variant
is no longer gains `@Sendable` attribute.
2025-06-06 17:08:22 -07:00
Michael Gottesman
662dbdb55a [silgen] Teach SILGen how to emit a forced dynamic member ref given nonisolated(nonsending) casts.
Specifically, I taught SILGen how to emit an AST like the following:

```
(force_value_expr implicit type="nonisolated(nonsending) (Date?) async -> Void" implicit_iuo_unwrap
  (open_existential_expr implicit type="(nonisolated(nonsending) (Date?) async  -> Void)?"
    (opaque_value_expr implicit type="AnyObject")
    (declref_expr type="AnyObject" decl="test.(file).repro().anyObject@test.swift:6:7" function_ref=unapplied)
    (optional_evaluation_expr type="(nonisolated(nonsending) (Date?) async -> Void)?"
      (inject_into_optional type="(nonisolated(nonsending) (Date?) async -> Void)?"
        (function_conversion_expr type="nonisolated(nonsending) (Date?) async -> Void"
          (bind_optional_expr type="(Date?) async -> Void" depth=0
            (dynamic_member_ref_expr type="((Date?) async -> Void)?" decl="__ObjC.(file).Foo.start(at:)"
              (opaque_value_expr type="AnyObject"))))))))
```

Since we are emitting an objc async function, there isn't an extra implicit
parameter like if we were using a swift async function. So, I just reused code
that was already used locally to look through these sorts of conversions. I
just had to add to that code support for conversions that add
nonisolated(nonsending). Previously it only supported looking through global
actor conversions.

rdar://152596823
2025-06-05 13:34:42 -07:00
John McCall
e9ebc7c848 Pass a zero normal result to ObjC async completion handlers on the error path.
Fixes #65199
2025-03-26 00:58:27 -04:00
Pavel Yaskevich
4ce370d0b8 [Frontend] SE-0463: Enable SendableCompletionHandlers feature by default 2025-03-13 15:34:34 -07:00
Erik Eckstein
7cceaff5f3 SIL: don't print operand types in textual SIL
Type annotations for instruction operands are omitted, e.g.

```
  %3 = struct $S(%1, %2)
```

Operand types are redundant anyway and were only used for sanity checking in the SIL parser.

But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:

* if the block with the definition appears after the block where the operand's instruction is located

* if a block or instruction is printed in isolation, e.g. in a debugger

The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
2024-11-21 18:49:52 +01:00
Michael Gottesman
dddfdc891f [region-isolation] Codegen unsafe continuation result using calls to foreign APIs in the same manner as with checked continuation.
The reason why I am doing this is that the unlike the codegen for checked
continuation, the codegen for unchecked continuation uses a sendable value
instead of Any as the block storage which prevents me from being able to create
a dependency from a non-Sendable @out parameter to the block.

By changing to use Any consistently, we are able to take advantage of Any not
being sendable to properly propagate this information.
2024-11-01 11:25:17 -07:00
Allan Shortlidge
cb578172ea Tests: Remove -disable-availability-checking in more tests that use concurrency.
Use the `%target-swift-5.1-abi-triple` substitution to compile the tests for
deployment to the minimum OS versions required for use of _Concurrency APIs,
instead of disabling availability checking.
2024-10-19 12:35:20 -07:00
John McCall
cecf041c4e Remove random test dependency on exact value numbers. 2024-02-26 22:51:35 -05:00
Slava Pestov
47ca44c4a8 SIL: Fix printing of opaque parameter types
While printing them as `some P` makes sense in the AST since they
only ever appear at their definition point, in the body of a SIL
function, opaque parameter types can be referenced by various
instructions, like any other generic parameter type.

Instead of printing out `some P` or `<anonymous>` depending on
context, neither of which actually parsed, instead print them
with the canonical type `τ_d_i` notation. Since it's printed this
way in the generic parameter list as well, it parses back in.

Fixes rdar://problem/119823811.
2024-01-02 15:41:13 -05:00
Kavon Farvardin
06ac850d74 [SILGen] avoid hop before autoreleased foreign error is retained
For an isolated ObjC function that is not async, we
emit a hops around the call. But if that function
returns an autoreleased pointer, we need to ensure
we're retaining that pointer before hopping back
after the call. We weren't doing that in the case
of an autoreleased NSError:

```
%10 = alloc_stack $@sil_unmanaged Optional<NSError>
%19 = ... a bunch of steps to wrap up %10 ...
%20 = enum $Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, #Optional.some!enumelt, %19 : $AutoreleasingUnsafeMutablePointer<Optional<NSError>>
hop_to_executor $MainActor
%26 = apply X(Y, %20) : $@convention(objc_method) (NSObject, Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>) -> @autoreleased Optional<NSString>
hop_to_executor $Optional<Builtin.Executor>
// retain the autoreleased pointer written-out.
%28 = load [trivial] %10 : $*@sil_unmanaged Optional<NSError>
%29 = unmanaged_to_ref %28 : $@sil_unmanaged Optional<NSError> to $Optional<NSError>
%30 = copy_value %29 : $Optional<NSError>
assign %31 to %7 : $*Optional<NSError>
```

This patch sinks the hop emission after the call
so it happens after doing that copy.

rdar://114049646
2023-12-19 13:16:59 -08:00
Pavel Yaskevich
7d6c4b7491 [Tests] NFC: Move a test from dynamic lookup to objc_async* because it's using async continuations 2023-09-07 17:35:38 -07:00
Pavel Yaskevich
b8fb94b73c [Frontend] NFC: Add a flag to enable bridging of completion handlers to checked continuations 2023-09-07 17:35:35 -07:00
Holly Borla
8713d78704 [PrintOptions] Print explicit 'any' in SIL. 2022-08-18 01:15:12 -04:00
Kavon Farvardin
814fb42554 fix nested suspension issue with objc async calls
when two objc async functions are composed with each other,
i.e., f(g()), then the clean-ups for g() would get emitted
at an unexpected time, namely, during the suspension for
the call to f(). This means that using a clean-up to emit
the executor-hop breadcrumb was incorrect. The hop could
appear between a get_async continuation and its matching
await_continuation, which is an unsupported nested suspension.

This commit fixes that by removing the use of the breadcrumb
clean-up in favor of providing that breadcrumb directly to
the result plan, so that it may be emitted later on when the
result plan sees fit.

Fixes rdar://91502776
2022-05-02 18:20:59 -07:00
Kavon Farvardin
cb952ed37e Revert "Revert "[SR-15703] Fix missing hop in error path of foreign async throws call""
This reverts commit 05214f0d00.
2022-04-27 14:11:44 -07:00
Kavon Farvardin
6f86e2980a Revert "Revert "Simplify lifetime extension for async ObjC calls.""
This reverts commit 8441e07c0b.
2022-04-27 14:11:36 -07:00
Kavon Farvardin
8441e07c0b Revert "Simplify lifetime extension for async ObjC calls."
This reverts commit 01d470ce32.

Just to be safe, I'm reverting this part of https://github.com/apple/swift/pull/41571
as well, until it can be reimplemented in light of issues where a hop
can appear between a get_continuation and an await_continuation

resolves rdar://91502776
2022-04-25 12:12:26 -07:00
Kavon Farvardin
05214f0d00 Revert "[SR-15703] Fix missing hop in error path of foreign async throws call"
This reverts commit afd26d3974 to solve
a critical miscompile caused by a hop_to_executor appearing between
a get_continuation and await_continuation instruction in SIL.

A reimplementation of SR-15703 will be forthcoming.

Fixes rdar://91502776
2022-04-25 11:00:37 -07:00
Kavon Farvardin
afd26d3974 [SR-15703] Fix missing hop in error path of foreign async throws call
resolves rdar://89479707
2022-02-25 18:32:43 -07:00
Kavon Farvardin
01d470ce32 Simplify lifetime extension for async ObjC calls.
Since the clean-up is not unwind only, we can rely on the
clean-ups to be emitted on both result and throw paths.

This does slightly change when the hop_to_executor is emitted,
in those paths, but that shouldn't matter.

refactors solution for rdar://78982371
2022-02-25 18:32:13 -07:00
Nate Chandler
03e175a13e [Test] Added for call-as-async Optional<NS_EXTENSIBLE_STRING_ENUM>.
The underlying problem was fixed by the change for rdar://81590807 .
Add tests for the specific case that was originally reported.

rdar://80704382
2021-08-09 19:06:21 -07:00
Nate Chandler
6eb4f2ca8a [SILGen] Handled transforming Bridged? -> Swift.
Previously, the function emitCBridgedToNativeValue handled three
situations around optionals:
- Bridged?, Native?
- Bridged, Native?
- Bridged, Native

Here, handling for the fourth case
- Bridged?, Native
is added.

To enable this, the number of Optional wrappings that the bridged type
has that the native type does not is passed in to the function.  Then,
in the portions of the function where actual transformations are done,
the values are unwrapped an appropriate number of times.  Mostly that
means force unwrapping N times before doing the transformation.  In the
case of types that conform to _ObjectiveCBridgeable, however, it means
force unwrapping the value N-1 times after doing the transformation
because _ObjectiveCBridgeable._unconditionallyBridgeFromObjectiveC
performs one layer of unwrapping itself.

rdar://81590807
2021-08-09 19:02:27 -07:00
Doug Gregor
0fbe17185e Merge pull request #38767 from DougGregor/foreign-async-hop-back
Emit `hop_to_executor` instructors for foreign `async` calls.
2021-08-05 21:32:31 -07:00
Doug Gregor
865de722bb Emit hop_to_executor instructors for foreign async calls.
Fix a miscompile where a foreign `async` call would fail to emit an
appropriate `hop_to_executor` instruction to hop back to the current
executor afterward, meaning that subsequent code would not execute on
the correct actor.

Fixes rdar://81468980.
2021-08-05 13:44:20 -07:00
Nate Chandler
1ae317dd88 [SILGen] Handle foreign funcs with error and async conventions.
Previously, SILGen assumed that a foreign function could either have a
foreign async convention or a foreign error convention, but if it had
both, the error would be subsumed into the completion.  That resulted in
failures to emit code for async calls of functions like

```
- (BOOL)minimalWithError:(NSError* _Nullable*)error
         completionHandler:(void (^ _Nonnull)(void))completionHandler;
```

Here, SILGen gains the ability to emit such functions.  To enable that,
a few changes were required when both conventions are present:
- a separate argument for each convention is used
- the ResultPlan is a ForeignErrorResultPlan nesting a
  ForeignAsyncResultPlan
- the continuation is always of the form UnsafeContinuation<_, Error>
  regardless of whether the completion handler takes an error
- the foreign error block fills the continuation with the error that was
  passed by reference out of the ObjC method call
- the foreign error block branches to the block containing the await
  instruction

rdar://80704984
2021-08-03 18:36:15 -07:00
swift-ci
b1b9a76f73 Merge pull request #38642 from DougGregor/remove-experimental-concurrency-flag 2021-07-27 00:11:18 -07:00
Doug Gregor
eeeea49764 Remove -enable-experimental-concurrency almost everywhere. 2021-07-26 21:24:43 -07:00
nate-chandler
8345174bae Merge pull request #38370 from nate-chandler/rdar79383990
[SILGen] Used formal type when bridging completion handler arguments.
2021-07-26 10:57:49 -07:00
Nate Chandler
c493632b68 [SILGen] Used type AbstractionPattern.
Previously, AbstractionPattern::getOpaque() was used for async
continuations.  That was problematic for functions like

```objc
- (void)performVoid2VoidWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull)(void)))completion;
```

whose completion takes a closure.  Doing so resulted in attempting to
build a block to func thunk where one of the functions had an out
parameter.

Instead, use the AbstractionPattern(ty).

rdar://79383990
2021-07-24 14:25:27 -07:00
Meghana Gupta
a2bd36a2ea Merge pull request #38556 from meg-gupta/fixobjcasyncsilgen
Fix arg cleanup for objc continuations
2021-07-22 21:32:07 -07:00
Meghana Gupta
3372ab7a39 Fix arg cleanup for objc continuations
Current SILGen for objc continuations, can end the lifetime of args
before await_async_continuation.
This PR fixes it by extending the lifetime of the args until await_async_continuation
by creating copies. And then inserts manual cleanup with fix_lifetime + destroy

Fixes rdar://78982371
2021-07-22 15:23:57 -07:00
Doug Gregor
1e2012d816 Disable availability checking in tests that use concurrency 2021-07-20 12:46:26 -07:00
Joe Groff
fb199df1c7 SILGen: Support overriding/conforming to ObjC APIs with async error flag arguments. 2021-02-23 08:56:44 -08:00
Joe Groff
4bb49ba521 SILGen/ClangImporter: Handle async imports with a boolean error flag argument.
Import APIs with the `swift_async_error` attribute in `zero_argument` or `nonzero_argument`
modes by checking the corresponding boolean argument to indicate the error status, instead of
treating it as part of the result tuple. rdar://70594666
2021-02-19 17:31:09 -08:00
Joe Groff
eea3a6c27f SILGen: Handle pseudogeneric completion-handler-based async APIs.
Plumb generic signatures through the codegen for invoking foreign APIs as async, so that we
correctly handle APIs declared on ObjC lightweight generic classes. rdar://74361267
2021-02-16 16:05:04 -08:00
Jonathan Grynspan
d8f7f20c4b [Concurrency] Simplify the type story for Continuation by eliminating Throwing variants
The goal of doing this is to reduce the amount of boilerplate and repeated code w.r.t. Continuation. Having just added `resume()` in four places, I got the sense that there was a lot of common code that was being duplicated. I removed the Throwing variants of these types (they can be expressed as Continuation<T, E:Error> instead of ThrowingContinuation<E>) and I broke out a significant amount of common code between CheckedContinuation and UnsafeContinuation into an implementation-only protocol to avoid repeating it. D.R.Y.

This change resolves rdar://74154769.
2021-02-10 12:09:33 -05:00
Joe Groff
99599149a7 Merge pull request #35720 from jckarter/async-unbridged-result-optional-unwrap
SILGen: Unwrap optional async callback arguments if imported return is unbridged and not optional
2021-02-03 11:28:54 -08:00
Joe Groff
8a81052e8f SILGen: Unwrap optional async callback arguments if imported return is unbridged and not optional
The bridging code handles optional wrapping and unwrapping, but in cases where a nullable completion
callback argument did not need bridging, it would get short circuited out of the bridging code, and
did not get unwrapped. Fixes rdar://73798726
2021-02-02 15:34:45 -08:00
Richard Howell
6b6e5b84a6 [Testing] Add missing REQUIRES: concurrency 2021-01-22 14:16:15 -08:00
Joe Groff
82fc441895 SILGen: Copy values fed from completion handler invocation to balance retains.
If a completion handler takes an error argument, then the non-error arguments are bridged and forwarded to
the continuation only on the happy path. Make sure we forward a copy so the retain level of the success values
remains balanced across both branches. Fixes rdar://72604599.
2021-01-07 14:02:36 -08:00
Doug Gregor
3c38ffe0ea [Concurrency] await try -> try await
The `try await` ordering is both easier to read and indicates the order
of operations better, because the suspension point occurs first and
then one can observe a thrown error.
2020-12-23 13:21:59 -08:00
Joe Groff
0b0264cbdc SILGen: Implement native-to-foreign thunks for async interfaces with nullable completion handlers.
If the ObjC interface is passed a null completion handler, just discard the result of the native async call after it
finishes.
2020-12-15 17:21:35 -08:00
Joe Groff
bd2a6a4892 SILGen: Handle _Nullable completion handler arguments to imported async APIs. 2020-12-11 14:11:13 -08:00
Doug Gregor
18ef1869f3 [Concurrency] Diagnose "try await" with a Fix-It 2020-12-04 00:57:18 -08:00
Slava Pestov
a2dbdecdab SIL: Refactor get_async_continuation[_addr] to return a RawUnsafeContinuation 2020-12-01 20:04:09 -05:00
Joe Groff
6db85203db SIL: Abstraction pattern support for multiple foreign async returns.
An ObjC API maybe imported as async that had multiple non-error arguments to
its completion handler, which we treat in Swift as returning a tuple. Use a new
form of abstraction pattern to represent this return type, to maintain the
correct relation between individual tuple elements and the Clang block parameter
types they map to.
2020-11-12 16:53:21 -08:00
Joe Groff
368dc0f401 SILGen: Generate bodies for completion handler block impls 2020-11-10 16:36:50 -08:00
Joe Groff
4b33f26add Reserve a mangling for predefined completion handler impls in the runtime.
To manage code size in user binaries, we want to be able to implement common completion handler signatures in
the Swift runtime once. Using a different mangling for these lets us add new ones without clobbering symbols in
existing binaries.
2020-11-03 12:29:22 -08:00