Repository: apple/swift
File: stdlib/public/Concurrency/PartialAsyncTask.swift (Swift)

Code before:
/// detect or diagnose any kind of misuse, so you need to be extra careful to avoid
/// calling `resume` twice or forgetting to call resume before letting go of the
/// continuation object.
///
/// - Parameter fn: A closure that takes an `UnsafeContinuation` parameter.
/// - Returns: The value continuation is resumed with.
///
/// - SeeAlso: `withUnsafeContinuation(function:_:)`
/// - SeeAlso: `withCheckedContinuation(function:_:)`
/// - SeeAlso: `withCheckedThrowingContinuation(function:_:)`
@available(SwiftStdlib 5.1, *)
@_alwaysEmitIntoClient
@unsafe
public func withUnsafeThrowingContinuation<T>(
  isolation: isolated (any Actor)? = #isolation,
  _ fn: (UnsafeContinuation<T, Error>) -> Void
) async throws -> sending T {
  return try await Builtin.withUnsafeThrowingContinuation {
    unsafe fn(UnsafeContinuation<T, Error>($0))
  }
}

// Note: hack to stage out @_unsafeInheritExecutor forms of various functions
// in favor of #isolation. The _unsafeInheritExecutor_ prefix is meaningful
// to the type checker.
@available(SwiftStdlib 5.1, *)
@_alwaysEmitIntoClient
@_unsafeInheritExecutor
public func _unsafeInheritExecutor_withUnsafeContinuation<T>(
  _ fn: (UnsafeContinuation<T, Never>) -> Void
) async -> sending T {
  return await Builtin.withUnsafeContinuation {
    unsafe fn(UnsafeContinuation<T, Never>($0))
  }
}

// Note: hack to stage out @_unsafeInheritExecutor forms of various functions
// in favor of #isolation. The _unsafeInheritExecutor_ prefix is meaningful
// to the type checker.
@available(SwiftStdlib 5.1, *)
@_alwaysEmitIntoClient
@_unsafeInheritExecutor
public func _unsafeInheritExecutor_withUnsafeThrowingContinuation<T>(
  _ fn: (UnsafeContinuation<T, Error>) -> Void
) async throws -> sending T {
  return try await Builtin.withUnsafeThrowingContinuation {
    unsafe fn(UnsafeContinuation<T, Error>($0))
  }
}

/// A hack to mark an SDK that supports swift_continuation_await.

Review comment (bug):
can the now-most-general forms now be the ones named `with{Checked|Unsafe}Continuation` rather than keeping the split b/w throwing and non-throwing? although it wasn't accepted AFAIK, @FranzBusch had [posed in this pitch](https://github.com/swiftlang/swift-evolution/pull/2197/changes?short_path=358b7f5#diff-358b7f52f311c2d654aa888af748c9bc574c594b93394f0224fa6a23a084ce1fR111) that when doing this, we should prefer the non-throwing names:

> Since, the natural
> spelling would be without the `Throwing` in the method name. We propose
> to add the following two new methods:
>
> ```swift
> public func withCheckedContinuation<T, Failure: Error>(
>     function: String = #function,
>     _ body: (CheckedContinuation<T, Failure>) -> Void
> ) async throws(Failure) -> T
>
> public func withUnsafeContinuation<T, Failure: Error>(
>   _ fn: (UnsafeContinuation<T, Failure>) -> Void
> ) async throws(Failure) -> T
> ```

i suppose the existing throwing functions still need to get the `nonisolated(nonsending)` treatment and will have to continue to exist, but could functions like the two floated in the pitch now subsume all the other existing variants?

Code after:
/// the calling task is suspended. It is possible to immediately resume the task, or escape the
/// continuation in order to complete it afterwards, which will then resume the suspended task.
///
/// If `resume(throwing:)` is called on the continuation, this function throws that error.
///
/// You must invoke the continuation's `resume` method exactly once.
///
/// Missing to invoke it (eventually) will cause the calling task to remain suspended
/// indefinitely which will result in the task "hanging" as well as being leaked with
/// no possibility to destroy it.
///
/// Unlike the "checked" continuation variant, the `UnsafeContinuation` does not
/// detect or diagnose any kind of misuse, so you need to be extra careful to avoid
/// calling `resume` twice or forgetting to call resume before letting go of the
/// continuation object.
///
/// - Parameter fn: A closure that takes an `UnsafeContinuation` parameter.
/// - Returns: The value continuation is resumed with.
///
/// - SeeAlso: `withUnsafeContinuation(function:_:)`
/// - SeeAlso: `withCheckedContinuation(function:_:)`
/// - SeeAlso: `withCheckedThrowingContinuation(function:_:)`
@available(SwiftStdlib 5.1, *)
@_alwaysEmitIntoClient
@unsafe
public nonisolated(nonsending) func withUnsafeThrowingContinuation<T, E>(
  _ fn: (UnsafeContinuation<T, E>) -> Void
) async throws(E) -> sending T {
  do {
    return try await Builtin.withUnsafeThrowingContinuation {
      unsafe fn(UnsafeContinuation<T, E>($0))
    }
  } catch {
    throw error as! E
  }
}

@available(SwiftStdlib 5.1, *)
@_alwaysEmitIntoClient
@unsafe
public nonisolated(nonsending) func withUnsafeThrowingContinuation<T>(
  _ fn: (UnsafeContinuation<T, Error>) -> Void
) async throws(Error) -> sending T {
  return try await Builtin.withUnsafeThrowingContinuation {
    unsafe fn(UnsafeContinuation<T, Error>($0))
  }
}

// Note: hack to stage out @_unsafeInheritExecutor forms of various functions
// in favor of #isolation. The _unsafeInheritExecutor_ prefix is meaningful
// to the type checker.