Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherit the caller's executor in with*Continuation #41376

Merged
merged 2 commits into from
Feb 15, 2022

Conversation

rjmccall
Copy link
Member

Not inheriting the caller's executor is a major problem for these functions. Under SE-0338, treating them as non-isolated means that it's illegal to pass them anything non-Sendable from a different isolation context. Since these functions are declared to take a non-Sendable function parameter, effectively, SE-0338 means that these functions can only be safely called from non-isolated contexts. That's not really acceptable, but it gets worse: since we haven't implemented the sendability rule for that yet, we're immediately bypassing isolation safety when using these functions with no warning.

The short-term fix is to add an attribute which restores the pre-SE-0338 behavior. This will also be necessary in the long term for ABI-stable emission of the withCheckedContinuation functions, although it's really an oversight that we even have ABI-stable emission of these functions, and we should be able to replace them with @_alwaysEmitIntoClient versions that use whatever the proper long-term semantic fix is.

@rjmccall
Copy link
Member Author

@swift-ci Please test

SE-0338 changed the execution of non-actor async functions
so that they always hop to the generic executor, but some
functions need a way to suppress this so that they inherit
the caller's executor.

The right way to implement this is to have the caller pass
down the target executor in some reliable way and then
switch to it in all the appropriate places in the caller.
We might reasonably be able to build this on top of isolated
parameters, using some sort of default argument, or we might
need a wholly novel mechanism.

But those things are all ABI-breaking absent some sort of
guarantee about switching that we probably don't want to make,
and unfortunately we have functions in the library which we
need to export that need to inherit executors.  So in the
short term, we need some unsafe way of getting back to the
previous behavior.
Not inheriting the caller's executor is a major problem for
these functions.  Under SE-0338, treating them as non-isolated
means that it's illegal to pass them anytthing non-Sendable
from a different isolation context; since the function is
declared to take a non-sendable function parameter, effectively,
SE-0338 means that these functions can only be safely called
from non-isolated contexts.  That's not really acceptable, but
it gets worse: since we haven't implemented the sendability
rule for that yet, we're immediately bypassing isolation safety
when using these functions with no warning.

The `withCheckedContinuation` functions are not
`@_alwaysEmitIntoClient` (an oversight in the initial release),
and so we need to use the unsafe attribute on them.  When we
eventually implement a safe mechanism for this, we should make
`@_alwaysEmitIntoClient` variants of these functions which use
the new feature, and we can demote the existing functions to
`internal @availableFromInline`.

I've gone ahead and made `withChecked*Continuation` `@inlinable`.
@rjmccall
Copy link
Member Author

@swift-ci Please test

@rjmccall rjmccall merged commit 2827804 into apple:main Feb 15, 2022
@rjmccall rjmccall deleted the unsafe-inherits-executor branch February 15, 2022 05:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant