-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.L-unreachable_codeLint: unreachable_codeLint: unreachable_codeT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Code
pub enum Void {}
pub struct S<T>(T);
pub fn foo(void: Void) {
let s = S(void);
drop(s)
}
Current output
warning: unreachable expression
--> src/lib.rs:7:10
|
6 | let s = S(void);
| ------- any code following this expression is unreachable
7 | drop(s)
| ^ unreachable expression
|
note: this expression has type `S<Void>`, which is uninhabited
--> src/lib.rs:6:13
|
6 | let s = S(void);
| ^^^^^^^
= note: `#[warn(unreachable_code)]` on by default
warning: unused variable: `s`
--> src/lib.rs:6:9
|
6 | let s = S(void);
| ^ help: if this is intentional, prefix it with an underscore: `_s`
|
= note: `#[warn(unused_variables)]` on by default
warning: `playground` (lib) generated 2 warnings
Desired output
Preferably no warning at all.
Rationale and extra context
I can technically agree that the drop(s)
expression is unreachable, but this is not because S(void)
is of an uninhabited type — it's because this function is impossible to call. However, since a body of a function is not marked as unreachable just because of the function's parameters, and since constructors do not divert on their own (even if using an impossible value for one of the fields), there should be no warning about unreachable code here. Moreover, in this example, the warning caused another unhelpful warning about an unused variable that is actually used.
Other cases
Changing `let s = S(void);` to `let s = (void,);` removes both warnings. Changing it to `let s = S { 0: void };` also removes both warnings.
Rust Version
$ rustc --version --verbose
rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-unknown-linux-gnu
release: 1.86.0
LLVM version: 19.1.7
Anything else?
No response
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.L-unreachable_codeLint: unreachable_codeLint: unreachable_codeT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.