diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index a1981e11477..0b057f2f577 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -491,17 +491,6 @@ impl<'a> Parser<'a> { if let PatKind::Ident(_, _, sub @ None) = &mut rhs.kind { // The user inverted the order, so help them fix that. - let mut applicability = Applicability::MachineApplicable; - // FIXME(bindings_after_at): Remove this code when stabilizing the feature. - lhs.walk(&mut |p| match p.kind { - // `check_match` is unhappy if the subpattern has a binding anywhere. - PatKind::Ident(..) => { - applicability = Applicability::MaybeIncorrect; - false // Short-circuit. - } - _ => true, - }); - let lhs_span = lhs.span; // Move the LHS into the RHS as a subpattern. // The RHS is now the full pattern. @@ -510,7 +499,12 @@ impl<'a> Parser<'a> { self.struct_span_err(sp, "pattern on wrong side of `@`") .span_label(lhs_span, "pattern on the left, should be on the right") .span_label(rhs.span, "binding on the right, should be on the left") - .span_suggestion(sp, "switch the order", pprust::pat_to_string(&rhs), applicability) + .span_suggestion( + sp, + "switch the order", + pprust::pat_to_string(&rhs), + Applicability::MachineApplicable, + ) .emit(); } else { // The special case above doesn't apply so we may have e.g. `A(x) @ B(y)`. diff --git a/src/test/ui/parser/intersection-patterns-1.fixed b/src/test/ui/parser/intersection-patterns-1.fixed new file mode 100644 index 00000000000..44773095b87 --- /dev/null +++ b/src/test/ui/parser/intersection-patterns-1.fixed @@ -0,0 +1,35 @@ +// This tests the parser recovery in `recover_intersection_pat` +// and serves as a regression test for the diagnostics issue #65400. +// +// The general idea is that for `$pat_lhs @ $pat_rhs` where +// `$pat_lhs` is not generated by `ref? mut? $ident` we want +// to suggest either switching the order or note that intersection +// patterns are not allowed. + +// run-rustfix + +#![allow(unused_variables)] + +fn main() { + let s: Option = None; + + match s { + y @ Some(x) => {} + //~^ ERROR pattern on wrong side of `@` + //~| pattern on the left, should be on the right + //~| binding on the right, should be on the left + //~| HELP switch the order + //~| SUGGESTION y @ Some(x) + _ => {} + } + + match 2 { + e @ 1..=5 => {} + //~^ ERROR pattern on wrong side of `@` + //~| pattern on the left, should be on the right + //~| binding on the right, should be on the left + //~| HELP switch the order + //~| SUGGESTION e @ 1..=5 + _ => {} + } +} diff --git a/src/test/ui/parser/intersection-patterns.rs b/src/test/ui/parser/intersection-patterns-1.rs similarity index 78% rename from src/test/ui/parser/intersection-patterns.rs rename to src/test/ui/parser/intersection-patterns-1.rs index a6d27aab4f6..1036b9daf64 100644 --- a/src/test/ui/parser/intersection-patterns.rs +++ b/src/test/ui/parser/intersection-patterns-1.rs @@ -6,6 +6,10 @@ // to suggest either switching the order or note that intersection // patterns are not allowed. +// run-rustfix + +#![allow(unused_variables)] + fn main() { let s: Option = None; @@ -19,15 +23,6 @@ fn main() { _ => {} } - match s { - Some(x) @ Some(y) => {} - //~^ ERROR left-hand side of `@` must be a binding - //~| interpreted as a pattern, not a binding - //~| also a pattern - //~| NOTE bindings are `x`, `mut x`, `ref x`, and `ref mut x` - _ => {} - } - match 2 { 1 ..= 5 @ e => {} //~^ ERROR pattern on wrong side of `@` diff --git a/src/test/ui/parser/intersection-patterns.stderr b/src/test/ui/parser/intersection-patterns-1.stderr similarity index 55% rename from src/test/ui/parser/intersection-patterns.stderr rename to src/test/ui/parser/intersection-patterns-1.stderr index 9dc4c469a60..dc968656c91 100644 --- a/src/test/ui/parser/intersection-patterns.stderr +++ b/src/test/ui/parser/intersection-patterns-1.stderr @@ -1,5 +1,5 @@ error: pattern on wrong side of `@` - --> $DIR/intersection-patterns.rs:13:9 + --> $DIR/intersection-patterns-1.rs:17:9 | LL | Some(x) @ y => {} | -------^^^- @@ -8,19 +8,8 @@ LL | Some(x) @ y => {} | pattern on the left, should be on the right | help: switch the order: `y @ Some(x)` -error: left-hand side of `@` must be a binding - --> $DIR/intersection-patterns.rs:23:9 - | -LL | Some(x) @ Some(y) => {} - | -------^^^------- - | | | - | | also a pattern - | interpreted as a pattern, not a binding - | - = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x` - error: pattern on wrong side of `@` - --> $DIR/intersection-patterns.rs:32:9 + --> $DIR/intersection-patterns-1.rs:27:9 | LL | 1 ..= 5 @ e => {} | -------^^^- @@ -29,5 +18,5 @@ LL | 1 ..= 5 @ e => {} | pattern on the left, should be on the right | help: switch the order: `e @ 1..=5` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/intersection-patterns-2.rs b/src/test/ui/parser/intersection-patterns-2.rs new file mode 100644 index 00000000000..408415e87ef --- /dev/null +++ b/src/test/ui/parser/intersection-patterns-2.rs @@ -0,0 +1,20 @@ +// This tests the parser recovery in `recover_intersection_pat` +// and serves as a regression test for the diagnostics issue #65400. +// +// The general idea is that for `$pat_lhs @ $pat_rhs` where +// `$pat_lhs` is not generated by `ref? mut? $ident` we want +// to suggest either switching the order or note that intersection +// patterns are not allowed. + +fn main() { + let s: Option = None; + + match s { + Some(x) @ Some(y) => {} + //~^ ERROR left-hand side of `@` must be a binding + //~| interpreted as a pattern, not a binding + //~| also a pattern + //~| NOTE bindings are `x`, `mut x`, `ref x`, and `ref mut x` + _ => {} + } +} diff --git a/src/test/ui/parser/intersection-patterns-2.stderr b/src/test/ui/parser/intersection-patterns-2.stderr new file mode 100644 index 00000000000..f7e78814ca5 --- /dev/null +++ b/src/test/ui/parser/intersection-patterns-2.stderr @@ -0,0 +1,13 @@ +error: left-hand side of `@` must be a binding + --> $DIR/intersection-patterns-2.rs:13:9 + | +LL | Some(x) @ Some(y) => {} + | -------^^^------- + | | | + | | also a pattern + | interpreted as a pattern, not a binding + | + = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x` + +error: aborting due to previous error +