[Pitch] Rethrowing protocol conformances

There might be an answer there, but you have to be explicit at every use site for it to work. Let's try to implement my map2 example on top of your FailableIterator. The same code does not work:

extension FailableSequence {
  func map2<Transformed>(transform: (Element) throws -> Transformed) rethrows -> [Transformed] {
    var result = [Transformed]()
    var iterator = self.makeIterator()
    while let element = try iterator.next() { // error: call can throw, but the error 'Self.Iterator.Error` is not handled; a function declared 'rethrows' may only throw if its parameter does
      result.append(try transform(element))
    }
    return result
  }
}

There is no direct solution for this in the current typed throws pitch. One can mimic the expected behavior with overloading:

extension FailableSequence {
  // Always throwing (not rethrows) because Self.Iterator.makeIterator can throw 
  func map2<Transformed>(transform: (Element) throws -> Transformed) throws -> [Transformed] {
    // implementation ..
        var result = [Transformed]()
    var iterator = self.makeIterator()
    while let element = try iterator.next() {
      result.append(try transform(element))
    }
    return result
  }
}

extension FailableSequence where Self.Iterator.Error == Never {
  // Throws when the function argument throws
  func map2<Transformed>(transform: (Element) throws -> Transformed) rethrows -> [Transformed] {
    // implementation ..
        var result = [Transformed]()
    var iterator = self.makeIterator()
    while let element = try iterator.next() {
      result.append(try transform(element))
    }
    return result
  }
}

One could perhaps extend the typed-throws proposal to have rethrows in addition to a throws clause, with a declaration like this:

extension FailableSequence {
  func map2<Transformed>(transform: (Element) throws -> Transformed) throws Self.Iterator.Error rethrows -> [Transformed] { ... }
}

Or extend the typed-throws proposal to put typed throws into function parameters as well (with inference from closure arguments, which is tricky to implement today) and allow functions to specify multiple typed throws:

extension FailableSequence {
  func map2<Transformed, TransformError: Error>(transform: (Element) throws(TransformError) -> Transformed) throws(Self.Iterator.Error, TransformError) -> [Transformed] { ... }
}

Note that you'll hit all of these same problems if you want to write zip2 with typed-throws.

That last one is arguably the best answer for a typed-throws solution because it subsumes rethrows entirely within a more-general framework. But here's the thing---the rethrows solution I wrote is more concise and far easier to get right. If we implement the proposed rethrows, it could later become syntactic sugar for typed throws. I think that should be an explicit goal of any typed-throws design.

Doug