Use TokenTree straight from proc_macro2
diff --git a/src/attr.rs b/src/attr.rs
index 6069302..4171553 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -3,11 +3,16 @@
 
 use std::iter;
 
-use proc_macro2::{self, Delimiter, TokenNode, Spacing};
+use proc_macro2::{Delimiter, TokenNode, TokenTree, Spacing};
+
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
+#[cfg(feature = "extra-traits")]
+use mac::SliceTokenTreeHelper;
 
 ast_struct! {
     /// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
-    pub struct Attribute {
+    pub struct Attribute #manual_extra_traits {
         pub style: AttrStyle,
         pub pound_token: Token![#],
         pub bracket_token: token::Bracket,
@@ -28,6 +33,35 @@
     }
 }
 
+#[cfg(feature = "extra-traits")]
+impl Eq for Attribute {}
+
+#[cfg(feature = "extra-traits")]
+impl PartialEq for Attribute {
+    fn eq(&self, other: &Self) -> bool {
+        self.style == other.style
+            && self.pound_token == other.pound_token
+            && self.bracket_token == other.bracket_token
+            && self.path == other.path
+            && SliceTokenTreeHelper(&self.tts) == SliceTokenTreeHelper(&other.tts)
+            && self.is_sugared_doc == other.is_sugared_doc
+    }
+}
+
+#[cfg(feature = "extra-traits")]
+impl Hash for Attribute {
+    fn hash<H>(&self, state: &mut H)
+        where H: Hasher
+    {
+        self.style.hash(state);
+        self.pound_token.hash(state);
+        self.bracket_token.hash(state);
+        self.path.hash(state);
+        SliceTokenTreeHelper(&self.tts).hash(state);
+        self.is_sugared_doc.hash(state);
+    }
+}
+
 impl Attribute {
     /// Parses the tokens after the path as a [`MetaItem`](enum.MetaItem.html) if possible.
     pub fn meta_item(&self) -> Option<MetaItem> {
@@ -42,11 +76,11 @@
         }
 
         if self.tts.len() == 1 {
-            if let TokenNode::Group(Delimiter::Parenthesis, ref ts) = self.tts[0].0.kind {
+            if let TokenNode::Group(Delimiter::Parenthesis, ref ts) = self.tts[0].kind {
                 let tokens = ts.clone().into_iter().collect::<Vec<_>>();
                 if let Some(nested_meta_items) = list_of_nested_meta_items_from_tokens(&tokens) {
                     return Some(MetaItem::List(MetaItemList {
-                        paren_token: token::Paren(self.tts[0].0.span),
+                        paren_token: token::Paren(self.tts[0].span),
                         ident: *name,
                         nested: nested_meta_items,
                     }));
@@ -55,14 +89,14 @@
         }
 
         if self.tts.len() == 2 {
-            if let TokenNode::Op('=', Spacing::Alone) = self.tts[0].0.kind {
-                if let TokenNode::Literal(ref lit) = self.tts[1].0.kind {
+            if let TokenNode::Op('=', Spacing::Alone) = self.tts[0].kind {
+                if let TokenNode::Literal(ref lit) = self.tts[1].kind {
                     return Some(MetaItem::NameValue(MetaNameValue {
                         ident: *name,
-                        eq_token: Token![=]([self.tts[0].0.span]),
+                        eq_token: Token![=]([self.tts[0].span]),
                         lit: Lit {
                             value: LitKind::Other(lit.clone()),
-                            span: self.tts[1].0.span,
+                            span: self.tts[1].span,
                         },
                     }));
                 }
@@ -73,8 +107,8 @@
     }
 }
 
-fn nested_meta_item_from_tokens(tts: &[proc_macro2::TokenTree])
-    -> Option<(NestedMetaItem, &[proc_macro2::TokenTree])>
+fn nested_meta_item_from_tokens(tts: &[TokenTree])
+    -> Option<(NestedMetaItem, &[TokenTree])>
 {
     assert!(!tts.is_empty());
 
@@ -130,7 +164,7 @@
     }
 }
 
-fn list_of_nested_meta_items_from_tokens(mut tts: &[proc_macro2::TokenTree])
+fn list_of_nested_meta_items_from_tokens(mut tts: &[TokenTree])
     -> Option<Delimited<NestedMetaItem, Token![,]>>
 {
     let mut delimited = Delimited::new();
@@ -311,7 +345,7 @@
                 bang: punct!(!) >>
                 path_and_tts: brackets!(tuple!(
                     call!(::Path::parse_mod_style),
-                    call!(::TokenTree::parse_list)
+                    call!(mac::parsing::parse_tt_list)
                 )) >>
                 ({
                     let ((path, tts), bracket) = path_and_tts;
@@ -333,8 +367,8 @@
                     style: AttrStyle::Inner(<Token![!]>::default()),
                     path: "doc".into(),
                     tts: vec![
-                        ::TokenTree(eq()),
-                        ::TokenTree(lit),
+                        eq(),
+                        lit,
                     ],
                     is_sugared_doc: true,
                     pound_token: <Token![#]>::default(),
@@ -348,7 +382,7 @@
                 pound: punct!(#) >>
                 path_and_tts: brackets!(tuple!(
                     call!(::Path::parse_mod_style),
-                    call!(::TokenTree::parse_list)
+                    call!(mac::parsing::parse_tt_list)
                 )) >>
                 ({
                     let ((path, tts), bracket) = path_and_tts;
@@ -370,8 +404,8 @@
                     style: AttrStyle::Outer,
                     path: "doc".into(),
                     tts: vec![
-                        ::TokenTree(eq()),
-                        ::TokenTree(lit),
+                        eq(),
+                        lit,
                     ],
                     is_sugared_doc: true,
                     pound_token: <Token![#]>::default(),
diff --git a/src/expr.rs b/src/expr.rs
index 21ed9fa..ba1fc02 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1847,10 +1847,10 @@
             Macro {
                 path: what,
                 bang_token: bang,
-                tokens: vec![TokenTree(proc_macro2::TokenTree {
+                tokens: vec![proc_macro2::TokenTree {
                     span: (data.1).0,
                     kind: TokenNode::Group(Delimiter::Brace, data.0),
-                })],
+                }],
             },
             match semi {
                 Some(semi) => MacStmtStyle::Semicolon(semi),
diff --git a/src/item.rs b/src/item.rs
index 5467f26..9549823 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -1,5 +1,11 @@
 use super::*;
 use delimited::Delimited;
+use proc_macro2::TokenTree;
+
+#[cfg(feature = "extra-traits")]
+use mac::TokenTreeHelper;
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
 
 ast_enum_of_structs! {
     /// Things that can appear directly inside of a module.
@@ -192,7 +198,7 @@
             pub mac: Macro,
         }),
         /// FIXME will need to revisit what this looks like in the AST.
-        pub Macro2(ItemMacro2 {
+        pub Macro2(ItemMacro2 #manual_extra_traits {
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub macro_token: Token![macro],
@@ -203,6 +209,35 @@
     }
 }
 
+#[cfg(feature = "extra-traits")]
+impl Eq for ItemMacro2 {}
+
+#[cfg(feature = "extra-traits")]
+impl PartialEq for ItemMacro2 {
+    fn eq(&self, other: &Self) -> bool {
+        self.attrs == other.attrs
+            && self.vis == other.vis
+            && self.macro_token == other.macro_token
+            && self.ident == other.ident
+            && TokenTreeHelper(&self.args) == TokenTreeHelper(&other.args)
+            && TokenTreeHelper(&self.body) == TokenTreeHelper(&other.body)
+    }
+}
+
+#[cfg(feature = "extra-traits")]
+impl Hash for ItemMacro2 {
+    fn hash<H>(&self, state: &mut H)
+        where H: Hasher
+    {
+        self.attrs.hash(state);
+        self.vis.hash(state);
+        self.macro_token.hash(state);
+        self.ident.hash(state);
+        TokenTreeHelper(&self.args).hash(state);
+        TokenTreeHelper(&self.body).hash(state);
+    }
+}
+
 impl From<DeriveInput> for Item {
     fn from(input: DeriveInput) -> Item {
         match input.body {
@@ -484,8 +519,8 @@
         what: syn!(Path) >>
         bang: punct!(!) >>
         ident: option!(syn!(Ident)) >>
-        body: call!(TokenTree::parse_delimited) >>
-        cond!(!body.is_braced(), punct!(;)) >>
+        body: call!(mac::parsing::parse_tt_delimited) >>
+        cond!(!mac::is_braced(&body), punct!(;)) >>
         (ItemMacro {
             attrs: attrs,
             ident: ident,
@@ -503,8 +538,8 @@
         vis: syn!(Visibility) >>
         macro_: keyword!(macro) >>
         ident: syn!(Ident) >>
-        args: call!(TokenTree::parse_delimited) >>
-        body: call!(TokenTree::parse_delimited) >>
+        args: call!(mac::parsing::parse_tt_delimited) >>
+        body: call!(mac::parsing::parse_tt_delimited) >>
         (ItemMacro2 {
             attrs: attrs,
             vis: vis,
diff --git a/src/lib.rs b/src/lib.rs
index 474a0c0..e133f75 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -90,7 +90,7 @@
 pub use lit::{Lit, LitKind};
 
 mod mac;
-pub use mac::{Macro, TokenTree};
+pub use mac::Macro;
 
 mod derive;
 pub use derive::{Body, DeriveInput, BodyEnum, BodyStruct};
diff --git a/src/lit.rs b/src/lit.rs
index f55e398..9480563 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -1,9 +1,7 @@
 use std::fmt;
 use std::hash::{Hash, Hasher};
 
-use proc_macro2::{self, Span, Literal, TokenNode, Term};
-
-use TokenTree;
+use proc_macro2::{self, Span, Literal, TokenNode, TokenTree, Term};
 
 #[derive(Clone)]
 pub struct Lit {
@@ -24,10 +22,10 @@
             LitKind::Bool(false) => TokenNode::Term(Term::intern("false")),
             LitKind::Other(l) => TokenNode::Literal(l),
         };
-        TokenTree(proc_macro2::TokenTree {
+        proc_macro2::TokenTree {
             span: self.span,
             kind: kind,
-        })
+        }
     }
 }
 
diff --git a/src/mac.rs b/src/mac.rs
index e370acd..b2a6a19 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -1,45 +1,66 @@
-#[cfg(feature = "extra-traits")]
-use std::fmt;
-
 use super::*;
 
-use proc_macro2::{TokenNode, Delimiter};
+use proc_macro2::{TokenNode, TokenTree, Delimiter};
+
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
 
 ast_struct! {
     /// Represents a macro invocation. The Path indicates which macro
     /// is being invoked, and the vector of token-trees contains the source
     /// of the macro invocation.
-    pub struct Macro {
+    pub struct Macro #manual_extra_traits {
         pub path: Path,
         pub bang_token: Token![!],
         pub tokens: Vec<TokenTree>,
     }
 }
 
-#[cfg_attr(feature = "clone-impls", derive(Clone))]
-pub struct TokenTree(pub proc_macro2::TokenTree);
+#[cfg(feature = "extra-traits")]
+impl Eq for Macro {}
+
+#[cfg(feature = "extra-traits")]
+impl PartialEq for Macro {
+    fn eq(&self, other: &Self) -> bool {
+        self.path == other.path
+            && self.bang_token == other.bang_token
+            && SliceTokenTreeHelper(&self.tokens) == SliceTokenTreeHelper(&other.tokens)
+    }
+}
+
+#[cfg(feature = "extra-traits")]
+impl Hash for Macro {
+    fn hash<H>(&self, state: &mut H)
+        where H: Hasher
+    {
+        self.path.hash(state);
+        self.bang_token.hash(state);
+        SliceTokenTreeHelper(&self.tokens).hash(state);
+    }
+}
 
 impl Macro {
     pub fn is_braced(&self) -> bool {
         match self.tokens.last() {
-            Some(t) => t.is_braced(),
+            Some(t) => is_braced(t),
             None => false,
         }
     }
 }
 
-impl TokenTree {
-    pub fn is_braced(&self) -> bool {
-        match self.0.kind {
-            TokenNode::Group(Delimiter::Brace, _) => true,
-            _ => false,
-        }
+pub fn is_braced(tt: &TokenTree) -> bool {
+    match tt.kind {
+        TokenNode::Group(Delimiter::Brace, _) => true,
+        _ => false,
     }
 }
 
 #[cfg(feature = "extra-traits")]
-impl PartialEq for TokenTree {
-    fn eq(&self, other: &TokenTree) -> bool {
+pub struct TokenTreeHelper<'a>(pub &'a TokenTree);
+
+#[cfg(feature = "extra-traits")]
+impl<'a> PartialEq for TokenTreeHelper<'a> {
+    fn eq(&self, other: &Self) -> bool {
         use proc_macro2::Spacing;
 
         match (&self.0.kind, &other.0.kind) {
@@ -60,7 +81,7 @@
                         Some(item) => item,
                         None => return false,
                     };
-                    if TokenTree(item1) != TokenTree(item2) {
+                    if TokenTreeHelper(&item1) != TokenTreeHelper(&item2) {
                         return false
                     }
                 }
@@ -85,11 +106,8 @@
 }
 
 #[cfg(feature = "extra-traits")]
-impl Eq for TokenTree {}
-
-#[cfg(feature = "extra-traits")]
-impl ::std::hash::Hash for TokenTree {
-    fn hash<H: ::std::hash::Hasher>(&self, h: &mut H) {
+impl<'a> Hash for TokenTreeHelper<'a> {
+    fn hash<H: Hasher>(&self, h: &mut H) {
         use proc_macro2::Spacing;
 
         match self.0.kind {
@@ -103,7 +121,7 @@
                 }
 
                 for item in stream.clone() {
-                    TokenTree(item).hash(h);
+                    TokenTreeHelper(&item).hash(h);
                 }
                 0xffu8.hash(h); // terminator w/ a variant we don't normally hash
             }
@@ -122,9 +140,30 @@
 }
 
 #[cfg(feature = "extra-traits")]
-impl fmt::Debug for TokenTree {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.to_string().fmt(f)
+pub struct SliceTokenTreeHelper<'a>(pub &'a [TokenTree]);
+
+#[cfg(feature = "extra-traits")]
+impl<'a> PartialEq for SliceTokenTreeHelper<'a> {
+    fn eq(&self, other: &Self) -> bool {
+        if self.0.len() != other.0.len() {
+            return false;
+        }
+        for (a, b) in self.0.iter().zip(other.0) {
+            if TokenTreeHelper(a) != TokenTreeHelper(b) {
+                return false;
+            }
+        }
+        true
+    }
+}
+
+#[cfg(feature = "extra-traits")]
+impl<'a> Hash for SliceTokenTreeHelper<'a> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.0.len().hash(state);
+        for tt in self.0 {
+            TokenTreeHelper(tt).hash(state);
+        }
     }
 }
 
@@ -141,7 +180,7 @@
         named!(parse -> Self, do_parse!(
             what: syn!(Path) >>
             bang: punct!(!) >>
-            body: call!(::TokenTree::parse_delimited) >>
+            body: call!(parse_tt_delimited) >>
             (Macro {
                 path: what,
                 bang_token: bang,
@@ -150,18 +189,16 @@
         ));
     }
 
-    impl ::TokenTree {
-        pub fn parse_list(input: Cursor) -> PResult<Vec<Self>> {
-            Ok((Cursor::empty(), input.token_stream().into_iter().map(::TokenTree).collect()))
-        }
+    pub fn parse_tt_list(input: Cursor) -> PResult<Vec<TokenTree>> {
+        Ok((Cursor::empty(), input.token_stream().into_iter().collect()))
+    }
 
-        pub fn parse_delimited(input: Cursor) -> PResult<Self> {
-            match input.token_tree() {
-                Some((rest, token @ TokenTree { kind: TokenNode::Group(..), .. })) => {
-                    Ok((rest, ::TokenTree(token)))
-                }
-                _ => parse_error(),
+    pub fn parse_tt_delimited(input: Cursor) -> PResult<TokenTree> {
+        match input.token_tree() {
+            Some((rest, token @ TokenTree { kind: TokenNode::Group(..), .. })) => {
+                Ok((rest, token))
             }
+            _ => parse_error(),
         }
     }
 }
@@ -178,10 +215,4 @@
             tokens.append_all(&self.tokens);
         }
     }
-
-    impl ToTokens for TokenTree {
-        fn to_tokens(&self, tokens: &mut Tokens) {
-            self.0.to_tokens(tokens);
-        }
-    }
 }
diff --git a/src/macros.rs b/src/macros.rs
index cf49640..1710444 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -20,6 +20,16 @@
 
     (
         $(#[$attr:meta])*
+        pub struct $name:ident #manual_extra_traits $($rest:tt)*
+    ) => {
+        $(#[$attr])*
+        #[cfg_attr(feature = "extra-traits", derive(Debug))]
+        #[cfg_attr(feature = "clone-impls", derive(Clone))]
+        pub struct $name $($rest)*
+    };
+
+    (
+        $(#[$attr:meta])*
         pub struct $name:ident $($rest:tt)*
     ) => {
         $(#[$attr])*
diff --git a/src/parsers.rs b/src/parsers.rs
index 66561c1..ae17365 100644
--- a/src/parsers.rs
+++ b/src/parsers.rs
@@ -667,7 +667,7 @@
 /// extern crate syn;
 /// extern crate proc_macro2;
 ///
-/// use syn::{Ident, TokenTree};
+/// use syn::Ident;
 /// use syn::token::Paren;
 /// use proc_macro2::TokenStream;
 ///