Skip to content

Incorrect dead_code lint with items only used in const. #118424

Open
@zachs18

Description

@zachs18

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)

Metadata

Metadata

Labels

A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.L-dead_codeLint: dead_codeL-false-positiveLint: False positive (should not have fired).T-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