diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fallback.rs | 20 | ||||
-rw-r--r-- | src/lib.rs | 13 | ||||
-rw-r--r-- | src/parse.rs | 4 | ||||
-rw-r--r-- | src/wrapper.rs | 38 |
4 files changed, 67 insertions, 8 deletions
diff --git a/src/fallback.rs b/src/fallback.rs index 50d10db..3d2feae 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -43,6 +43,12 @@ impl LexError { pub(crate) fn span(&self) -> Span { self.span } + + fn call_site() -> Self { + LexError { + span: Span::call_site(), + } + } } impl TokenStream { @@ -887,6 +893,20 @@ impl Literal { } } +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result<Self, Self::Err> { + let cursor = get_cursor(repr); + if let Ok((_rest, literal)) = parse::literal(cursor) { + if literal.text.len() == repr.len() { + return Ok(literal); + } + } + Err(LexError::call_site()) + } +} + impl Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Display::fmt(&self.text, f) @@ -78,7 +78,7 @@ //! a different thread. // Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.26")] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.27")] #![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] #![cfg_attr(super_unstable, feature(proc_macro_raw_ident, proc_macro_def_site))] #![cfg_attr(doc_cfg, feature(doc_cfg))] @@ -1203,6 +1203,17 @@ impl Literal { } } +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result<Self, LexError> { + repr.parse().map(Literal::_new).map_err(|inner| LexError { + inner, + _marker: Marker, + }) + } +} + impl Debug for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Debug::fmt(&self.inner, f) diff --git a/src/parse.rs b/src/parse.rs index e5caed8..13a05a8 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -59,7 +59,7 @@ impl<'a> Cursor<'a> { } } -struct Reject; +pub(crate) struct Reject; type PResult<'a, O> = Result<(Cursor<'a>, O), Reject>; fn skip_whitespace(input: Cursor) -> Cursor { @@ -310,7 +310,7 @@ fn ident_not_raw(input: Cursor) -> PResult<&str> { Ok((input.advance(end), &input.rest[..end])) } -fn literal(input: Cursor) -> PResult<Literal> { +pub(crate) fn literal(input: Cursor) -> PResult<Literal> { let rest = literal_nocapture(input)?; let end = input.len() - rest.len(); Ok((rest, Literal::_new(input.rest[..end].to_string()))) diff --git a/src/wrapper.rs b/src/wrapper.rs index 24d86e8..2829dd7 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -29,6 +29,14 @@ pub(crate) enum LexError { Fallback(fallback::LexError), } +impl LexError { + fn call_site() -> Self { + LexError::Fallback(fallback::LexError { + span: fallback::Span::call_site(), + }) + } +} + fn mismatch() -> ! { panic!("stable/nightly mismatch") } @@ -108,11 +116,7 @@ impl FromStr for TokenStream { // Work around https://github.com/rust-lang/rust/issues/58736. fn proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError> { let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler)); - result.unwrap_or_else(|_| { - Err(LexError::Fallback(fallback::LexError { - span: fallback::Span::call_site(), - })) - }) + result.unwrap_or_else(|_| Err(LexError::call_site())) } impl Display for TokenStream { @@ -912,6 +916,30 @@ impl From<fallback::Literal> for Literal { } } +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result<Self, Self::Err> { + if inside_proc_macro() { + // TODO: use libproc_macro's FromStr impl once it is available in + // rustc. https://github.com/rust-lang/rust/pull/84717 + let tokens = proc_macro_parse(repr)?; + let mut iter = tokens.into_iter(); + if let (Some(proc_macro::TokenTree::Literal(literal)), None) = + (iter.next(), iter.next()) + { + if literal.to_string().len() == repr.len() { + return Ok(Literal::Compiler(literal)); + } + } + Err(LexError::call_site()) + } else { + let literal = fallback::Literal::from_str(repr)?; + Ok(Literal::Fallback(literal)) + } + } +} + impl Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { |