rust-lang / rust-lang/rust

Incorrect `dead_code` lint with items only used in `const`.

Open
#118,424 4 comments 1 reaction 1 assignee View on GitHub

@long-long-float is already working on this.

Since Dec 1, 2023.

A-lints C-bug L-dead_code L-false-positive T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
type T = u32;
const fn hmm() -> usize { 0 }
struct Struct;
const B: usize = 42;
impl Struct {
    const fn hmmm(&self) -> usize { 0 }
}

const _A: usize = 
    std::mem::size_of::<T>()
    + hmm()
    + std::mem::size_of::<Struct>()
    + B
    + Struct.hmmm();
fn main() {
  // let _a = _A; // uncomment for no warnings
}
Original code
macro_rules! maybe_generic_static_assert {
    (generic = $T:ident, $expr:expr, $msg:expr) => {
        mod _generic_helper {
            type $T = u32;
            const _: () = assert!($expr, $msg);
        }
    };
    ($expr:expr, $msg:expr) => {
        const _: () = assert!($expr, $msg);
    }
}

maybe_generic_static_assert!(
    std::mem::align_of::<u32>() == std::mem::align_of::<std::sync::atomic::AtomicU32>(),
    "aaa"
);

maybe_generic_static_assert!(
    generic = T,
    std::mem::align_of::<*mut T>() == std::mem::align_of::<std::sync::atomic::AtomicPtr<T>>(),
    "aaa"
);
Current output
    Compiling playground v0.0.1 (/playground)
warning: type alias `T` is never used
 --> src/main.rs:1:6
  |
1 | type T = u32;
  |      ^
  |
  = note: `#[warn(dead_code)]` on by default

warning: function `hmm` is never used
 --> src/main.rs:2:10
  |
2 | const fn hmm() -> usize { 0 }
  |          ^^^

warning: struct `Struct` is never constructed
 --> src/main.rs:3:8
  |
3 | struct Struct;
  |        ^^^^^^

warning: constant `B` is never used
 --> src/main.rs:4:7
  |
4 | const B: usize = 42;
  |       ^

warning: method `hmmm` is never used
 --> src/main.rs:6:14
  |
5 | impl Struct {
  | ----------- method in this implementation
6 |     const fn hmmm(&self) -> usize { 0 }
  |              ^^^^

warning: `playground` (bin "playground") generated 5 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 2.55s
     Running `target/debug/playground`
Warnings for original code
Compiling playground v0.0.1 (/playground)
warning: type alias `T` is never used
  --> src/lib.rs:19:15
   |
19 |     generic = T,
   |               ^
   |
   = note: `#[warn(dead_code)]` on by default
   = note: this warning originates in the macro `maybe_generic_static_assert` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: `playground` (lib) generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 2.11s

Output with -Zmacro-backtrace

warning: type alias `T` is never used
  --> <source>:11:5
   |
1  | / macro_rules! the_macro {
2  | |     ($T:ident) => {
3  | |         type $T = u32;
4  | |         const _: () = assert!(
...  |
7  | |     }
8  | | }
   | |_- in this expansion of `the_macro!`
9  |
10 | / the_macro!(
11 | |     T
   | |     ^
12 | | );
   | |_- in this macro invocation
   |
   = note: `#[warn(dead_code)]` on by default

warning: 1 warning emitted
Desired output
<no warnings>
Rationale and extra context

(Playground link)

The items T, Struct, B, hmm, and hmmm are not unused; and removing them causes the code to fail to compile.

Other cases

No response

Anything else?

(edit: minimized, appears unrelated to macros)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.