Repository navigation
Specifying lint levels does not work on macros #87391
Copy link
Copy link
Closed as duplicate
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: 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.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
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);
}
}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!, andasm!with allow, warn, and deny forirrefutable_let_patternsas well as in in my in progress lintnamed_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
Reacted by Steven Engler
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: 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.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
asquared31415 commentedon Jan 24, 2024
Update: I'm not sure this is fixed but the compiler at least tells you that it doesn't work now
However it does not offer any suggestions to work around this issue.
Anutrix commentedon Apr 30, 2025
Just faced the same issue. Why can't:
work?
No response from core team for almost 4 years seems odd.
peter-lyons-kehl commentedon Nov 30, 2025
Lints don't work well with macros from other crate(s), which includes
std. This is a sister issue of #110613.cmbartschat commentedon Dec 23, 2025
For anyone else finding themselves in the situation of:
When attempting to do:
I found that using an enclosing block with an inner attribute (switching
#[to#![) does the trick.Playground