Skip to content

Specifying lint levels does not work on macros #87391

Closed as duplicate
Closed as duplicate

Description

@asquared31415

Given the following code:

fn main() {
    #[allow(irrefutable_let_patterns)]
    println!("{}", if let _ = 1 { 42 } else { 0 });
    
    // The macro doesn't matter, even macros like `asm!` exhibit this behavior
    #[allow(irrefutable_let_patterns)]
    dbg!("{}", if let _ = 1 { 42 } else { 0 });
    
    #[allow(irrefutable_let_patterns)]
    {
        println!("{}", if let _ = 2 { 84 } else { 0 });
    }
    
    #[allow(irrefutable_let_patterns)]
    if let _ = 3 { 
        println!("{}", 168);
    } else { 
        println!("{}", 0);
    }
}

playground

The current output is:

warning: irrefutable `if let` pattern
 --> src/main.rs:3:20
  |
3 |     println!("{}", if let _ = 1 { 42 } else { 0 });
  |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(irrefutable_let_patterns)]` on by default
  = note: this pattern will always match, so the `if let` is useless
  = help: consider replacing the `if let` with a `let`

warning: irrefutable `if let` pattern
 --> src/main.rs:7:16
  |
7 |     dbg!("{}", if let _ = 1 { 42 } else { 0 });
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: this pattern will always match, so the `if let` is useless
  = help: consider replacing the `if let` with a `let`

warning: 2 warnings emitted

Ideally in this case, the compilation should succeed without warning, as the lint appears to have been explicitly allowed everywhere it is used.

This likely applies for all lints and all lint levels and all macros

  • (only tested println!, dbg!, and asm! with allow, warn, and deny for irrefutable_let_patterns as well as in in my in progress lint named_asm_labels)

A current workaround is to create a scope to put the macro in, and apply the lint level to that scope, as demonstrated in the example.

Applying the lint level to the crate with #![level(lint)] works as expected, however this is often not desirable.

Possibly related: #59306

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jul 23, 2021
  2. asquared31415 commented on Jan 24, 2024

    @asquared31415
    ContributorAuthor

    Update: I'm not sure this is fixed but the compiler at least tells you that it doesn't work now

    warning: unused attribute `allow`
     --> src/main.rs:2:5
      |
    2 |     #[allow(irrefutable_let_patterns)]
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
    note: the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `println`
     --> src/main.rs:3:5
      |
    3 |     println!("{}", if let _ = 1 { 42 } else { 0 });
      |     ^^^^^^^
      = note: `#[warn(unused_attributes)]` on by default
    
    warning: unused attribute `allow`
     --> src/main.rs:6:5
      |
    6 |     #[allow(irrefutable_let_patterns)]
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
    note: the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `dbg`
     --> src/main.rs:7:5
      |
    7 |     dbg!("{}", if let _ = 1 { 42 } else { 0 });
      |     ^^^
    

    However it does not offer any suggestions to work around this issue.

  3. Anutrix commented on Apr 30, 2025

    @Anutrix

    Just faced the same issue. Why can't:

    #[allow(arithmetic_overflow)]
    println!("1 - 2 = {}", 1u32 - 2);
    

    work?

    No response from core team for almost 4 years seems odd.

  4. peter-lyons-kehl commented on Nov 30, 2025

    @peter-lyons-kehl
    Contributor

    Lints don't work well with macros from other crate(s), which includes std. This is a sister issue of #110613.

  5. cmbartschat commented on Dec 23, 2025

    @cmbartschat

    For anyone else finding themselves in the situation of:

    the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `println`
    

    When attempting to do:

    #[allow(clippy::print_stdout)]
    println!("hello, world");
    

    I found that using an enclosing block with an inner attribute (switching #[ to #![) does the trick.

    {
      #![allow(clippy::print_stdout)]
      println!("hello, world");
    }
    

    Playground

  6. added
    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.
    on Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.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