Skip to content

Unhelpful unreachable_code warning on a tuple constructor with fields of uninhabited types #139627

Closed
@snejugal

Description

@snejugal

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 lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.L-unreachable_codeLint: unreachable_codeT-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