]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_parse/src/parser/diagnostics.rs
Auto merge of #107267 - cjgillot:keep-aggregate, r=oli-obk
[rust.git] / compiler / rustc_parse / src / parser / diagnostics.rs
index eda7046c748e5f52121854349a3fa6f903e502d2..cd9d85b1d919c9c3f45541e83a9223857550be9c 100644 (file)
@@ -2030,7 +2030,7 @@ pub(super) fn parameter_without_type(
     }
 
     pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::Ty>)> {
-        let pat = self.parse_pat_no_top_alt(Some("argument name"))?;
+        let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName))?;
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
 
@@ -2353,6 +2353,28 @@ pub fn recover_const_arg(
         Err(err)
     }
 
+    /// Try to recover from an unbraced const argument whose first token [could begin a type][ty].
+    ///
+    /// [ty]: token::Token::can_begin_type
+    pub(crate) fn recover_unbraced_const_arg_that_can_begin_ty(
+        &mut self,
+        mut snapshot: SnapshotParser<'a>,
+    ) -> Option<P<ast::Expr>> {
+        match snapshot.parse_expr_res(Restrictions::CONST_EXPR, None) {
+            // Since we don't know the exact reason why we failed to parse the type or the
+            // expression, employ a simple heuristic to weed out some pathological cases.
+            Ok(expr) if let token::Comma | token::Gt = snapshot.token.kind => {
+                self.restore_snapshot(snapshot);
+                Some(expr)
+            }
+            Ok(_) => None,
+            Err(err) => {
+                err.cancel();
+                None
+            }
+        }
+    }
+
     /// Creates a dummy const argument, and reports that the expression must be enclosed in braces
     pub fn dummy_const_arg_needs_braces(
         &self,
@@ -2372,10 +2394,10 @@ pub fn dummy_const_arg_needs_braces(
 
     /// Some special error handling for the "top-level" patterns in a match arm,
     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
-    pub(crate) fn maybe_recover_colon_colon_in_pat_typo_or_anon_enum(
+    pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
         &mut self,
         mut first_pat: P<Pat>,
-        expected: Expected,
+        expected: Option<Expected>,
     ) -> P<Pat> {
         if token::Colon != self.token.kind {
             return first_pat;
@@ -2413,8 +2435,9 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo_or_anon_enum(
         // Create error for "unexpected `:`".
         match self.expected_one_of_not_found(&[], &[]) {
             Err(mut err) => {
-                snapshot_pat.bump(); // Skip the `:`.
-                snapshot_type.bump(); // Skip the `:`.
+                // Skip the `:`.
+                snapshot_pat.bump();
+                snapshot_type.bump();
                 match snapshot_pat.parse_pat_no_top_alt(expected) {
                     Err(inner_err) => {
                         inner_err.cancel();