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

Bad diagnostics with multiple typed throws #74554

Open
NachoSoto opened this issue Jun 19, 2024 · 3 comments
Open

Bad diagnostics with multiple typed throws #74554

NachoSoto opened this issue Jun 19, 2024 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. typed throws Feature → error handling → throws & rethrows: Typed throws

Comments

@NachoSoto
Copy link
Contributor

NachoSoto commented Jun 19, 2024

Description

Multiple throws of the same type inside of a function don't compile (even though I'd expect them to), and instead produce FOUR bad diagnostics.

Reproduction

enum Error: Swift.Error {
  case a
  case b
}

func f() throws(Error) {
  throw .a
}
func g() throws {
  throw Error.b
}

func h() {
  do {
    // Errors thrown from here are not handled because the enclosing catch is not exhaustive
    try f()

    do {
      try g()
    } catch {
      // Error is not handled because the enclosing catch is not exhaustive
      throw Error.b
    }
  } catch .a { // Type '_ErrorCodeProtocol' has no member 'a'

  } catch .b { // Type '_ErrorCodeProtocol' has no member 'b'

  }
}

Expected behavior

Code compiles since all errors are handled.

Environment

swift-driver version: 1.109.2 Apple Swift version 6.0 (swiftlang-6.0.0.3.300 clang-1600.0.20.10)
Target: arm64-apple-macosx14.0

Additional information

This is related to #74555, but this also doesn't compile:

func h() {
  do {
    // Errors thrown from here are not handled because the enclosing catch is not exhaustive
    try f()

    do {
      try g()
    } catch {
      // Error is not handled because the enclosing catch is not exhaustive
      throw Error.b
    }
  } catch _ as Error {
  }
}
@NachoSoto NachoSoto added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Jun 19, 2024
@Jumhyn
Copy link
Member

Jumhyn commented Jun 19, 2024

This looks to me like an issue with properly considering the explicit throw considering that in the following I'm seeing i fail to compile but j succeed without issue:

func i() {
  do {
    throw MyError.b
  } catch _ as MyError {
  }
}

func j() {
    do {
        try f()
        do {
            try g()
        } catch {
            try f()
        }
    } catch _ as MyError {
    }
}
Never mind, this is expected

@Jumhyn
Copy link
Member

Jumhyn commented Jun 19, 2024

Ah, also note this part of the typed throws proposal:

Note that the only way to write an exhaustive do...catch statement is to have an unconditional catch block. The dynamic checking provided by is or as patterns in the catch block cannot be used to make a catch exhaustive, even if the type specified is the same as the type thrown from the body of the do:

func f() {
  do /*infers throws(CatError)*/ {
    try callCat()
  } catch let ce as CatError {
    
  } // error: do...catch is not exhaustive, so this code rethrows CatError and is ill-formed
}

(though that does make it interesting that j compiles above, especially with a warning that the as cast is redundant.)

@Jumhyn
Copy link
Member

Jumhyn commented Jun 20, 2024

This is expected without the experimental feature FullTypedThrows enabled. The implementation has not been completed and this feature will not be part of the Swift 6 language mode.

@hborla hborla added typed throws Feature → error handling → throws & rethrows: Typed throws and removed triage needed This issue needs more specific labels labels Jul 14, 2024
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. typed throws Feature → error handling → throws & rethrows: Typed throws
Projects
None yet
Development

No branches or pull requests

3 participants