diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index f7f7ac89a1864..983aa43916fa8 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -295,6 +295,8 @@ impl<'a> Parser<'a> { // A rest pattern `..`. self.bump(); // `..` PatKind::Rest + } else if self.check(&token::DotDotDot) && !self.is_pat_range_end_start(1) { + self.recover_dotdotdot_rest_pat(lo) } else if let Some(form) = self.parse_range_end() { self.parse_pat_range_to(form)? // `..=X`, `...X`, or `..X`. } else if self.eat_keyword(kw::Underscore) { @@ -362,6 +364,25 @@ impl<'a> Parser<'a> { Ok(pat) } + /// Recover from a typoed `...` pattern that was encountered + /// Ref: Issue #70388 + fn recover_dotdotdot_rest_pat(&mut self, lo: Span) -> PatKind { + // A typoed rest pattern `...`. + self.bump(); // `...` + + // The user probably mistook `...` for a rest pattern `..`. + self.struct_span_err(lo, "unexpected `...`") + .span_label(lo, "not a valid pattern") + .span_suggestion_short( + lo, + "for a rest pattern, use `..` instead of `...`", + "..".to_owned(), + Applicability::MachineApplicable, + ) + .emit(); + PatKind::Rest + } + /// Try to recover the more general form `intersect ::= $pat_lhs @ $pat_rhs`. /// /// Allowed binding patterns generated by `binding ::= ref? mut? $ident @ $pat_rhs` diff --git a/src/test/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs b/src/test/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs new file mode 100644 index 0000000000000..ca8abd78c47ac --- /dev/null +++ b/src/test/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs @@ -0,0 +1,7 @@ +struct Foo(i32); + +fn main() { + let Foo(...) = Foo(0); //~ ERROR unexpected `...` + let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...` + let _recovery_witness: () = 0; //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/issue-70388-recover-dotdotdot-rest-pat.stderr b/src/test/ui/parser/issue-70388-recover-dotdotdot-rest-pat.stderr new file mode 100644 index 0000000000000..4961e8fc0492d --- /dev/null +++ b/src/test/ui/parser/issue-70388-recover-dotdotdot-rest-pat.stderr @@ -0,0 +1,29 @@ +error: unexpected `...` + --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:4:13 + | +LL | let Foo(...) = Foo(0); + | ^^^ + | | + | not a valid pattern + | help: for a rest pattern, use `..` instead of `...` + +error: unexpected `...` + --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:5:13 + | +LL | let [_, ..., _] = [0, 1]; + | ^^^ + | | + | not a valid pattern + | help: for a rest pattern, use `..` instead of `...` + +error[E0308]: mismatched types + --> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:6:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`.