about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2021-10-01 09:18:17 -0700
committerGitHub <noreply@github.com>2021-10-01 09:18:17 -0700
commit1708219940806d3620fb1cc10a0a673f7bfbbe45 (patch)
treec123a2b666324698e0d9ff08851503c245e6c0ca /compiler/rustc_parse/src/parser
parent6f1e93058137eb606cbee5ef778d30b379903f7c (diff)
parent105b60f2501fac061284ea7f5fbb8fb3f8134a92 (diff)
downloadrust-1708219940806d3620fb1cc10a0a673f7bfbbe45.tar.gz
rust-1708219940806d3620fb1cc10a0a673f7bfbbe45.zip
Rollup merge of #89029 - notriddle:notriddle/issue-89013, r=estebank
feat(rustc_parse): recover from pre-RFC-2000 const generics syntax

Fixes #89013
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/path.rs37
1 files changed, 32 insertions, 5 deletions
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 953c6915068..c7d080a80fe 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -495,20 +495,28 @@ impl<'a> Parser<'a> {
             None => {
                 let after_eq = eq.shrink_to_hi();
                 let before_next = self.token.span.shrink_to_lo();
-                self.struct_span_err(after_eq.to(before_next), "missing type to the right of `=`")
-                    .span_suggestion(
+                let mut err = self
+                    .struct_span_err(after_eq.to(before_next), "missing type to the right of `=`");
+                if matches!(self.token.kind, token::Comma | token::Gt) {
+                    err.span_suggestion(
                         self.sess.source_map().next_point(eq).to(before_next),
                         "to constrain the associated type, add a type after `=`",
                         " TheType".to_string(),
                         Applicability::HasPlaceholders,
-                    )
-                    .span_suggestion(
+                    );
+                    err.span_suggestion(
                         eq.to(before_next),
                         &format!("remove the `=` if `{}` is a type", ident),
                         String::new(),
                         Applicability::MaybeIncorrect,
                     )
-                    .emit();
+                } else {
+                    err.span_label(
+                        self.token.span,
+                        &format!("expected type, found {}", super::token_descr(&self.token)),
+                    )
+                };
+                return Err(err);
             }
         }
         Ok(self.mk_ty(span, ast::TyKind::Err))
@@ -572,6 +580,25 @@ impl<'a> Parser<'a> {
                     return self.recover_const_arg(start, err).map(Some);
                 }
             }
+        } else if self.eat_keyword_noexpect(kw::Const) {
+            // Detect and recover from the old, pre-RFC2000 syntax for const generics.
+            let mut err = self.struct_span_err(
+                start,
+                "expected lifetime, type, or constant, found keyword `const`",
+            );
+            if self.check_const_arg() {
+                err.span_suggestion_verbose(
+                    start.until(self.token.span),
+                    "the `const` keyword is only needed in the definition of the type",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+                err.emit();
+                GenericArg::Const(self.parse_const_arg()?)
+            } else {
+                let after_kw_const = self.token.span;
+                return self.recover_const_arg(after_kw_const, err).map(Some);
+            }
         } else {
             return Ok(None);
         };