diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index af5b22d1c6..70d9692383 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs @@ -86,10 +86,13 @@ pub(crate) fn macro_def( log::warn!("fail on macro_def to token tree: {:#?}", arg); None })?; - let rules = MacroRules::parse(&tt).ok().or_else(|| { - log::warn!("fail on macro_def parse: {:#?}", tt); - None - })?; + let rules = match MacroRules::parse(&tt) { + Ok(it) => it, + Err(err) => { + log::warn!("fail on macro_def parse: error: {:#?} {:#?}", err, tt); + return None; + } + }; Some(Arc::new((TokenExpander::MacroRules(rules), tmap))) } MacroDefKind::BuiltIn(expander) => { @@ -150,7 +153,9 @@ pub(crate) fn parse_macro( // Note: // The final goal we would like to make all parse_macro success, // such that the following log will not call anyway. - log::warn!("fail on macro_parse: (reason: {})", err,); + let loc: MacroCallLoc = db.lookup_intern_macro(macro_call_id); + let node = loc.kind.node(db); + log::warn!("fail on macro_parse: (reason: {} macro_call: {:#})", err, node.value); }) .ok()?; diff --git a/crates/ra_mbe/src/parser.rs b/crates/ra_mbe/src/parser.rs index 10a6f300a7..0341504326 100644 --- a/crates/ra_mbe/src/parser.rs +++ b/crates/ra_mbe/src/parser.rs @@ -90,7 +90,11 @@ fn next_op<'a>( ) -> Result, ExpandError> { let res = match first { tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '$', .. })) => { - let second = src.next().ok_or_else(|| err!("bad var 1"))?; + // Note that the '$' itself is a valid token inside macro_rules. + let second = match src.next() { + None => return Ok(Op::TokenTree(first)), + Some(it) => it, + }; match second { tt::TokenTree::Subtree(subtree) => { let (separator, kind) = parse_repeat(src)?; diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs index cb228702fb..1dba829154 100644 --- a/crates/ra_mbe/src/tests.rs +++ b/crates/ra_mbe/src/tests.rs @@ -23,6 +23,7 @@ mod rule_parsing { check("($($i:ident)*) => ($_)"); check("($($true:ident)*) => ($true)"); check("($($false:ident)*) => ($false)"); + check("($) => ($)"); } #[test]