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

Unreliable warnings about unreachable code downstream of uninhabited expression #107179

Open
graydon opened this issue Jan 22, 2023 · 1 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.

Comments

@graydon
Copy link
Contributor

graydon commented Jan 22, 2023

Code

use core::convert::Infallible;
use core::hint::unreachable_unchecked;

fn make_infallible() -> Infallible { 
    // Infallible implements From<!>
    loop { }
}

extern {
    fn side_effects();
}

pub fn has_unit_type() {
    let _a : Infallible = make_infallible();

    // This gets no unreachable-code warning
    println!("I cannot execute");

    // This gets no unreachable-code warning
    unsafe { side_effects() }

    // This gets an unreachable-code warning
    if false { }
}

pub fn has_never_type_no_warning() -> ! {
    let _ : Infallible = make_infallible();

    // This gets no unreachable-code warning (probably correctly?)
    unsafe { unreachable_unchecked() }
}

pub fn has_never_type_has_warning() -> ! {
    let _ : Infallible = make_infallible();
    // This has the same never-type, but does get a warning
    loop {}
}

Current output

warning: unreachable expression
  --> src/lib.rs:23:5
   |
14 |     let _a : Infallible = make_infallible();
   |                           ----------------- any code following this expression is unreachable
...
23 |     if false { }
   |     ^^^^^^^^^^^^ unreachable expression
   |
note: this expression has type `Infallible`, which is uninhabited
  --> src/lib.rs:14:27
   |
14 |     let _a : Infallible = make_infallible();
   |                           ^^^^^^^^^^^^^^^^^
   = note: `#[warn(unreachable_code)]` on by default

warning: unreachable expression
  --> src/lib.rs:36:5
   |
34 |     let _ : Infallible = make_infallible();
   |                          ----------------- any code following this expression is unreachable
35 |     // This has the same never-type, but does get a warning
36 |     loop {}
   |     ^^^^^^^ unreachable expression
   |
note: this expression has type `Infallible`, which is uninhabited
  --> src/lib.rs:34:26
   |
34 |     let _ : Infallible = make_infallible();
   |                          ^^^^^^^^^^^^^^^^^

Rationale and extra context

It should warn on the first (and every) unreachable expression, not just the seemingly random set of expressions it fires on here. Note that if you change any of the make_infallible() calls to panic!() it will warn at the correct spots. So I think this is specifically related to the treatment of empty types.

@graydon graydon 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 Jan 22, 2023
@graydon
Copy link
Contributor Author

graydon commented Jan 22, 2023

At a guess I would say this might be related to #100288 and so perhaps @camsteffen would be interested (i.e. it might be a typeck issue not a "diagnostics", it's hard for me to tell from my current level of ignorance of how this lint works)

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

No branches or pull requests

1 participant