Skip to content

Commit 0df324b

Browse files
MaxDesiatovfurby-tm
authored andcommitted
Enable strict concurrency checks on Basics module (swiftlang#7451)
Also refactored `URLSessionHTTPClient` to remove `weak` references, which were incompatible with strict concurrency checks.
1 parent 21c9d7e commit 0df324b

14 files changed

+88
-181
lines changed

Package.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ let systemSQLitePkgConfig: String? = "sqlite3"
8181
*/
8282
let autoProducts = [swiftPMProduct, swiftPMDataModelProduct]
8383

84-
8584
let packageModelResourcesSettings: [SwiftSetting]
8685
let packageModelResources: [Resource]
8786
if ProcessInfo.processInfo.environment["SWIFTPM_USE_LIBRARIES_METADATA"] == nil {
@@ -193,7 +192,10 @@ let package = Package(
193192
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
194193
.product(name: "SystemPackage", package: "swift-system"),
195194
],
196-
exclude: ["CMakeLists.txt", "Vendor/README.md"]
195+
exclude: ["CMakeLists.txt", "Vendor/README.md"],
196+
swiftSettings: [
197+
.enableExperimentalFeature("StrictConcurrency"),
198+
]
197199
),
198200

199201
.target(
@@ -701,7 +703,7 @@ package.targets.append(contentsOf: [
701703
name: "FunctionalPerformanceTests",
702704
dependencies: [
703705
"swift-package-manager",
704-
"SPMTestSupport"
706+
"SPMTestSupport",
705707
]
706708
),
707709
])

Sources/Basics/Archiver/Archiver.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import _Concurrency
1414

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

@@ -27,7 +27,7 @@ public protocol Archiver {
2727
func extract(
2828
from archivePath: AbsolutePath,
2929
to destinationPath: AbsolutePath,
30-
completion: @escaping (Result<Void, Error>) -> Void
30+
completion: @escaping @Sendable (Result<Void, Error>) -> Void
3131
)
3232

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

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

@@ -65,8 +65,8 @@ extension Archiver {
6565
from archivePath: AbsolutePath,
6666
to destinationPath: AbsolutePath
6767
) async throws {
68-
try await withCheckedThrowingContinuation {
69-
self.extract(from: archivePath, to: destinationPath, completion: $0.resume(with:))
68+
try await withCheckedThrowingContinuation { continuation in
69+
self.extract(from: archivePath, to: destinationPath, completion: { continuation.resume(with: $0) })
7070
}
7171
}
7272

@@ -79,8 +79,8 @@ extension Archiver {
7979
directory: AbsolutePath,
8080
to destinationPath: AbsolutePath
8181
) async throws {
82-
try await withCheckedThrowingContinuation {
83-
self.compress(directory: directory, to: destinationPath, completion: $0.resume(with:))
82+
try await withCheckedThrowingContinuation { continuation in
83+
self.compress(directory: directory, to: destinationPath, completion: { continuation.resume(with: $0) })
8484
}
8585
}
8686

@@ -91,8 +91,8 @@ extension Archiver {
9191
public func validate(
9292
path: AbsolutePath
9393
) async throws -> Bool {
94-
try await withCheckedThrowingContinuation {
95-
self.validate(path: path, completion: $0.resume(with:))
94+
try await withCheckedThrowingContinuation { continuation in
95+
self.validate(path: path, completion: { continuation.resume(with: $0) })
9696
}
9797
}
9898
}

Sources/Basics/Archiver/TarArchiver.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public struct TarArchiver: Archiver {
4747
public func extract(
4848
from archivePath: AbsolutePath,
4949
to destinationPath: AbsolutePath,
50-
completion: @escaping (Result<Void, Error>) -> Void
50+
completion: @escaping @Sendable (Result<Void, Error>) -> Void
5151
) {
5252
do {
5353
guard self.fileSystem.exists(archivePath) else {
@@ -84,7 +84,7 @@ public struct TarArchiver: Archiver {
8484
public func compress(
8585
directory: AbsolutePath,
8686
to destinationPath: AbsolutePath,
87-
completion: @escaping (Result<Void, Error>) -> Void
87+
completion: @escaping @Sendable (Result<Void, Error>) -> Void
8888
) {
8989
do {
9090
guard self.fileSystem.isDirectory(directory) else {
@@ -115,7 +115,7 @@ public struct TarArchiver: Archiver {
115115
}
116116
}
117117

118-
public func validate(path: AbsolutePath, completion: @escaping (Result<Bool, Error>) -> Void) {
118+
public func validate(path: AbsolutePath, completion: @escaping @Sendable (Result<Bool, Error>) -> Void) {
119119
do {
120120
guard self.fileSystem.exists(path) else {
121121
throw FileSystemError(.noEntry, path.underlying)

Sources/Basics/Archiver/UniversalArchiver.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public struct UniversalArchiver: Archiver {
7373
public func extract(
7474
from archivePath: AbsolutePath,
7575
to destinationPath: AbsolutePath,
76-
completion: @escaping (Result<Void, Swift.Error>) -> Void
76+
completion: @escaping @Sendable (Result<Void, Swift.Error>) -> Void
7777
) {
7878
do {
7979
let archiver = try archiver(for: archivePath)
@@ -86,7 +86,7 @@ public struct UniversalArchiver: Archiver {
8686
public func compress(
8787
directory: AbsolutePath,
8888
to destinationPath: AbsolutePath,
89-
completion: @escaping (Result<Void, Swift.Error>) -> Void
89+
completion: @escaping @Sendable (Result<Void, Swift.Error>) -> Void
9090
) {
9191
do {
9292
let archiver = try archiver(for: destinationPath)
@@ -98,7 +98,7 @@ public struct UniversalArchiver: Archiver {
9898

9999
public func validate(
100100
path: AbsolutePath,
101-
completion: @escaping (Result<Bool, Swift.Error>) -> Void
101+
completion: @escaping @Sendable (Result<Bool, Swift.Error>) -> Void
102102
) {
103103
do {
104104
let archiver = try archiver(for: path)

Sources/Basics/Archiver/ZipArchiver.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public struct ZipArchiver: Archiver, Cancellable {
3737
public func extract(
3838
from archivePath: AbsolutePath,
3939
to destinationPath: AbsolutePath,
40-
completion: @escaping (Result<Void, Error>) -> Void
40+
completion: @escaping @Sendable (Result<Void, Error>) -> Void
4141
) {
4242
do {
4343
guard self.fileSystem.exists(archivePath) else {
@@ -77,7 +77,7 @@ public struct ZipArchiver: Archiver, Cancellable {
7777
public func compress(
7878
directory: AbsolutePath,
7979
to destinationPath: AbsolutePath,
80-
completion: @escaping (Result<Void, Error>) -> Void
80+
completion: @escaping @Sendable (Result<Void, Error>) -> Void
8181
) {
8282
do {
8383
guard self.fileSystem.isDirectory(directory) else {
@@ -125,7 +125,7 @@ public struct ZipArchiver: Archiver, Cancellable {
125125
}
126126
}
127127

128-
public func validate(path: AbsolutePath, completion: @escaping (Result<Bool, Error>) -> Void) {
128+
public func validate(path: AbsolutePath, completion: @escaping @Sendable (Result<Bool, Error>) -> Void) {
129129
do {
130130
guard self.fileSystem.exists(path) else {
131131
throw FileSystemError(.noEntry, path.underlying)

Sources/Basics/Cancellator.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import class TSCBasic.Thread
1818
import WinSDK
1919
#endif
2020

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

23-
public final class Cancellator: Cancellable {
23+
public final class Cancellator: Cancellable, Sendable {
2424
public typealias RegistrationKey = String
2525

2626
private let observabilityScope: ObservabilityScope?
@@ -119,7 +119,7 @@ public final class Cancellator: Cancellable {
119119
}
120120

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

Sources/Basics/Concurrency/ConcurrencyHelpers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public func safe_async<T, ErrorType: Error>(
6464
}
6565

6666
/// Bridges between potentially blocking methods that take a result completion closure and async/await
67-
public func safe_async<T>(_ body: @escaping (@escaping (Result<T, Never>) -> Void) -> Void) async -> T {
67+
public func safe_async<T>(_ body: @escaping @Sendable (@escaping (Result<T, Never>) -> Void) -> Void) async -> T {
6868
await withCheckedContinuation { continuation in
6969
// It is possible that body make block indefinitely on a lock, semaphore,
7070
// or similar then synchronously call the completion handler. For full safety

Sources/Basics/Concurrency/TokenBucket.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public actor TokenBucket {
3030
/// invocations of `withToken` will suspend until a "free" token is available.
3131
/// - Parameter body: The closure to invoke when a token is available.
3232
/// - Returns: Resulting value returned by `body`.
33-
public func withToken<ReturnType>(
33+
public func withToken<ReturnType: Sendable>(
3434
_ body: @Sendable () async throws -> ReturnType
3535
) async rethrows -> ReturnType {
3636
await self.getToken()

Sources/Basics/FileSystem/FileSystem+Extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import var TSCBasic.localFileSystem
2525
import protocol TSCBasic.WritableByteStream
2626

2727
public typealias FileSystem = TSCBasic.FileSystem
28-
public var localFileSystem = TSCBasic.localFileSystem
28+
public let localFileSystem = TSCBasic.localFileSystem
2929

3030
// MARK: - Custom path
3131

Sources/Basics/FileSystem/TemporaryFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public func withTemporaryDirectory<Result>(
7272
dir: AbsolutePath? = nil,
7373
prefix: String = "TemporaryDirectory",
7474
removeTreeOnDeinit: Bool = false,
75-
_ body: @escaping (AbsolutePath) async throws -> Result
75+
_ body: @escaping @Sendable (AbsolutePath) async throws -> Result
7676
) throws -> Task<Result, Error> {
7777
try withTemporaryDirectory(fileSystem: fileSystem, dir: dir, prefix: prefix) { path, cleanup in
7878
defer { if removeTreeOnDeinit { cleanup(path) } }

Sources/Basics/HTTPClient/LegacyHTTPClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public final class LegacyHTTPClient: Cancellable {
2525
public typealias Configuration = LegacyHTTPClientConfiguration
2626
public typealias Request = LegacyHTTPClientRequest
2727
public typealias Response = HTTPClientResponse
28-
public typealias Handler = (Request, ProgressHandler?, @escaping (Result<Response, Error>) -> Void) -> Void
28+
public typealias Handler = (Request, ProgressHandler?, @escaping @Sendable (Result<Response, Error>) -> Void) -> Void
2929
public typealias ProgressHandler = @Sendable (_ bytesReceived: Int64, _ totalBytes: Int64?) throws -> Void
3030
public typealias CompletionHandler = @Sendable (Result<HTTPClientResponse, Error>) -> Void
3131

0 commit comments

Comments
 (0)