diff options
-rw-r--r-- | crates/ra_mbe/src/mbe_expander.rs | 20 | ||||
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 2 | ||||
-rw-r--r-- | crates/ra_mbe/src/tt_cursor.rs | 11 |
3 files changed, 28 insertions, 5 deletions
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index d5189b537..1b579f319 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs | |||
@@ -206,8 +206,24 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
206 | ); | 206 | ); |
207 | } | 207 | } |
208 | "vis" => { | 208 | "vis" => { |
209 | let vis = input.eat_vis().ok_or(ExpandError::UnexpectedToken)?.clone(); | 209 | // `vis` is optional |
210 | res.inner.insert(text.clone(), Binding::Simple(vis.into())); | 210 | if let Some(vis) = input.try_eat_vis() { |
211 | let vis = vis.clone(); | ||
212 | res.inner.insert(text.clone(), Binding::Simple(vis.into())); | ||
213 | } else { | ||
214 | // FIXME: Do we have a better way to represent an empty token ? | ||
215 | // Insert an empty subtree for empty token | ||
216 | res.inner.insert( | ||
217 | text.clone(), | ||
218 | Binding::Simple( | ||
219 | tt::Subtree { | ||
220 | delimiter: tt::Delimiter::None, | ||
221 | token_trees: vec![], | ||
222 | } | ||
223 | .into(), | ||
224 | ), | ||
225 | ); | ||
226 | } | ||
211 | } | 227 | } |
212 | 228 | ||
213 | _ => return Err(ExpandError::UnexpectedToken), | 229 | _ => return Err(ExpandError::UnexpectedToken), |
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs index 8176296e6..3554dc110 100644 --- a/crates/ra_mbe/src/subtree_source.rs +++ b/crates/ra_mbe/src/subtree_source.rs | |||
@@ -319,7 +319,7 @@ fn convert_ident(ident: &tt::Ident) -> TtToken { | |||
319 | 319 | ||
320 | fn convert_punct(p: &tt::Punct) -> TtToken { | 320 | fn convert_punct(p: &tt::Punct) -> TtToken { |
321 | let kind = match p.char { | 321 | let kind = match p.char { |
322 | // lexer may produce combpund tokens for these ones | 322 | // lexer may produce compound tokens for these ones |
323 | '.' => DOT, | 323 | '.' => DOT, |
324 | ':' => COLON, | 324 | ':' => COLON, |
325 | '=' => EQ, | 325 | '=' => EQ, |
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs index 8f15d215b..d85ab43e4 100644 --- a/crates/ra_mbe/src/tt_cursor.rs +++ b/crates/ra_mbe/src/tt_cursor.rs | |||
@@ -149,9 +149,16 @@ impl<'a> TtCursor<'a> { | |||
149 | self.eat_ident().cloned().map(|ident| tt::Leaf::from(ident).into()) | 149 | self.eat_ident().cloned().map(|ident| tt::Leaf::from(ident).into()) |
150 | } | 150 | } |
151 | 151 | ||
152 | pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> { | 152 | pub(crate) fn try_eat_vis(&mut self) -> Option<tt::TokenTree> { |
153 | // `vis` matcher is optional | ||
154 | let old_pos = self.pos; | ||
153 | let parser = Parser::new(&mut self.pos, self.subtree); | 155 | let parser = Parser::new(&mut self.pos, self.subtree); |
154 | parser.parse_vis() | 156 | |
157 | let res = parser.parse_vis(); | ||
158 | if res.is_none() { | ||
159 | self.pos = old_pos; | ||
160 | } | ||
161 | res | ||
155 | } | 162 | } |
156 | 163 | ||
157 | pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { | 164 | pub(crate) fn expect_char(&mut self, char: char) -> Result<(), ParseError> { |