aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_mbe/src/lib.rs32
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs3
2 files changed, 34 insertions, 1 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index 922256c03..ec12192cc 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -176,7 +176,7 @@ impl_froms!(TokenTree: Leaf, Subtree);
176 } 176 }
177 177
178 #[test] 178 #[test]
179 fn test_fail_match_pattern_by_token() { 179 fn test_fail_match_pattern_by_first_token() {
180 let macro_definition = r#" 180 let macro_definition = r#"
181 macro_rules! foo { 181 macro_rules! foo {
182 ($ i:ident) => ( 182 ($ i:ident) => (
@@ -206,4 +206,34 @@ impl_froms!(TokenTree: Leaf, Subtree);
206 assert_expansion(&rules, "foo! { + Baz }", "struct Baz ;"); 206 assert_expansion(&rules, "foo! { + Baz }", "struct Baz ;");
207 } 207 }
208 208
209 #[test]
210 fn test_fail_match_pattern_by_last_token() {
211 let macro_definition = r#"
212 macro_rules! foo {
213 ($ i:ident) => (
214 mod $ i {}
215 );
216 ($ i:ident =) => (
217 fn $ i() {}
218 );
219 ($ i:ident +) => (
220 struct $ i;
221 )
222 }
223"#;
224
225 let source_file = ast::SourceFile::parse(macro_definition);
226 let macro_definition = source_file
227 .syntax()
228 .descendants()
229 .find_map(ast::MacroCall::cast)
230 .unwrap();
231
232 let definition_tt = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
233 let rules = crate::MacroRules::parse(&definition_tt).unwrap();
234
235 assert_expansion(&rules, "foo! { foo }", "mod foo {}");
236 assert_expansion(&rules, "foo! { bar = }", "fn bar () {}");
237 assert_expansion(&rules, "foo! { Baz + }", "struct Baz ;");
238 }
209} 239}
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index af5beb786..2945e7359 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<t
13fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> Option<tt::Subtree> { 13fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> Option<tt::Subtree> {
14 let mut input = TtCursor::new(input); 14 let mut input = TtCursor::new(input);
15 let bindings = match_lhs(&rule.lhs, &mut input)?; 15 let bindings = match_lhs(&rule.lhs, &mut input)?;
16 if !input.is_eof() {
17 return None;
18 }
16 expand_subtree(&rule.rhs, &bindings, &mut Vec::new()) 19 expand_subtree(&rule.rhs, &bindings, &mut Vec::new())
17} 20}
18 21