Tweak how the library's interface is implemented
The stable/unstable modules still implemented the *very first* iteration of the
`proc_macro` API which has long since gone away. This tweaks notably the
`Literal` constructors to match what's proposed today, allowing lossless
conversions of literals on the stable implementation.
diff --git a/src/lib.rs b/src/lib.rs
index 715fccf..627ec39 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -455,20 +455,10 @@
_marker: marker::PhantomData<Rc<()>>,
}
-macro_rules! suffixed_int_literals {
+macro_rules! int_literals {
($($name:ident => $kind:ident,)*) => ($(
- #[allow(unused_comparisons)]
pub fn $name(n: $kind) -> Literal {
- Literal::_new(n.into())
- }
- )*)
-}
-
-macro_rules! unsuffixed_int_literals {
- ($($name:ident => $kind:ident,)*) => ($(
- #[allow(unused_comparisons)]
- pub fn $name(n: $kind) -> Literal {
- Literal::_new(imp::Literal::integer(n as i64))
+ Literal::_new(imp::Literal::$name(n))
}
)*)
}
@@ -481,7 +471,7 @@
}
}
- suffixed_int_literals! {
+ int_literals! {
u8_suffixed => u8,
u16_suffixed => u16,
u32_suffixed => u32,
@@ -492,9 +482,7 @@
i32_suffixed => i32,
i64_suffixed => i64,
isize_suffixed => isize,
- }
- unsuffixed_int_literals! {
u8_unsuffixed => u8,
u16_unsuffixed => u16,
u32_unsuffixed => u32,
@@ -509,30 +497,30 @@
pub fn f64_unsuffixed(f: f64) -> Literal {
assert!(f.is_finite());
- Literal::_new(imp::Literal::float(f))
+ Literal::_new(imp::Literal::f64_unsuffixed(f))
}
pub fn f64_suffixed(f: f64) -> Literal {
assert!(f.is_finite());
- Literal::_new(f.into())
+ Literal::_new(imp::Literal::f64_suffixed(f))
}
pub fn f32_unsuffixed(f: f32) -> Literal {
assert!(f.is_finite());
- Literal::_new(imp::Literal::float(f as f64))
+ Literal::_new(imp::Literal::f32_unsuffixed(f))
}
pub fn f32_suffixed(f: f32) -> Literal {
assert!(f.is_finite());
- Literal::_new(f.into())
+ Literal::_new(imp::Literal::f32_suffixed(f))
}
pub fn string(string: &str) -> Literal {
- Literal::_new(string.into())
+ Literal::_new(imp::Literal::string(string))
}
pub fn character(ch: char) -> Literal {
- Literal::_new(ch.into())
+ Literal::_new(imp::Literal::character(ch))
}
pub fn byte_string(s: &[u8]) -> Literal {
diff --git a/src/stable.rs b/src/stable.rs
index 8741d51..3e2f28c 100644
--- a/src/stable.rs
+++ b/src/stable.rs
@@ -1,6 +1,5 @@
-#![allow(dead_code)]
+#![cfg_attr(not(procmacro2_semver_exempt), allow(dead_code))]
-use std::ascii;
use std::borrow::Borrow;
use std::cell::RefCell;
#[cfg(procmacro2_semver_exempt)]
@@ -260,7 +259,7 @@
}
}
-/// Computes the offsets of each line in the given source string.
+/// Computesthe offsets of each line in the given source string.
#[cfg(procmacro2_semver_exempt)]
fn lines_offsets(s: &str) -> Vec<usize> {
let mut lines = vec![0];
@@ -406,7 +405,7 @@
pub fn new(string: &str, span: Span) -> Term {
Term {
intern: SYMBOLS.with(|s| s.borrow_mut().intern(string)),
- span,
+ span: span,
}
}
@@ -477,25 +476,86 @@
span: Span,
}
+macro_rules! suffixed_numbers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(format!(concat!("{}", stringify!($kind)), n))
+ }
+ )*)
+}
+
+macro_rules! unsuffixed_numbers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(n.to_string())
+ }
+ )*)
+}
+
impl Literal {
fn _new(text: String) -> Literal {
Literal {
- text,
+ text: text,
span: Span::call_site(),
}
}
- pub fn byte_char(byte: u8) -> Literal {
- match byte {
- 0 => Literal::_new(format!("b'\\0'")),
- b'\"' => Literal::_new(format!("b'\"'")),
- n => {
- let mut escaped = "b'".to_string();
- escaped.extend(ascii::escape_default(n).map(|c| c as char));
- escaped.push('\'');
- Literal::_new(escaped)
- }
+ suffixed_numbers! {
+ u8_suffixed => u8,
+ u16_suffixed => u16,
+ u32_suffixed => u32,
+ u64_suffixed => u64,
+ usize_suffixed => usize,
+ i8_suffixed => i8,
+ i16_suffixed => i16,
+ i32_suffixed => i32,
+ i64_suffixed => i64,
+ isize_suffixed => isize,
+
+ f32_suffixed => f32,
+ f64_suffixed => f64,
+ }
+
+ unsuffixed_numbers! {
+ u8_unsuffixed => u8,
+ u16_unsuffixed => u16,
+ u32_unsuffixed => u32,
+ u64_unsuffixed => u64,
+ usize_unsuffixed => usize,
+ i8_unsuffixed => i8,
+ i16_unsuffixed => i16,
+ i32_unsuffixed => i32,
+ i64_unsuffixed => i64,
+ isize_unsuffixed => isize,
+ }
+
+ pub fn f32_unsuffixed(f: f32) -> Literal {
+ let mut s = f.to_string();
+ if !s.contains(".") {
+ s.push_str(".0");
}
+ Literal::_new(s)
+ }
+
+ pub fn f64_unsuffixed(f: f64) -> Literal {
+ let mut s = f.to_string();
+ if !s.contains(".") {
+ s.push_str(".0");
+ }
+ Literal::_new(s)
+ }
+
+ pub fn string(t: &str) -> Literal {
+ let mut s = t.chars()
+ .flat_map(|c| c.escape_default())
+ .collect::<String>();
+ s.push('"');
+ s.insert(0, '"');
+ Literal::_new(s)
+ }
+
+ pub fn character(t: char) -> Literal {
+ Literal::_new(format!("'{}'", t.escape_default().collect::<String>()))
}
pub fn byte_string(bytes: &[u8]) -> Literal {
@@ -516,21 +576,6 @@
Literal::_new(escaped)
}
- pub fn float(n: f64) -> Literal {
- if !n.is_finite() {
- panic!("Invalid float literal {}", n);
- }
- let mut s = n.to_string();
- if !s.contains('.') {
- s += ".0";
- }
- Literal::_new(s)
- }
-
- pub fn integer(s: i64) -> Literal {
- Literal::_new(s.to_string())
- }
-
pub fn span(&self) -> Span {
self.span
}
@@ -546,54 +591,6 @@
}
}
-macro_rules! ints {
- ($($t:ty,)*) => {$(
- impl From<$t> for Literal {
- fn from(t: $t) -> Literal {
- Literal::_new(format!(concat!("{}", stringify!($t)), t))
- }
- }
- )*}
-}
-
-ints! {
- u8, u16, u32, u64, usize,
- i8, i16, i32, i64, isize,
-}
-
-macro_rules! floats {
- ($($t:ty,)*) => {$(
- impl From<$t> for Literal {
- fn from(t: $t) -> Literal {
- assert!(!t.is_nan());
- assert!(!t.is_infinite());
- Literal::_new(format!(concat!("{}", stringify!($t)), t))
- }
- }
- )*}
-}
-
-floats! {
- f32, f64,
-}
-
-impl<'a> From<&'a str> for Literal {
- fn from(t: &'a str) -> Literal {
- let mut s = t.chars()
- .flat_map(|c| c.escape_default())
- .collect::<String>();
- s.push('"');
- s.insert(0, '"');
- Literal::_new(s)
- }
-}
-
-impl From<char> for Literal {
- fn from(t: char) -> Literal {
- Literal::_new(format!("'{}'", t.escape_default().collect::<String>()))
- }
-}
-
named!(token_stream -> ::TokenStream, map!(
many0!(token_tree),
|trees| ::TokenStream::_new(TokenStream { inner: trees })
diff --git a/src/unstable.rs b/src/unstable.rs
index a178d18..55c72ba 100644
--- a/src/unstable.rs
+++ b/src/unstable.rs
@@ -1,6 +1,5 @@
-#![allow(dead_code)]
+#![cfg_attr(not(procmacro2_semver_exempt), allow(dead_code))]
-use std::ascii;
use std::fmt;
use std::iter;
use std::str::FromStr;
@@ -308,6 +307,22 @@
span: Span,
}
+macro_rules! suffixed_numbers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(proc_macro::Literal::$kind(n))
+ }
+ )*)
+}
+
+macro_rules! unsuffixed_integers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(proc_macro::Literal::integer(n as i128))
+ }
+ )*)
+}
+
impl Literal {
fn _new(lit: proc_macro::Literal) -> Literal {
Literal {
@@ -316,31 +331,56 @@
}
}
- pub fn byte_char(byte: u8) -> Literal {
- match byte {
- 0 => Literal::_new(to_literal("b'\\0'")),
- b'\"' => Literal::_new(to_literal("b'\"'")),
- n => {
- let mut escaped = "b'".to_string();
- escaped.extend(ascii::escape_default(n).map(|c| c as char));
- escaped.push('\'');
- Literal::_new(to_literal(&escaped))
- }
- }
+ suffixed_numbers! {
+ u8_suffixed => u8,
+ u16_suffixed => u16,
+ u32_suffixed => u32,
+ u64_suffixed => u64,
+ usize_suffixed => usize,
+ i8_suffixed => i8,
+ i16_suffixed => i16,
+ i32_suffixed => i32,
+ i64_suffixed => i64,
+ isize_suffixed => isize,
+
+ f32_suffixed => f32,
+ f64_suffixed => f64,
+ }
+
+ unsuffixed_integers! {
+ u8_unsuffixed => u8,
+ u16_unsuffixed => u16,
+ u32_unsuffixed => u32,
+ u64_unsuffixed => u64,
+ usize_unsuffixed => usize,
+ i8_unsuffixed => i8,
+ i16_unsuffixed => i16,
+ i32_unsuffixed => i32,
+ i64_unsuffixed => i64,
+ isize_unsuffixed => isize,
+ }
+
+ pub fn f32_unsuffixed(f: f32) -> Literal {
+ Literal::f64_unsuffixed(f.into())
+ }
+
+ pub fn f64_unsuffixed(f: f64) -> Literal {
+ Literal::_new(proc_macro::Literal::float(f))
+ }
+
+
+ pub fn string(t: &str) -> Literal {
+ Literal::_new(proc_macro::Literal::string(t))
+ }
+
+ pub fn character(t: char) -> Literal {
+ Literal::_new(proc_macro::Literal::character(t))
}
pub fn byte_string(bytes: &[u8]) -> Literal {
Literal::_new(proc_macro::Literal::byte_string(bytes))
}
- pub fn float(s: f64) -> Literal {
- Literal::_new(proc_macro::Literal::float(s))
- }
-
- pub fn integer(s: i64) -> Literal {
- Literal::_new(proc_macro::Literal::integer(s.into()))
- }
-
pub fn span(&self) -> Span {
self.span
}
@@ -361,52 +401,3 @@
self.lit.fmt(f)
}
}
-
-fn to_literal(s: &str) -> proc_macro::Literal {
- let stream = s.parse::<proc_macro::TokenStream>().unwrap();
- match stream.into_iter().next().unwrap().kind {
- proc_macro::TokenNode::Literal(l) => l,
- _ => unreachable!(),
- }
-}
-
-macro_rules! ints {
- ($($t:ident,)*) => {$(
- impl From<$t> for Literal {
- fn from(t: $t) -> Literal {
- Literal::_new(proc_macro::Literal::$t(t))
- }
- }
- )*}
-}
-
-ints! {
- u8, u16, u32, u64, usize,
- i8, i16, i32, i64, isize,
-}
-
-macro_rules! floats {
- ($($t:ident,)*) => {$(
- impl From<$t> for Literal {
- fn from(t: $t) -> Literal {
- Literal::_new(proc_macro::Literal::$t(t))
- }
- }
- )*}
-}
-
-floats! {
- f32, f64,
-}
-
-impl<'a> From<&'a str> for Literal {
- fn from(t: &'a str) -> Literal {
- Literal::_new(proc_macro::Literal::string(t))
- }
-}
-
-impl From<char> for Literal {
- fn from(t: char) -> Literal {
- Literal::_new(proc_macro::Literal::character(t))
- }
-}