about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorCatherine Flores <catherine.3.flores@gmail.com>2023-07-24 17:05:10 +0000
committerCatherine Flores <catherine.3.flores@gmail.com>2023-07-24 17:05:10 +0000
commitdece622ee48d9744d6e64891a734e8fd25eac903 (patch)
treed8b35c977d78e486b19c40850f25abb52283b2ec /compiler/rustc_parse/src/parser
parent287db04636ffefa3fdaa39fe0fdcc3cf75b60444 (diff)
downloadrust-dece622ee48d9744d6e64891a734e8fd25eac903.tar.gz
rust-dece622ee48d9744d6e64891a734e8fd25eac903.zip
Recover from some macros
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/item.rs46
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs6
2 files changed, 36 insertions, 16 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 6ec3a1ff1a5..7b479067ecd 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1343,10 +1343,14 @@ impl<'a> Parser<'a> {
                 let ident = this.parse_field_ident("enum", vlo)?;
 
                 if this.token == token::Not {
-                    return this.unexpected().map_err(|mut err| {
-                        err.note(fluent::parse_macro_expands_to_enum_variant);
-                        err
-                    });
+                    if let Err(mut err) = this.unexpected::<()>() {
+                        err.note(fluent::parse_macro_expands_to_enum_variant).emit();
+                    }
+
+                    this.bump();
+                    this.parse_delim_args()?;
+
+                    return Ok((None, TrailingToken::MaybeComma));
                 }
 
                 let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) {
@@ -1586,7 +1590,8 @@ impl<'a> Parser<'a> {
         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
             let lo = this.token.span;
             let vis = this.parse_visibility(FollowedByType::No)?;
-            Ok((this.parse_single_struct_field(adt_ty, lo, vis, attrs)?, TrailingToken::None))
+            this.parse_single_struct_field(adt_ty, lo, vis, attrs)
+                .map(|field| (field, TrailingToken::None))
         })
     }
 
@@ -1698,10 +1703,9 @@ impl<'a> Parser<'a> {
         Ok(a_var)
     }
 
-    fn expect_field_ty_separator(&mut self, adt_ty: &str) -> PResult<'a, ()> {
+    fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
         if let Err(mut err) = self.expect(&token::Colon) {
             let sm = self.sess.source_map();
-            let mac_invoc = self.token.kind == token::Not;
             let eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start());
             let semi_typo = self.token.kind == token::Semi
                 && self.look_ahead(1, |t| {
@@ -1713,9 +1717,7 @@ impl<'a> Parser<'a> {
                         _ => true,
                     }
                 });
-            if mac_invoc {
-                err.subdiagnostic(MacroExpandsToAdtField { adt_ty }).emit();
-            } else if eq_typo || semi_typo {
+            if eq_typo || semi_typo {
                 self.bump();
                 // Gracefully handle small typos.
                 err.span_suggestion_short(
@@ -1741,7 +1743,29 @@ impl<'a> Parser<'a> {
         attrs: AttrVec,
     ) -> PResult<'a, FieldDef> {
         let name = self.parse_field_ident(adt_ty, lo)?;
-        self.expect_field_ty_separator(adt_ty)?;
+        // Parse the macro invocation and recover
+        if self.token.kind == token::Not {
+            if let Err(mut err) = self.unexpected::<FieldDef>() {
+                err.subdiagnostic(MacroExpandsToAdtField { adt_ty }).emit();
+                self.bump();
+                self.parse_delim_args()?;
+                return Ok(FieldDef {
+                    span: DUMMY_SP,
+                    ident: None,
+                    vis,
+                    id: DUMMY_NODE_ID,
+                    ty: P(Ty {
+                        id: DUMMY_NODE_ID,
+                        kind: TyKind::Err,
+                        span: DUMMY_SP,
+                        tokens: None,
+                    }),
+                    attrs,
+                    is_placeholder: false,
+                });
+            }
+        }
+        self.expect_field_ty_separator()?;
         let ty = self.parse_ty()?;
         if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
             self.sess.emit_err(errors::SingleColonStructType { span: self.token.span });
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index b477453615d..58c00ebdea0 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -181,11 +181,7 @@ impl<'a> Parser<'a> {
                 err
             })?;
             if rc == RecoverComma::Yes {
-                self.maybe_recover_unexpected_comma(
-                    pat.span,
-                    matches!(pat.kind, PatKind::MacCall(_)),
-                    rt,
-                )?;
+                self.maybe_recover_unexpected_comma(pat.span, false, rt)?;
             }
             pats.push(pat);
         }