Skip to content

Commit 7a59cd4

Browse files
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` : https://github.com/alexcrichton/proc-macro2/blob/4173a21dc497c67326095e438ff989cc63cd9279/src/lib.rs#L939 OT: I am quite happy we finally need to fix this bug :) Co-authored-by: Edwin Cheng <[email protected]>
2 parents b95b77f + a1b5cf8 commit 7a59cd4

File tree

5 files changed

+47
-14
lines changed

5 files changed

+47
-14
lines changed

crates/ra_mbe/src/mbe_expander/matcher.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ impl<'a> TtIter<'a> {
187187
_ => false,
188188
},
189189
Separator::Literal(lhs) => match fork.expect_literal() {
190-
Ok(rhs) => rhs.text == lhs.text,
190+
Ok(rhs) => match rhs {
191+
tt::Leaf::Literal(rhs) => rhs.text == lhs.text,
192+
tt::Leaf::Ident(rhs) => rhs.text == lhs.text,
193+
tt::Leaf::Punct(_) => false,
194+
},
191195
_ => false,
192196
},
193197
Separator::Puncts(lhss) => lhss.iter().all(|lhs| match fork.expect_punct() {

crates/ra_mbe/src/subtree_source.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,20 +158,17 @@ fn convert_literal(l: &tt::Literal) -> TtToken {
158158
let kind = lex_single_syntax_kind(&l.text)
159159
.map(|(kind, _error)| kind)
160160
.filter(|kind| kind.is_literal())
161-
.unwrap_or_else(|| match l.text.as_ref() {
162-
"true" => T![true],
163-
"false" => T![false],
164-
_ => panic!("Fail to convert given literal {:#?}", &l),
165-
});
161+
.unwrap_or_else(|| panic!("Fail to convert given literal {:#?}", &l));
166162

167163
TtToken { kind, is_joint_to_next: false, text: l.text.clone() }
168164
}
169165

170166
fn convert_ident(ident: &tt::Ident) -> TtToken {
171-
let kind = if ident.text.starts_with('\'') {
172-
LIFETIME
173-
} else {
174-
SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT)
167+
let kind = match ident.text.as_ref() {
168+
"true" => T![true],
169+
"false" => T![false],
170+
i if i.starts_with('\'') => LIFETIME,
171+
_ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT),
175172
};
176173

177174
TtToken { kind, is_joint_to_next: false, text: ident.text.clone() }

crates/ra_mbe/src/syntax_bridge.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ trait TokenConvertor {
376376
};
377377
}
378378
let leaf: tt::Leaf = match k {
379-
T![true] | T![false] => make_leaf!(Literal),
379+
T![true] | T![false] => make_leaf!(Ident),
380380
IDENT => make_leaf!(Ident),
381381
k if k.is_keyword() => make_leaf!(Ident),
382382
k if k.is_literal() => make_leaf!(Literal),

crates/ra_mbe/src/tests.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,36 @@ fn test_literal() {
10151015
.assert_expand_items(r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#);
10161016
}
10171017

1018+
#[test]
1019+
fn test_boolean_is_ident() {
1020+
parse_macro(
1021+
r#"
1022+
macro_rules! foo {
1023+
($lit0:literal, $lit1:literal) => { const VALUE: (bool,bool) = ($lit0,$lit1); };
1024+
}
1025+
"#,
1026+
)
1027+
.assert_expand(
1028+
r#"foo!(true,false);"#,
1029+
r#"
1030+
SUBTREE $
1031+
IDENT const 14
1032+
IDENT VALUE 15
1033+
PUNCH : [alone] 16
1034+
SUBTREE () 17
1035+
IDENT bool 18
1036+
PUNCH , [alone] 19
1037+
IDENT bool 20
1038+
PUNCH = [alone] 21
1039+
SUBTREE () 22
1040+
IDENT true 29
1041+
PUNCH , [joint] 25
1042+
IDENT false 31
1043+
PUNCH ; [alone] 28
1044+
"#,
1045+
);
1046+
}
1047+
10181048
#[test]
10191049
fn test_vis() {
10201050
parse_macro(

crates/ra_mbe/src/tt_iter.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ impl<'a> TtIter<'a> {
4040
}
4141
}
4242

43-
pub(crate) fn expect_literal(&mut self) -> Result<&'a tt::Literal, ()> {
44-
match self.expect_leaf()? {
45-
tt::Leaf::Literal(it) => Ok(it),
43+
pub(crate) fn expect_literal(&mut self) -> Result<&'a tt::Leaf, ()> {
44+
let it = self.expect_leaf()?;
45+
match it {
46+
tt::Leaf::Literal(_) => Ok(it),
47+
tt::Leaf::Ident(ident) if ident.text == "true" || ident.text == "false" => Ok(it),
4648
_ => Err(()),
4749
}
4850
}

0 commit comments

Comments
 (0)