mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
e15897f6c4
The AST pretty printer was dropping parentheses around or-patterns
when they appeared inside `@` bindings, `&` references, or `box`
patterns. For example:
- `v @ (1 | 2 | 3)` was printed as `v @ 1 | 2 | 3`
- `&(1 | 2 | 3)` was printed as `&1 | 2 | 3`
- `box (1 | 2 | 3)` was printed as `box 1 | 2 | 3`
Since `|` has the lowest precedence among pattern operators, all of
these are parsed incorrectly without parentheses — e.g. `v @ 1 | 2 | 3`
becomes `(v @ 1) | 2 | 3`, binding `v` only to the first alternative.
This caused E0408 ("variable not bound in all patterns") when the
expanded output was fed back to the compiler, affecting crates like
html5ever and wgpu-core that use macros expanding to or-patterns
after `@`.
The fix adds a `print_pat_paren_if_or` helper that wraps `PatKind::Or`
subpatterns in parentheses, and uses it in the `@`, `&`, and `box`
printing arms. This is similar in spirit to the existing `FixupContext`
parenthesization approach used for expression printing.
Signed-off-by: Andrew V. Teylu <andrew.teylu@vector.com>
37 lines
579 B
Rust
37 lines
579 B
Rust
#![feature(box_patterns)]
|
|
|
|
//@ pretty-compare-only
|
|
//@ pretty-mode:expanded
|
|
//@ pp-exact:or-pattern-paren.pp
|
|
|
|
macro_rules! or_pat {
|
|
($($name:pat),+) => { $($name)|+ }
|
|
}
|
|
|
|
fn check_at(x: Option<i32>) {
|
|
match x {
|
|
Some(v @ or_pat!(1, 2, 3)) => println!("{v}"),
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn check_ref(x: &i32) {
|
|
match x {
|
|
&or_pat!(1, 2, 3) => {}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn check_box(x: Box<i32>) {
|
|
match x {
|
|
box or_pat!(1, 2, 3) => {}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
check_at(Some(2));
|
|
check_ref(&1);
|
|
check_box(Box::new(1));
|
|
}
|