Merge pull request #72 from alexcrichton/tweak-interfaces

Tweak implementation details for upcoming changes
diff --git a/src/lib.rs b/src/lib.rs
index 7ec1a73..627ec39 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -169,7 +169,6 @@
 }
 
 #[derive(Copy, Clone)]
-#[cfg_attr(procmacro2_semver_exempt, derive(PartialEq, Eq))]
 pub struct Span {
     inner: imp::Span,
     _marker: marker::PhantomData<Rc<()>>,
@@ -239,6 +238,11 @@
     pub fn join(&self, other: Span) -> Option<Span> {
         self.inner.join(other.inner).map(Span::_new)
     }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn eq(&self, other: &Span) -> bool {
+        self.inner.eq(&other.inner)
+    }
 }
 
 impl fmt::Debug for Span {
@@ -405,21 +409,19 @@
 #[derive(Copy, Clone)]
 pub struct Term {
     inner: imp::Term,
-    span: Span,
     _marker: marker::PhantomData<Rc<()>>,
 }
 
 impl Term {
-    fn _new(inner: imp::Term, span: Span) -> Term {
+    fn _new(inner: imp::Term) -> Term {
         Term {
             inner: inner,
-            span: span,
             _marker: marker::PhantomData,
         }
     }
 
     pub fn new(string: &str, span: Span) -> Term {
-        Term::_new(imp::Term::intern(string), span)
+        Term::_new(imp::Term::new(string, span.inner))
     }
 
     pub fn as_str(&self) -> &str {
@@ -427,11 +429,11 @@
     }
 
     pub fn span(&self) -> Span {
-        self.span
+        Span::_new(self.inner.span())
     }
 
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.inner.set_span(span.inner);
     }
 }
 
@@ -450,24 +452,13 @@
 #[derive(Clone)]
 pub struct Literal {
     inner: imp::Literal,
-    span: Span,
     _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))
         }
     )*)
 }
@@ -476,12 +467,11 @@
     fn _new(inner: imp::Literal) -> Literal {
         Literal {
             inner: inner,
-            span: Span::call_site(),
             _marker: marker::PhantomData,
         }
     }
 
-    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 {
@@ -540,11 +528,11 @@
     }
 
     pub fn span(&self) -> Span {
-        self.span
+        Span::_new(self.inner.span())
     }
 
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.inner.set_span(span.inner);
     }
 }
 
diff --git a/src/stable.rs b/src/stable.rs
index b04e4ca..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)]
@@ -8,7 +7,6 @@
 use std::collections::HashMap;
 use std::fmt;
 use std::iter;
-use std::marker::PhantomData;
 use std::rc::Rc;
 use std::str::FromStr;
 use std::vec;
@@ -105,13 +103,7 @@
                         Spacing::Joint => joint = true,
                     }
                 }
-                TokenTree::Literal(ref tt) => {
-                    write!(f, "{}", tt)?;
-                    // handle comments
-                    if tt.inner.0.starts_with("/") {
-                        write!(f, "\n")?;
-                    }
-                }
+                TokenTree::Literal(ref tt) => write!(f, "{}", tt)?,
             }
         }
 
@@ -267,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];
@@ -404,16 +396,16 @@
 #[derive(Copy, Clone)]
 pub struct Term {
     intern: usize,
-    not_send_sync: PhantomData<*const ()>,
+    span: Span,
 }
 
 thread_local!(static SYMBOLS: RefCell<Interner> = RefCell::new(Interner::new()));
 
 impl Term {
-    pub fn intern(string: &str) -> Term {
+    pub fn new(string: &str, span: Span) -> Term {
         Term {
             intern: SYMBOLS.with(|s| s.borrow_mut().intern(string)),
-            not_send_sync: PhantomData,
+            span: span,
         }
     }
 
@@ -424,6 +416,14 @@
             unsafe { &*(s as *const str) }
         })
     }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
+    }
 }
 
 impl fmt::Debug for Term {
@@ -471,22 +471,93 @@
 }
 
 #[derive(Clone, Debug)]
