about summary refs log tree commit diff
path: root/library/proc_macro
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2021-04-29 12:08:35 -0700
committerDavid Tolnay <dtolnay@gmail.com>2021-05-19 11:38:24 -0700
commit34585cb678bc492be7e48ff48a2633f4ce1dc5ae (patch)
tree2e06e0541f8b26fb43c555d6f7066d8a32f083a8 /library/proc_macro
parent965bce48348bbcc3c86898bdb5e18d4c57c35d00 (diff)
downloadrust-34585cb678bc492be7e48ff48a2633f4ce1dc5ae.tar.gz
rust-34585cb678bc492be7e48ff48a2633f4ce1dc5ae.zip
impl FromStr for proc_macro::Literal
Diffstat (limited to 'library/proc_macro')
-rw-r--r--library/proc_macro/src/bridge/mod.rs14
-rw-r--r--library/proc_macro/src/lib.rs28
2 files changed, 42 insertions, 0 deletions
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 355ad1f9f88..a2953b68564 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -107,6 +107,7 @@ macro_rules! with_api {
             Literal {
                 fn drop($self: $S::Literal);
                 fn clone($self: &$S::Literal) -> $S::Literal;
+                fn from_str(s: &str) -> Result<$S::Literal, ()>;
                 fn debug_kind($self: &$S::Literal) -> String;
                 fn symbol($self: &$S::Literal) -> String;
                 fn suffix($self: &$S::Literal) -> Option<String>;
@@ -315,6 +316,19 @@ impl<T: Unmark> Unmark for Option<T> {
     }
 }
 
+impl<T: Mark, E: Mark> Mark for Result<T, E> {
+    type Unmarked = Result<T::Unmarked, E::Unmarked>;
+    fn mark(unmarked: Self::Unmarked) -> Self {
+        unmarked.map(T::mark).map_err(E::mark)
+    }
+}
+impl<T: Unmark, E: Unmark> Unmark for Result<T, E> {
+    type Unmarked = Result<T::Unmarked, E::Unmarked>;
+    fn unmark(self) -> Self::Unmarked {
+        self.map(T::unmark).map_err(E::unmark)
+    }
+}
+
 macro_rules! mark_noop {
     ($($ty:ty),* $(,)?) => {
         $(
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 525fd0fbe34..281999fe715 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -91,6 +91,12 @@ pub struct LexError {
     _inner: (),
 }
 
+impl LexError {
+    fn new() -> Self {
+        LexError { _inner: () }
+    }
+}
+
 #[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
 impl fmt::Display for LexError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1171,6 +1177,28 @@ impl Literal {
     }
 }
 
+/// Parse a single literal from its stringified representation.
+///
+/// In order to parse successfully, the input string must not contain anything
+/// but the literal token. Specifically, it must not contain whitespace or
+/// comments in addition to the literal.
+///
+/// The resulting literal token will have a `Span::call_site()` span.
+///
+/// NOTE: some errors may cause panics instead of returning `LexError`. We
+/// reserve the right to change these errors into `LexError`s later.
+#[stable(feature = "proc_macro_literal_parse", since = "1.54.0")]
+impl FromStr for Literal {
+    type Err = LexError;
+
+    fn from_str(src: &str) -> Result<Self, LexError> {
+        match bridge::client::Literal::from_str(src) {
+            Ok(literal) => Ok(Literal(literal)),
+            Err(()) => Err(LexError::new()),
+        }
+    }
+}
+
 // N.B., the bridge only provides `to_string`, implement `fmt::Display`
 // based on it (the reverse of the usual relationship between the two).
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]