Repository: apple/swift-nio
File: Sources/NIOCore/AsyncSequences/NIOThrowingAsyncSequenceProducer.swift (Swift)

Code before:

        /// Actions returned by `cancelled()`.
        @usableFromInline
        enum CancelledAction {
            /// Indicates that ``NIOAsyncSequenceProducerDelegate/didTerminate()`` should be called.
            case callDidTerminate
            /// Indicates that the continuation should be resumed with a `CancellationError` and
            /// that ``NIOAsyncSequenceProducerDelegate/didTerminate()`` should be called.
            case resumeContinuationWithCancellationErrorAndCallDidTerminate(CheckedContinuation<Element?, Error>)
            /// Indicates that nothing should be done.
            case none
        }

        @inlinable
        mutating func cancelled() -> CancelledAction {
            switch self._state {
            case .initial(_, let iteratorInitialized):
                // This can happen if the `Task` that calls `next()` is already cancelled.
                
                // We have deprecated the generic Failure type in the public API and Failure should
                // now be `Swift.Error`. However, if users have not migrated to the new API the could
                // still use a custom generic Error type and this cast might fail.
                // In addition, we use `NIOThrowingAsyncSequenceProducer` in the implementation of the
                // non-throwing variant `NIOAsyncSequenceProducer` where `Failure` will be `Never` and
                // this cast will fail as well.
                // Everything is marked @inlinable and the Failure type is know at compile time,
                // therefore this cast should be optimised away in release build.
                if let failure = CancellationError() as? Failure {
                    self._state = .sourceFinished(
                        buffer: .init(),
                        iteratorInitialized: iteratorInitialized,
                        failure: failure
                    )
                } else {
                    self._state = .finished(iteratorInitialized: iteratorInitialized)
                }
                
                return .none

            case .streaming(_, _, .some(let continuation), _, let iteratorInitialized):
                // We have an outstanding continuation that needs to resumed
                // and we can transition to finished here and inform the delegate
                self._state = .finished(iteratorInitialized: iteratorInitialized)

                return .resumeContinuationWithCancellationErrorAndCallDidTerminate(continuation)

            case .streaming(_, _, continuation: .none, _, let iteratorInitialized):
                self._state = .finished(iteratorInitialized: iteratorInitialized)

                return .callDidTerminate


Review comment (bug):
```suggestion
                // Everything is marked @inlinable and the Failure type is known at compile time,
```

Code after:

        /// Actions returned by `cancelled()`.
        @usableFromInline
        enum CancelledAction {
            /// Indicates that ``NIOAsyncSequenceProducerDelegate/didTerminate()`` should be called.
            case callDidTerminate
            /// Indicates that the continuation should be resumed with a `CancellationError` and
            /// that ``NIOAsyncSequenceProducerDelegate/didTerminate()`` should be called.
            case resumeContinuationWithCancellationErrorAndCallDidTerminate(CheckedContinuation<Element?, Error>)
            /// Indicates that nothing should be done.
            case none
        }

        @inlinable
        mutating func cancelled() -> CancelledAction {
            switch self._state {
            case .initial(_, let iteratorInitialized):
                // This can happen if the `Task` that calls `next()` is already cancelled.
                
                // We have deprecated the generic Failure type in the public API and Failure should
                // now be `Swift.Error`. However, if users have not migrated to the new API they could
                // still use a custom generic Error type and this cast might fail.
                // In addition, we use `NIOThrowingAsyncSequenceProducer` in the implementation of the
                // non-throwing variant `NIOAsyncSequenceProducer` where `Failure` will be `Never` and
                // this cast will fail as well.
                // Everything is marked @inlinable and the Failure type is known at compile time,
                // therefore this cast should be optimised away in release build.
                if let failure = CancellationError() as? Failure {
                    self._state = .sourceFinished(
                        buffer: .init(),
                        iteratorInitialized: iteratorInitialized,
                        failure: failure
                    )
                } else {
                    self._state = .finished(iteratorInitialized: iteratorInitialized)
                }
                
                return .none

            case .streaming(_, _, .some(let continuation), _, let iteratorInitialized):
                // We have an outstanding continuation that needs to resumed
                // and we can transition to finished here and inform the delegate
                self._state = .finished(iteratorInitialized: iteratorInitialized)

                return .resumeContinuationWithCancellationErrorAndCallDidTerminate(continuation)

            case .streaming(_, _, continuation: .none, _, let iteratorInitialized):
                self._state = .finished(iteratorInitialized: iteratorInitialized)

                return .callDidTerminate