From c5983b85fc9e520208684a8c625cdb96bb219b31 Mon Sep 17 00:00:00 2001
From: Edwin Cheng <edwin0cheng@gmail.com>
Date: Fri, 19 Apr 2019 21:21:47 +0800
Subject: Add literal matcher

---
 crates/ra_mbe/src/lib.rs          | 12 ++++++++++++
 crates/ra_mbe/src/mbe_expander.rs |  9 +++++++++
 crates/ra_mbe/src/tt_cursor.rs    | 14 ++++++++++++++
 3 files changed, 35 insertions(+)

(limited to 'crates/ra_mbe')

diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index a143eaa36..b9dd22dc9 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -797,4 +797,16 @@ MACRO_ITEMS@[0; 40)
         );
         assert_expansion(&rules, r#"foo!{'a}"#, r#"struct Ref < 'a > {s : & 'a str}"#);
     }
+
+    #[test]
+    fn test_literal() {
+        let rules = create_rules(
+            r#"
+        macro_rules! foo {
+              ($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;};
+        }
+"#,
+        );
+        assert_expansion(&rules, r#"foo!(u8 0)"#, r#"const VALUE: u8 = 0;"#);
+    }
 }
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index cacc3da19..548b15535 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -185,6 +185,15 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
                                 input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone();
                             res.inner.insert(text.clone(), Binding::Simple(lifetime.into()));
                         }
+                        "literal" => {
+                            let literal =
+                                input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone();
+                            res.inner.insert(
+                                text.clone(),
+                                Binding::Simple(tt::Leaf::from(literal).into()),
+                            );
+                        }
+
                         _ => return Err(ExpandError::UnexpectedToken),
                     }
                 }
diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs
index 9c49648fa..6184fb31f 100644
--- a/crates/ra_mbe/src/tt_cursor.rs
+++ b/crates/ra_mbe/src/tt_cursor.rs
@@ -41,6 +41,13 @@ impl<'a> TtCursor<'a> {
         }
     }
 
+    pub(crate) fn at_literal(&mut self) -> Option<&'a tt::Literal> {
+        match self.current() {
+            Some(tt::TokenTree::Leaf(tt::Leaf::Literal(i))) => Some(i),
+            _ => None,
+        }
+    }
+
     pub(crate) fn bump(&mut self) {
         self.pos += 1;
     }
@@ -79,6 +86,13 @@ impl<'a> TtCursor<'a> {
         })
     }
 
+    pub(crate) fn eat_literal(&mut self) -> Option<&'a tt::Literal> {
+        self.at_literal().map(|i| {
+            self.bump();
+            i
+        })
+    }
+
     pub(crate) fn eat_path(&mut self) -> Option<tt::TokenTree> {
         let parser = Parser::new(&mut self.pos, self.subtree);
         parser.parse_path()
-- 
cgit v1.2.3