Skip to content

#[expect(redundant_lifetimes)] doesn't work when #[derive(Debug)] is present #150553

@LuisFerLCC

Description

@LuisFerLCC

Consider the following code:

#![deny(redundant_lifetimes)]

use std::fmt::Debug;

#[derive(Debug)]
pub struct RefWrapper<'a, T>
where
    'a: 'static,
    T: Debug,
{
    pub t_ref: &'a T
}

As expected, the compiler throws an error because the 'a lifetime is redundant:

➜  rust-playground git:(master) ✗ cargo check
    Checking rust-playground v0.1.0 (/Users/luisferlcc/rust-playground)
error: unnecessary lifetime parameter `'a`
 --> src/lib.rs:6:23
  |
6 | pub struct RefWrapper<'a, T>
  |                       ^^
  |
  = note: you can use the `'static` lifetime directly, in place of `'a`
note: the lint level is defined here
 --> src/lib.rs:1:9
  |
1 | #![deny(redundant_lifetimes)]
  |         ^^^^^^^^^^^^^^^^^^^

error: unnecessary lifetime parameter `'a`
 --> src/lib.rs:6:23
  |
6 | pub struct RefWrapper<'a, T>
  |                       ^^
  |
  = note: you can use the `'static` lifetime directly, in place of `'a`

error: could not compile `rust-playground` (lib) due to 2 previous errors

Adding #[allow(redundant_lifetimes)] to the type definition...

#![deny(redundant_lifetimes)]

use std::fmt::Debug;

#[derive(Debug)]
#[allow(redundant_lifetimes)]
pub struct RefWrapper<'a, T>
where
    'a: 'static,
    T: Debug,
{
    pub t_ref: &'a T
}

...predictably eliminates the error:

➜  rust-playground git:(master) ✗ cargo check
    Checking rust-playground v0.1.0 (/Users/luisferlcc/rust-playground)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s

However, changing the allow attribute to expect...

#![deny(redundant_lifetimes)]

use std::fmt::Debug;

#[derive(Debug)]
#[expect(redundant_lifetimes)]
pub struct RefWrapper<'a, T>
where
    'a: 'static,
    T: Debug,
{
    pub t_ref: &'a T
}

...inexplicably fails to make the linter stand down:

➜  rust-playground git:(master) ✗ cargo check
    Checking rust-playground v0.1.0 (/Users/luisferlcc/rust-playground)
error: unnecessary lifetime parameter `'a`
 --> src/lib.rs:7:23
  |
7 | pub struct RefWrapper<'a, T>
  |                       ^^
  |
  = note: you can use the `'static` lifetime directly, in place of `'a`
note: the lint level is defined here
 --> src/lib.rs:1:9
  |
1 | #![deny(redundant_lifetimes)]
  |         ^^^^^^^^^^^^^^^^^^^

error: could not compile `rust-playground` (lib) due to 1 previous error

But removing #[derive(Debug)] allows the expect attribute to take effect:

#![deny(redundant_lifetimes)]

use std::fmt::Debug;

#[expect(redundant_lifetimes)]
pub struct RefWrapper<'a, T>
where
    'a: 'static,
    T: Debug,
{
    pub t_ref: &'a T
}
➜  rust-playground git:(master) ✗ cargo check
    Checking rust-playground v0.1.0 (/Users/luisferlcc/rust-playground)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s

Meta

This issue occurs on the latest versions of all three channels:

➜  rust-playground git:(master) ✗ rustc --version --verbose
rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: aarch64-apple-darwin
release: 1.92.0
LLVM version: 21.1.3
➜  rust-playground git:(master) ✗ rustc +beta --version --verbose
rustc 1.93.0-beta.5 (72b6488ba 2025-12-21)
binary: rustc
commit-hash: 72b6488ba485fd08cd96f194ffdd83ba8aa0b057
commit-date: 2025-12-21
host: aarch64-apple-darwin
release: 1.93.0-beta.5
LLVM version: 21.1.8
➜  rust-playground git:(master) ✗ rustc +nightly --version --verbose
rustc 1.94.0-nightly (0e8999942 2025-12-30)
binary: rustc
commit-hash: 0e8999942552691afc20495af6227eca8ab0af05
commit-date: 2025-12-30
host: aarch64-apple-darwin
release: 1.94.0-nightly
LLVM version: 21.1.8
Backtrace

➜  rust-playground git:(master) ✗ RUST_BACKTRACE=1 cargo check
    Checking rust-playground v0.1.0 (/Users/luisferlcc/rust-playground)
error: unnecessary lifetime parameter `'a`
 --> src/lib.rs:7:54
  |
7 | pub struct RefWrapper<#[expect(redundant_lifetimes)] 'a, T>
  |                                                      ^^
  |
  = note: you can use the `'static` lifetime directly, in place of `'a`
note: the lint level is defined here
 --> src/lib.rs:1:9
  |
1 | #![deny(redundant_lifetimes)]
  |         ^^^^^^^^^^^^^^^^^^^

error: could not compile `rust-playground` (lib) due to 1 previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions