Skip to content

Commit

Permalink
Enable strict concurrency checks on Basics module (swiftlang#7451)
Browse files Browse the repository at this point in the history
Also refactored `URLSessionHTTPClient` to remove `weak` references,
which were incompatible with strict concurrency checks.

(cherry picked from commit f249153)
  • Loading branch information
MaxDesiatov authored and bnbarham committed May 18, 2024
1 parent ea779ee commit 49e47f9
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 181 deletions.
8 changes: 5 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ automatic linking type with `-auto` suffix appended to product's name.
*/
let autoProducts = [swiftPMProduct, swiftPMDataModelProduct]


let packageModelResourcesSettings: [SwiftSetting]
let packageModelResources: [Resource]
if ProcessInfo.processInfo.environment["SWIFTPM_USE_LIBRARIES_METADATA"] == nil {
Expand Down Expand Up @@ -186,7 +185,10 @@ let package = Package(
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
.product(name: "SystemPackage", package: "swift-system"),
],
exclude: ["CMakeLists.txt", "Vendor/README.md"]
exclude: ["CMakeLists.txt", "Vendor/README.md"],
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency"),
]
),

.target(
Expand Down Expand Up @@ -717,7 +719,7 @@ package.targets.append(contentsOf: [
name: "FunctionalPerformanceTests",
dependencies: [
"swift-package-manager",
"SPMTestSupport"
"SPMTestSupport",
]
),
])
Expand Down
20 changes: 10 additions & 10 deletions Sources/Basics/Archiver/Archiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import _Concurrency

