aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_mbe/src')
-rw-r--r--crates/ra_mbe/src/lib.rs13
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs5
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs5
-rw-r--r--crates/ra_mbe/src/tt_cursor.rs4
4 files changed, 25 insertions, 2 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index ae8a62036..a143eaa36 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -209,7 +209,6 @@ impl_froms!(TokenTree: Leaf, Subtree);
209 209
210 pub(crate) fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) { 210 pub(crate) fn assert_expansion(rules: &MacroRules, invocation: &str, expansion: &str) {
211 let expanded = expand(rules, invocation); 211 let expanded = expand(rules, invocation);
212 assert_eq!(expanded.to_string(), expansion);
213 212
214 let tree = token_tree_to_macro_items(&expanded); 213 let tree = token_tree_to_macro_items(&expanded);
215 214
@@ -786,4 +785,16 @@ MACRO_ITEMS@[0; 40)
786 ); 785 );
787 assert_expansion(&rules, r#"foo! { fn foo() {} }"#, r#"fn foo () {}"#); 786 assert_expansion(&rules, r#"foo! { fn foo() {} }"#, r#"fn foo () {}"#);
788 } 787 }
788
789 #[test]
790 fn test_lifetime() {
791 let rules = create_rules(
792 r#"
793 macro_rules! foo {
794 ($ lt:lifetime) => { struct Ref<$ lt>{ s: &$ lt str } }
795 }
796"#,
797 );
798 assert_expansion(&rules, r#"foo!{'a}"#, r#"struct Ref < 'a > {s : & 'a str}"#);
799 }
789} 800}
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index 4261dee8d..cacc3da19 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -180,6 +180,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
180 input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); 180 input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone();
181 res.inner.insert(text.clone(), Binding::Simple(item.into())); 181 res.inner.insert(text.clone(), Binding::Simple(item.into()));
182 } 182 }
183 "lifetime" => {
184 let lifetime =
185 input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone();
186 res.inner.insert(text.clone(), Binding::Simple(lifetime.into()));
187 }
183 _ => return Err(ExpandError::UnexpectedToken), 188 _ => return Err(ExpandError::UnexpectedToken),
184 } 189 }
185 } 190 }
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index 5844d3f12..38a481029 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -157,7 +157,10 @@ fn convert_tt(
157 ); 157 );
158 } 158 }
159 } else { 159 } else {
160 let child = if token.kind().is_keyword() || token.kind() == IDENT { 160 let child: tt::TokenTree = if token.kind().is_keyword()
161 || token.kind() == IDENT
162 || token.kind() == LIFETIME
163 {
161 let relative_range = token.range() - global_offset; 164 let relative_range = token.range() - global_offset;
162 let id = token_map.alloc(relative_range); 165 let id = token_map.alloc(relative_range);
163 let text = token.text().clone(); 166 let text = token.text().clone();
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs
index 04bb6b563..9c49648fa 100644
--- a/crates/ra_mbe/src/tt_cursor.rs
+++ b/crates/ra_mbe/src/tt_cursor.rs
@@ -119,6 +119,10 @@ impl<'a> TtCursor<'a> {
119 parser.parse_item() 119 parser.parse_item()
120 } 120 }
121 121
122 pub(crate) fn eat_lifetime(&mut self) -> Option<tt::TokenTree> {
123 self.eat_ident().cloned().map(|ident| tt::Leaf::from(ident).into())
124 }
125
122 pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { 126 pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> {
123 if self.at_char(char) { 127 if self.at_char(char) {
124 self.bump(); 128 self.bump();