`let-else` does not respect `macro_rules` `expr` metavariable grouping
@bb1yd is already working on this.
Since Jun 28, 2026.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code 1: let-else with &&
macro_rules! foo {
($e:expr) => {
let true = $e else { return; };
}
}
fn main() {
foo!(true && true);
}
error: a `&&` expression cannot be directly assigned in `let...else`
--> src/main.rs:8:10
|
8 | foo!(true && true);
| ^^^^^^^^^^^^
|
help: wrap the expression in parentheses
|
8 | foo!((true && true));
| + +
Code 2: let-else with braces
#![allow(irrefutable_let_patterns)]
macro_rules! foo {
($e:expr) => {
let _ = $e else { return; };
}
}
struct Thing {}
fn main() {
foo!(Thing {});
}
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> src/main.rs:12:17
|
12 | foo!(Thing {});
| ^
|
help: wrap the expression in parentheses
|
12 | foo!((Thing {}));
| + +
I expected both of the above code snippets to compile. Instead, I got the above compile errors.
expr metavariables in macros are supposed to be opaque, and treated as if they're wrapped in "invisible parentheses". Therefore, I shouldn't need to wrap the expression in another layer of parentheses. However, let-else seems to not respect this grouping.
In contrast, if let correctly respects the grouping
if let with &&
This code correctly prints "works" three times.
macro_rules! foo {
($e:expr) => {
if let false = $e {
println!("works");
} else {
unreachable!();
}
}
}
fn main() {
foo!(true && false);
if let false = (true && false) {
println!("works");
} else {
unreachable!();
}
if let false = true && false {
unreachable!();
} else {
println!("works");
}
}
if let with braces
This code compiles
#![allow(irrefutable_let_patterns)]
macro_rules! foo {
($e:expr) => {
if let _ = $e {}
}
}
struct Thing {}
fn main() {
foo!(Thing {});
}
Meta
Reproducible on the playground with version 1.92.0-nightly (2025-10-19 f04e3dfc87d7e2b6ad53)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.