/// The `Archiver` protocol abstracts away the different operations surrounding archives.
public protocol Archiver {
public protocol Archiver: Sendable {
/// A set of extensions the current archiver supports.
var supportedExtensions: Set<String> { get }

Expand All @@ -27,7 +27,7 @@ public protocol Archiver {
func extract(
from archivePath: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
completion: @escaping @Sendable (Result<Void, Error>) -> Void
)

/// Asynchronously compress the contents of a directory to a destination archive.
Expand All @@ -40,7 +40,7 @@ public protocol Archiver {
func compress(
directory: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
completion: @escaping @Sendable (Result<Void, Error>) -> Void
)

/// Asynchronously validates if a file is an archive.
Expand All @@ -51,7 +51,7 @@ public protocol Archiver {
@available(*, noasync, message: "Use the async alternative")
func validate(
path: AbsolutePath,
completion: @escaping (Result<Bool, Error>) -> Void
completion: @escaping @Sendable (Result<Bool, Error>) -> Void
)
}

Expand All @@ -65,8 +65,8 @@ extension Archiver {
from archivePath: AbsolutePath,
to destinationPath: AbsolutePath
) async throws {
try await withCheckedThrowingContinuation {
self.extract(from: archivePath, to: destinationPath, completion: $0.resume(with:))
try await withCheckedThrowingContinuation { continuation in
self.extract(from: archivePath, to: destinationPath, completion: { continuation.resume(with: $0) })
}
}

Expand All @@ -79,8 +79,8 @@ extension Archiver {
directory: AbsolutePath,
to destinationPath: AbsolutePath
) async throws {
try await withCheckedThrowingContinuation {
self.compress(directory: directory, to: destinationPath, completion: $0.resume(with:))
try await withCheckedThrowingContinuation { continuation in
self.compress(directory: directory, to: destinationPath, completion: { continuation.resume(with: $0) })
}
}

Expand All @@ -91,8 +91,8 @@ extension Archiver {
public func validate(
path: AbsolutePath
) async throws -> Bool {
try await withCheckedThrowingContinuation {
self.validate(path: path, completion: $0.resume(with:))
try await withCheckedThrowingContinuation { continuation in
self.validate(path: path, completion: { continuation.resume(with: $0) })
}
}
}
6 changes: 3 additions & 3 deletions Sources/Basics/Archiver/TarArchiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public struct TarArchiver: Archiver {
public func extract(
from archivePath: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
completion: @escaping @Sendable (Result<Void, Error>) -> Void
) {
do {
guard self.fileSystem.exists(archivePath) else {
Expand Down Expand Up @@ -84,7 +84,7 @@ public struct TarArchiver: Archiver {
public func compress(
directory: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
completion: @escaping @Sendable (Result<Void, Error>) -> Void
) {
do {
guard self.fileSystem.isDirectory(directory) else {
Expand Down Expand Up @@ -115,7 +115,7 @@ public struct TarArchiver: Archiver {
}
}

public func validate(path: AbsolutePath, completion: @escaping (Result<Bool, Error>) -> Void) {
public func validate(path: AbsolutePath, completion: @escaping @Sendable (Result<Bool, Error>) -> Void) {
do {
guard self.fileSystem.exists(path) else {
throw FileSystemError(.noEntry, path.underlying)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Basics/Archiver/UniversalArchiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public struct UniversalArchiver: Archiver {
public func extract(
from archivePath: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Swift.Error>) -> Void
completion: @escaping @Sendable (Result<Void, Swift.Error>) -> Void
) {
do {
let archiver = try archiver(for: archivePath)
Expand All @@ -86,7 +86,7 @@ public struct UniversalArchiver: Archiver {
public func compress(
directory: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Swift.Error>) -> Void
completion: @escaping @Sendable (Result<Void, Swift.Error>) -> Void
) {
do {
let archiver = try archiver(for: destinationPath)
Expand All @@ -98,7 +98,7 @@ public struct UniversalArchiver: Archiver {

public func validate(
path: AbsolutePath,
completion: @escaping (Result<Bool, Swift.Error>) -> Void
completion: @escaping @Sendable (Result<Bool, Swift.Error>) -> Void
) {
do {
let archiver = try archiver(for: path)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Basics/Archiver/ZipArchiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public struct ZipArchiver: Archiver, Cancellable {
public func extract(
from archivePath: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
completion: @escaping @Sendable (Result<Void, Error>) -> Void
) {
do {
guard self.fileSystem.exists(archivePath) else {
Expand Down Expand Up @@ -77,7 +77,7 @@ public struct ZipArchiver: Archiver, Cancellable {
public func compress(
directory: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
completion: @escaping @Sendable (Result<Void, Error>) -> Void
) {
do {
guard self.fileSystem.isDirectory(directory) else {
Expand Down Expand Up @@ -125,7 +125,7 @@ public struct ZipArchiver: Archiver, Cancellable {
}
}

public func validate(path: AbsolutePath, completion: @escaping (Result<Bool, Error>) -> Void) {
public func validate(path: AbsolutePath, completion: @escaping @Sendable (Result<Bool, Error>) -> Void) {
do {
guard self.fileSystem.exists(path) else {
throw FileSystemError(.noEntry, path.underlying)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Basics/Cancellator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import class TSCBasic.Thread
import WinSDK
#endif

public typealias CancellationHandler = (DispatchTime) throws -> Void
public typealias CancellationHandler = @Sendable (DispatchTime) throws -> Void

public final class Cancellator: Cancellable {
public final class Cancellator: Cancellable, Sendable {
public typealias RegistrationKey = String

private let observabilityScope: ObservabilityScope?
Expand Down Expand Up @@ -119,7 +119,7 @@ public final class Cancellator: Cancellable {
}

@discardableResult
public func register(name: String, handler: @escaping () throws -> Void) -> RegistrationKey? {
public func register(name: String, handler: @escaping @Sendable () throws -> Void) -> RegistrationKey? {
self.register(name: name, handler: { _ in try handler() })
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Basics/Concurrency/ConcurrencyHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public func safe_async<T, ErrorType: Error>(
}

/// Bridges between potentially blocking methods that take a result completion closure and async/await
public func safe_async<T>(_ body: @escaping (@escaping (Result<T, Never>) -> Void) -> Void) async -> T {
public func safe_async<T>(_ body: @escaping @Sendable (@escaping (Result<T, Never>) -> Void) -> Void) async -> T {
await withCheckedContinuation { continuation in
// It is possible that body make block indefinitely on a lock, semaphore,
// or similar then synchronously call the completion handler. For full safety
Expand Down
2 changes: 1 addition & 1 deletion Sources/Basics/Concurrency/TokenBucket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public actor TokenBucket {
/// invocations of `withToken` will suspend until a "free" token is available.
/// - Parameter body: The closure to invoke when a token is available.
/// - Returns: Resulting value returned by `body`.
public func withToken<ReturnType>(
public func withToken<ReturnType: Sendable>(
_ body: @Sendable () async throws -> ReturnType
) async rethrows -> ReturnType {
await self.getToken()
Expand Down
2 changes: 1 addition & 1 deletion Sources/Basics/FileSystem/FileSystem+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import var TSCBasic.localFileSystem
import protocol TSCBasic.WritableByteStream

public typealias FileSystem = TSCBasic.FileSystem
public var localFileSystem = TSCBasic.localFileSystem
public let localFileSystem = TSCBasic.localFileSystem

// MARK: - Custom path

Expand Down
2 changes: 1 addition & 1 deletion Sources/Basics/FileSystem/TemporaryFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public func withTemporaryDirectory<Result>(
dir: AbsolutePath? = nil,
prefix: String = "TemporaryDirectory",
removeTreeOnDeinit: Bool = false,
_ body: @escaping (AbsolutePath) async throws -> Result
_ body: @escaping @Sendable (AbsolutePath) async throws -> Result
) throws -> Task<Result, Error> {
try withTemporaryDirectory(fileSystem: fileSystem, dir: dir, prefix: prefix) { path, cleanup in
defer { if removeTreeOnDeinit { cleanup(path) } }
Expand Down
2 changes: 1 addition & 1 deletion Sources/Basics/HTTPClient/LegacyHTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public final class LegacyHTTPClient: Cancellable {
public typealias Configuration = LegacyHTTPClientConfiguration
public typealias Request = LegacyHTTPClientRequest
public typealias Response = HTTPClientResponse
public typealias Handler = (Request, ProgressHandler?, @escaping (Result<Response, Error>) -> Void) -> Void
public typealias Handler = (Request, ProgressHandler?, @escaping @Sendable (Result<Response, Error>) -> Void) -> Void
public typealias ProgressHandler = @Sendable (_ bytesReceived: Int64, _ totalBytes: Int64?) throws -> Void
public typealias CompletionHandler = @Sendable (Result<HTTPClientResponse, Error>) -> Void

Expand Down
Loading

0 comments on commit 49e47f9

Please sign in to comment.