diff options
Diffstat (limited to 'crates/ra_mbe/src/mbe_expander.rs')
-rw-r--r-- | crates/ra_mbe/src/mbe_expander.rs | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index 00fb09a3b..91b6db522 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs | |||
@@ -179,10 +179,10 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
179 | // Enable followiing code when everything is fixed | 179 | // Enable followiing code when everything is fixed |
180 | // At least we can dogfood itself to not stackoverflow | 180 | // At least we can dogfood itself to not stackoverflow |
181 | // | 181 | // |
182 | // "tt" => { | 182 | "tt" => { |
183 | // let token = input.eat().ok_or(ExpandError::UnexpectedToken)?.clone(); | 183 | let token = input.eat().ok_or(ExpandError::UnexpectedToken)?.clone(); |
184 | // res.inner.insert(text.clone(), Binding::Simple(token.into())); | 184 | res.inner.insert(text.clone(), Binding::Simple(token.into())); |
185 | // } | 185 | } |
186 | "item" => { | 186 | "item" => { |
187 | let item = | 187 | let item = |
188 | input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); | 188 | input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); |
@@ -226,18 +226,36 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
226 | // This should be replaced by a propper macro-by-example implementation | 226 | // This should be replaced by a propper macro-by-example implementation |
227 | let mut limit = 128; | 227 | let mut limit = 128; |
228 | let mut counter = 0; | 228 | let mut counter = 0; |
229 | while let Ok(nested) = match_lhs(subtree, input) { | 229 | |
230 | counter += 1; | 230 | let mut memento = input.save(); |
231 | limit -= 1; | 231 | |
232 | if limit == 0 { | 232 | loop { |
233 | break; | 233 | match match_lhs(subtree, input) { |
234 | } | 234 | Ok(nested) => { |
235 | res.push_nested(nested)?; | 235 | counter += 1; |
236 | if let Some(separator) = *separator { | 236 | limit -= 1; |
237 | if !input.is_eof() { | 237 | if limit == 0 { |
238 | if input.eat_punct().map(|p| p.char) != Some(separator) { | 238 | break; |
239 | return Err(ExpandError::UnexpectedToken); | ||
240 | } | 239 | } |
240 | |||
241 | memento = input.save(); | ||
242 | res.push_nested(nested)?; | ||
243 | if counter == 1 { | ||
244 | if let crate::RepeatKind::ZeroOrOne = kind { | ||
245 | break; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | if let Some(separator) = *separator { | ||
250 | if input.eat_punct().map(|p| p.char) != Some(separator) { | ||
251 | input.rollback(memento); | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | Err(_) => { | ||
257 | input.rollback(memento); | ||
258 | break; | ||
241 | } | 259 | } |
242 | } | 260 | } |
243 | } | 261 | } |
@@ -246,10 +264,6 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
246 | crate::RepeatKind::OneOrMore if counter == 0 => { | 264 | crate::RepeatKind::OneOrMore if counter == 0 => { |
247 | return Err(ExpandError::UnexpectedToken); | 265 | return Err(ExpandError::UnexpectedToken); |
248 | } | 266 | } |
249 | crate::RepeatKind::ZeroOrOne if counter > 1 => { | ||
250 | return Err(ExpandError::UnexpectedToken); | ||
251 | } | ||
252 | |||
253 | _ => {} | 267 | _ => {} |
254 | } | 268 | } |
255 | } | 269 | } |
@@ -333,10 +347,7 @@ fn expand_tt( | |||
333 | } | 347 | } |
334 | } | 348 | } |
335 | nesting.pop().unwrap(); | 349 | nesting.pop().unwrap(); |
336 | 350 | if has_sep { | |
337 | // Dirty hack for remove the last sep | ||
338 | // if it is a "," undo the push | ||
339 | if has_sep && repeat.separator.unwrap() == ',' { | ||
340 | token_trees.pop(); | 351 | token_trees.pop(); |
341 | } | 352 | } |
342 | 353 | ||