Skip to content
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

Issue in rethrowing protocol #60821

Open
twittemb opened this issue Aug 28, 2022 · 0 comments
Open

Issue in rethrowing protocol #60821

twittemb opened this issue Aug 28, 2022 · 0 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. concurrency Feature: umbrella label for concurrency language features

Comments

@twittemb
Copy link

Describe the bug
There might be an issue with the current implementation of rethrowing protocol conformance, that makes possible to throw an Error while the generic parameter is a non Throwing implementation.

Steps To Reproduce
Steps to reproduce the behavior:

Given a type that conforms to a rethrowing protocol such as this AsyncSequence:

struct AsyncDummySequence<Base: AsyncSequence>: AsyncSequence {
  typealias Element = Base.Element
  typealias AsyncIterator = Iterator

  let base: Base

  func makeAsyncIterator() -> AsyncIterator {
    Iterator(base: self.base.makeAsyncIterator())
  }

  struct Iterator: AsyncIteratorProtocol {
    var base: Base.AsyncIterator

    mutating func next() async rethrows -> Element? {
      try await withTaskCancellationHandler {
      } operation: {
        try Result<Element?, Error>.failure(NSError(domain: "", code: 1)).get(). // -> here the compiler does not complain about trying on a type that is not a generic parameter, because of the call being wrapped inside a rethrowing function.
      }
    }
}

we can use it with a non throwing generic AsyncSequence, not using try await although we clearly will throw an error in the next() function:

let nonThrowingSequence = AsyncStream<Int> { continuation in
  continuation.yield(1)
  continuation.finish()
}

let seq = AsyncDummySequence(base: nonThrowingSequence)

for await element in seq { // -> no need to use `try await` although the sequence will throw
  print(element)
}

When running that code, the iteration seems to be blocked.

Expected behavior
The compiler should complain about using try on a type that is not the generic parameter, just as it does with this code:

mutating func next() async rethrows -> Element? {
  try Result<Element, Error>.failure(NSError(domain: "", code: 1)).get() // -> does not compile
}

Environment (please fill out the following information)

  • OS Monterey 12.5.1
  • Xcode Version/Tag/Branch: Xcode 13.4.1 (13F100)
  • Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12)
  • MacBook Pro M1 ultra

Additional context
Forum link: Forum

@twittemb twittemb added the bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. label Aug 28, 2022
@LucianoPAlmeida LucianoPAlmeida added the concurrency Feature: umbrella label for concurrency language features label Aug 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. concurrency Feature: umbrella label for concurrency language features
Projects
None yet
Development

No branches or pull requests

2 participants