about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs102
1 files changed, 45 insertions, 57 deletions
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index f0f534fe2e7..b8a477b2b34 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -83,7 +83,7 @@ impl CfgEval<'_> {
         self.0.configure(node)
     }
 
-    fn configure_annotatable(mut self, mut annotatable: Annotatable) -> Annotatable {
+    fn configure_annotatable(mut self, annotatable: Annotatable) -> Annotatable {
         // Tokenizing and re-parsing the `Annotatable` can have a significant
         // performance impact, so try to avoid it if possible
         if !has_cfg_or_cfg_attr(&annotatable) {
@@ -100,39 +100,6 @@ impl CfgEval<'_> {
         // the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization
         // process is lossless, so this process is invisible to proc-macros.
 
-        let parse_annotatable_with: for<'a> fn(&mut Parser<'a>) -> PResult<'a, _> =
-            match annotatable {
-                Annotatable::Item(_) => {
-                    |parser| Ok(Annotatable::Item(parser.parse_item(ForceCollect::Yes)?.unwrap()))
-                }
-                Annotatable::AssocItem(_, AssocCtxt::Trait) => |parser| {
-                    Ok(Annotatable::AssocItem(
-                        parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap(),
-                        AssocCtxt::Trait,
-                    ))
-                },
-                Annotatable::AssocItem(_, AssocCtxt::Impl) => |parser| {
-                    Ok(Annotatable::AssocItem(
-                        parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap(),
-                        AssocCtxt::Impl,
-                    ))
-                },
-                Annotatable::ForeignItem(_) => |parser| {
-                    Ok(Annotatable::ForeignItem(
-                        parser.parse_foreign_item(ForceCollect::Yes)?.unwrap().unwrap(),
-                    ))
-                },
-                Annotatable::Stmt(_) => |parser| {
-                    Ok(Annotatable::Stmt(P(parser
-                        .parse_stmt_without_recovery(false, ForceCollect::Yes)?
-                        .unwrap())))
-                },
-                Annotatable::Expr(_) => {
-                    |parser| Ok(Annotatable::Expr(parser.parse_expr_force_collect()?))
-                }
-                _ => unreachable!(),
-            };
-
         // 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`)
         // to `None`-delimited groups containing the corresponding tokens. This
         // is normally delayed until the proc-macro server actually needs to
@@ -151,34 +118,55 @@ impl CfgEval<'_> {
         // Re-parse the tokens, setting the `capture_cfg` flag to save extra information
         // to the captured `AttrTokenStream` (specifically, we capture
         // `AttrTokenTree::AttrsTarget` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
+        //
+        // After that we have our re-parsed `AttrTokenStream`, recursively configuring
+        // our attribute target will correctly configure the tokens as well.
         let mut parser = Parser::new(&self.0.sess.psess, orig_tokens, None);
         parser.capture_cfg = true;
-        match parse_annotatable_with(&mut parser) {
-            Ok(a) => annotatable = a,
-            Err(err) => {
-                err.emit();
-                return annotatable;
+        let res: PResult<'_, Annotatable> = try {
+            match annotatable {
+                Annotatable::Item(_) => {
+                    let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
+                    Annotatable::Item(self.flat_map_item(item).pop().unwrap())
+                }
+                Annotatable::AssocItem(_, AssocCtxt::Trait) => {
+                    let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap();
+                    Annotatable::AssocItem(
+                        self.flat_map_assoc_item(item, AssocCtxt::Trait).pop().unwrap(),
+                        AssocCtxt::Trait,
+                    )
+                }
+                Annotatable::AssocItem(_, AssocCtxt::Impl) => {
+                    let item = parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap();
+                    Annotatable::AssocItem(
+                        self.flat_map_assoc_item(item, AssocCtxt::Impl).pop().unwrap(),
+                        AssocCtxt::Impl,
+                    )
+                }
+                Annotatable::ForeignItem(_) => {
+                    let item = parser.parse_foreign_item(ForceCollect::Yes)?.unwrap().unwrap();
+                    Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap())
+                }
+                Annotatable::Stmt(_) => {
+                    let stmt =
+                        parser.parse_stmt_without_recovery(false, ForceCollect::Yes)?.unwrap();
+                    Annotatable::Stmt(P(self.flat_map_stmt(stmt).pop().unwrap()))
+                }
+                Annotatable::Expr(_) => {
+                    let mut expr = parser.parse_expr_force_collect()?;
+                    self.visit_expr(&mut expr);
+                    Annotatable::Expr(expr)
+                }
+                _ => unreachable!(),
             }
-        }
+        };
 
-        // Now that we have our re-parsed `AttrTokenStream`, recursively configuring
-        // our attribute target will correctly configure the tokens as well.
-        match annotatable {
-            Annotatable::Item(item) => Annotatable::Item(self.flat_map_item(item).pop().unwrap()),
-            Annotatable::AssocItem(item, ctxt) => {
-                Annotatable::AssocItem(self.flat_map_assoc_item(item, ctxt).pop().unwrap(), ctxt)
-            }
-            Annotatable::ForeignItem(item) => {
-                Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap())
-            }
-            Annotatable::Stmt(stmt) => {
-                Annotatable::Stmt(P(self.flat_map_stmt(stmt.into_inner()).pop().unwrap()))
-            }
-            Annotatable::Expr(mut expr) => {
-                self.visit_expr(&mut expr);
-                Annotatable::Expr(expr)
+        match res {
+            Ok(ann) => ann,
+            Err(err) => {
+                err.emit();
+                annotatable
             }
-            _ => unreachable!(),
         }
     }
 }