aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/mbe_expander.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_mbe/src/mbe_expander.rs')
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs57
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