about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2021-02-08 10:43:54 +0300
committerÖmer Sinan Ağacan <omeragacan@gmail.com>2021-02-08 10:46:19 +0300
commit6eb1bd4c3e3ad9a28d0a3b0f1579a4769d9a88d2 (patch)
tree6b9617fdbfadb5ae72b10ccb0b9c488e21f31cbe /compiler/rustc_parse/src/parser
parent0b7a598e12649d7ab2415a82cbc3fea879fa9dab (diff)
downloadrust-6eb1bd4c3e3ad9a28d0a3b0f1579a4769d9a88d2.tar.gz
rust-6eb1bd4c3e3ad9a28d0a3b0f1579a4769d9a88d2.zip
parser: Fix panic in 'const impl' recovery
The panic happens when in recovery parsing a full `impl`
(`parse_item_impl`) fails and we drop the `DiagnosticBuilder` for the
recovery suggestion and return the `parse_item_impl` error.

We now raise the original error "expected identifier found `impl`" when
parsing the `impl` fails.

Note that the regression test is slightly simplified version of the
original repro in #81806, to make the error output smaller and more
resilient to unrelated changes in parser error messages.

Fixes #81806
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/item.rs14
1 files changed, 12 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index c44ccfadda5..ee242862414 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1010,9 +1010,18 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, ItemInfo> {
         let impl_span = self.token.span;
         let mut err = self.expected_ident_found();
-        let mut impl_info = self.parse_item_impl(attrs, defaultness)?;
+
+        // Only try to recover if this is implementing a trait for a type
+        let mut impl_info = match self.parse_item_impl(attrs, defaultness) {
+            Ok(impl_info) => impl_info,
+            Err(mut recovery_error) => {
+                // Recovery failed, raise the "expected identifier" error
+                recovery_error.cancel();
+                return Err(err);
+            }
+        };
+
         match impl_info.1 {
-            // only try to recover if this is implementing a trait for a type
             ItemKind::Impl(box ImplKind {
                 of_trait: Some(ref trai), ref mut constness, ..
             }) => {
@@ -1030,6 +1039,7 @@ impl<'a> Parser<'a> {
             ItemKind::Impl { .. } => return Err(err),
             _ => unreachable!(),
         }
+
         Ok(impl_info)
     }