negative sign matching in mbe matching for literal

This commit is contained in:
Edwin Cheng 2020-12-11 17:59:04 +08:00
parent 41321d9678
commit 175229ab3d
2 changed files with 39 additions and 6 deletions

View file

@ -356,6 +356,18 @@ impl<'a> TtIter<'a> {
ExpandResult { value: _, err: Some(_) } => None,
}
}
pub(crate) fn eat_char(&mut self) -> Option<tt::TokenTree> {
let mut fork = self.clone();
match fork.expect_char('-') {
Ok(_) => {
let tt = self.next().cloned();
*self = fork;
tt
}
Err(_) => None,
}
}
}
pub(super) fn match_repeat(
@ -447,10 +459,22 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
.expect_lifetime()
.map(|tt| Some(tt))
.map_err(|()| err!("expected lifetime")),
"literal" => input
"literal" => {
let neg = input.eat_char();
input
.expect_literal()
.map(|literal| Some(tt::Leaf::from(literal.clone()).into()))
.map_err(|()| err!()),
.map(|literal| {
let lit = tt::Leaf::from(literal.clone());
match neg {
None => Some(lit.into()),
Some(neg) => Some(tt::TokenTree::Subtree(tt::Subtree {
delimiter: None,
token_trees: vec![neg, lit.into()],
})),
}
})
.map_err(|()| err!())
}
// `vis` is optional
"vis" => match input.eat_vis() {
Some(vis) => Ok(Some(vis)),

View file

@ -1008,11 +1008,20 @@ fn test_literal() {
parse_macro(
r#"
macro_rules! foo {
($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;};
($ type:ty , $ lit:literal) => { const VALUE: $ type = $ lit;};
}
"#,
)
.assert_expand_items(r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#);
.assert_expand_items(r#"foo!(u8,0);"#, r#"const VALUE : u8 = 0 ;"#);
parse_macro(
r#"
macro_rules! foo {
($ type:ty , $ lit:literal) => { const VALUE: $ type = $ lit;};
}
"#,
)
.assert_expand_items(r#"foo!(i32,-1);"#, r#"const VALUE : i32 = - 1 ;"#);
}
#[test]