-pub struct Literal(String);
+pub struct Literal {
+    text: String,
+    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 {
-    pub fn byte_char(byte: u8) -> Literal {
-        match byte {
-            0 => Literal(format!("b'\\0'")),
-            b'\"' => Literal(format!("b'\"'")),
-            n => {
-                let mut escaped = "b'".to_string();
-                escaped.extend(ascii::escape_default(n).map(|c| c as char));
-                escaped.push('\'');
-                Literal(escaped)
-            }
+    fn _new(text: String) -> Literal {
+        Literal {
+            text: text,
+            span: Span::call_site(),
         }
     }
 
+    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 {
         let mut escaped = "b\"".to_string();
         for b in bytes {
@@ -502,100 +573,21 @@
             }
         }
         escaped.push('"');
-        Literal(escaped)
+        Literal::_new(escaped)
     }
 
-    pub fn doccomment(s: &str) -> Literal {
-        Literal(s.to_string())
+    pub fn span(&self) -> Span {
+        self.span
     }
 
-    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(s)
-    }
-
-    pub fn integer(s: i64) -> Literal {
-        Literal(s.to_string())
-    }
-
-    pub fn raw_string(s: &str, pounds: usize) -> Literal {
-        let mut ret = format!("r");
-        ret.extend((0..pounds).map(|_| "#"));
-        ret.push('"');
-        ret.push_str(s);
-        ret.push('"');
-        ret.extend((0..pounds).map(|_| "#"));
-        Literal(ret)
-    }
-
-    pub fn raw_byte_string(s: &str, pounds: usize) -> Literal {
-        let mut ret = format!("br");
-        ret.extend((0..pounds).map(|_| "#"));
-        ret.push('"');
-        ret.push_str(s);
-        ret.push('"');
-        ret.extend((0..pounds).map(|_| "#"));
-        Literal(ret)
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
     }
 }
 
 impl fmt::Display for Literal {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-macro_rules! ints {
-    ($($t:ty,)*) => {$(
-        impl From<$t> for Literal {
-            fn from(t: $t) -> Literal {
-                Literal(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(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(s)
-    }
-}
-
-impl From<char> for Literal {
-    fn from(t: char) -> Literal {
-        Literal(format!("'{}'", t.escape_default().collect::<String>()))
+        self.text.fmt(f)
     }
 }
 
@@ -710,7 +702,7 @@
             let end = start + len;
             Ok((
                 a,
-                ::Literal::_new(Literal(input.rest[start..end].to_string())),
+                ::Literal::_new(Literal::_new(input.rest[start..end].to_string())),
             ))
         }
         Err(LexError) => Err(LexError),
diff --git a/src/unstable.rs b/src/unstable.rs
index 49d1d2c..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;
@@ -60,7 +59,7 @@
                     Delimiter::Brace => proc_macro::Delimiter::Brace,
                     Delimiter::None => proc_macro::Delimiter::None,
                 };
-                let span = tt.span();
+                let span = tt.span().inner;
                 let group = proc_macro::TokenNode::Group(delim, tt.stream.inner.0);
                 (span, group)
             }
@@ -69,14 +68,14 @@
                     Spacing::Joint => proc_macro::Spacing::Joint,
                     Spacing::Alone => proc_macro::Spacing::Alone,
                 };
-                (tt.span(), proc_macro::TokenNode::Op(tt.op(), kind))
+                (tt.span().inner, proc_macro::TokenNode::Op(tt.op(), kind))
             }
-            TokenTree::Term(tt) => (tt.span(), proc_macro::TokenNode::Term(tt.inner.0)),
-            TokenTree::Literal(tt) => (tt.span(), proc_macro::TokenNode::Literal(tt.inner.0)),
+            TokenTree::Term(tt) => (tt.inner.span, proc_macro::TokenNode::Term(tt.inner.term)),
+            TokenTree::Literal(tt) => (tt.inner.span, proc_macro::TokenNode::Literal(tt.inner.lit)),
         };
         TokenStream(
             proc_macro::TokenTree {
-                span: span.inner.0,
+                span: span.0,
                 kind,
             }.into(),
         )
@@ -141,11 +140,17 @@
                 o.span = span;
                 o.into()
             }
-            proc_macro::TokenNode::Term(s) => ::Term::_new(Term(s), span).into(),
+            proc_macro::TokenNode::Term(s) => {
+                ::Term::_new(Term {
+                    term: s,
+                    span: span.inner,
+                }).into()
+            }
             proc_macro::TokenNode::Literal(l) => {
-                let mut l = ::Literal::_new(Literal(l));
-                l.span = span;
-                l.into()
+                ::Literal::_new(Literal {
+                    lit: l,
+                    span: span.inner,
+                }).into()
             }
         })
     }
