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

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

Closed
udoprog opened this issue Feb 15, 2024 · 0 comments · Fixed by #121146
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@udoprog
Copy link
Contributor

udoprog commented Feb 15, 2024

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

@udoprog udoprog added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 15, 2024
@compiler-errors compiler-errors self-assigned this Feb 15, 2024
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Feb 15, 2024
…rms, r=estebank

Only point out non-diverging arms for match suggestions

Fixes rust-lang#121144

There is no reason to point at diverging arms, which will always coerce to whatever is the match block's evaluated type.

This also removes the suggestion from rust-lang#106601, since as I pointed out in rust-lang#72634 (comment) the added suggestion is not firing in the right cases, but instead only when one of the match arms already *actually* evaluates to `()`.

r? estebank
oli-obk added a commit to oli-obk/rust that referenced this issue Feb 15, 2024
…rms, r=estebank

Only point out non-diverging arms for match suggestions

Fixes rust-lang#121144

There is no reason to point at diverging arms, which will always coerce to whatever is the match block's evaluated type.

This also removes the suggestion from rust-lang#106601, since as I pointed out in rust-lang#72634 (comment) the added suggestion is not firing in the right cases, but instead only when one of the match arms already *actually* evaluates to `()`.

r? estebank
@bors bors closed this as completed in 77eaa80 Feb 16, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 16, 2024
Rollup merge of rust-lang#121146 - compiler-errors:ignore-diverging-arms, r=estebank

Only point out non-diverging arms for match suggestions

Fixes rust-lang#121144

There is no reason to point at diverging arms, which will always coerce to whatever is the match block's evaluated type.

This also removes the suggestion from rust-lang#106601, since as I pointed out in rust-lang#72634 (comment) the added suggestion is not firing in the right cases, but instead only when one of the match arms already *actually* evaluates to `()`.

r? estebank
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants