# Type checking hole regarding \`rethrows\`

**URL:** <https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162>\
**Category:** Using Swift\
**Created:** [April 10, 2024, 6:44am UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162 "2024-04-10T06:44:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![CrystDragon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/crystdragon/32/10461_2.png) [@CrystDragon](https://forums.swift.org/u/CrystDragon)\
**Post date:** [April 10, 2024, 6:44am UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/1 "2024-04-10T06:44:30Z")

</div>

The following code compiles fine but will produce a guaranteed crash when used at runtime.

```swift
func mayThrow(_ op: () throws -> Void) rethrows {
  func mustThrow() throws {
    try op() // <- even this line is not need to show case this problem
    throw MyError()
  }
  try mustThrow()
}

```

Now, no matter how you try to call the above function, an error will escape and cause a crash.

```swift
try? mayThrow() // crash

// nor does this work
do {
  try mayThrow {} // also crash
} catch { }

```

The compiler will complain there's nothing to "try" though.

In conclusion, it seems at the moment the compiler does not correctly type-check rethrow proprgation considering local functions.

---

<div class="post-metadata">

**Author:** ![bbrk24](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bbrk24/32/27370_2.png) [@bbrk24](https://forums.swift.org/u/bbrk24)\
**Post date:** [April 10, 2024, 7:08am UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/2 "2024-04-10T07:08:05Z")

</div>

There are known issues with `rethrows`-checking, but they can’t be fixed because the problem is (ab)used by standard functions like `DispatchQueue.sync`, which follow the spirit of `rethrows` (only throw if the argument does) but in a way that a more sound implementation wouldn’t allow.

This isn’t really going to matter soon, after typed throws become a thing (if they aren’t already?) and you can say:

```swift
func mayThrow<E: Error>(_ op: () throws(E) -> Void) throws(E) {
  try op() // okay
  throw MyError() // error, MyError is not E
}

```

---

<div class="post-metadata">

**Author:** ![CrystDragon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/crystdragon/32/10461_2.png) [@CrystDragon](https://forums.swift.org/u/CrystDragon)\
**Post date:** [April 10, 2024, 7:30am UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/3 "2024-04-10T07:30:56Z")

</div>

Thanks for your background info.  
Follow your words, I find some thorough discussion in the forum. ([Pitch: Fix rethrows checking and add rethrows(unsafe)](https://forums.swift.org/t/pitch-fix-rethrows-checking-and-add-rethrows-unsafe/44863))

And yes, I love the proposal of typed throws.  
The thing that worries me is the fact that `rethrows` will likely always be in the language (because there are patterns out there which cannot be expressed by typed throws easily), and this pitfall will always be there.

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [April 10, 2024, 10:52am UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/4 "2024-04-10T10:52:58Z")

</div>

Afaics this is a "simple" (might be hard to fix ;-) bug: The compiler should complain that `mayThrow` has to be marked with `throws`.

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 11, 2024, 1:33pm UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/5 "2024-04-11T13:33:42Z")

</div>

> [@CrystDragon](#):
>
> The thing that worries me is the fact that `rethrows` will likely always be in the language (because there are patterns out there which cannot be expressed by typed throws easily), and this pitfall will always be there.

My personal hope is that those patterns are sufficiently weird and rare that typed throws can completely replace rethrows in all new code, and one day we can deprecate rethrows.

The fix here is completely trivial, but it would break source compatibility, that's why we never landed it.

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [April 11, 2024, 5:12pm UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/6 "2024-04-11T17:12:26Z")

</div>

> [@Slava\_Pestov](#):
>
> The fix here is completely trivial, but it would break source compatibility, that's why we never landed it.

Imo it is a sad thing if Swift has reached a state where bugs are not fixed because of compability ☹

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 11, 2024, 5:33pm UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/7 "2024-04-11T17:33:37Z")

</div>

> [@Tino](#):
>
> Imo it is a sad thing if Swift has reached a state where bugs are not fixed because of compability ☹

It's about the cost vs benefit. For example, there were two minor source breaking fixes documented in CHANGELOG.md here: [Document two minor source-breaking bug fixes in Swift 6.0 · apple/swift@582ec11 · GitHub](https://github.com/apple/swift/commit/582ec11cee58b7d35944ef8a77ff98e7dda50f6d#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4edR8-R37). I think most people will agree that fixing these makes total sense even though it might theoretically result in an existing project no longer compiling.

With the `rethrows` thing here on the other hand there are existing usages of `rethrows` that were written _because_ they specifically rely on this soundness hole. Fixing it would require introducing a `rethrows(unsafe)` escape hatch, or migrating the existing usages to typed throws, and it's just not worth the hassle at this point. If we didn't have typed throws, I would have advocated for fixing and extending rethrows, of course.

---

<div class="post-metadata">

**Author:** ![jlukas](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jlukas/32/317_2.png) [@jlukas](https://forums.swift.org/u/jlukas)\
**Post date:** [April 12, 2024, 8:38pm UTC](https://forums.swift.org/t/type-checking-hole-regarding-rethrows/71162/8 "2024-04-12T20:38:54Z")

</div>

Would it be reasonable to add a warning for this case, now that we have typed throws?
