Merge #4035
4035: Convert bool to ident instead of literal in mbe r=matklad a=edwin0cheng
Fixed #1249
Currently we treat boolean literal as `tt::Literal` , which makes parsing $lit:lit matcher easily.
However, proc-macro2 treat boolean literal as `ident` :
4173a21dc4/src/lib.rs (L939)
OT: I am quite happy we finally need to fix this bug :)
Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
7a59cd49ff
@ -187,7 +187,11 @@ fn eat_separator(&mut self, separator: &Separator) -> bool {
|
||||
_ => false,
|
||||
},
|
||||
Separator::Literal(lhs) => match fork.expect_literal() {
|
||||
Ok(rhs) => rhs.text == lhs.text,
|
||||
Ok(rhs) => match rhs {
|
||||
tt::Leaf::Literal(rhs) => rhs.text == lhs.text,
|
||||
tt::Leaf::Ident(rhs) => rhs.text == lhs.text,
|
||||
tt::Leaf::Punct(_) => false,
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
Separator::Puncts(lhss) => lhss.iter().all(|lhs| match fork.expect_punct() {
|
||||
|
@ -158,20 +158,17 @@ fn convert_literal(l: &tt::Literal) -> TtToken {
|
||||
let kind = lex_single_syntax_kind(&l.text)
|
||||
.map(|(kind, _error)| kind)
|
||||
.filter(|kind| kind.is_literal())
|
||||
.unwrap_or_else(|| match l.text.as_ref() {
|
||||
"true" => T![true],
|
||||
"false" => T![false],
|
||||
_ => panic!("Fail to convert given literal {:#?}", &l),
|
||||
});
|
||||
.unwrap_or_else(|| panic!("Fail to convert given literal {:#?}", &l));
|
||||
|
||||
TtToken { kind, is_joint_to_next: false, text: l.text.clone() }
|
||||
}
|
||||
|
||||
fn convert_ident(ident: &tt::Ident) -> TtToken {
|
||||
let kind = if ident.text.starts_with('\'') {
|
||||
LIFETIME
|
||||
} else {
|
||||
SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT)
|
||||
let kind = match ident.text.as_ref() {
|
||||
"true" => T![true],
|
||||
"false" => T![false],
|
||||
i if i.starts_with('\'') => LIFETIME,
|
||||
_ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT),
|
||||
};
|
||||
|
||||
TtToken { kind, is_joint_to_next: false, text: ident.text.clone() }
|
||||
|
@ -376,7 +376,7 @@ macro_rules! make_leaf {
|
||||
};
|
||||
}
|
||||
let leaf: tt::Leaf = match k {
|
||||
T![true] | T![false] => make_leaf!(Literal),
|
||||
T![true] | T![false] => make_leaf!(Ident),
|
||||
IDENT => make_leaf!(Ident),
|
||||
k if k.is_keyword() => make_leaf!(Ident),
|
||||
k if k.is_literal() => make_leaf!(Literal),
|
||||
|
@ -1015,6 +1015,36 @@ macro_rules! foo {
|
||||
.assert_expand_items(r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boolean_is_ident() {
|
||||
parse_macro(
|
||||
r#"
|
||||
macro_rules! foo {
|
||||
($lit0:literal, $lit1:literal) => { const VALUE: (bool,bool) = ($lit0,$lit1); };
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.assert_expand(
|
||||
r#"foo!(true,false);"#,
|
||||
r#"
|
||||
SUBTREE $
|
||||
IDENT const 14
|
||||
IDENT VALUE 15
|
||||
PUNCH : [alone] 16
|
||||
SUBTREE () 17
|
||||
IDENT bool 18
|
||||
PUNCH , [alone] 19
|
||||
IDENT bool 20
|
||||
PUNCH = [alone] 21
|
||||
SUBTREE () 22
|
||||
IDENT true 29
|
||||
PUNCH , [joint] 25
|
||||
IDENT false 31
|
||||
PUNCH ; [alone] 28
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vis() {
|
||||
parse_macro(
|
||||
|
@ -40,9 +40,11 @@ pub(crate) fn expect_ident(&mut self) -> Result<&'a tt::Ident, ()> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn expect_literal(&mut self) -> Result<&'a tt::Literal, ()> {
|
||||
match self.expect_leaf()? {
|
||||
tt::Leaf::Literal(it) => Ok(it),
|
||||
pub(crate) fn expect_literal(&mut self) -> Result<&'a tt::Leaf, ()> {
|
||||
let it = self.expect_leaf()?;
|
||||
match it {
|
||||
tt::Leaf::Literal(_) => Ok(it),
|
||||
tt::Leaf::Ident(ident) if ident.text == "true" || ident.text == "false" => Ok(it),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user