diff --git a/include/swift/AST/KnownSDKTypes.def b/include/swift/AST/KnownSDKTypes.def index f9d0c2a0c24c1..a281f059b3931 100644 --- a/include/swift/AST/KnownSDKTypes.def +++ b/include/swift/AST/KnownSDKTypes.def @@ -39,7 +39,8 @@ KNOWN_SDK_TYPE_DECL(ObjectiveC, ObjCBool, StructDecl, 0) // standardized KNOWN_SDK_TYPE_DECL(Concurrency, UnsafeContinuation, NominalTypeDecl, 2) KNOWN_SDK_TYPE_DECL(Concurrency, MainActor, NominalTypeDecl, 0) -KNOWN_SDK_TYPE_DECL(Concurrency, Job, StructDecl, 0) +KNOWN_SDK_TYPE_DECL(Concurrency, Job, StructDecl, 0) // TODO: remove in favor of ExecutorJob +KNOWN_SDK_TYPE_DECL(Concurrency, ExecutorJob, StructDecl, 0) KNOWN_SDK_TYPE_DECL(Concurrency, UnownedJob, StructDecl, 0) KNOWN_SDK_TYPE_DECL(Concurrency, Executor, NominalTypeDecl, 0) KNOWN_SDK_TYPE_DECL(Concurrency, SerialExecutor, NominalTypeDecl, 0) diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 198486725663a..4dd2ef0eed0ea 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -1266,7 +1266,7 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C, auto module = nominal->getParentModule(); Type nominalTy = nominal->getDeclaredInterfaceType(); - // enqueue(_: UnownedJob) + // enqueue(_:) auto enqueueDeclName = DeclName(C, DeclBaseName(C.Id_enqueue), { Identifier() }); FuncDecl *unownedEnqueueRequirement = nullptr; @@ -1283,8 +1283,16 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C, if (funcDecl->getParameters()->size() != 1) continue; if (auto param = funcDecl->getParameters()->front()) { - if (C.getJobDecl() && - param->getType()->isEqual(C.getJobDecl()->getDeclaredInterfaceType())) { + StructDecl* jobDecl; + if (auto decl = C.getExecutorJobDecl()) { + jobDecl = decl; + } else if (auto decl = C.getJobDecl()) { + // old standard library, before we introduced the `typealias Job = ExecutorJob` + jobDecl = decl; + } + + if (jobDecl && + param->getType()->isEqual(jobDecl->getDeclaredInterfaceType())) { assert(moveOnlyEnqueueRequirement == nullptr); moveOnlyEnqueueRequirement = funcDecl; } else if (param->getType()->isEqual(C.getUnownedJobDecl()->getDeclaredInterfaceType())) { diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index 49c1390dddc4e..6b2185355d17b 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -17,16 +17,16 @@ import Swift public protocol Executor: AnyObject, Sendable { #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - @available(macOS, introduced: 10.15, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") - @available(iOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") - @available(watchOS, introduced: 6.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") - @available(tvOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") + @available(macOS, introduced: 10.15, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") + @available(iOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") + @available(watchOS, introduced: 6.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") + @available(tvOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY func enqueue(_ job: UnownedJob) #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY @available(SwiftStdlib 5.9, *) - func enqueue(_ job: __owned Job) + func enqueue(_ job: __owned ExecutorJob) #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY } @@ -39,10 +39,10 @@ public protocol SerialExecutor: Executor { // work-scheduling operation. @_nonoverride #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY - @available(macOS, introduced: 10.15, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") - @available(iOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") - @available(watchOS, introduced: 6.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") - @available(tvOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned Job)' instead") + @available(macOS, introduced: 10.15, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") + @available(iOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") + @available(watchOS, introduced: 6.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") + @available(tvOS, introduced: 13.0, deprecated: 9999, message: "Implement 'enqueue(_: __owned ExecutorJob)' instead") #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY func enqueue(_ job: UnownedJob) @@ -53,7 +53,7 @@ public protocol SerialExecutor: Executor { // work-scheduling operation. @_nonoverride @available(SwiftStdlib 5.9, *) - func enqueue(_ job: __owned Job) + func enqueue(_ job: __owned ExecutorJob) #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY /// Convert this executor value to the optimized form of borrowed @@ -87,10 +87,10 @@ public protocol SerialExecutor: Executor { @available(SwiftStdlib 5.9, *) extension Executor { public func enqueue(_ job: UnownedJob) { - self.enqueue(Job(job)) + self.enqueue(ExecutorJob(job)) } - public func enqueue(_ job: __owned Job) { + public func enqueue(_ job: __owned ExecutorJob) { self.enqueue(UnownedJob(job)) } } @@ -219,10 +219,10 @@ func _checkExpectedExecutor(_filenameStart: Builtin.RawPointer, /// Primarily a debug utility. /// -/// If the passed in Job is a Task, returns the complete 64bit TaskId, +/// If the passed in ExecutorJob is a Task, returns the complete 64bit TaskId, /// otherwise returns only the job's 32bit Id. /// -/// - Returns: the Id stored in this Job or Task, for purposes of debug printing +/// - Returns: the Id stored in this ExecutorJob or Task, for purposes of debug printing @available(SwiftStdlib 5.9, *) @_silgen_name("swift_task_getJobTaskId") internal func _getJobTaskId(_ job: UnownedJob) -> UInt64 @@ -250,7 +250,7 @@ internal func _enqueueOnExecutor(job unownedJob: UnownedJob, executor: E) where E: SerialExecutor { #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY if #available(SwiftStdlib 5.9, *) { - executor.enqueue(Job(context: unownedJob._context)) + executor.enqueue(ExecutorJob(context: unownedJob._context)) } else { executor.enqueue(unownedJob) } diff --git a/stdlib/public/Concurrency/PartialAsyncTask.swift b/stdlib/public/Concurrency/PartialAsyncTask.swift index cd0482124521b..5f375b965af61 100644 --- a/stdlib/public/Concurrency/PartialAsyncTask.swift +++ b/stdlib/public/Concurrency/PartialAsyncTask.swift @@ -13,7 +13,7 @@ import Swift @_implementationOnly import _SwiftConcurrencyShims -// TODO(swift): rename the file to Job.swift eventually, we don't use PartialTask terminology anymore +// TODO(swift): rename the file to ExecutorJob.swift eventually, we don't use PartialTask terminology anymore @available(SwiftStdlib 5.1, *) @_silgen_name("swift_job_run") @@ -65,7 +65,7 @@ public struct UnownedJob: Sendable { /// Deprecated API to run a job on a specific executor. @_alwaysEmitIntoClient @inlinable - @available(*, deprecated, renamed: "Job.runSynchronously(on:)") + @available(*, deprecated, renamed: "ExecutorJob.runSynchronously(on:)") public func _runSynchronously(on executor: UnownedSerialExecutor) { _swiftJobRun(self, executor) } @@ -105,6 +105,11 @@ extension UnownedJob: CustomStringConvertible { } #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY + +@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *) +@available(*, deprecated, renamed: "ExecutorJob") +public typealias Job = ExecutorJob + /// A unit of scheduleable work. /// /// Unless you're implementing a scheduler, @@ -112,7 +117,7 @@ extension UnownedJob: CustomStringConvertible { @available(SwiftStdlib 5.9, *) @frozen @_moveOnly -public struct Job: Sendable { +public struct ExecutorJob: Sendable { internal var context: Builtin.Job @usableFromInline @@ -145,7 +150,7 @@ public struct Job: Sendable { } @available(SwiftStdlib 5.9, *) -extension Job { +extension ExecutorJob { /// Run this job on the passed in executor. /// @@ -158,7 +163,7 @@ extension Job { /// /// This operation consumes the job, preventing it accidental use after it has ben run. /// - /// Converting a `Job` to an ``UnownedJob`` and invoking ``UnownedJob/runSynchronously(_:)` on it multiple times is undefined behavior, + /// Converting a `ExecutorJob` to an ``UnownedJob`` and invoking ``UnownedJob/runSynchronously(_:)` on it multiple times is undefined behavior, /// as a job can only ever be run once, and must not be accessed after it has been run. /// /// - Parameter executor: the executor this job will be semantically running on. @@ -182,7 +187,7 @@ extension Job { /// However, the semantics of how priority is treated are left up to each /// platform and `Executor` implementation. /// -/// A Job's priority is roughly equivalent to a `TaskPriority`, +/// A ExecutorJob's priority is roughly equivalent to a `TaskPriority`, /// however, since not all jobs are tasks, represented as separate type. /// /// Conversions between the two priorities are available as initializers on the respective types. diff --git a/stdlib/public/Distributed/DistributedDefaultExecutor.swift b/stdlib/public/Distributed/DistributedDefaultExecutor.swift index 770a734ca66af..b72ed28ff8fdd 100644 --- a/stdlib/public/Distributed/DistributedDefaultExecutor.swift +++ b/stdlib/public/Distributed/DistributedDefaultExecutor.swift @@ -26,7 +26,7 @@ internal final class DistributedRemoteActorReferenceExecutor: SerialExecutor { @inlinable public func enqueue(_ job: __owned Job) { let jobDescription = job.description - fatalError("Attempted to enqueue \(Job.self) (\(jobDescription)) on executor of remote distributed actor reference!") + fatalError("Attempted to enqueue \(ExecutorJob.self) (\(jobDescription)) on executor of remote distributed actor reference!") } public func asUnownedSerialExecutor() -> UnownedSerialExecutor { @@ -50,4 +50,4 @@ public func buildDefaultDistributedRemoteActorExecutor( _ actor: Act ) -> UnownedSerialExecutor where Act: DistributedActor { return DistributedRemoteActorReferenceExecutor.sharedUnownedExecutor -} \ No newline at end of file +} diff --git a/test/Concurrency/custom_executor_enqueue_impls.swift b/test/Concurrency/custom_executor_enqueue_impls.swift index b24d3dc159086..46db955cced2f 100644 --- a/test/Concurrency/custom_executor_enqueue_impls.swift +++ b/test/Concurrency/custom_executor_enqueue_impls.swift @@ -25,7 +25,7 @@ final class OldExecutor: SerialExecutor { /// That's why we do log the deprecation warning, people should use the move-only version. final class BothExecutor: SerialExecutor { func enqueue(_ job: UnownedJob) {} // expected-warning{{'Executor.enqueue(UnownedJob)' is deprecated as a protocol requirement; conform type 'BothExecutor' to 'Executor' by implementing 'func enqueue(Job)' instead}} - func enqueue(_ job: __owned Job) {} + func enqueue(_ job: __owned ExecutorJob) {} func asUnownedSerialExecutor() -> UnownedSerialExecutor { UnownedSerialExecutor(ordinary: self) @@ -45,7 +45,7 @@ final class NoneExecutor: SerialExecutor { // expected-error{{type 'NoneExecutor /// Just implementing the new signature causes no warnings, good. final class NewExecutor: SerialExecutor { - func enqueue(_ job: __owned Job) {} // no warnings + func enqueue(_ job: __owned ExecutorJob) {} // no warnings func asUnownedSerialExecutor() -> UnownedSerialExecutor { UnownedSerialExecutor(ordinary: self) diff --git a/test/Distributed/Runtime/distributed_actor_executor_asserts.swift b/test/Distributed/Runtime/distributed_actor_executor_asserts.swift index 0614a60e5f33a..d65ef585d242d 100644 --- a/test/Distributed/Runtime/distributed_actor_executor_asserts.swift +++ b/test/Distributed/Runtime/distributed_actor_executor_asserts.swift @@ -83,7 +83,7 @@ actor EnqueueTest { } tests.test("remote actor reference should have crash-on-enqueue executor") { - expectCrashLater(withMessage: "Attempted to enqueue Job (Job(id: 1)) on executor of remote distributed actor reference!") + expectCrashLater(withMessage: "Attempted to enqueue ExecutorJob (ExecutorJob(id: 1)) on executor of remote distributed actor reference!") // we do the bad idea of taking an executor from a remote worker // and then force another actor to run on it; this will cause an enqueue on the "crash on enqueue" executor. let wrongUse = EnqueueTest(unownedExecutor: normalRemoteWorker.unownedExecutor)