From d81da3a5f036bfe162e440e2ac87027e7d98b20b Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Tue, 4 Nov 2025 18:00:45 +0000 Subject: [PATCH 1/5] [Concurrency] Change all of the StdlibDeploymentTarget 6.2s to 6.3. These were right when they were written, but they are now causing trouble. Move them to 6.3. --- stdlib/public/Concurrency/Clock.swift | 2 +- .../public/Concurrency/ContinuousClock.swift | 2 +- .../Concurrency/CooperativeExecutor.swift | 14 ++-- stdlib/public/Concurrency/Executor.swift | 70 +++++++++---------- .../public/Concurrency/ExecutorBridge.swift | 42 +++++------ .../GlobalConcurrentExecutor.swift | 2 +- .../public/Concurrency/PartialAsyncTask.swift | 22 +++--- .../PlatformExecutorCooperative.swift | 2 +- .../Concurrency/PlatformExecutorLinux.swift | 2 +- .../Concurrency/PlatformExecutorNone.swift | 2 +- .../Concurrency/PlatformExecutorWindows.swift | 2 +- .../public/Concurrency/SuspendingClock.swift | 2 +- stdlib/public/Concurrency/Task.swift | 4 +- stdlib/public/Concurrency/TaskSleep.swift | 4 +- .../Concurrency/TaskSleepDuration.swift | 4 +- .../Concurrency/UnimplementedExecutor.swift | 4 +- 16 files changed, 90 insertions(+), 90 deletions(-) diff --git a/stdlib/public/Concurrency/Clock.swift b/stdlib/public/Concurrency/Clock.swift index da51df65424..de4282b8cf5 100644 --- a/stdlib/public/Concurrency/Clock.swift +++ b/stdlib/public/Concurrency/Clock.swift @@ -190,7 +190,7 @@ internal func _getClockRes( nanoseconds: UnsafeMutablePointer, clock: CInt) -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_sleep") internal func _sleep( seconds: Int64, diff --git a/stdlib/public/Concurrency/ContinuousClock.swift b/stdlib/public/Concurrency/ContinuousClock.swift index 274cb191031..19fe29bda14 100644 --- a/stdlib/public/Concurrency/ContinuousClock.swift +++ b/stdlib/public/Concurrency/ContinuousClock.swift @@ -113,7 +113,7 @@ extension ContinuousClock: Clock { public func sleep( until deadline: Instant, tolerance: Swift.Duration? = nil ) async throws { - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { try await Task._sleep(until: deadline, tolerance: tolerance, clock: self) diff --git a/stdlib/public/Concurrency/CooperativeExecutor.swift b/stdlib/public/Concurrency/CooperativeExecutor.swift index 654db0b65d6..706bf1bce0c 100644 --- a/stdlib/public/Concurrency/CooperativeExecutor.swift +++ b/stdlib/public/Concurrency/CooperativeExecutor.swift @@ -17,7 +17,7 @@ import Swift // Store the Timestamp in the executor private data, if it will fit; otherwise, // use the allocator to allocate space for it and stash a pointer in the private // data area. -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension ExecutorJob { fileprivate var cooperativeExecutorTimestampIsIndirect: Bool { return MemoryLayout<(Int, Int)>.size @@ -99,7 +99,7 @@ extension ExecutorJob { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY /// A wait queue is a specialised priority queue used to run a timer. -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) struct WaitQueue { var queue: PriorityQueue var clock: _ClockID @@ -157,7 +157,7 @@ struct WaitQueue { /// A co-operative executor that can be used as the main executor or as a /// task executor. -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) final class CooperativeExecutor: Executor, @unchecked Sendable { var runQueue: PriorityQueue #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @@ -282,7 +282,7 @@ extension CooperativeExecutor: SchedulingExecutor { } #endif -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension CooperativeExecutor: RunLoopExecutor { public func run() throws { try runUntil { false } @@ -340,13 +340,13 @@ extension CooperativeExecutor: RunLoopExecutor { } } -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension CooperativeExecutor: SerialExecutor {} -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension CooperativeExecutor: TaskExecutor {} -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension CooperativeExecutor: MainExecutor {} #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index 91236cfb916..eec5da4d78a 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -38,7 +38,7 @@ public protocol Executor: AnyObject, Sendable { #if os(WASI) || !$Embedded /// `true` if this is the main executor. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) var isMainExecutor: Bool { get } #endif // os(WASI) || !$Embedded @@ -49,12 +49,12 @@ public protocol Executor: AnyObject, Sendable { /// Executors that implement SchedulingExecutor should provide their /// own copy of this method, which will allow the compiler to avoid a /// potentially expensive runtime cast. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) var asSchedulingExecutor: (any SchedulingExecutor)? { get } #endif } -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public protocol SchedulingExecutor: Executor { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @@ -74,7 +74,7 @@ public protocol SchedulingExecutor: Executor { /// - tolerance: The maximum additional delay permissible before the /// job is executed. `nil` means no limit. /// - clock: The clock used for the delay. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) func enqueue(_ job: consuming ExecutorJob, after delay: C.Duration, tolerance: C.Duration?, @@ -94,7 +94,7 @@ public protocol SchedulingExecutor: Executor { /// - tolerance: The maximum additional delay permissible before the /// job is executed. `nil` means no limit. /// - clock: The clock used for the delay. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) func enqueue(_ job: consuming ExecutorJob, at instant: C.Instant, tolerance: C.Duration?, @@ -138,7 +138,7 @@ extension Executor { /// Executors that implement SchedulingExecutor should provide their /// own copy of this method, which will allow the compiler to avoid a /// potentially expensive runtime cast. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public var asSchedulingExecutor: (any SchedulingExecutor)? { return self as? SchedulingExecutor } @@ -162,19 +162,19 @@ extension Executor { #if os(WASI) || !$Embedded // This defaults to `false` so that existing third-party Executor // implementations will work as expected. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public var isMainExecutor: Bool { false } #endif // os(WASI) || !$Embedded } // Delay support -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension SchedulingExecutor { #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func enqueue(_ job: consuming ExecutorJob, after delay: C.Duration, tolerance: C.Duration? = nil, @@ -185,7 +185,7 @@ extension SchedulingExecutor { tolerance: tolerance, clock: clock) } - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func enqueue(_ job: consuming ExecutorJob, at instant: C.Instant, tolerance: C.Duration? = nil, @@ -374,7 +374,7 @@ public protocol SerialExecutor: Executor { /// The default implementation returns `nil` is used to indicate that it is "unknown" if the current context is /// isolated by this serial executor. The runtime then _may_ proceed to invoke `checkIsolated()` as a last-resort /// attempt to verify the isolation of the current context. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) func isIsolatingCurrentContext() -> Bool? } @@ -383,7 +383,7 @@ public protocol SerialExecutor: Executor { extension SerialExecutor { #if os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY) - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public var isMainExecutor: Bool { return MainActor.executor._isSameExecutor(self) } #endif // os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY) @@ -397,13 +397,13 @@ extension SerialExecutor { } #if SWIFT_CONCURRENCY_USES_DISPATCH - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) private var _dispatchQueue: OpaquePointer? { return unsafe _getDispatchQueueForExecutor(self.asUnownedSerialExecutor()) } #endif - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) internal func _isSameExecutor(_ rhs: some SerialExecutor) -> Bool { if rhs === self { return true @@ -423,10 +423,10 @@ extension SerialExecutor { } } -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension SerialExecutor { - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func isIsolatingCurrentContext() -> Bool? { return nil } @@ -526,10 +526,10 @@ extension SerialExecutor { } -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension SerialExecutor where Self: Equatable { - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func isSameExclusiveExecutionContext(other: Self) -> Bool { return self == other } @@ -541,7 +541,7 @@ extension SerialExecutor where Self: Equatable { /// The idea here is that some executors may work by running a loop /// that processes events of some sort; we want a way to enter that loop, /// and we would also like a way to trigger the loop to exit. -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public protocol RunLoopExecutor: Executor { /// Run the executor's run loop. /// @@ -572,7 +572,7 @@ public protocol RunLoopExecutor: Executor { func stop() } -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension RunLoopExecutor { public func runUntil(_ condition: () -> Bool) throws { @@ -584,14 +584,14 @@ extension RunLoopExecutor { /// The main executor must conform to these two protocols; we have to /// make this a protocol for compatibility with Embedded Swift. -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public protocol MainExecutor: RunLoopExecutor, SerialExecutor { } /// An ExecutorFactory is used to create the default main and task /// executors. -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public protocol ExecutorFactory { #if os(WASI) || !$Embedded /// Constructs and returns the main executor, which is started implicitly @@ -607,7 +607,7 @@ public protocol ExecutorFactory { @available(StdlibDeploymentTarget 6.3, *) typealias DefaultExecutorFactory = PlatformExecutorFactory -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_createExecutors") public func _createExecutors(factory: F.Type) { #if os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY) @@ -626,7 +626,7 @@ func _createDefaultExecutors() { #if os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY) extension MainActor { - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) static var _executor: (any MainExecutor)? = nil /// The main executor, which is started implicitly by the `async main` @@ -634,7 +634,7 @@ extension MainActor { /// /// Attempting to set this after the first `enqueue` on the main /// executor is a fatal error. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public static var executor: any MainExecutor { // It would be good if there was a Swift way to do this _createDefaultExecutorsOnce() @@ -642,7 +642,7 @@ extension MainActor { } /// An unowned version of the above, for performance - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) static var unownedExecutor: UnownedSerialExecutor { _createDefaultExecutorsOnce() return unsafe UnownedSerialExecutor(ordinary: _executor!) @@ -651,7 +651,7 @@ extension MainActor { #endif // os(WASI) || (!$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY) extension Task where Success == Never, Failure == Never { - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) static var _defaultExecutor: (any TaskExecutor)? = nil /// The default or global executor, which is the default place in which @@ -659,7 +659,7 @@ extension Task where Success == Never, Failure == Never { /// /// Attempting to set this after the first `enqueue` on the global /// executor is a fatal error. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public static var defaultExecutor: any TaskExecutor { // It would be good if there was a Swift way to do this _createDefaultExecutorsOnce() @@ -667,7 +667,7 @@ extension Task where Success == Never, Failure == Never { } /// An unowned version of the above, for performance - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) static var unownedDefaultExecutor: UnownedTaskExecutor { _createDefaultExecutorsOnce() return unsafe UnownedTaskExecutor(_defaultExecutor!) @@ -686,7 +686,7 @@ extension Task where Success == Never, Failure == Never { /// 3. The task executor for the current thread /// /// If none of these exist, returns the default executor. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) @_unavailableInEmbedded public static var currentExecutor: any Executor { if let activeExecutor = unsafe _getActiveExecutor().asSerialExecutor() { @@ -700,7 +700,7 @@ extension Task where Success == Never, Failure == Never { } /// Get the preferred executor for the current `Task`, if any. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public static var preferredExecutor: (any TaskExecutor)? { if let taskExecutor = unsafe _getPreferredTaskExecutor().asTaskExecutor() { return taskExecutor @@ -713,7 +713,7 @@ extension Task where Success == Never, Failure == Never { /// /// This follows the same logic as `currentExecutor`, except that it ignores /// any executor that isn't a `SchedulingExecutor`. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public static var currentSchedulingExecutor: (any SchedulingExecutor)? { if let activeExecutor = unsafe _getActiveExecutor().asSerialExecutor(), let scheduling = activeExecutor.asSchedulingExecutor { @@ -806,7 +806,7 @@ public struct UnownedSerialExecutor: Sendable { unsafe _executor_isComplexEquality(self) } - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func asSerialExecutor() -> (any SerialExecutor)? { return unsafe unsafeBitCast(executor, to: (any SerialExecutor)?.self) } @@ -837,13 +837,13 @@ public struct UnownedTaskExecutor: Sendable { unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor) } - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) @inlinable public init(_ executor: __shared E) { unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor) } - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func asTaskExecutor() -> (any TaskExecutor)? { return unsafe unsafeBitCast(executor, to: (any TaskExecutor)?.self) } diff --git a/stdlib/public/Concurrency/ExecutorBridge.swift b/stdlib/public/Concurrency/ExecutorBridge.swift index c52798bd80e..f74c8e11f96 100644 --- a/stdlib/public/Concurrency/ExecutorBridge.swift +++ b/stdlib/public/Concurrency/ExecutorBridge.swift @@ -17,19 +17,19 @@ import Swift -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_exit") internal func _exit(result: CInt) #if !$Embedded -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_task_isMainExecutorSwift") internal func _isMainExecutor(_ executor: E) -> Bool where E: SerialExecutor { return executor.isMainExecutor } #endif -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_task_checkIsolatedSwift") internal func checkIsolated(executor: E) where E: SerialExecutor { executor.checkIsolated() @@ -40,7 +40,7 @@ internal func checkIsolated(executor: E) where E: SerialExecutor { /// -1: unknown /// 0: not isolated /// 1: isolated -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_task_isIsolatingCurrentContextSwift") internal func isIsolatingCurrentContext(executor: E) -> Int8 where E: SerialExecutor { @@ -51,41 +51,41 @@ internal func isIsolatingCurrentContext(executor: E) -> Int8 } } -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_getActiveExecutor") internal func _getActiveExecutor() -> UnownedSerialExecutor -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_getCurrentTaskExecutor") internal func _getCurrentTaskExecutor() -> UnownedTaskExecutor -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_getPreferredTaskExecutor") internal func _getPreferredTaskExecutor() -> UnownedTaskExecutor -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_job_allocate") internal func _jobAllocate(_ job: Builtin.Job, _ capacity: Int) -> UnsafeMutableRawPointer -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_job_deallocate") internal func _jobDeallocate(_ job: Builtin.Job, _ address: UnsafeMutableRawPointer) -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_job_getPriority") internal func _jobGetPriority(_ job: Builtin.Job) -> UInt8 -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_job_setPriority") internal func _jobSetPriority(_ job: Builtin.Job, _ priority: UInt8) -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_job_getKind") internal func _jobGetKind(_ job: Builtin.Job) -> UInt8 -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_job_getExecutorPrivateData") internal func _jobGetExecutorPrivateData( _ job: Builtin.Job @@ -93,38 +93,38 @@ internal func _jobGetExecutorPrivateData( #if os(WASI) || !$Embedded #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_getMainExecutor") internal func _getMainExecutorAsSerialExecutor() -> UnownedSerialExecutor { return unsafe MainActor.unownedExecutor } #else // For task-to-thread model, this is implemented in C++ -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_getMainExecutor") internal func _getMainExecutorAsSerialExecutor() -> UnownedSerialExecutor #endif // SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY #endif // os(WASI) || !$Embedded -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_getDefaultExecutor") internal func _getDefaultExecutorAsTaskExecutor() -> UnownedTaskExecutor { return unsafe Task.unownedDefaultExecutor } -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_dispatchMain") internal func _dispatchMain() -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_dispatchEnqueueMain") internal func _dispatchEnqueueMain(_ job: UnownedJob) -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_dispatchEnqueueGlobal") internal func _dispatchEnqueueGlobal(_ job: UnownedJob) -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_dispatchEnqueueWithDeadline") internal func _dispatchEnqueueWithDeadline(_ global: CBool, _ sec: CLongLong, @@ -134,7 +134,7 @@ internal func _dispatchEnqueueWithDeadline(_ global: CBool, _ clock: CInt, _ job: UnownedJob) -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("swift_dispatchAssertMainQueue") internal func _dispatchAssertMainQueue() diff --git a/stdlib/public/Concurrency/GlobalConcurrentExecutor.swift b/stdlib/public/Concurrency/GlobalConcurrentExecutor.swift index c8e0a0a4a54..c4f21c96d4a 100644 --- a/stdlib/public/Concurrency/GlobalConcurrentExecutor.swift +++ b/stdlib/public/Concurrency/GlobalConcurrentExecutor.swift @@ -34,7 +34,7 @@ import Swift @_unavailableInEmbedded public var globalConcurrentExecutor: any TaskExecutor { get { - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { return Task.defaultExecutor } else { fatalError("we shouldn't get here; if we have, availability is broken") diff --git a/stdlib/public/Concurrency/PartialAsyncTask.swift b/stdlib/public/Concurrency/PartialAsyncTask.swift index a255d34d345..821d134796d 100644 --- a/stdlib/public/Concurrency/PartialAsyncTask.swift +++ b/stdlib/public/Concurrency/PartialAsyncTask.swift @@ -88,7 +88,7 @@ public struct UnownedJob: Sendable { @available(StdlibDeploymentTarget 5.9, *) public var priority: JobPriority { let raw: UInt8 - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { raw = _jobGetPriority(context) } else { fatalError("we shouldn't get here; if we have, availability is broken") @@ -227,7 +227,7 @@ public struct Job: Sendable, ~Copyable { public var priority: JobPriority { let raw: UInt8 - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { raw = _jobGetPriority(self.context) } else { fatalError("we shouldn't get here; if we have, availability is broken") @@ -301,7 +301,7 @@ public struct ExecutorJob: Sendable, ~Copyable { internal(set) public var priority: JobPriority { get { let raw: UInt8 - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { raw = _jobGetPriority(self.context) } else { fatalError("we shouldn't get here; if we have, availability is broken") @@ -309,7 +309,7 @@ public struct ExecutorJob: Sendable, ~Copyable { return JobPriority(rawValue: raw) } set { - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { _jobSetPriority(self.context, newValue.rawValue) } else { fatalError("we shouldn't get here; if we have, availability is broken") @@ -327,7 +327,7 @@ public struct ExecutorJob: Sendable, ~Copyable { /// - body: The closure to execute. /// /// Returns the result of executing the closure. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func withUnsafeExecutorPrivateData(body: (UnsafeMutableRawBufferPointer) throws(E) -> R) throws(E) -> R { let base = unsafe _jobGetExecutorPrivateData(self.context) let size = unsafe 2 * MemoryLayout.stride @@ -336,7 +336,7 @@ public struct ExecutorJob: Sendable, ~Copyable { } /// Kinds of schedulable jobs - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) @frozen public struct Kind: Sendable, RawRepresentable { public typealias RawValue = UInt8 @@ -357,7 +357,7 @@ public struct ExecutorJob: Sendable, ~Copyable { } /// What kind of job this is. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public var kind: Kind { return Kind(rawValue: _jobGetKind(self.context))! } @@ -454,7 +454,7 @@ extension ExecutorJob { // Helper to create a trampoline job to execute a job on a specified // executor. -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension ExecutorJob { /// Create a trampoline to enqueue the specified job on the specified @@ -471,7 +471,7 @@ extension ExecutorJob { /// /// A new ExecutorJob that will enqueue the specified job on the specified /// executor. - @available(StdlibDeploymentTarget 6.2, *) + @available(StdlibDeploymentTarget 6.3, *) public func createTrampoline(to executor: some Executor) -> ExecutorJob { let flags = taskCreateFlags( priority: TaskPriority(priority), @@ -496,7 +496,7 @@ extension ExecutorJob { } // Stack-disciplined job-local allocator support -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) extension ExecutorJob { /// Obtain a stack-disciplined job-local allocator. @@ -971,7 +971,7 @@ public func _abiEnableAwaitContinuation() { } #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) @_silgen_name("_swift_createJobForTestingOnly") public func _swift_createJobForTestingOnly( priority: TaskPriority = TaskPriority.medium, diff --git a/stdlib/public/Concurrency/PlatformExecutorCooperative.swift b/stdlib/public/Concurrency/PlatformExecutorCooperative.swift index e9288bfc7cd..03b7b7633cf 100644 --- a/stdlib/public/Concurrency/PlatformExecutorCooperative.swift +++ b/stdlib/public/Concurrency/PlatformExecutorCooperative.swift @@ -13,7 +13,7 @@ import Swift // This platform uses a single, global, CooperativeExecutor -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public struct PlatformExecutorFactory: ExecutorFactory { static let executor = CooperativeExecutor() public static var mainExecutor: any MainExecutor { executor } diff --git a/stdlib/public/Concurrency/PlatformExecutorLinux.swift b/stdlib/public/Concurrency/PlatformExecutorLinux.swift index 19d245a1a7e..cb975e7b1a5 100644 --- a/stdlib/public/Concurrency/PlatformExecutorLinux.swift +++ b/stdlib/public/Concurrency/PlatformExecutorLinux.swift @@ -15,7 +15,7 @@ import Swift // The default executors for now are Dispatch-based -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = DispatchMainExecutor() public static let defaultExecutor: any TaskExecutor diff --git a/stdlib/public/Concurrency/PlatformExecutorNone.swift b/stdlib/public/Concurrency/PlatformExecutorNone.swift index c052893f541..35f857de4e4 100644 --- a/stdlib/public/Concurrency/PlatformExecutorNone.swift +++ b/stdlib/public/Concurrency/PlatformExecutorNone.swift @@ -12,7 +12,7 @@ import Swift -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = UnimplementedMainExecutor() public static let defaultExecutor: any TaskExecutor = UnimplementedTaskExecutor() diff --git a/stdlib/public/Concurrency/PlatformExecutorWindows.swift b/stdlib/public/Concurrency/PlatformExecutorWindows.swift index 08ec7051993..f8936cef694 100644 --- a/stdlib/public/Concurrency/PlatformExecutorWindows.swift +++ b/stdlib/public/Concurrency/PlatformExecutorWindows.swift @@ -15,7 +15,7 @@ import Swift // The default executors for now are Dispatch-based -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public struct PlatformExecutorFactory: ExecutorFactory { public static let mainExecutor: any MainExecutor = DispatchMainExecutor() public static let defaultExecutor: any TaskExecutor = diff --git a/stdlib/public/Concurrency/SuspendingClock.swift b/stdlib/public/Concurrency/SuspendingClock.swift index 89eeef1e1df..0206678f5bb 100644 --- a/stdlib/public/Concurrency/SuspendingClock.swift +++ b/stdlib/public/Concurrency/SuspendingClock.swift @@ -101,7 +101,7 @@ extension SuspendingClock: Clock { public func sleep( until deadline: Instant, tolerance: Swift.Duration? = nil ) async throws { - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { try await Task._sleep(until: deadline, tolerance: tolerance, clock: self) diff --git a/stdlib/public/Concurrency/Task.swift b/stdlib/public/Concurrency/Task.swift index 3d2b9caaf57..597e3635085 100644 --- a/stdlib/public/Concurrency/Task.swift +++ b/stdlib/public/Concurrency/Task.swift @@ -637,7 +637,7 @@ extension Task where Success == Never, Failure == Never { continuation: continuation) #if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { let executor = Task.currentExecutor executor.enqueue(ExecutorJob(context: job)) @@ -898,7 +898,7 @@ internal func _runAsyncMain(_ asyncFun: @Sendable @escaping () async throws -> ( } let job = Builtin.convertTaskToJob(theTask) - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { MainActor.executor.enqueue(ExecutorJob(context: job)) } else { fatalError("we shouldn't get here; if we have, availability is broken") diff --git a/stdlib/public/Concurrency/TaskSleep.swift b/stdlib/public/Concurrency/TaskSleep.swift index b9994e01698..d7568f6bf7d 100644 --- a/stdlib/public/Concurrency/TaskSleep.swift +++ b/stdlib/public/Concurrency/TaskSleep.swift @@ -28,7 +28,7 @@ extension Task where Success == Never, Failure == Never { priority: Int(Task.currentPriority.rawValue), continuation: continuation) - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { #if !$Embedded if let executor = Task.currentSchedulingExecutor { executor.enqueue(ExecutorJob(context: job), @@ -272,7 +272,7 @@ extension Task where Success == Never, Failure == Never { let job = Builtin.convertTaskToJob(sleepTask) - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { #if !$Embedded if let executor = Task.currentSchedulingExecutor { executor.enqueue(ExecutorJob(context: job), diff --git a/stdlib/public/Concurrency/TaskSleepDuration.swift b/stdlib/public/Concurrency/TaskSleepDuration.swift index 27f35eb321b..c87073c1c13 100644 --- a/stdlib/public/Concurrency/TaskSleepDuration.swift +++ b/stdlib/public/Concurrency/TaskSleepDuration.swift @@ -116,7 +116,7 @@ extension Task where Success == Never, Failure == Never { let job = Builtin.convertTaskToJob(sleepTask) - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { #if !$Embedded if let executor = Task.currentSchedulingExecutor { executor.enqueue(ExecutorJob(context: job), @@ -136,7 +136,7 @@ extension Task where Success == Never, Failure == Never { clock: clock) let toleranceSeconds: Int64 let toleranceNanoseconds: Int64 - if #available(StdlibDeploymentTarget 6.2, *) { + if #available(StdlibDeploymentTarget 6.3, *) { if let tolerance = tolerance { (toleranceSeconds, toleranceNanoseconds) = durationComponents(for: tolerance, clock: clock) diff --git a/stdlib/public/Concurrency/UnimplementedExecutor.swift b/stdlib/public/Concurrency/UnimplementedExecutor.swift index f4a299fc550..aca56a3086d 100644 --- a/stdlib/public/Concurrency/UnimplementedExecutor.swift +++ b/stdlib/public/Concurrency/UnimplementedExecutor.swift @@ -14,7 +14,7 @@ import Swift // .. Main Executor ............................................................ -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public final class UnimplementedMainExecutor: MainExecutor, @unchecked Sendable { public init() {} @@ -45,7 +45,7 @@ public final class UnimplementedMainExecutor: MainExecutor, @unchecked Sendable // .. Task Executor ............................................................ -@available(StdlibDeploymentTarget 6.2, *) +@available(StdlibDeploymentTarget 6.3, *) public final class UnimplementedTaskExecutor: TaskExecutor, @unchecked Sendable { public init() {} From 34dfbf7bbd2f63af5b2703d104f4a7ccd4ed68f5 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Wed, 5 Nov 2025 09:29:27 +0000 Subject: [PATCH 2/5] [Concurrency] Tweak some things after the availability change. We need to fix some call sites to make this work. --- stdlib/public/Concurrency/Executor.swift | 2 +- stdlib/public/Concurrency/ExecutorImpl.swift | 68 +++++++++++++------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index eec5da4d78a..8dd8a046e74 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -374,7 +374,7 @@ public protocol SerialExecutor: Executor { /// The default implementation returns `nil` is used to indicate that it is "unknown" if the current context is /// isolated by this serial executor. The runtime then _may_ proceed to invoke `checkIsolated()` as a last-resort /// attempt to verify the isolation of the current context. - @available(StdlibDeploymentTarget 6.3, *) + @available(StdlibDeploymentTarget 6.2, *) func isIsolatingCurrentContext() -> Bool? } diff --git a/stdlib/public/Concurrency/ExecutorImpl.swift b/stdlib/public/Concurrency/ExecutorImpl.swift index 52ed84d0f71..5d36647768d 100644 --- a/stdlib/public/Concurrency/ExecutorImpl.swift +++ b/stdlib/public/Concurrency/ExecutorImpl.swift @@ -24,8 +24,12 @@ import Swift @_silgen_name("swift_task_asyncMainDrainQueueImpl") internal func drainMainQueue() { #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - try! MainActor.executor.run() - _exit(result: 0) + if #available(StdlibDeploymentTarget 6.3, *) { + try! MainActor.executor.run() + _exit(result: 0) + } else { + fatalError("this should never happen") + } #else fatalError("swift_task_asyncMainDrainQueue() not supported with task-to-thread") #endif @@ -37,10 +41,14 @@ internal func donateToGlobalExecutor( condition: @convention(c) (_ ctx: UnsafeMutableRawPointer) -> CBool, context: UnsafeMutableRawPointer ) { - if let runnableExecutor = Task.defaultExecutor as? RunLoopExecutor { - try! runnableExecutor.runUntil { unsafe Bool(condition(context)) } + if #available(StdlibDeploymentTarget 6.3, *) { + if let runnableExecutor = Task.defaultExecutor as? RunLoopExecutor { + try! runnableExecutor.runUntil { unsafe Bool(condition(context)) } + } else { + fatalError("Global executor does not support thread donation") + } } else { - fatalError("Global executor does not support thread donation") + fatalError("this should never happen") } } @@ -63,7 +71,11 @@ internal func enqueueOnMainExecutor(job unownedJob: UnownedJob) { @available(SwiftStdlib 6.2, *) @_silgen_name("swift_task_enqueueGlobalImpl") internal func enqueueOnGlobalExecutor(job unownedJob: UnownedJob) { - Task.defaultExecutor.enqueue(unownedJob) + if #available(StdlibDeploymentTarget 6.3, *) { + Task.defaultExecutor.enqueue(unownedJob) + } else { + fatalError("this should never happen") + } } #if !$Embedded @@ -72,9 +84,13 @@ internal func enqueueOnGlobalExecutor(job unownedJob: UnownedJob) { internal func enqueueOnGlobalExecutor(delay: CUnsignedLongLong, job unownedJob: UnownedJob) { #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob), - after: .nanoseconds(delay), - clock: .continuous) + if #available(StdlibDeploymentTarget 6.3, *) { + Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob), + after: .nanoseconds(delay), + clock: .continuous) + } else { + fatalError("this should never happen") + } #else fatalError("swift_task_enqueueGlobalWithDelay() not supported for task-to-thread") #endif @@ -91,19 +107,27 @@ internal func enqueueOnGlobalExecutor(seconds: CLongLong, #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY let delay = Duration.seconds(seconds) + Duration.nanoseconds(nanoseconds) let leeway = Duration.seconds(leewaySeconds) + Duration.nanoseconds(leewayNanoseconds) - switch clock { - case _ClockID.suspending.rawValue: - Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob), - after: delay, - tolerance: leeway, - clock: .suspending) - case _ClockID.continuous.rawValue: - Task.defaultExecutor.asSchedulingExecutor!.enqueue(ExecutorJob(unownedJob), - after: delay, - tolerance: leeway, - clock: .continuous) - default: - fatalError("Unknown clock ID \(clock)") + if #available(StdlibDeploymentTarget 6.3, *) { + switch clock { + case _ClockID.suspending.rawValue: + Task.defaultExecutor.asSchedulingExecutor!.enqueue( + ExecutorJob(unownedJob), + after: delay, + tolerance: leeway, + clock: .suspending + ) + case _ClockID.continuous.rawValue: + Task.defaultExecutor.asSchedulingExecutor!.enqueue( + ExecutorJob(unownedJob), + after: delay, + tolerance: leeway, + clock: .continuous + ) + default: + fatalError("Unknown clock ID \(clock)") + } + } else { + fatalError("this should never happen") } #else fatalError("swift_task_enqueueGlobalWithDeadline() not supported for task-to-thread") From 844130fb8c6a9d4788d7bc39b856a9c863f401ba Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Tue, 11 Nov 2025 16:38:55 +0000 Subject: [PATCH 3/5] [Concurrency] Fix isIsolatingCurrentContext. `isIsolatingCurrentContext` _should_ be in 6.2, not 6.3. --- stdlib/public/Concurrency/Executor.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index 8dd8a046e74..f9186f59da9 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -423,10 +423,10 @@ extension SerialExecutor { } } -@available(StdlibDeploymentTarget 6.3, *) +@available(StdlibDeploymentTarget 6.2, *) extension SerialExecutor { - @available(StdlibDeploymentTarget 6.3, *) + @available(StdlibDeploymentTarget 6.2, *) public func isIsolatingCurrentContext() -> Bool? { return nil } From 629d708577ccc049b3a9d2f9814224641b9b7b8c Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Tue, 11 Nov 2025 17:59:29 +0000 Subject: [PATCH 4/5] [Concurrency] Add more availability tests. Some additional availability tests required. --- stdlib/public/Concurrency/ExecutorImpl.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/stdlib/public/Concurrency/ExecutorImpl.swift b/stdlib/public/Concurrency/ExecutorImpl.swift index 5d36647768d..6df654fed83 100644 --- a/stdlib/public/Concurrency/ExecutorImpl.swift +++ b/stdlib/public/Concurrency/ExecutorImpl.swift @@ -55,14 +55,22 @@ internal func donateToGlobalExecutor( @available(SwiftStdlib 6.2, *) @_silgen_name("swift_task_getMainExecutorImpl") internal func getMainExecutor() -> UnownedSerialExecutor { - return unsafe _getMainExecutorAsSerialExecutor() + if #available(StdlibDeploymentTarget 6.3, *) { + return unsafe _getMainExecutorAsSerialExecutor() + } else { + fatalError("this should never happen") + } } @available(SwiftStdlib 6.2, *) @_silgen_name("swift_task_enqueueMainExecutorImpl") internal func enqueueOnMainExecutor(job unownedJob: UnownedJob) { #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - MainActor.executor.enqueue(unownedJob) + if #available(StdlibDeploymentTarget 6.3, *) { + MainActor.executor.enqueue(unownedJob) + } else { + fatalError("this should never happen") + } #else fatalError("swift_task_enqueueMainExecutor() not supported for task-to-thread") #endif From 748ba0516198273e9708736710abd4959687e8c1 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Tue, 18 Nov 2025 12:08:46 +0000 Subject: [PATCH 5/5] [Concurrency][Tests] Bump availability in a couple of tests. Since we've bumped availability elsewhere, we need to bump these tests also. --- test/Concurrency/Runtime/isolated_conformance.swift | 2 +- test/Concurrency/Runtime/sleep_executor.swift | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Concurrency/Runtime/isolated_conformance.swift b/test/Concurrency/Runtime/isolated_conformance.swift index 609bd3a8c22..0399f4764b9 100644 --- a/test/Concurrency/Runtime/isolated_conformance.swift +++ b/test/Concurrency/Runtime/isolated_conformance.swift @@ -203,7 +203,7 @@ await Task.detached { @SomeGlobalActor in // CHECK: Testing a separate task off the main actor print("Testing a separate task off the main actor") await Task.detached { - if #available(SwiftStdlib 6.2, *) { + if #available(SwiftStdlib 6.3, *) { // Skip tests on platforms that use the same executor for the main // actor and the global concurrent executor. guard Task.defaultExecutor !== MainActor.executor else { return } diff --git a/test/Concurrency/Runtime/sleep_executor.swift b/test/Concurrency/Runtime/sleep_executor.swift index d911a71eb93..bd2a75781ba 100644 --- a/test/Concurrency/Runtime/sleep_executor.swift +++ b/test/Concurrency/Runtime/sleep_executor.swift @@ -15,14 +15,14 @@ import Dispatch import StdlibUnittest -@available(SwiftStdlib 6.2, *) +@available(SwiftStdlib 6.3, *) actor MyActor { public func doSleep() async { try! await Task.sleep(for: .seconds(0.1)) } } -@available(SwiftStdlib 6.2, *) +@available(SwiftStdlib 6.3, *) final class TestExecutor: TaskExecutor, SchedulingExecutor, @unchecked Sendable { var asScheduling: SchedulingExecutor? { return self @@ -58,7 +58,7 @@ final class TestExecutor: TaskExecutor, SchedulingExecutor, @unchecked Sendable } } -@available(SwiftStdlib 6.2, *) +@available(SwiftStdlib 6.3, *) @main struct Main { static func main() async { let tests = TestSuite("sleep_executor")