Skip to content

The "this and all prior arms are found to be of type" diagnostic is less helpful for many unreachable branches #121144

Closed

Description

Code

If we try this code:

fn main() {
    let m = 42u32;

    let value = 'out: {
        match value {
            1 => break 'out Some(1u16),
            2 => Some(2u16),
            3 => break 'out Some(3u16),
            4 => break 'out Some(4u16),
            5 => break 'out Some(5u16),
            _ => {}
        }

        None
    };
}

Current output

We get this output:

error[E0308]: `match` arms have incompatible types
  --> src/main.rs:11:18
   |
5  | /         match value {
6  | |             1 => break 'out Some(1u16),
7  | |             2 => Some(2u16),
8  | |             3 => break 'out Some(3u16),
9  | |             4 => break 'out Some(4u16),
10 | |             5 => break 'out Some(5u16),
   | |                  --------------------- this and all prior arms are found to be of type `Option<u16>`
11 | |             _ => {}
   | |                  ^^ expected `Option<u16>`, found `()`
12 | |         }
   | |_________- `match` arms have incompatible types
   |
   = note:   expected enum `Option<u16>`
           found unit type `()`
help: consider using a semicolon here, but this will discard any values in the match arms
   |
12 |         };
   |          +

Desired output

The diagnostic could point out which branch (or branches) caused the type to be Option<u16>, preferably skipping branches which are not reachable.

Other cases

Note that if we reduce the number of branches to 4, we get a complete enumeration of branches. While more helpful, could still be improved by skipping and possibly noting the number of branches that have been skipped due to not being reachable:

error[E0308]: `match` arms have incompatible types
  --> src/main.rs:10:18
   |
5  | /         match value {
6  | |             1 => break 'out Some(1u16),
   | |                  --------------------- this is found to be of type `Option<u16>`
7  | |             2 => Some(2u16),
   | |                  ---------- this is found to be of type `Option<u16>`
8  | |             3 => break 'out Some(3u16),
   | |                  --------------------- this is found to be of type `Option<u16>`
9  | |             4 => break 'out Some(4u16),
   | |                  --------------------- this is found to be of type `Option<u16>`
10 | |             _ => {}
   | |                  ^^ expected `Option<u16>`, found `()`
11 | |         }
   | |_________- `match` arms have incompatible types
   |
   = note:   expected enum `Option<u16>`
           found unit type `()`
help: consider using a semicolon here, but this will discard any values in the match arms
   |
11 |         };
   |          +

Rust Version

rustc 1.76.0 (07dca489a 2024-02-04)
binary: rustc
commit-hash: 07dca489ac2d933c78d3c5158e3f43beefeb02ce
commit-date: 2024-02-04
host: x86_64-pc-windows-msvc
release: 1.76.0
LLVM version: 17.0.6

Anything else?

Playground Link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions