Skip to content

Cleanup Sendable conformances and @preconcurrency imports to build as strict concurrency clean #230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Sources/AsyncAlgorithms/AsyncBufferSequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ public actor AsyncLimitBuffer<Element: Sendable>: AsyncBuffer {
}
}

extension AsyncSequence where Element: Sendable {
extension AsyncSequence where Element: Sendable, Self: Sendable {
/// Creates an asynchronous sequence that buffers elements using a buffer created from a supplied closure.
///
/// Use the `buffer(_:)` method to account for `AsyncSequence` types that may produce elements faster
Expand All @@ -224,7 +224,7 @@ extension AsyncSequence where Element: Sendable {
}

/// An `AsyncSequence` that buffers elements utilizing an `AsyncBuffer`.
public struct AsyncBufferSequence<Base: AsyncSequence, Buffer: AsyncBuffer> where Base.Element == Buffer.Input, Base.AsyncIterator: Sendable {
public struct AsyncBufferSequence<Base: AsyncSequence & Sendable, Buffer: AsyncBuffer> where Base.Element == Buffer.Input {
let base: Base
let createBuffer: @Sendable () -> Buffer

Expand All @@ -246,11 +246,11 @@ extension AsyncBufferSequence: AsyncSequence {
let buffer: Buffer
let state: AsyncBufferState<Buffer.Input, Buffer.Output>

init(_ iterator: Base.AsyncIterator, buffer: Buffer, state: AsyncBufferState<Buffer.Input, Buffer.Output>) {
init(_ base: Base, buffer: Buffer, state: AsyncBufferState<Buffer.Input, Buffer.Output>) {
self.buffer = buffer
self.state = state
task = Task {
var iter = iterator
var iter = base.makeAsyncIterator()
do {
while let item = try await iter.next() {
await state.enqueue(item, buffer: buffer)
Expand Down Expand Up @@ -279,21 +279,21 @@ extension AsyncBufferSequence: AsyncSequence {
}

enum State {
case idle(Base.AsyncIterator, @Sendable () -> Buffer)
case idle(Base, @Sendable () -> Buffer)
case active(Active)
}

var state: State

init(_ iterator: Base.AsyncIterator, createBuffer: @Sendable @escaping () -> Buffer) {
state = .idle(iterator, createBuffer)
init(_ base: Base, createBuffer: @Sendable @escaping () -> Buffer) {
state = .idle(base, createBuffer)
}

public mutating func next() async rethrows -> Element? {
switch state {
case .idle(let iterator, let createBuffer):
case .idle(let base, let createBuffer):
let bufferState = AsyncBufferState<Base.Element, Buffer.Output>()
let buffer = Active(iterator, buffer: createBuffer(), state: bufferState)
let buffer = Active(base, buffer: createBuffer(), state: bufferState)
state = .active(buffer)
return try await buffer.next()
case .active(let buffer):
Expand All @@ -303,6 +303,6 @@ extension AsyncBufferSequence: AsyncSequence {
}

public func makeAsyncIterator() -> Iterator {
Iterator(base.makeAsyncIterator(), createBuffer: createBuffer)
Iterator(base, createBuffer: createBuffer)
}
}
8 changes: 4 additions & 4 deletions Sources/AsyncAlgorithms/AsyncChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

import OrderedCollections
@preconcurrency import OrderedCollections

/// A channel for sending elements from one task to another with back pressure.
///
Expand Down Expand Up @@ -58,7 +58,7 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
typealias Pending = ChannelToken<UnsafeContinuation<UnsafeContinuation<Element?, Never>?, Never>>
typealias Awaiting = ChannelToken<UnsafeContinuation<Element?, Never>>

struct ChannelToken<Continuation>: Hashable {
struct ChannelToken<Continuation: Sendable>: Hashable, Sendable {
var generation: Int
var continuation: Continuation?

Expand Down Expand Up @@ -86,14 +86,14 @@ public final class AsyncChannel<Element: Sendable>: AsyncSequence, Sendable {
case cancelled
}

enum Emission {
enum Emission : Sendable {
case idle
case pending(OrderedSet<Pending>)
case awaiting(OrderedSet<Awaiting>)
case finished
}

struct State {
struct State : Sendable {
var emission: Emission = .idle
var generation = 0
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/AsyncAlgorithms/AsyncCompactedSequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ extension AsyncSequence {
}
}

extension AsyncCompactedSequence: Sendable where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }
extension AsyncCompactedSequence: Sendable where Base: Sendable, Base.Element: Sendable { }
2 changes: 1 addition & 1 deletion Sources/AsyncAlgorithms/AsyncInterspersedSequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ extension AsyncInterspersedSequence: AsyncSequence {
}
}

extension AsyncInterspersedSequence: Sendable where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }
extension AsyncInterspersedSequence: Sendable where Base: Sendable, Base.Element: Sendable { }
2 changes: 1 addition & 1 deletion Sources/AsyncAlgorithms/AsyncJoinedSequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,4 @@ public struct AsyncJoinedSequence<Base: AsyncSequence>: AsyncSequence where Base
}

extension AsyncJoinedSequence: Sendable
where Base: Sendable, Base.Element: Sendable, Base.Element.Element: Sendable, Base.AsyncIterator: Sendable, Base.Element.AsyncIterator: Sendable { }
where Base: Sendable, Base.Element: Sendable, Base.Element.Element: Sendable { }
7 changes: 3 additions & 4 deletions Sources/AsyncAlgorithms/AsyncRemoveDuplicatesSequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ public struct AsyncRemoveDuplicatesSequence<Base: AsyncSequence>: AsyncSequence
}
}

extension AsyncRemoveDuplicatesSequence: Sendable where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }


/// An asynchronous sequence that omits repeated elements by testing them with an error-throwing predicate.
public struct AsyncThrowingRemoveDuplicatesSequence<Base: AsyncSequence>: AsyncSequence {
public typealias Element = Base.Element
Expand Down Expand Up @@ -143,4 +140,6 @@ public struct AsyncThrowingRemoveDuplicatesSequence<Base: AsyncSequence>: AsyncS
}
}

extension AsyncThrowingRemoveDuplicatesSequence: Sendable where Base: Sendable, Base.Element: Sendable, Base.AsyncIterator: Sendable { }

extension AsyncRemoveDuplicatesSequence: Sendable where Base: Sendable, Base.Element: Sendable { }
extension AsyncThrowingRemoveDuplicatesSequence: Sendable where Base: Sendable, Base.Element: Sendable { }
8 changes: 4 additions & 4 deletions Sources/AsyncAlgorithms/AsyncThrowingChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

import OrderedCollections
@preconcurrency import OrderedCollections
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should mark these as @_implementationOnly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, I consider it a best practice nowadays to mark every import as @_implementationOnly it really should be the default.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will follow-up with an additional audit of those


/// An error-throwing channel for sending elements from on task to another with back pressure.
///
Expand Down Expand Up @@ -61,7 +61,7 @@ public final class AsyncThrowingChannel<Element: Sendable, Failure: Error>: Asyn
typealias Pending = ChannelToken<UnsafeContinuation<UnsafeContinuation<Element?, Error>?, Never>>
typealias Awaiting = ChannelToken<UnsafeContinuation<Element?, Error>>

struct ChannelToken<Continuation>: Hashable {
struct ChannelToken<Continuation: Sendable>: Hashable, Sendable {
var generation: Int
var continuation: Continuation?

Expand Down Expand Up @@ -95,14 +95,14 @@ public final class AsyncThrowingChannel<Element: Sendable, Failure: Error>: Asyn
case failed(Error)
}

enum Emission {
enum Emission: Sendable {
case idle
case pending(OrderedSet<Pending>)
case awaiting(OrderedSet<Awaiting>)
case terminated(Termination)
}

struct State {
struct State : Sendable {
var emission: Emission = .idle
var generation = 0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public func combineLatest<
public struct AsyncCombineLatest2Sequence<
Base1: AsyncSequence,
Base2: AsyncSequence
>: AsyncSequence where
>: AsyncSequence, Sendable where
Base1: Sendable,
Base1.Element: Sendable,
Base2: Sendable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public struct AsyncCombineLatest3Sequence<
Base1: AsyncSequence,
Base2: AsyncSequence,
Base3: AsyncSequence
>: AsyncSequence where
>: AsyncSequence, Sendable where
Base1: Sendable,
Base1.Element: Sendable,
Base2: Sendable,
Expand Down
2 changes: 1 addition & 1 deletion Sources/AsyncAlgorithms/Zip/AsyncZip2Sequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public func zip<Base1: AsyncSequence, Base2: AsyncSequence>(

/// An asynchronous sequence that concurrently awaits values from two `AsyncSequence` types
/// and emits a tuple of the values.
public struct AsyncZip2Sequence<Base1: AsyncSequence, Base2: AsyncSequence>: AsyncSequence
public struct AsyncZip2Sequence<Base1: AsyncSequence, Base2: AsyncSequence>: AsyncSequence, Sendable
where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element: Sendable {
public typealias Element = (Base1.Element, Base2.Element)
public typealias AsyncIterator = Iterator
Expand Down
2 changes: 1 addition & 1 deletion Sources/AsyncAlgorithms/Zip/AsyncZip3Sequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public func zip<Base1: AsyncSequence, Base2: AsyncSequence, Base3: AsyncSequence

/// An asynchronous sequence that concurrently awaits values from three `AsyncSequence` types
/// and emits a tuple of the values.
public struct AsyncZip3Sequence<Base1: AsyncSequence, Base2: AsyncSequence, Base3: AsyncSequence>: AsyncSequence
public struct AsyncZip3Sequence<Base1: AsyncSequence, Base2: AsyncSequence, Base3: AsyncSequence>: AsyncSequence, Sendable
where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element: Sendable, Base3: Sendable, Base3.Element: Sendable {
public typealias Element = (Base1.Element, Base2.Element, Base3.Element)
public typealias AsyncIterator = Iterator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import AsyncAlgorithms
import Foundation
@preconcurrency import XCTest
import XCTest

#if canImport(Darwin)
public struct InfiniteAsyncSequence<Value: Sendable>: AsyncSequence, Sendable {
Expand Down
2 changes: 1 addition & 1 deletion Tests/AsyncAlgorithmsTests/Support/ReportingSequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ final class ReportingSequence<Element>: Sequence, IteratorProtocol {
}
}

final class ReportingAsyncSequence<Element>: AsyncSequence, AsyncIteratorProtocol {
final class ReportingAsyncSequence<Element: Sendable>: AsyncSequence, AsyncIteratorProtocol, @unchecked Sendable {
enum Event: Equatable, CustomStringConvertible {
case next
case makeAsyncIterator
Expand Down
2 changes: 1 addition & 1 deletion Tests/AsyncAlgorithmsTests/TestAdjacentPairs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

@preconcurrency import XCTest
import XCTest
import AsyncAlgorithms

final class TestAdjacentPairs: XCTestCase {
Expand Down
Loading