Repository: rust-lang/rust-analyzer (Rust)

Issue:
Boolean Literal should not belong to `tt::Literal`
Currently we treat boolean literal as `tt::Literal` as it makes parsing `$lit:lit` matcher easily. 
However, `proc-macro2` treat boolean literal as `ident` :

https://github.com/alexcrichton/proc-macro2/blob/79c8ed793f9afe4bc491575a86256651dcf777b6/src/lib.rs#L940-L950

We should change it back to `tt::ident` for future proof of supporting proc-macro. 


Discussion:

Patch:
diff --git a/crates/ra_mbe/src/mbe_expander/matcher.rs b/crates/ra_mbe/src/mbe_expander/matcher.rs
index 9485c62b839a..78f9efa1b692 100644
--- a/crates/ra_mbe/src/mbe_expander/matcher.rs
+++ b/crates/ra_mbe/src/mbe_expander/matcher.rs
@@ -187,7 +187,11 @@ impl<'a> TtIter<'a> {
                 _ => 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() {
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs
index 46791efaaefb..d7866452dd94 100644
--- a/crates/ra_mbe/src/subtree_source.rs
+++ b/crates/ra_mbe/src/subtree_source.rs
@@ -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() }
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index 70899bc5d93f..2b4390eb26ed 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -376,7 +376,7 @@ trait TokenConvertor {
                 };
             }
             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),
diff --git a/crates/ra_mbe/src/tt_iter.rs b/crates/ra_mbe/src/tt_iter.rs
index 100184e66af6..46c4207185f6 100644
--- a/crates/ra_mbe/src/tt_iter.rs
+++ b/crates/ra_mbe/src/tt_iter.rs
@@ -40,9 +40,11 @@ impl<'a> TtIter<'a> {
         }
     }
 
-    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(()),
         }
     }


Test patch:
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs
index f2a726538c25..100ed41f234a 100644
--- a/crates/ra_mbe/src/tests.rs
+++ b/crates/ra_mbe/src/tests.rs
@@ -1015,6 +1015,36 @@ fn test_literal() {
     .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(