about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-22 08:32:41 +0000
committerbors <bors@rust-lang.org>2022-08-22 08:32:41 +0000
commitee8c31e64d229cac4eba6d8f03bb70e16f34a14b (patch)
tree0c9ff6127f19cacf68070cea3a978ca3a01d9c4d /compiler/rustc_parse/src/parser
parenta9bb589cd678e034d194193fa892942315b10e2a (diff)
parent88e39b2c2e875d78f8c04fe8c6a52a6a48632af5 (diff)
downloadrust-ee8c31e64d229cac4eba6d8f03bb70e16f34a14b.tar.gz
rust-ee8c31e64d229cac4eba6d8f03bb70e16f34a14b.zip
Auto merge of #100868 - Dylan-DPC:rollup-a1hfi1r, r=Dylan-DPC
Rollup of 5 pull requests

Successful merges:

 - #93162 (Std module docs improvements)
 - #99386 (Add tests that check `Vec::retain` predicate execution order.)
 - #99915 (Recover keywords in trait bounds)
 - #100694 (Migrate rustc_ast_passes diagnostics to `SessionDiagnostic` and translatable messages (first part))
 - #100757 (Catch overflow early)

Failed merges:

 - #99917 (Move Error trait into core)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs22
1 files changed, 21 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 76b710095d7..4a2cf74905b 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")
@@ -804,6 +810,20 @@ impl<'a> Parser<'a> {
             let span = tilde.to(self.prev_token.span);
             self.sess.gated_spans.gate(sym::const_trait_impl, span);
             Some(span)
+        } else if self.eat_keyword(kw::Const) {
+            let span = self.prev_token.span;
+            self.sess.gated_spans.gate(sym::const_trait_impl, span);
+
+            self.struct_span_err(span, "const bounds must start with `~`")
+                .span_suggestion(
+                    span.shrink_to_lo(),
+                    "add `~`",
+                    "~",
+                    Applicability::MachineApplicable,
+                )
+                .emit();
+
+            Some(span)
         } else {
             None
         };