diff options
| author | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-07-29 20:04:28 +0400 |
|---|---|---|
| committer | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-07-29 21:43:35 +0400 |
| commit | c6558c0bc71024b8aca1db317c15cdf701d917d8 (patch) | |
| tree | d77c9d6f4dbf6203f11908bcd14a05555432ae8e | |
| parent | e5682615bb4fdb90e3a37b810a1b7bded2a1199e (diff) | |
| download | rust-c6558c0bc71024b8aca1db317c15cdf701d917d8.tar.gz rust-c6558c0bc71024b8aca1db317c15cdf701d917d8.zip | |
Recover keywords in bounds
For example, this fixes a error for `impl fn()` (notice the capitalization)
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs | 3 | ||||
| -rw-r--r-- | src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr | 12 |
3 files changed, 18 insertions, 5 deletions
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 31b40a83e60..b76ba8ff2d9 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -640,7 +640,13 @@ impl<'a> Parser<'a> { let mut bounds = Vec::new(); let mut negative_bounds = Vec::new(); - while self.can_begin_bound() || self.token.is_keyword(kw::Dyn) { + while self.can_begin_bound() + // Continue even if we find a keyword. + // This is necessary for error recover on, for example, `impl fn()`. + // + // The only keyword that can go after generic bounds is `where`, so stop if it's it. + || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where)) + { if self.token.is_keyword(kw::Dyn) { // Account for `&dyn Trait + dyn Other`. self.struct_span_err(self.token.span, "invalid `dyn` keyword") diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs index e8b26154549..e0d3e0b497b 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs @@ -3,4 +3,5 @@ #![feature(const_trait_impl)] struct S<T: const Tr>; -//~^ ERROR expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path +//~^ ERROR expected identifier, found keyword `const` +//~| ERROR expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr` diff --git a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr index b6b77ac4a2f..243f0979509 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr @@ -1,8 +1,14 @@ -error: expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path, found keyword `const` +error: expected identifier, found keyword `const` --> $DIR/without-tilde.rs:5:13 | LL | struct S<T: const Tr>; - | ^^^^^ expected one of 10 possible tokens + | ^^^^^ expected identifier, found keyword -error: aborting due to previous error +error: expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Tr` + --> $DIR/without-tilde.rs:5:19 + | +LL | struct S<T: const Tr>; + | ^^ expected one of 7 possible tokens + +error: aborting due to 2 previous errors |
