Skip to content

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

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

Open
zachs18 opened this issue Nov 28, 2023 · 4 comments
Open

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

zachs18 opened this issue Nov 28, 2023 · 4 comments
Assignees
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. L-dead_code Lint: dead_code L-false-positive Lint: False positive (should not have fired). T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@zachs18
Copy link
Contributor

zachs18 commented Nov 28, 2023

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)

@zachs18 zachs18 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 Nov 28, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 28, 2023
@zachs18 zachs18 changed the title Incorrect dead_code lint with generics using type aliases in macros. Incorrect dead_code lint with type alias declared in macro from ident passed to macro, used in expr passed to macro. Nov 28, 2023
@clubby789 clubby789 added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Nov 28, 2023
@zachs18 zachs18 changed the title Incorrect dead_code lint with type alias declared in macro from ident passed to macro, used in expr passed to macro. Incorrect dead_code lint with type alias used in const. Nov 30, 2023
@zachs18
Copy link
Contributor Author

zachs18 commented Nov 30, 2023

@rustbot label -A-macros

Upon further minimizing, this actually appears to have nothing to do with the type alias being declared in a macro; the warning shows up even for

type T = u32;
const _: () = assert!(
    std::mem::size_of::<T>() == std::mem::size_of::<T>()
);
const _A: () = assert!(
    std::mem::size_of::<T>() == std::mem::size_of::<T>()
);

The const _A: () = { ... }; should definitely be quieting the lint for anything used in ... even if _A is not used anywhere since it's name starts with _, and I'd expect the const _: () = { ... }; should too, but neither do.

Note that let _ = assert!(size_of::<T>() == size_of::<T>()); (or let _a = ...;) does quiet the lint.

@rustbot rustbot removed the A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) label Nov 30, 2023
@long-long-float
Copy link
Contributor

@rustbot claim

@long-long-float
Copy link
Contributor

The problem happens without assert!.

type T = u32;
const _A: usize = std::mem::size_of::<T>();

fn main() {}

@zachs18
Copy link
Contributor Author

zachs18 commented Dec 7, 2023

This also happens with several other kinds of items, not just type aliases:

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
}
   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`

(Playground link)

@zachs18 zachs18 changed the title Incorrect dead_code lint with type alias used in const. Incorrect dead_code lint with items only used in const. Dec 7, 2023
@jieyouxu jieyouxu added the L-dead_code Lint: dead_code label Sep 12, 2024
@fmease fmease added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. L-false-positive Lint: False positive (should not have fired). and removed A-diagnostics Area: Messages for errors, warnings, and lints labels Jun 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. L-dead_code Lint: dead_code L-false-positive Lint: False positive (should not have fired). T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants