diff --git a/Sources/Action.swift b/Sources/Action.swift
index b7c4076a3..3f542e3e7 100644
--- a/Sources/Action.swift
+++ b/Sources/Action.swift
@@ -116,7 +116,8 @@ public final class Action {
let isEnabled = MutableProperty(actionState.value.isEnabled)
self.isEnabled = Property(capturing: isEnabled)
- func modifyActionState(_ action: (inout ActionState) throws -> Result) rethrows -> Result {
+ @Sendable
+ func modifyActionState(_ action: @Sendable (inout ActionState) throws -> Result) rethrows -> Result {
return try actionState.begin { storage in
let oldState = storage.value
defer {
diff --git a/Sources/Atomic.swift b/Sources/Atomic.swift
index 96fd6775b..6778e35e8 100644
--- a/Sources/Atomic.swift
+++ b/Sources/Atomic.swift
@@ -14,7 +14,7 @@ import MachO
/// A simple, generic lock-free finite state machine.
///
/// - warning: `deinitialize` must be called to dispose of the consumed memory.
-internal struct UnsafeAtomicState where State.RawValue == Int32 {
+internal struct UnsafeAtomicState: Sendable where State.RawValue == Int32 {
internal typealias Transition = (expected: State, next: State)
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
private let value: UnsafeMutablePointer
@@ -29,6 +29,7 @@ internal struct UnsafeAtomicState where State.RawValue
}
/// Deinitialize the finite state machine.
+ @Sendable
internal func deinitialize() {
value.deinitialize(count: 1)
value.deallocate()
@@ -104,7 +105,8 @@ internal struct UnsafeAtomicState where State.RawValue
/// `Lock` exposes `os_unfair_lock` on supported platforms, with pthread mutex as the
/// fallback.
-internal class Lock: LockProtocol {
+// TODO: unckecked? subclass?
+internal class Lock: LockProtocol, @unchecked Sendable {
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
@available(iOS 10.0, *)
@available(macOS 10.12, *)
@@ -212,7 +214,7 @@ internal class Lock: LockProtocol {
func `try`() -> Bool { fatalError() }
}
-internal protocol LockProtocol {
+internal protocol LockProtocol: Sendable {
static func make() -> Self
func lock()
@@ -229,7 +231,7 @@ internal struct NoLock: LockProtocol {
}
/// An atomic variable.
-public final class Atomic {
+public final class Atomic: @unchecked Sendable {
private let lock: Lock
private var _value: Value
diff --git a/Sources/Bag.swift b/Sources/Bag.swift
index e38b92b04..f2e9a5079 100644
--- a/Sources/Bag.swift
+++ b/Sources/Bag.swift
@@ -10,7 +10,7 @@
public struct Bag {
/// A uniquely identifying token for removing a value that was inserted into a
/// Bag.
- public struct Token {
+ public struct Token: Sendable {
fileprivate let value: UInt64
}
@@ -97,3 +97,5 @@ extension Bag: RandomAccessCollection {
}
}
}
+
+extension Bag: Sendable where Element: Sendable {}
diff --git a/Sources/Disposable.swift b/Sources/Disposable.swift
index 4930c83cf..0d1569bc0 100644
--- a/Sources/Disposable.swift
+++ b/Sources/Disposable.swift
@@ -8,7 +8,7 @@
/// Represents something that can be “disposed”, usually associated with freeing
/// resources or canceling work.
-public protocol Disposable: AnyObject {
+public protocol Disposable: AnyObject, Sendable {
/// Whether this disposable has been disposed already.
var isDisposed: Bool { get }
@@ -16,6 +16,7 @@ public protocol Disposable: AnyObject {
/// been disposed of, it does nothing.
///
/// - note: Implementations must issue a memory barrier.
+ @Sendable
func dispose()
}
@@ -58,22 +59,22 @@ internal final class _SimpleDisposable: Disposable {
/// A disposable that has already been disposed.
internal final class NopDisposable: Disposable {
static let shared = NopDisposable()
- var isDisposed = true
+ let isDisposed = true
func dispose() {}
private init() {}
}
/// A type-erased disposable that forwards operations to an underlying disposable.
public final class AnyDisposable: Disposable {
- private final class ActionDisposable: Disposable {
+ private final class ActionDisposable: Disposable, @unchecked Sendable {
let state: UnsafeAtomicState
- var action: (() -> Void)?
+ var action: (@Sendable () -> Void)?
var isDisposed: Bool {
return state.is(.disposed)
}
- init(_ action: (() -> Void)?) {
+ init(_ action: (@Sendable () -> Void)?) {
self.state = UnsafeAtomicState(.active)
self.action = action
}
@@ -100,7 +101,7 @@ public final class AnyDisposable: Disposable {
///
/// - parameters:
/// - action: A closure to run when calling `dispose()`.
- public init(_ action: @escaping () -> Void) {
+ public init(_ action: @escaping @Sendable () -> Void) {
base = ActionDisposable(action)
}
@@ -123,7 +124,7 @@ public final class AnyDisposable: Disposable {
}
/// A disposable that will dispose of any number of other disposables.
-public final class CompositeDisposable: Disposable {
+public final class CompositeDisposable: Disposable, @unchecked Sendable {
private let disposables: Atomic?>
private var state: UnsafeAtomicState
@@ -203,7 +204,7 @@ public final class CompositeDisposable: Disposable {
/// composite has been disposed of, `disposable` has been disposed of, or
/// `disposable` is `nil`.
@discardableResult
- public func add(_ action: @escaping () -> Void) -> Disposable? {
+ public func add(_ action: @escaping @Sendable () -> Void) -> Disposable? {
return add(AnyDisposable(action))
}
@@ -246,7 +247,7 @@ public final class CompositeDisposable: Disposable {
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
/// remove the disposable later (if desired).
@discardableResult
- public static func += (lhs: CompositeDisposable, rhs: @escaping () -> Void) -> Disposable? {
+ public static func += (lhs: CompositeDisposable, rhs: @escaping @Sendable () -> Void) -> Disposable? {
return lhs.add(rhs)
}
}
@@ -325,7 +326,7 @@ extension ScopedDisposable where Inner == CompositeDisposable {
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
/// remove the disposable later (if desired).
@discardableResult
- public static func += (lhs: ScopedDisposable, rhs: @escaping () -> Void) -> Disposable? {
+ public static func += (lhs: ScopedDisposable, rhs: @escaping @Sendable () -> Void) -> Disposable? {
return lhs.inner.add(rhs)
}
}
@@ -334,7 +335,7 @@ extension ScopedDisposable where Inner == CompositeDisposable {
/// wrapped disposable to be replaced.
public final class SerialDisposable: Disposable {
private let _inner: Atomic
- private var state: UnsafeAtomicState
+ private let state: UnsafeAtomicState
public var isDisposed: Bool {
return state.is(.disposed)
diff --git a/Sources/Event.swift b/Sources/Event.swift
index c8137938f..bc93a5eec 100644
--- a/Sources/Event.swift
+++ b/Sources/Event.swift
@@ -206,27 +206,27 @@ extension Signal.Event: EventProtocol {
// This operator performs side effect upon interruption.
extension Signal.Event {
- internal typealias Transformation = (ReactiveSwift.Observer, Lifetime) -> ReactiveSwift.Observer
+ internal typealias Transformation = (any ReactiveSwift.Observer, Lifetime) -> (any ReactiveSwift.Observer)
- internal static func filter(_ isIncluded: @escaping (Value) -> Bool) -> Transformation {
+ internal static func filter(_ isIncluded: @escaping @Sendable (Value) -> Bool) -> Transformation {
return { downstream, _ in
Operators.Filter(downstream: downstream, predicate: isIncluded)
}
}
- internal static func compactMap(_ transform: @escaping (Value) -> U?) -> Transformation {
+ internal static func compactMap(_ transform: @escaping @Sendable (Value) -> U?) -> Transformation {
return { downstream, _ in
Operators.CompactMap(downstream: downstream, transform: transform)
}
}
- internal static func map(_ transform: @escaping (Value) -> U) -> Transformation {
+ internal static func map(_ transform: @escaping @Sendable (Value) -> U) -> Transformation {
return { downstream, _ in
Operators.Map(downstream: downstream, transform: transform)
}
}
- internal static func mapError(_ transform: @escaping (Error) -> E) -> Transformation {
+ internal static func mapError(_ transform: @escaping @Sendable (Error) -> E) -> Transformation {
return { downstream, _ in
Operators.MapError(downstream: downstream, transform: transform)
}
@@ -244,13 +244,13 @@ extension Signal.Event {
}
}
- internal static func attemptMap(_ transform: @escaping (Value) -> Result) -> Transformation {
+ internal static func attemptMap(_ transform: @escaping @Sendable (Value) -> Result) -> Transformation {
return { downstream, _ in
Operators.AttemptMap(downstream: downstream, transform: transform)
}
}
- internal static func attempt(_ action: @escaping (Value) -> Result<(), Error>) -> Transformation {
+ internal static func attempt(_ action: @escaping @Sendable (Value) -> Result<(), Error>) -> Transformation {
return attemptMap { value -> Result in
return action(value).map { _ in value }
}
@@ -285,13 +285,13 @@ extension Signal.Event {
}
}
- internal static func take(while shouldContinue: @escaping (Value) -> Bool) -> Transformation {
+ internal static func take(while shouldContinue: @escaping @Sendable (Value) -> Bool) -> Transformation {
return { downstream, _ in
Operators.TakeWhile(downstream: downstream, shouldContinue: shouldContinue)
}
}
- internal static func take(until shouldContinue: @escaping (Value) -> Bool) -> Transformation {
+ internal static func take(until shouldContinue: @escaping @Sendable (Value) -> Bool) -> Transformation {
return { downstream, _ in
Operators.TakeUntil(downstream: downstream, shouldContinue: shouldContinue)
}
@@ -397,7 +397,7 @@ extension Signal.Event {
return scan(into: initialResult) { $0 = nextPartialResult($0, $1) }
}
- internal static func scanMap(into initialState: State, _ next: @escaping (inout State, Value) -> U) -> Transformation {
+ internal static func scanMap(into initialState: State, _ next: @escaping @Sendable (inout State, Value) -> U) -> Transformation {
return { downstream, _ in
Operators.ScanMap(downstream: downstream, initial: initialState, next: next)
}
diff --git a/Sources/EventLogger.swift b/Sources/EventLogger.swift
index 16713d13b..4147c163d 100644
--- a/Sources/EventLogger.swift
+++ b/Sources/EventLogger.swift
@@ -31,7 +31,7 @@ public func defaultEventLog(identifier: String, event: String, fileName: String,
/// A type that represents an event logging function.
/// Signature is:
-/// - identifier
+/// - identifier
/// - event
/// - fileName
/// - functionName
@@ -52,14 +52,14 @@ fileprivate struct LogContext {
let functionName: String
let lineNumber: Int
let logger: EventLogger
-
- func log(_ event: Event) -> ((T) -> Void)? {
+
+ func log(_ event: Event) -> (@Sendable (T) -> Void)? {
return event.logIfNeeded(events: self.events) { event in
self.logger(self.identifier, event, self.fileName, self.functionName, self.lineNumber)
}
}
-
- func log(_ event: Event) -> (() -> Void)? {
+
+ func log(_ event: Event) -> (@Sendable () -> Void)? {
return event.logIfNeededNoArg(events: self.events) { event in
self.logger(self.identifier, event, self.fileName, self.functionName, self.lineNumber)
}
@@ -67,7 +67,7 @@ fileprivate struct LogContext {
}
extension Signal {
- /// Logs all events that the receiver sends. By default, it will print to
+ /// Logs all events that the receiver sends. By default, it will print to
/// the standard output.
///
/// - parameters:
@@ -80,14 +80,21 @@ extension Signal {
/// - logger: Logger that logs the events.
///
/// - returns: Signal that, when observed, logs the fired events.
- public func logEvents(identifier: String = "", events: Set = Set(LoggingEvent.Signal.allCases), fileName: String = #file, functionName: String = #function, lineNumber: Int = #line, logger: @escaping EventLogger = defaultEventLog) -> Signal {
+ public func logEvents(
+ identifier: String = "",
+ events: Set = Set(LoggingEvent.Signal.allCases),
+ fileName: String = #file,
+ functionName: String = #function,
+ lineNumber: Int = #line,
+ logger: @escaping EventLogger = defaultEventLog
+ ) -> Signal {
let logContext = LogContext(events: events,
identifier: identifier,
fileName: fileName,
functionName: functionName,
lineNumber: lineNumber,
logger: logger)
-
+
return self.on(
failed: logContext.log(.failed),
completed: logContext.log(.completed),
@@ -100,7 +107,7 @@ extension Signal {
}
extension SignalProducer {
- /// Logs all events that the receiver sends. By default, it will print to
+ /// Logs all events that the receiver sends. By default, it will print to
/// the standard output.
///
/// - parameters:
@@ -149,14 +156,14 @@ private extension LoggingEventProtocol {
// Due to differences in the type checker, this method cannot
// overload the generic `logIfNeeded`, or otherwise it would lead to
// infinite recursion with Swift 4.0.x.
- func logIfNeededNoArg(events: Set, logger: @escaping (String) -> Void) -> (() -> Void)? {
+ func logIfNeededNoArg(events: Set, logger: @escaping (String) -> Void) -> (@Sendable () -> Void)? {
return (self.logIfNeeded(events: events, logger: logger) as ((()) -> Void)?)
.map { closure in
- { closure(()) }
+ { @Sendable in closure(()) }
}
}
-
- func logIfNeeded(events: Set, logger: @escaping (String) -> Void) -> ((T) -> Void)? {
+
+ func logIfNeeded(events: Set, logger: @escaping (String) -> Void) -> (@Sendable (T) -> Void)? {
guard events.contains(self) else {
return nil
}
diff --git a/Sources/Flatten.swift b/Sources/Flatten.swift
index 658d790c3..d24c00a05 100644
--- a/Sources/Flatten.swift
+++ b/Sources/Flatten.swift
@@ -299,14 +299,14 @@ extension SignalProducer where Value: SignalProducerConvertible, Value.Error ==
extension Signal where Value: Sequence {
/// Flattens the `sequence` value sent by `signal`.
public func flatten() -> Signal {
- return self.flatMap(.merge, SignalProducer.init)
+ return self.flatMap(.merge) { SignalProducer($0) }
}
}
extension SignalProducer where Value: Sequence {
/// Flattens the `sequence` value sent by `signal`.
public func flatten() -> SignalProducer {
- return self.flatMap(.merge, SignalProducer.init)
+ return self.flatMap(.merge) { SignalProducer($0) }
}
}
@@ -322,6 +322,7 @@ extension Signal where Value: SignalProducerConvertible, Error == Value.Error {
fileprivate func observeConcurrent(_ observer: Signal.Observer, _ limit: UInt, _ lifetime: Lifetime) -> Disposable? {
let state = Atomic(ConcurrentFlattenState(limit: limit))
+ @Sendable
func startNextIfNeeded() {
while let producer = state.modify({ $0.dequeue() }) {
let producerState = UnsafeAtomicState(.starting)
@@ -763,7 +764,7 @@ extension Signal where Value: SignalProducerConvertible, Error == Value.Error {
let disposableHandle = relayDisposable.add(innerDisposable)
var isWinningSignal = false
- innerSignal.observe { event in
+ innerSignal.observe { @Sendable event in
if !isWinningSignal {
isWinningSignal = state.modify { state in
guard !state.isActivated else {
@@ -965,7 +966,7 @@ extension Signal {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> Signal{
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> Signal{
return map(transform).flatten(strategy)
}
@@ -980,7 +981,7 @@ extension Signal {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> Signal where Inner.Error == Error {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> Signal where Inner.Error == Error {
return flatMap(strategy) { transform($0).producer }
}
@@ -995,7 +996,7 @@ extension Signal {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> Signal {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> Signal {
return map(transform).flatten(strategy)
}
@@ -1010,7 +1011,7 @@ extension Signal {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> Signal where Inner.Error == Never {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> Signal where Inner.Error == Never {
return flatMap(strategy) { transform($0).producer }
}
}
@@ -1027,7 +1028,7 @@ extension Signal where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> Signal {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> Signal {
return map(transform).flatten(strategy)
}
@@ -1042,7 +1043,7 @@ extension Signal where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> Signal {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> Signal {
return flatMap(strategy) { transform($0).producer }
}
@@ -1054,7 +1055,7 @@ extension Signal where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> Signal {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> Signal {
return map(transform).flatten(strategy)
}
@@ -1066,7 +1067,7 @@ extension Signal where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> Signal where Inner.Error == Never {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> Signal where Inner.Error == Never {
return flatMap(strategy) { transform($0).producer }
}
}
@@ -1083,7 +1084,7 @@ extension SignalProducer {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> SignalProducer {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> SignalProducer {
return map(transform).flatten(strategy)
}
@@ -1098,7 +1099,7 @@ extension SignalProducer {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> SignalProducer where Inner.Error == Error {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> SignalProducer where Inner.Error == Error {
return flatMap(strategy) { transform($0).producer }
}
@@ -1113,7 +1114,7 @@ extension SignalProducer {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> SignalProducer {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> SignalProducer {
return map(transform).flatten(strategy)
}
@@ -1128,7 +1129,7 @@ extension SignalProducer {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> SignalProducer where Inner.Error == Never {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> SignalProducer where Inner.Error == Never {
return flatMap(strategy) { transform($0).producer }
}
}
@@ -1142,7 +1143,7 @@ extension SignalProducer where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> SignalProducer {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> SignalProducer {
return map(transform).flatten(strategy)
}
@@ -1154,7 +1155,7 @@ extension SignalProducer where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> SignalProducer where Inner.Error == Error {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> SignalProducer where Inner.Error == Error {
return flatMap(strategy) { transform($0).producer }
}
@@ -1169,7 +1170,7 @@ extension SignalProducer where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> SignalProducer) -> SignalProducer {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> SignalProducer) -> SignalProducer {
return map(transform).flatten(strategy)
}
@@ -1184,7 +1185,7 @@ extension SignalProducer where Error == Never {
/// - strategy: Strategy used when flattening signals.
/// - transform: A closure that takes a value emitted by `self` and
/// returns a signal producer with transformed value.
- public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping (Value) -> Inner) -> SignalProducer {
+ public func flatMap(_ strategy: FlattenStrategy, _ transform: @escaping @Sendable (Value) -> Inner) -> SignalProducer {
return flatMap(strategy) { transform($0).producer }
}
}
@@ -1196,7 +1197,7 @@ extension Signal {
/// - parameters:
/// - transform: A closure that accepts emitted error and returns a signal
/// producer with a different type of error.
- public func flatMapError(_ transform: @escaping (Error) -> SignalProducer) -> Signal {
+ public func flatMapError(_ transform: @escaping @Sendable (Error) -> SignalProducer) -> Signal {
return Signal { observer, lifetime in
lifetime += self.observeFlatMapError(transform, observer, SerialDisposable())
}
@@ -1208,7 +1209,7 @@ extension Signal {
/// - parameters:
/// - transform: A closure that accepts emitted error and returns a signal
/// producer with a different type of error.
- public func flatMapError(_ transform: @escaping (Error) -> Inner) -> Signal where Inner.Value == Value {
+ public func flatMapError(_ transform: @escaping @Sendable (Error) -> Inner) -> Signal where Inner.Value == Value {
return flatMapError { transform($0).producer }
}
diff --git a/Sources/FoundationExtensions.swift b/Sources/FoundationExtensions.swift
index d0273fa31..a47292ff0 100644
--- a/Sources/FoundationExtensions.swift
+++ b/Sources/FoundationExtensions.swift
@@ -74,7 +74,7 @@ extension Reactive where Base: URLSession {
}
}
- lifetime.observeEnded(task.cancel)
+ lifetime.observeEnded { @Sendable in task.cancel() }
task.resume()
}
}
diff --git a/Sources/Lifetime.swift b/Sources/Lifetime.swift
index 4af0c0a29..8ee2d89a1 100644
--- a/Sources/Lifetime.swift
+++ b/Sources/Lifetime.swift
@@ -2,7 +2,7 @@ import Foundation
/// Represents the lifetime of an object, and provides a hook to observe when
/// the object deinitializes.
-public final class Lifetime {
+public final class Lifetime: Sendable {
private let disposables: CompositeDisposable
/// A signal that sends a `completed` event when the lifetime ends.
@@ -49,7 +49,7 @@ public final class Lifetime {
/// - returns: A disposable that detaches `action` from the lifetime, or `nil`
/// if `lifetime` has already ended.
@discardableResult
- public func observeEnded(_ action: @escaping () -> Void) -> Disposable? {
+ public func observeEnded(_ action: @escaping @Sendable () -> Void) -> Disposable? {
return disposables += action
}
diff --git a/Sources/Observers/AttemptMap.swift b/Sources/Observers/AttemptMap.swift
index 922a3c819..446385e20 100644
--- a/Sources/Observers/AttemptMap.swift
+++ b/Sources/Observers/AttemptMap.swift
@@ -1,14 +1,14 @@
extension Operators {
- internal final class AttemptMap: Observer {
- let downstream: Observer
- let transform: (InputValue) -> Result
+ internal final class AttemptMap: Observer {
+ let downstream: any Observer
+ let transform: @Sendable (InputValue) -> Result
- init(downstream: Observer, transform: @escaping (InputValue) -> Result) {
+ init(downstream: some Observer, transform: @escaping @Sendable (InputValue) -> Result) {
self.downstream = downstream
self.transform = transform
}
- override func receive(_ value: InputValue) {
+ func receive(_ value: InputValue) {
switch transform(value) {
case let .success(value):
downstream.receive(value)
@@ -17,7 +17,7 @@ extension Operators {
}
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
downstream.terminate(termination)
}
}
diff --git a/Sources/Observers/Collect.swift b/Sources/Observers/Collect.swift
index 7704c1c1e..cb9177d0b 100644
--- a/Sources/Observers/Collect.swift
+++ b/Sources/Observers/Collect.swift
@@ -1,12 +1,12 @@
extension Operators {
- internal final class Collect: Observer {
- let downstream: Observer<[Value], Error>
- let modify: (_ collected: inout [Value], _ latest: Value) -> [Value]?
+ internal final class Collect: Observer, @unchecked Sendable {
+ let downstream: any Observer<[Value], Error>
+ let modify: @Sendable (_ collected: inout [Value], _ latest: Value) -> [Value]?
private var values: [Value] = []
private var hasReceivedValues = false
- convenience init(downstream: Observer<[Value], Error>, shouldEmit: @escaping (_ collected: [Value], _ latest: Value) -> Bool) {
+ convenience init(downstream: some Observer<[Value], Error>, shouldEmit: @escaping (_ collected: [Value], _ latest: Value) -> Bool) {
self.init(downstream: downstream, modify: { collected, latest in
if shouldEmit(collected, latest) {
defer { collected = [latest] }
@@ -18,7 +18,7 @@ extension Operators {
})
}
- convenience init(downstream: Observer<[Value], Error>, shouldEmit: @escaping (_ collected: [Value]) -> Bool) {
+ convenience init(downstream: some Observer<[Value], Error>, shouldEmit: @escaping (_ collected: [Value]) -> Bool) {
self.init(downstream: downstream, modify: { collected, latest in
collected.append(latest)
@@ -31,12 +31,12 @@ extension Operators {
})
}
- private init(downstream: Observer<[Value], Error>, modify: @escaping (_ collected: inout [Value], _ latest: Value) -> [Value]?) {
+ private init(downstream: some Observer<[Value], Error>, modify: @escaping @Sendable (_ collected: inout [Value], _ latest: Value) -> [Value]?) {
self.downstream = downstream
self.modify = modify
}
- override func receive(_ value: Value) {
+ func receive(_ value: Value) {
if let outgoing = modify(&values, value) {
downstream.receive(outgoing)
}
@@ -46,7 +46,7 @@ extension Operators {
}
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
if case .completed = termination {
if !values.isEmpty {
downstream.receive(values)
diff --git a/Sources/Observers/CollectEvery.swift b/Sources/Observers/CollectEvery.swift
index 91d61ea8c..4515cf53b 100644
--- a/Sources/Observers/CollectEvery.swift
+++ b/Sources/Observers/CollectEvery.swift
@@ -10,7 +10,7 @@ extension Operators {
private let timerDisposable = SerialDisposable()
init(
- downstream: Observer<[Value], Error>,
+ downstream: some Observer<[Value], Error>,
downstreamLifetime: Lifetime,
target: DateScheduler,
interval: DispatchTimeInterval,
diff --git a/Sources/Observers/CombinePrevious.swift b/Sources/Observers/CombinePrevious.swift
index 70fa09cb5..e5fc3679b 100644
--- a/Sources/Observers/CombinePrevious.swift
+++ b/Sources/Observers/CombinePrevious.swift
@@ -1,14 +1,14 @@
extension Operators {
- internal final class CombinePrevious: Observer {
- let downstream: Observer<(Value, Value), Error>
+ internal final class CombinePrevious: Observer, @unchecked Sendable {
+ let downstream: any Observer<(Value, Value), Error>
var previous: Value?
- init(downstream: Observer<(Value, Value), Error>, initial: Value?) {
+ init(downstream: some Observer<(Value, Value), Error>, initial: Value?) {
self.downstream = downstream
self.previous = initial
}
- override func receive(_ value: Value) {
+ func receive(_ value: Value) {
if let previous = previous {
downstream.receive((previous, value))
}
@@ -16,7 +16,7 @@ extension Operators {
previous = value
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
downstream.terminate(termination)
}
}
diff --git a/Sources/Observers/CompactMap.swift b/Sources/Observers/CompactMap.swift
index d51c448e4..99c162cad 100644
--- a/Sources/Observers/CompactMap.swift
+++ b/Sources/Observers/CompactMap.swift
@@ -1,20 +1,20 @@
extension Operators {
- internal final class CompactMap: Observer {
- let downstream: Observer
- let transform: (InputValue) -> OutputValue?
+ internal final class CompactMap: Observer {
+ let downstream: any Observer
+ let transform: @Sendable (InputValue) -> OutputValue?
- init(downstream: Observer, transform: @escaping (InputValue) -> OutputValue?) {
+ init(downstream: some Observer, transform: @escaping @Sendable (InputValue) -> OutputValue?) {
self.downstream = downstream
self.transform = transform
}
- override func receive(_ value: InputValue) {
+ func receive(_ value: InputValue) {
if let output = transform(value) {
downstream.receive(output)
}
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
downstream.terminate(termination)
}
}
diff --git a/Sources/Observers/Debounce.swift b/Sources/Observers/Debounce.swift
index bfe0ef2a3..05b244aed 100644
--- a/Sources/Observers/Debounce.swift
+++ b/Sources/Observers/Debounce.swift
@@ -10,7 +10,7 @@ extension Operators {
private let schedulerDisposable = SerialDisposable()
init(
- downstream: Observer,
+ downstream: some Observer,
downstreamLifetime: Lifetime,
target: DateScheduler,
interval: TimeInterval,
diff --git a/Sources/Observers/Delay.swift b/Sources/Observers/Delay.swift
index 1c4eb42c0..82ed0f808 100644
--- a/Sources/Observers/Delay.swift
+++ b/Sources/Observers/Delay.swift
@@ -6,7 +6,7 @@ extension Operators {
let targetWithClock: DateScheduler
init(
- downstream: Observer,
+ downstream: some Observer,
downstreamLifetime: Lifetime,
target: DateScheduler,
interval: TimeInterval
diff --git a/Sources/Observers/Dematerialize.swift b/Sources/Observers/Dematerialize.swift
index 6c8c15e33..a9f33fee8 100644
--- a/Sources/Observers/Dematerialize.swift
+++ b/Sources/Observers/Dematerialize.swift
@@ -1,12 +1,12 @@
extension Operators {
- internal final class Dematerialize: Observer where Event: EventProtocol {
- let downstream: Observer
+ internal final class Dematerialize: Observer where Event: EventProtocol {
+ let downstream: any Observer
- init(downstream: Observer) {
+ init(downstream: some Observer) {
self.downstream = downstream
}
- override func receive(_ event: Event) {
+ func receive(_ event: Event) {
switch event.event {
case let .value(value):
downstream.receive(value)
@@ -19,7 +19,7 @@ extension Operators {
}
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
switch termination {
case .completed:
downstream.terminate(.completed)
diff --git a/Sources/Observers/DematerializeResults.swift b/Sources/Observers/DematerializeResults.swift
index 986582b99..2af721460 100644
--- a/Sources/Observers/DematerializeResults.swift
+++ b/Sources/Observers/DematerializeResults.swift
@@ -1,12 +1,12 @@
extension Operators {
- internal final class DematerializeResults: Observer where Result: ResultProtocol {
- let downstream: Observer
+ internal final class DematerializeResults: Observer where Result: ResultProtocol {
+ let downstream: any Observer
- init(downstream: Observer) {
+ init(downstream: some Observer) {
self.downstream = downstream
}
- override func receive(_ value: Result) {
+ func receive(_ value: Result) {
switch value.result {
case let .success(value):
downstream.receive(value)
@@ -15,7 +15,7 @@ extension Operators {
}
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
switch termination {
case .completed:
downstream.terminate(.completed)
diff --git a/Sources/Observers/Filter.swift b/Sources/Observers/Filter.swift
index 060164d73..89cad6942 100644
--- a/Sources/Observers/Filter.swift
+++ b/Sources/Observers/Filter.swift
@@ -1,20 +1,20 @@
extension Operators {
- internal final class Filter: Observer {
- let downstream: Observer
- let predicate: (Value) -> Bool
+ internal final class Filter: Observer {
+ let downstream: any Observer
+ let predicate: @Sendable (Value) -> Bool
- init(downstream: Observer, predicate: @escaping (Value) -> Bool) {
+ init(downstream: some Observer, predicate: @escaping @Sendable (Value) -> Bool) {
self.downstream = downstream
self.predicate = predicate
}
- override func receive(_ value: Value) {
+ func receive(_ value: Value) {
if predicate(value) {
downstream.receive(value)
}
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
downstream.terminate(termination)
}
}
diff --git a/Sources/Observers/LazyMap.swift b/Sources/Observers/LazyMap.swift
index 5cab84648..c1f624b78 100644
--- a/Sources/Observers/LazyMap.swift
+++ b/Sources/Observers/LazyMap.swift
@@ -2,10 +2,10 @@ extension Operators {
internal final class LazyMap: UnaryAsyncOperator {
let transform: (Value) -> NewValue
let box = Atomic(nil)
- let valueDisposable = SerialDisposable()
+ let valueDisposable = SerialDisposable()
init(
- downstream: Observer,
+ downstream: some Observer,
downstreamLifetime: Lifetime,
target: Scheduler,
transform: @escaping (Value) -> NewValue
diff --git a/Sources/Observers/Map.swift b/Sources/Observers/Map.swift
index 58ac26173..2d63c84f1 100644
--- a/Sources/Observers/Map.swift
+++ b/Sources/Observers/Map.swift
@@ -1,18 +1,18 @@
extension Operators {
- internal final class Map: Observer {
- let downstream: Observer
- let transform: (InputValue) -> OutputValue
+ internal final class Map: Observer {
+ let downstream: any Observer
+ let transform: @Sendable (InputValue) -> OutputValue
- init(downstream: Observer, transform: @escaping (InputValue) -> OutputValue) {
+ init(downstream: some Observer, transform: @escaping @Sendable (InputValue) -> OutputValue) {
self.downstream = downstream
self.transform = transform
}
- override func receive(_ value: InputValue) {
+ func receive(_ value: InputValue) {
downstream.receive(transform(value))
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination) {
downstream.terminate(termination)
}
}
diff --git a/Sources/Observers/MapError.swift b/Sources/Observers/MapError.swift
index c8dc9a95b..5c9952a21 100644
--- a/Sources/Observers/MapError.swift
+++ b/Sources/Observers/MapError.swift
@@ -1,18 +1,18 @@
extension Operators {
- internal final class MapError: Observer {
- let downstream: Observer
- let transform: (InputError) -> OutputError
+ internal final class MapError: Observer {
+ let downstream: any Observer
+ let transform: @Sendable (InputError) -> OutputError
- init(downstream: Observer, transform: @escaping (InputError) -> OutputError) {
+ init(downstream: some Observer, transform: @escaping @Sendable (InputError) -> OutputError) {
self.downstream = downstream
self.transform = transform
}
- override func receive(_ value: Value) {
+ func receive(_ value: Value) {
downstream.receive(value)
}
- override func terminate(_ termination: Termination) {
+ func terminate(_ termination: Termination