From a49e00b4d7132dea8004de74b3580f369debd32a Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Wed, 28 Mar 2018 18:14:51 +0900 Subject: [PATCH] Avoid panicking on macro call with a single comma `parse_item` from libsyntax may return `None`, so we need to discard the result in that case. --- src/macros.rs | 18 +++++++++--------- src/spanned.rs | 2 +- tests/source/macros.rs | 2 ++ tests/target/macros.rs | 2 ++ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index bd8b86a49d4..649abdca3e7 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -76,8 +76,7 @@ pub enum MacroArg { Expr(ptr::P), Ty(ptr::P), Pat(ptr::P), - // `parse_item` returns `Option>`. - Item(Option>), + Item(ptr::P), } impl Rewrite for ast::Item { @@ -96,14 +95,14 @@ impl Rewrite for MacroArg { 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 { 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 @@ fn parse_macro_arg(parser: &mut Parser) -> Option { } 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 @@ fn parse_macro_arg(parser: &mut Parser) -> Option { }; } - 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| Some(x)); + parse_macro_arg!(Ty, parse_ty, |x: ptr::P| Some(x)); + parse_macro_arg!(Pat, parse_pat, |x: ptr::P| Some(x)); + // `parse_item` returns `Option>`. + parse_macro_arg!(Item, parse_item, |x: Option>| x); None } diff --git a/src/spanned.rs b/src/spanned.rs index bcbf6bd6060..41fa0da8dd1 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -187,7 +187,7 @@ impl Spanned for MacroArg { 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(), } } } diff --git a/tests/source/macros.rs b/tests/source/macros.rs index 11e6d52c6c8..030c56b5f82 100644 --- a/tests/source/macros.rs +++ b/tests/source/macros.rs @@ -10,6 +10,8 @@ peg_file! modname ("mygrammarfile.rustpeg"); fn main() { foo! ( ); + foo!(,); + bar!( a , b , c ); bar!( a , b , c , ); diff --git a/tests/target/macros.rs b/tests/target/macros.rs index f5d8e11e35e..0a103d5d61b 100644 --- a/tests/target/macros.rs +++ b/tests/target/macros.rs @@ -15,6 +15,8 @@ peg_file! modname("mygrammarfile.rustpeg"); fn main() { foo!(); + foo!(,); + bar!(a, b, c); bar!(a, b, c,);