From 087aacc9fdca4128f266390b6db0ac444d5bcfe3 Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Tue, 10 Jan 2023 10:24:28 -0800 Subject: [PATCH] [TaskLocals] Avoid use of `defer` in back deployed functions in the standard library. Older versions of the 5.8 compiler have a bug when generating SIL for functions with `@_backDeploy` containing defer blocks (https://github.com/apple/swift/pull/62444) and for now we need the standard library interface to be compatible with those older compilers. Resolves rdar://104045168 --- .../BackDeployConcurrency/TaskCancellation.swift | 11 ++++++++--- stdlib/public/BackDeployConcurrency/TaskLocal.swift | 11 ++++++++--- stdlib/public/Concurrency/TaskCancellation.swift | 11 ++++++++--- stdlib/public/Concurrency/TaskLocal.swift | 11 ++++++++--- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/stdlib/public/BackDeployConcurrency/TaskCancellation.swift b/stdlib/public/BackDeployConcurrency/TaskCancellation.swift index 88ec8e5a4ce98..a504dbeb0110a 100644 --- a/stdlib/public/BackDeployConcurrency/TaskCancellation.swift +++ b/stdlib/public/BackDeployConcurrency/TaskCancellation.swift @@ -46,9 +46,14 @@ public func withTaskCancellationHandler( // unconditionally add the cancellation record to the task. // if the task was already cancelled, it will be executed right away. let record = _taskAddCancellationHandler(handler: handler) - defer { _taskRemoveCancellationHandler(record: record) } - - return try await operation() + do { + let result = try await operation() + _taskRemoveCancellationHandler(record: record) + return result + } catch { + _taskRemoveCancellationHandler(record: record) + throw error + } } @available(SwiftStdlib 5.1, *) diff --git a/stdlib/public/BackDeployConcurrency/TaskLocal.swift b/stdlib/public/BackDeployConcurrency/TaskLocal.swift index b001dcca5e5a9..5a46e8f74c065 100644 --- a/stdlib/public/BackDeployConcurrency/TaskLocal.swift +++ b/stdlib/public/BackDeployConcurrency/TaskLocal.swift @@ -145,9 +145,14 @@ public final class TaskLocal: Sendable, CustomStringConvertible _checkIllegalTaskLocalBindingWithinWithTaskGroup(file: file, line: line) _taskLocalValuePush(key: key, value: valueDuringOperation) - defer { _taskLocalValuePop() } - - return try await operation() + do { + let result = try await operation() + _taskLocalValuePop() + return result + } catch { + _taskLocalValuePop() + throw error + } } /// Binds the task-local to the specific value for the duration of the diff --git a/stdlib/public/Concurrency/TaskCancellation.swift b/stdlib/public/Concurrency/TaskCancellation.swift index 88ec8e5a4ce98..a504dbeb0110a 100644 --- a/stdlib/public/Concurrency/TaskCancellation.swift +++ b/stdlib/public/Concurrency/TaskCancellation.swift @@ -46,9 +46,14 @@ public func withTaskCancellationHandler( // unconditionally add the cancellation record to the task. // if the task was already cancelled, it will be executed right away. let record = _taskAddCancellationHandler(handler: handler) - defer { _taskRemoveCancellationHandler(record: record) } - - return try await operation() + do { + let result = try await operation() + _taskRemoveCancellationHandler(record: record) + return result + } catch { + _taskRemoveCancellationHandler(record: record) + throw error + } } @available(SwiftStdlib 5.1, *) diff --git a/stdlib/public/Concurrency/TaskLocal.swift b/stdlib/public/Concurrency/TaskLocal.swift index 26614a2ecb2dd..976c7d9232359 100644 --- a/stdlib/public/Concurrency/TaskLocal.swift +++ b/stdlib/public/Concurrency/TaskLocal.swift @@ -145,9 +145,14 @@ public final class TaskLocal: Sendable, CustomStringConvertible _checkIllegalTaskLocalBindingWithinWithTaskGroup(file: file, line: line) _taskLocalValuePush(key: key, value: valueDuringOperation) - defer { _taskLocalValuePop() } - - return try await operation() + do { + let result = try await operation() + _taskLocalValuePop() + return result + } catch { + _taskLocalValuePop() + throw error + } } /// Binds the task-local to the specific value for the duration of the