about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-07-29 20:04:28 +0400
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-07-29 21:43:35 +0400
commitc6558c0bc71024b8aca1db317c15cdf701d917d8 (patch)
treed77c9d6f4dbf6203f11908bcd14a05555432ae8e
parente5682615bb4fdb90e3a37b810a1b7bded2a1199e (diff)
downloadrust-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.rs8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr12
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