From dbc307455632ba6d51899c0cbe5df0fb897e361b Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Sun, 3 Feb 2019 10:06:09 -0500 Subject: [PATCH] Make sure we match the entire pattern --- crates/ra_mbe/src/lib.rs | 32 ++++++++++++++++++++++++++++++- crates/ra_mbe/src/mbe_expander.rs | 3 +++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index 922256c03b..ec12192cc5 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs @@ -176,7 +176,7 @@ impl_froms!(TokenTree: Leaf, Subtree); } #[test] - fn test_fail_match_pattern_by_token() { + fn test_fail_match_pattern_by_first_token() { let macro_definition = r#" macro_rules! foo { ($ i:ident) => ( @@ -206,4 +206,34 @@ impl_froms!(TokenTree: Leaf, Subtree); assert_expansion(&rules, "foo! { + Baz }", "struct Baz ;"); } + #[test] + fn test_fail_match_pattern_by_last_token() { + let macro_definition = r#" + macro_rules! foo { + ($ i:ident) => ( + mod $ i {} + ); + ($ i:ident =) => ( + fn $ i() {} + ); + ($ i:ident +) => ( + struct $ i; + ) + } +"#; + + let source_file = ast::SourceFile::parse(macro_definition); + let macro_definition = source_file + .syntax() + .descendants() + .find_map(ast::MacroCall::cast) + .unwrap(); + + let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap(); + let rules = crate::MacroRules::parse(&definition_tt).unwrap(); + + assert_expansion(&rules, "foo! { foo }", "mod foo {}"); + assert_expansion(&rules, "foo! { bar = }", "fn bar () {}"); + assert_expansion(&rules, "foo! { Baz + }", "struct Baz ;"); + } } diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index af5beb786c..2945e73590 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs @@ -13,6 +13,9 @@ pub(crate) fn exapnd(rules: &crate::MacroRules, input: &tt::Subtree) -> Option Option { let mut input = TtCursor::new(input); let bindings = match_lhs(&rule.lhs, &mut input)?; + if !input.is_eof() { + return None; + } expand_subtree(&rule.rhs, &bindings, &mut Vec::new()) }