@@ -264,135 +269,135 @@
 }
 
 #[derive(Copy, Clone)]
-pub struct Term(proc_macro::Term);
+pub struct Term {
+    term: proc_macro::Term,
+    span: Span,
+}
 
 impl Term {
-    pub fn intern(string: &str) -> Term {
-        Term(proc_macro::Term::intern(string))
+    pub fn new(string: &str, span: Span) -> Term {
+        Term {
+            term: proc_macro::Term::intern(string),
+            span,
+        }
     }
 
     pub fn as_str(&self) -> &str {
-        self.0.as_str()
+        self.term.as_str()
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
     }
 }
 
 impl fmt::Debug for Term {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
+        self.term.fmt(f)
     }
 }
 
 #[derive(Clone)]
-pub struct Literal(proc_macro::Literal);
+pub struct Literal {
+    lit: proc_macro::Literal,
+    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 {
-    pub fn byte_char(byte: u8) -> Literal {
-        match byte {
-            0 => Literal(to_literal("b'\\0'")),
-            b'\"' => Literal(to_literal("b'\"'")),
-            n => {
-                let mut escaped = "b'".to_string();
-                escaped.extend(ascii::escape_default(n).map(|c| c as char));
-                escaped.push('\'');
-                Literal(to_literal(&escaped))
-            }
+    fn _new(lit: proc_macro::Literal) -> Literal {
+        Literal {
+            lit,
+            span: Span::call_site(),
         }
     }
 
+    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(proc_macro::Literal::byte_string(bytes))
+        Literal::_new(proc_macro::Literal::byte_string(bytes))
     }
 
-    pub fn doccomment(s: &str) -> Literal {
-        Literal(to_literal(s))
+    pub fn span(&self) -> Span {
+        self.span
     }
 
-    pub fn float(s: f64) -> Literal {
-        Literal(proc_macro::Literal::float(s))
-    }
-
-    pub fn integer(s: i64) -> Literal {
-        Literal(proc_macro::Literal::integer(s.into()))
-    }
-
-    pub fn raw_string(s: &str, pounds: usize) -> Literal {
-        let mut ret = format!("r");
-        ret.extend((0..pounds).map(|_| "#"));
-        ret.push('"');
-        ret.push_str(s);
-        ret.push('"');
-        ret.extend((0..pounds).map(|_| "#"));
-        Literal(to_literal(&ret))
-    }
-
-    pub fn raw_byte_string(s: &str, pounds: usize) -> Literal {
-        let mut ret = format!("br");
-        ret.extend((0..pounds).map(|_| "#"));
-        ret.push('"');
-        ret.push_str(s);
-        ret.push('"');
-        ret.extend((0..pounds).map(|_| "#"));
-        Literal(to_literal(&ret))
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
     }
 }
 
 impl fmt::Display for Literal {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
+        self.lit.fmt(f)
     }
 }
 
 impl fmt::Debug for Literal {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.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(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(proc_macro::Literal::$t(t))
-            }
-        }
-    )*}
-}
-
-floats! {
-    f32, f64,
-}
-
-impl<'a> From<&'a str> for Literal {
-    fn from(t: &'a str) -> Literal {
-        Literal(proc_macro::Literal::string(t))
-    }
-}
-
-impl From<char> for Literal {
-    fn from(t: char) -> Literal {
-        Literal(proc_macro::Literal::character(t))
+        self.lit.fmt(f)
     }
 }