Flatten TraitItem into an enum
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 7832767..8290450 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -328,7 +328,7 @@
 # [ cfg ( feature = "full" ) ]
 fn fold_trait_item_const(&mut self, i: TraitItemConst) -> TraitItemConst { fold_trait_item_const(self, i) }
 # [ cfg ( feature = "full" ) ]
-fn fold_trait_item_kind(&mut self, i: TraitItemKind) -> TraitItemKind { fold_trait_item_kind(self, i) }
+fn fold_trait_item_mac(&mut self, i: TraitItemMac) -> TraitItemMac { fold_trait_item_mac(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn fold_trait_item_method(&mut self, i: TraitItemMethod) -> TraitItemMethod { fold_trait_item_method(self, i) }
 # [ cfg ( feature = "full" ) ]
@@ -2234,25 +2234,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn fold_trait_item<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItem) -> TraitItem {
-    TraitItem {
-        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
-        node: _visitor.fold_trait_item_kind(_i . node),
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_trait_item_const<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItemConst) -> TraitItemConst {
-    TraitItemConst {
-        const_token: _i . const_token,
-        ident: _i . ident,
-        colon_token: _i . colon_token,
-        ty: _visitor.fold_ty(_i . ty),
-        default: _i . default,
-        semi_token: _i . semi_token,
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_trait_item_kind<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItemKind) -> TraitItemKind {
-    use ::TraitItemKind::*;
+    use ::TraitItem::*;
     match _i {
         Const(_binding_0, ) => {
             Const (
@@ -2271,14 +2253,34 @@
         }
         Macro(_binding_0, ) => {
             Macro (
-                _visitor.fold_mac(_binding_0),
+                _visitor.fold_trait_item_mac(_binding_0),
             )
         }
     }
 }
 # [ cfg ( feature = "full" ) ]
+pub fn fold_trait_item_const<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItemConst) -> TraitItemConst {
+    TraitItemConst {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        const_token: _i . const_token,
+        ident: _i . ident,
+        colon_token: _i . colon_token,
+        ty: _visitor.fold_ty(_i . ty),
+        default: _i . default,
+        semi_token: _i . semi_token,
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_trait_item_mac<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItemMac) -> TraitItemMac {
+    TraitItemMac {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        mac: _visitor.fold_mac(_i . mac),
+    }
+}
+# [ cfg ( feature = "full" ) ]
 pub fn fold_trait_item_method<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItemMethod) -> TraitItemMethod {
     TraitItemMethod {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         sig: _visitor.fold_method_sig(_i . sig),
         default: (_i . default).map(|it| { _visitor.fold_block(it) }),
         semi_token: _i . semi_token,
@@ -2287,6 +2289,7 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_trait_item_type<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitItemType) -> TraitItemType {
     TraitItemType {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         type_token: _i . type_token,
         ident: _i . ident,
         colon_token: _i . colon_token,
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index 6e9f7fc..69a9ec0 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -301,7 +301,7 @@
 # [ cfg ( feature = "full" ) ]
 fn visit_trait_item_const(&mut self, i: &TraitItemConst) { visit_trait_item_const(self, i) }
 # [ cfg ( feature = "full" ) ]
-fn visit_trait_item_kind(&mut self, i: &TraitItemKind) { visit_trait_item_kind(self, i) }
+fn visit_trait_item_mac(&mut self, i: &TraitItemMac) { visit_trait_item_mac(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn visit_trait_item_method(&mut self, i: &TraitItemMethod) { visit_trait_item_method(self, i) }
 # [ cfg ( feature = "full" ) ]
@@ -1721,21 +1721,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_trait_item<V: Visitor + ?Sized>(_visitor: &mut V, _i: &TraitItem) {
-    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
-    _visitor.visit_trait_item_kind(&_i . node);
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_trait_item_const<V: Visitor + ?Sized>(_visitor: &mut V, _i: &TraitItemConst) {
-    // Skipped field _i . const_token;
-    // Skipped field _i . ident;
-    // Skipped field _i . colon_token;
-    _visitor.visit_ty(&_i . ty);
-    // Skipped field _i . default;
-    // Skipped field _i . semi_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_trait_item_kind<V: Visitor + ?Sized>(_visitor: &mut V, _i: &TraitItemKind) {
-    use ::TraitItemKind::*;
+    use ::TraitItem::*;
     match *_i {
         Const(ref _binding_0, ) => {
             _visitor.visit_trait_item_const(&* _binding_0);
@@ -1747,18 +1733,35 @@
             _visitor.visit_trait_item_type(&* _binding_0);
         }
         Macro(ref _binding_0, ) => {
-            _visitor.visit_mac(&* _binding_0);
+            _visitor.visit_trait_item_mac(&* _binding_0);
         }
     }
 }
 # [ cfg ( feature = "full" ) ]
+pub fn visit_trait_item_const<V: Visitor + ?Sized>(_visitor: &mut V, _i: &TraitItemConst) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    // Skipped field _i . const_token;
+    // Skipped field _i . ident;
+    // Skipped field _i . colon_token;
+    _visitor.visit_ty(&_i . ty);
+    // Skipped field _i . default;
+    // Skipped field _i . semi_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_trait_item_mac<V: Visitor + ?Sized>(_visitor: &mut V, _i: &TraitItemMac) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_mac(&_i . mac);
+}
+# [ cfg ( feature = "full" ) ]
 pub fn visit_trait_item_method<V: Visitor + ?Sized>(_visitor: &mut V, _i: &TraitItemMethod) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_method_sig(&_i . sig);
     if let Some(ref it) = _i . default { _visitor.visit_block(&* it) };
     // Skipped field _i . semi_token;
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_trait_item_type<V: Visitor + ?Sized>(_visitor: &mut V, _i: &TraitItemType) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     // Skipped field _i . type_token;
     // Skipped field _i . ident;
     // Skipped field _i . colon_token;
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index a71d716..73dd895 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -301,7 +301,7 @@
 # [ cfg ( feature = "full" ) ]
 fn visit_trait_item_const_mut(&mut self, i: &mut TraitItemConst) { visit_trait_item_const_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
-fn visit_trait_item_kind_mut(&mut self, i: &mut TraitItemKind) { visit_trait_item_kind_mut(self, i) }
+fn visit_trait_item_mac_mut(&mut self, i: &mut TraitItemMac) { visit_trait_item_mac_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn visit_trait_item_method_mut(&mut self, i: &mut TraitItemMethod) { visit_trait_item_method_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
@@ -1721,21 +1721,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_trait_item_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItem) {
-    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
-    _visitor.visit_trait_item_kind_mut(&mut _i . node);
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_trait_item_const_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemConst) {
-    // Skipped field _i . const_token;
-    // Skipped field _i . ident;
-    // Skipped field _i . colon_token;
-    _visitor.visit_ty_mut(&mut _i . ty);
-    // Skipped field _i . default;
-    // Skipped field _i . semi_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_trait_item_kind_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemKind) {
-    use ::TraitItemKind::*;
+    use ::TraitItem::*;
     match *_i {
         Const(ref mut _binding_0, ) => {
             _visitor.visit_trait_item_const_mut(&mut * _binding_0);
@@ -1747,18 +1733,35 @@
             _visitor.visit_trait_item_type_mut(&mut * _binding_0);
         }
         Macro(ref mut _binding_0, ) => {
-            _visitor.visit_mac_mut(&mut * _binding_0);
+            _visitor.visit_trait_item_mac_mut(&mut * _binding_0);
         }
     }
 }
 # [ cfg ( feature = "full" ) ]
+pub fn visit_trait_item_const_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemConst) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    // Skipped field _i . const_token;
+    // Skipped field _i . ident;
+    // Skipped field _i . colon_token;
+    _visitor.visit_ty_mut(&mut _i . ty);
+    // Skipped field _i . default;
+    // Skipped field _i . semi_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_trait_item_mac_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemMac) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_mac_mut(&mut _i . mac);
+}
+# [ cfg ( feature = "full" ) ]
 pub fn visit_trait_item_method_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemMethod) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_method_sig_mut(&mut _i . sig);
     if let Some(ref mut it) = _i . default { _visitor.visit_block_mut(&mut * it) };
     // Skipped field _i . semi_token;
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_trait_item_type_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemType) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     // Skipped field _i . type_token;
     // Skipped field _i . ident;
     // Skipped field _i . colon_token;
diff --git a/src/item.rs b/src/item.rs
index 44d1302..7af0b49 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -304,20 +304,14 @@
     do_not_generate_to_tokens
 }
 
-ast_struct! {
+ast_enum_of_structs! {
     /// Represents an item declaration within a trait declaration,
     /// possibly including a default implementation. A trait item is
     /// either required (meaning it doesn't have an implementation, just a
     /// signature) or provided (meaning it has a default implementation).
-    pub struct TraitItem {
-        pub attrs: Vec<Attribute>,
-        pub node: TraitItemKind,
-    }
-}
-
-ast_enum_of_structs! {
-    pub enum TraitItemKind {
+    pub enum TraitItem {
         pub Const(TraitItemConst {
+            pub attrs: Vec<Attribute>,
             pub const_token: tokens::Const,
             pub ident: Ident,
             pub colon_token: tokens::Colon,
@@ -326,11 +320,13 @@
             pub semi_token: tokens::Semi,
         }),
         pub Method(TraitItemMethod {
+            pub attrs: Vec<Attribute>,
             pub sig: MethodSig,
             pub default: Option<Block>,
             pub semi_token: Option<tokens::Semi>,
         }),
         pub Type(TraitItemType {
+            pub attrs: Vec<Attribute>,
             pub type_token: tokens::Type,
             pub ident: Ident,
             pub colon_token: Option<tokens::Colon>,
@@ -338,7 +334,10 @@
             pub default: Option<(tokens::Eq, Ty)>,
             pub semi_token: tokens::Semi,
         }),
-        pub Macro(Mac),
+        pub Macro(TraitItemMac {
+            pub attrs: Vec<Attribute>,
+            pub mac: Mac,
+        }),
     }
 
     do_not_generate_to_tokens
@@ -1004,19 +1003,17 @@
         })
     ));
 
-    impl Synom for TraitItem {
-        named!(parse -> Self, alt!(
-            trait_item_const
-            |
-            trait_item_method
-            |
-            trait_item_type
-            |
-            trait_item_mac
-        ));
-    }
+    impl_synom!(TraitItem "trait item" alt!(
+        syn!(TraitItemConst) => { TraitItem::Const }
+        |
+        syn!(TraitItemMethod) => { TraitItem::Method }
+        |
+        syn!(TraitItemType) => { TraitItem::Type }
+        |
+        syn!(TraitItemMac) => { TraitItem::Macro }
+    ));
 
-    named!(trait_item_const -> TraitItem, do_parse!(
+    impl_synom!(TraitItemConst "const trait item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         const_: syn!(Const) >>
         ident: syn!(Ident) >>
@@ -1024,20 +1021,18 @@
         ty: syn!(Ty) >>
         default: option!(tuple!(syn!(Eq), syn!(Expr))) >>
         semi: syn!(Semi) >>
-        (TraitItem {
+        (TraitItemConst {
             attrs: attrs,
-            node: TraitItemConst {
-                const_token: const_,
-                ident: ident,
-                colon_token: colon,
-                ty: ty,
-                default: default,
-                semi_token: semi,
-            }.into(),
+            const_token: const_,
+            ident: ident,
+            colon_token: colon,
+            ty: ty,
+            default: default,
+            semi_token: semi,
         })
     ));
 
-    named!(trait_item_method -> TraitItem, do_parse!(
+    impl_synom!(TraitItemMethod "method trait item" do_parse!(
         outer_attrs: many0!(call!(Attribute::parse_outer)) >>
         constness: syn!(Constness) >>
         unsafety: syn!(Unsafety) >>
@@ -1058,44 +1053,42 @@
                 Some(((inner_attrs, stmts), b)) => (inner_attrs, Some((stmts, b))),
                 None => (Vec::new(), None),
             };
-            TraitItem {
+            TraitItemMethod {
                 attrs: {
                     let mut attrs = outer_attrs;
                     attrs.extend(inner_attrs);
                     attrs
                 },
-                node: TraitItemMethod {
-                    sig: MethodSig {
-                        constness: constness,
-                        unsafety: unsafety,
-                        abi: abi,
-                        ident: ident,
-                        decl: FnDecl {
-                            inputs: inputs.0,
-                            output: ret,
-                            variadic: false,
-                            fn_token: fn_,
-                            paren_token: inputs.1,
-                            dot_tokens: None,
-                            generics: Generics {
-                                where_clause: where_clause,
-                                .. generics
-                            },
+                sig: MethodSig {
+                    constness: constness,
+                    unsafety: unsafety,
+                    abi: abi,
+                    ident: ident,
+                    decl: FnDecl {
+                        inputs: inputs.0,
+                        output: ret,
+                        variadic: false,
+                        fn_token: fn_,
+                        paren_token: inputs.1,
+                        dot_tokens: None,
+                        generics: Generics {
+                            where_clause: where_clause,
+                            .. generics
                         },
                     },
-                    default: stmts.map(|stmts| {
-                        Block {
-                            stmts: stmts.0,
-                            brace_token: stmts.1,
-                        }
-                    }),
-                    semi_token: semi,
-                }.into(),
+                },
+                default: stmts.map(|stmts| {
+                    Block {
+                        stmts: stmts.0,
+                        brace_token: stmts.1,
+                    }
+                }),
+                semi_token: semi,
             }
         })
     ));
 
-    named!(trait_item_type -> TraitItem, do_parse!(
+    impl_synom!(TraitItemType "trait item type" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         type_: syn!(Type) >>
         ident: syn!(Ident) >>
@@ -1105,26 +1098,24 @@
         ) >>
         default: option!(tuple!(syn!(Eq), syn!(Ty))) >>
         semi: syn!(Semi) >>
-        (TraitItem {
+        (TraitItemType {
             attrs: attrs,
-            node: TraitItemType {
-                type_token: type_,
-                ident: ident,
-                colon_token: colon,
-                bounds: bounds.unwrap_or_default(),
-                default: default,
-                semi_token: semi,
-            }.into(),
+            type_token: type_,
+            ident: ident,
+            colon_token: colon,
+            bounds: bounds.unwrap_or_default(),
+            default: default,
+            semi_token: semi,
         })
     ));
 
-    named!(trait_item_mac -> TraitItem, do_parse!(
+    impl_synom!(TraitItemMac "trait item macro" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         mac: syn!(Mac) >>
         cond!(!mac.is_braced(), syn!(Semi)) >>
-        (TraitItem {
+        (TraitItemMac {
             attrs: attrs,
-            node: TraitItemKind::Macro(mac),
+            mac: mac,
         })
     ));
 
@@ -1550,9 +1541,9 @@
 
     impl ToTokens for TraitItem {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            tokens.append_all(self.attrs.outer());
-            match self.node {
-                TraitItemKind::Const(ref item) => {
+            match *self {
+                TraitItem::Const(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.const_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
                     item.colon_token.to_tokens(tokens);
@@ -1563,12 +1554,13 @@
                     }
                     item.semi_token.to_tokens(tokens);
                 }
-                TraitItemKind::Method(ref item) => {
+                TraitItem::Method(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.sig.to_tokens(tokens);
                     match item.default {
                         Some(ref block) => {
                             block.brace_token.surround(tokens, |tokens| {
-                                tokens.append_all(self.attrs.inner());
+                                tokens.append_all(item.attrs.inner());
                                 tokens.append_all(&block.stmts);
                             });
                         }
@@ -1577,7 +1569,8 @@
                         }
                     }
                 }
-                TraitItemKind::Type(ref item) => {
+                TraitItem::Type(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.type_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
                     if !item.bounds.is_empty() {
@@ -1590,9 +1583,10 @@
                     }
                     item.semi_token.to_tokens(tokens);
                 }
-                TraitItemKind::Macro(ref mac) => {
-                    mac.to_tokens(tokens);
-                    if !mac.is_braced() {
+                TraitItem::Macro(ref item) => {
+                    tokens.append_all(item.attrs.outer());
+                    item.mac.to_tokens(tokens);
+                    if !item.mac.is_braced() {
                         tokens::Semi::default().to_tokens(tokens);
                     }
                 }
diff --git a/src/lib.rs b/src/lib.rs
index 132f8dc..9e48858 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -54,11 +54,11 @@
 #[cfg(feature = "full")]
 pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ItemForeignMod,
                ImplItem, ImplItemKind, ImplPolarity, Item, MethodSig, PathListItem,
-               TraitItem, TraitItemKind, ViewPath, ItemExternCrate, ItemUse,
+               TraitItem, ViewPath, ItemExternCrate, ItemUse,
                ItemStatic, ItemConst, ItemFn, ItemMac, ItemMod, ItemTy, ItemEnum,
                ItemStruct, ItemUnion, ItemTrait, ItemDefaultImpl, ItemImpl,
                PathSimple, PathGlob, PathList, ForeignItemFn, ForeignItemStatic,
-               TraitItemConst, TraitItemMethod, TraitItemType,
+               TraitItemConst, TraitItemMac, TraitItemMethod, TraitItemType,
                ImplItemConst, ImplItemMethod, ImplItemType, ArgSelfRef,
                ArgSelf, ArgCaptured};