]> git.lizzy.rs Git - rust.git/commitdiff
Avoid panicking on macro call with a single comma
authorSeiichi Uchida <seuchida@gmail.com>
Wed, 28 Mar 2018 09:14:51 +0000 (18:14 +0900)
committerSeiichi Uchida <seuchida@gmail.com>
Wed, 28 Mar 2018 09:14:51 +0000 (18:14 +0900)
`parse_item` from libsyntax may return `None`, so we need to discard
the result in that case.

src/macros.rs
src/spanned.rs
tests/source/macros.rs
tests/target/macros.rs

index bd8b86a49d4c404ad2cbc37a2e99b4e6dd7d5681..649abdca3e7720cabbe0f271e4b35596143cfecf 100644 (file)
@@ -76,8 +76,7 @@ pub enum MacroArg {
     Expr(ptr::P<ast::Expr>),
     Ty(ptr::P<ast::Ty>),
     Pat(ptr::P<ast::Pat>),
-    // `parse_item` returns `Option<ptr::P<ast::Item>>`.
-    Item(Option<ptr::P<ast::Item>>),
+    Item(ptr::P<ast::Item>),
 }
 
 impl Rewrite for ast::Item {
@@ -96,14 +95,14 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
             MacroArg::Expr(ref expr) => expr.rewrite(context, shape),
             MacroArg::Ty(ref ty) => ty.rewrite(context, shape),
             MacroArg::Pat(ref pat) => pat.rewrite(context, shape),
-            MacroArg::Item(ref item) => item.as_ref().and_then(|item| item.rewrite(context, shape)),
+            MacroArg::Item(ref item) => item.rewrite(context, shape),
         }
     }
 }
 
 fn parse_macro_arg(parser: &mut Parser) -> Option<MacroArg> {
     macro_rules! parse_macro_arg {
-        ($macro_arg:ident, $parser:ident) => {
+        ($macro_arg:ident, $parser:ident, $f:expr) => {
             let mut cloned_parser = (*parser).clone();
             match cloned_parser.$parser() {
                 Ok(x) => {
@@ -112,7 +111,7 @@ macro_rules! parse_macro_arg {
                     } else {
                         // Parsing succeeded.
                         *parser = cloned_parser;
-                        return Some(MacroArg::$macro_arg(x.clone()));
+                        return Some(MacroArg::$macro_arg($f(x)?));
                     }
                 }
                 Err(mut e) => {
@@ -123,10 +122,11 @@ macro_rules! parse_macro_arg {
         };
     }
 
-    parse_macro_arg!(Expr, parse_expr);
-    parse_macro_arg!(Ty, parse_ty);
-    parse_macro_arg!(Pat, parse_pat);
-    parse_macro_arg!(Item, parse_item);
+    parse_macro_arg!(Expr, parse_expr, |x: ptr::P<ast::Expr>| Some(x));
+    parse_macro_arg!(Ty, parse_ty, |x: ptr::P<ast::Ty>| Some(x));
+    parse_macro_arg!(Pat, parse_pat, |x: ptr::P<ast::Pat>| Some(x));
+    // `parse_item` returns `Option<ptr::P<ast::Item>>`.
+    parse_macro_arg!(Item, parse_item, |x: Option<ptr::P<ast::Item>>| x);
 
     None
 }
index bcbf6bd60601e7d13ca215ddf7dbcb246e85df6e..41fa0da8dd1c502f7795a9cd1d04a246c995a7a9 100644 (file)
@@ -187,7 +187,7 @@ fn span(&self) -> Span {
             MacroArg::Expr(ref expr) => expr.span(),
             MacroArg::Ty(ref ty) => ty.span(),
             MacroArg::Pat(ref pat) => pat.span(),
-            MacroArg::Item(ref item) => item.as_ref().unwrap().span(),
+            MacroArg::Item(ref item) => item.span(),
         }
     }
 }
index 11e6d52c6c8e8ba0641d0305f25ff3e7807bcf8d..030c56b5f8297139dc1e7e1fe8686d828507b4df 100644 (file)
@@ -10,6 +10,8 @@
 fn main() {
     foo! ( );
 
+    foo!(,);
+
     bar!( a , b , c );
 
     bar!( a , b , c , );
index f5d8e11e35ebb6969426e47b3c43234d112da6a6..0a103d5d61b2dc86e3b2511dc0cb199473ec56de 100644 (file)
@@ -15,6 +15,8 @@
 fn main() {
     foo!();
 
+    foo!(,);
+
     bar!(a, b, c);
 
     bar!(a, b, c,);