diff options
author | Edwin Cheng <[email protected]> | 2020-12-11 09:59:04 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2020-12-11 09:59:04 +0000 |
commit | 175229ab3d3243991aebfad6cf7052c1b5bc4ecf (patch) | |
tree | e396b930e21ec66524ba5b69a0e8b385643c5412 /crates | |
parent | 41321d96789ed918eebda02ada76758765d19d16 (diff) |
negative sign matching in mbe matching for literal
Diffstat (limited to 'crates')
-rw-r--r-- | crates/mbe/src/mbe_expander/matcher.rs | 32 | ||||
-rw-r--r-- | crates/mbe/src/tests.rs | 13 |
2 files changed, 39 insertions, 6 deletions
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs index 3f8445897..4860b242d 100644 --- a/crates/mbe/src/mbe_expander/matcher.rs +++ b/crates/mbe/src/mbe_expander/matcher.rs | |||
@@ -356,6 +356,18 @@ impl<'a> TtIter<'a> { | |||
356 | ExpandResult { value: _, err: Some(_) } => None, | 356 | ExpandResult { value: _, err: Some(_) } => None, |
357 | } | 357 | } |
358 | } | 358 | } |
359 | |||
360 | pub(crate) fn eat_char(&mut self) -> Option<tt::TokenTree> { | ||
361 | let mut fork = self.clone(); | ||
362 | match fork.expect_char('-') { | ||
363 | Ok(_) => { | ||
364 | let tt = self.next().cloned(); | ||
365 | *self = fork; | ||
366 | tt | ||
367 | } | ||
368 | Err(_) => None, | ||
369 | } | ||
370 | } | ||
359 | } | 371 | } |
360 | 372 | ||
361 | pub(super) fn match_repeat( | 373 | pub(super) fn match_repeat( |
@@ -447,10 +459,22 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen | |||
447 | .expect_lifetime() | 459 | .expect_lifetime() |
448 | .map(|tt| Some(tt)) | 460 | .map(|tt| Some(tt)) |
449 | .map_err(|()| err!("expected lifetime")), | 461 | .map_err(|()| err!("expected lifetime")), |
450 | "literal" => input | 462 | "literal" => { |
451 | .expect_literal() | 463 | let neg = input.eat_char(); |
452 | .map(|literal| Some(tt::Leaf::from(literal.clone()).into())) | 464 | input |
453 | .map_err(|()| err!()), | 465 | .expect_literal() |
466 | .map(|literal| { | ||
467 | let lit = tt::Leaf::from(literal.clone()); | ||
468 | match neg { | ||
469 | None => Some(lit.into()), | ||
470 | Some(neg) => Some(tt::TokenTree::Subtree(tt::Subtree { | ||
471 | delimiter: None, | ||
472 | token_trees: vec![neg, lit.into()], | ||
473 | })), | ||
474 | } | ||
475 | }) | ||
476 | .map_err(|()| err!()) | ||
477 | } | ||
454 | // `vis` is optional | 478 | // `vis` is optional |
455 | "vis" => match input.eat_vis() { | 479 | "vis" => match input.eat_vis() { |
456 | Some(vis) => Ok(Some(vis)), | 480 | Some(vis) => Ok(Some(vis)), |
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs index 0796ceee1..843054fe8 100644 --- a/crates/mbe/src/tests.rs +++ b/crates/mbe/src/tests.rs | |||
@@ -1008,11 +1008,20 @@ fn test_literal() { | |||
1008 | parse_macro( | 1008 | parse_macro( |
1009 | r#" | 1009 | r#" |
1010 | macro_rules! foo { | 1010 | macro_rules! foo { |
1011 | ($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;}; | 1011 | ($ type:ty , $ lit:literal) => { const VALUE: $ type = $ lit;}; |
1012 | } | 1012 | } |
1013 | "#, | 1013 | "#, |
1014 | ) | 1014 | ) |
1015 | .assert_expand_items(r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#); | 1015 | .assert_expand_items(r#"foo!(u8,0);"#, r#"const VALUE : u8 = 0 ;"#); |
1016 | |||
1017 | parse_macro( | ||
1018 | r#" | ||
1019 | macro_rules! foo { | ||
1020 | ($ type:ty , $ lit:literal) => { const VALUE: $ type = $ lit;}; | ||
1021 | } | ||
1022 | "#, | ||
1023 | ) | ||
1024 | .assert_expand_items(r#"foo!(i32,-1);"#, r#"const VALUE : i32 = - 1 ;"#); | ||
1016 | } | 1025 | } |
1017 | 1026 | ||
1018 | #[test] | 1027 | #[test] |