Flatten ItemKind into an Item enum

Side note: this pattern is sort of nice:

    let item: &Item = /* ... */;

    match *item {
        Item::Mod(ref item) => {
            do_something_with(&item.ident, &item.content);
        }
        Item::Fn(ref item) => {
            do_something_with(&item.abi, &item.block);
        }
        /* ... */
    }

Basically pattern matching on an `item` and rebinding the same name `item`
just takes your variable and imbues it with those additional fields that exist
on the type of item that it happens to be.
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 459370f..7832767 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -236,7 +236,7 @@
 # [ cfg ( feature = "full" ) ]
 fn fold_item_impl(&mut self, i: ItemImpl) -> ItemImpl { fold_item_impl(self, i) }
 # [ cfg ( feature = "full" ) ]
-fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind { fold_item_kind(self, i) }
+fn fold_item_mac(&mut self, i: ItemMac) -> ItemMac { fold_item_mac(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn fold_item_mod(&mut self, i: ItemMod) -> ItemMod { fold_item_mod(self, i) }
 # [ cfg ( feature = "full" ) ]
@@ -1544,93 +1544,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn fold_item<V: Folder + ?Sized>(_visitor: &mut V, _i: Item) -> Item {
-    Item {
-        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
-        node: _visitor.fold_item_kind(_i . node),
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_const<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemConst) -> ItemConst {
-    ItemConst {
-        vis: _visitor.fold_visibility(_i . vis),
-        const_token: _i . const_token,
-        ident: _i . ident,
-        colon_token: _i . colon_token,
-        ty: Box::new(_visitor.fold_ty(* _i . ty)),
-        eq_token: _i . eq_token,
-        expr: Box::new(_visitor.fold_expr(* _i . expr)),
-        semi_token: _i . semi_token,
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_default_impl<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemDefaultImpl) -> ItemDefaultImpl {
-    ItemDefaultImpl {
-        unsafety: _visitor.fold_unsafety(_i . unsafety),
-        impl_token: _i . impl_token,
-        path: _visitor.fold_path(_i . path),
-        for_token: _i . for_token,
-        dot2_token: _i . dot2_token,
-        brace_token: _i . brace_token,
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_enum<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemEnum) -> ItemEnum {
-    ItemEnum {
-        vis: _visitor.fold_visibility(_i . vis),
-        enum_token: _i . enum_token,
-        ident: _i . ident,
-        generics: _visitor.fold_generics(_i . generics),
-        brace_token: _i . brace_token,
-        variants: FoldHelper::lift(_i . variants, |it| { _visitor.fold_variant(it) }),
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_extern_crate<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemExternCrate) -> ItemExternCrate {
-    ItemExternCrate {
-        vis: _visitor.fold_visibility(_i . vis),
-        extern_token: _i . extern_token,
-        crate_token: _i . crate_token,
-        ident: _i . ident,
-        rename: _i . rename,
-        semi_token: _i . semi_token,
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_fn<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemFn) -> ItemFn {
-    ItemFn {
-        vis: _visitor.fold_visibility(_i . vis),
-        constness: _visitor.fold_constness(_i . constness),
-        unsafety: _visitor.fold_unsafety(_i . unsafety),
-        abi: (_i . abi).map(|it| { _visitor.fold_abi(it) }),
-        decl: Box::new(_visitor.fold_fn_decl(* _i . decl)),
-        ident: _i . ident,
-        block: Box::new(_visitor.fold_block(* _i . block)),
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_foreign_mod<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemForeignMod) -> ItemForeignMod {
-    ItemForeignMod {
-        abi: _visitor.fold_abi(_i . abi),
-        brace_token: _i . brace_token,
-        items: FoldHelper::lift(_i . items, |it| { _visitor.fold_foreign_item(it) }),
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_impl<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemImpl) -> ItemImpl {
-    ItemImpl {
-        defaultness: _visitor.fold_defaultness(_i . defaultness),
-        unsafety: _visitor.fold_unsafety(_i . unsafety),
-        impl_token: _i . impl_token,
-        generics: _visitor.fold_generics(_i . generics),
-        trait_: _i . trait_,
-        self_ty: Box::new(_visitor.fold_ty(* _i . self_ty)),
-        brace_token: _i . brace_token,
-        items: FoldHelper::lift(_i . items, |it| { _visitor.fold_impl_item(it) }),
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_item_kind<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemKind) -> ItemKind {
-    use ::ItemKind::*;
+    use ::Item::*;
     match _i {
         ExternCrate(_binding_0, ) => {
             ExternCrate (
@@ -1704,14 +1618,108 @@
         }
         Mac(_binding_0, ) => {
             Mac (
-                _visitor.fold_mac(_binding_0),
+                _visitor.fold_item_mac(_binding_0),
             )
         }
     }
 }
 # [ cfg ( feature = "full" ) ]
+pub fn fold_item_const<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemConst) -> ItemConst {
+    ItemConst {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        vis: _visitor.fold_visibility(_i . vis),
+        const_token: _i . const_token,
+        ident: _i . ident,
+        colon_token: _i . colon_token,
+        ty: Box::new(_visitor.fold_ty(* _i . ty)),
+        eq_token: _i . eq_token,
+        expr: Box::new(_visitor.fold_expr(* _i . expr)),
+        semi_token: _i . semi_token,
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_item_default_impl<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemDefaultImpl) -> ItemDefaultImpl {
+    ItemDefaultImpl {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        unsafety: _visitor.fold_unsafety(_i . unsafety),
+        impl_token: _i . impl_token,
+        path: _visitor.fold_path(_i . path),
+        for_token: _i . for_token,
+        dot2_token: _i . dot2_token,
+        brace_token: _i . brace_token,
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_item_enum<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemEnum) -> ItemEnum {
+    ItemEnum {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        vis: _visitor.fold_visibility(_i . vis),
+        enum_token: _i . enum_token,
+        ident: _i . ident,
+        generics: _visitor.fold_generics(_i . generics),
+        brace_token: _i . brace_token,
+        variants: FoldHelper::lift(_i . variants, |it| { _visitor.fold_variant(it) }),
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_item_extern_crate<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemExternCrate) -> ItemExternCrate {
+    ItemExternCrate {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        vis: _visitor.fold_visibility(_i . vis),
+        extern_token: _i . extern_token,
+        crate_token: _i . crate_token,
+        ident: _i . ident,
+        rename: _i . rename,
+        semi_token: _i . semi_token,
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_item_fn<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemFn) -> ItemFn {
+    ItemFn {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        vis: _visitor.fold_visibility(_i . vis),
+        constness: _visitor.fold_constness(_i . constness),
+        unsafety: _visitor.fold_unsafety(_i . unsafety),
+        abi: (_i . abi).map(|it| { _visitor.fold_abi(it) }),
+        decl: Box::new(_visitor.fold_fn_decl(* _i . decl)),
+        ident: _i . ident,
+        block: Box::new(_visitor.fold_block(* _i . block)),
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_item_foreign_mod<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemForeignMod) -> ItemForeignMod {
+    ItemForeignMod {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        abi: _visitor.fold_abi(_i . abi),
+        brace_token: _i . brace_token,
+        items: FoldHelper::lift(_i . items, |it| { _visitor.fold_foreign_item(it) }),
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_item_impl<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemImpl) -> ItemImpl {
+    ItemImpl {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        defaultness: _visitor.fold_defaultness(_i . defaultness),
+        unsafety: _visitor.fold_unsafety(_i . unsafety),
+        impl_token: _i . impl_token,
+        generics: _visitor.fold_generics(_i . generics),
+        trait_: _i . trait_,
+        self_ty: Box::new(_visitor.fold_ty(* _i . self_ty)),
+        brace_token: _i . brace_token,
+        items: FoldHelper::lift(_i . items, |it| { _visitor.fold_impl_item(it) }),
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_item_mac<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemMac) -> ItemMac {
+    ItemMac {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+        mac: _visitor.fold_mac(_i . mac),
+    }
+}
+# [ cfg ( feature = "full" ) ]
 pub fn fold_item_mod<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemMod) -> ItemMod {
     ItemMod {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         mod_token: _i . mod_token,
         ident: _i . ident,
@@ -1722,6 +1730,7 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_item_static<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemStatic) -> ItemStatic {
     ItemStatic {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         static_token: _i . static_token,
         mutbl: _visitor.fold_mutability(_i . mutbl),
@@ -1736,6 +1745,7 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_item_struct<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemStruct) -> ItemStruct {
     ItemStruct {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         struct_token: _i . struct_token,
         ident: _i . ident,
@@ -1747,6 +1757,7 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_item_trait<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemTrait) -> ItemTrait {
     ItemTrait {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         unsafety: _visitor.fold_unsafety(_i . unsafety),
         trait_token: _i . trait_token,
@@ -1761,6 +1772,7 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_item_ty<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemTy) -> ItemTy {
     ItemTy {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         type_token: _i . type_token,
         ident: _i . ident,
@@ -1773,6 +1785,7 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_item_union<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemUnion) -> ItemUnion {
     ItemUnion {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         union_token: _i . union_token,
         ident: _i . ident,
@@ -1783,6 +1796,7 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_item_use<V: Folder + ?Sized>(_visitor: &mut V, _i: ItemUse) -> ItemUse {
     ItemUse {
+        attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         use_token: _i . use_token,
         path: Box::new(_visitor.fold_view_path(* _i . path)),
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index 2ed90cf..6e9f7fc 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -209,7 +209,7 @@
 # [ cfg ( feature = "full" ) ]
 fn visit_item_impl(&mut self, i: &ItemImpl) { visit_item_impl(self, i) }
 # [ cfg ( feature = "full" ) ]
-fn visit_item_kind(&mut self, i: &ItemKind) { visit_item_kind(self, i) }
+fn visit_item_mac(&mut self, i: &ItemMac) { visit_item_mac(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn visit_item_mod(&mut self, i: &ItemMod) { visit_item_mod(self, i) }
 # [ cfg ( feature = "full" ) ]
@@ -1203,77 +1203,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item<V: Visitor + ?Sized>(_visitor: &mut V, _i: &Item) {
-    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
-    _visitor.visit_item_kind(&_i . node);
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_const<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemConst) {
-    _visitor.visit_visibility(&_i . vis);
-    // Skipped field _i . const_token;
-    // Skipped field _i . ident;
-    // Skipped field _i . colon_token;
-    _visitor.visit_ty(&_i . ty);
-    // Skipped field _i . eq_token;
-    _visitor.visit_expr(&_i . expr);
-    // Skipped field _i . semi_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_default_impl<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemDefaultImpl) {
-    _visitor.visit_unsafety(&_i . unsafety);
-    // Skipped field _i . impl_token;
-    _visitor.visit_path(&_i . path);
-    // Skipped field _i . for_token;
-    // Skipped field _i . dot2_token;
-    // Skipped field _i . brace_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_enum<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemEnum) {
-    _visitor.visit_visibility(&_i . vis);
-    // Skipped field _i . enum_token;
-    // Skipped field _i . ident;
-    _visitor.visit_generics(&_i . generics);
-    // Skipped field _i . brace_token;
-    for el in (_i . variants).iter() { let it = el.item(); _visitor.visit_variant(&it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_extern_crate<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemExternCrate) {
-    _visitor.visit_visibility(&_i . vis);
-    // Skipped field _i . extern_token;
-    // Skipped field _i . crate_token;
-    // Skipped field _i . ident;
-    // Skipped field _i . rename;
-    // Skipped field _i . semi_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_fn<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemFn) {
-    _visitor.visit_visibility(&_i . vis);
-    _visitor.visit_constness(&_i . constness);
-    _visitor.visit_unsafety(&_i . unsafety);
-    if let Some(ref it) = _i . abi { _visitor.visit_abi(&* it) };
-    _visitor.visit_fn_decl(&_i . decl);
-    // Skipped field _i . ident;
-    _visitor.visit_block(&_i . block);
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_foreign_mod<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemForeignMod) {
-    _visitor.visit_abi(&_i . abi);
-    // Skipped field _i . brace_token;
-    for it in (_i . items).iter() { _visitor.visit_foreign_item(&it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_impl<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemImpl) {
-    _visitor.visit_defaultness(&_i . defaultness);
-    _visitor.visit_unsafety(&_i . unsafety);
-    // Skipped field _i . impl_token;
-    _visitor.visit_generics(&_i . generics);
-    // Skipped field _i . trait_;
-    _visitor.visit_ty(&_i . self_ty);
-    // Skipped field _i . brace_token;
-    for it in (_i . items).iter() { _visitor.visit_impl_item(&it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_kind<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemKind) {
-    use ::ItemKind::*;
+    use ::Item::*;
     match *_i {
         ExternCrate(ref _binding_0, ) => {
             _visitor.visit_item_extern_crate(&* _binding_0);
@@ -1318,12 +1248,90 @@
             _visitor.visit_item_impl(&* _binding_0);
         }
         Mac(ref _binding_0, ) => {
-            _visitor.visit_mac(&* _binding_0);
+            _visitor.visit_item_mac(&* _binding_0);
         }
     }
 }
 # [ cfg ( feature = "full" ) ]
+pub fn visit_item_const<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemConst) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_visibility(&_i . vis);
+    // Skipped field _i . const_token;
+    // Skipped field _i . ident;
+    // Skipped field _i . colon_token;
+    _visitor.visit_ty(&_i . ty);
+    // Skipped field _i . eq_token;
+    _visitor.visit_expr(&_i . expr);
+    // Skipped field _i . semi_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_default_impl<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemDefaultImpl) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_unsafety(&_i . unsafety);
+    // Skipped field _i . impl_token;
+    _visitor.visit_path(&_i . path);
+    // Skipped field _i . for_token;
+    // Skipped field _i . dot2_token;
+    // Skipped field _i . brace_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_enum<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemEnum) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_visibility(&_i . vis);
+    // Skipped field _i . enum_token;
+    // Skipped field _i . ident;
+    _visitor.visit_generics(&_i . generics);
+    // Skipped field _i . brace_token;
+    for el in (_i . variants).iter() { let it = el.item(); _visitor.visit_variant(&it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_extern_crate<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemExternCrate) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_visibility(&_i . vis);
+    // Skipped field _i . extern_token;
+    // Skipped field _i . crate_token;
+    // Skipped field _i . ident;
+    // Skipped field _i . rename;
+    // Skipped field _i . semi_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_fn<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemFn) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_visibility(&_i . vis);
+    _visitor.visit_constness(&_i . constness);
+    _visitor.visit_unsafety(&_i . unsafety);
+    if let Some(ref it) = _i . abi { _visitor.visit_abi(&* it) };
+    _visitor.visit_fn_decl(&_i . decl);
+    // Skipped field _i . ident;
+    _visitor.visit_block(&_i . block);
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_foreign_mod<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemForeignMod) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_abi(&_i . abi);
+    // Skipped field _i . brace_token;
+    for it in (_i . items).iter() { _visitor.visit_foreign_item(&it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_impl<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemImpl) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_defaultness(&_i . defaultness);
+    _visitor.visit_unsafety(&_i . unsafety);
+    // Skipped field _i . impl_token;
+    _visitor.visit_generics(&_i . generics);
+    // Skipped field _i . trait_;
+    _visitor.visit_ty(&_i . self_ty);
+    // Skipped field _i . brace_token;
+    for it in (_i . items).iter() { _visitor.visit_impl_item(&it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_mac<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemMac) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+    _visitor.visit_mac(&_i . mac);
+}
+# [ cfg ( feature = "full" ) ]
 pub fn visit_item_mod<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemMod) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     // Skipped field _i . mod_token;
     // Skipped field _i . ident;
@@ -1332,6 +1340,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_static<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemStatic) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     // Skipped field _i . static_token;
     _visitor.visit_mutability(&_i . mutbl);
@@ -1344,6 +1353,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_struct<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemStruct) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     // Skipped field _i . struct_token;
     // Skipped field _i . ident;
@@ -1353,6 +1363,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_trait<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemTrait) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     _visitor.visit_unsafety(&_i . unsafety);
     // Skipped field _i . trait_token;
@@ -1365,6 +1376,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_ty<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemTy) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     // Skipped field _i . type_token;
     // Skipped field _i . ident;
@@ -1375,6 +1387,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_union<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemUnion) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     // Skipped field _i . union_token;
     // Skipped field _i . ident;
@@ -1383,6 +1396,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_use<V: Visitor + ?Sized>(_visitor: &mut V, _i: &ItemUse) {
+    for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     // Skipped field _i . use_token;
     _visitor.visit_view_path(&_i . path);
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index bc4d28e..a71d716 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -209,7 +209,7 @@
 # [ cfg ( feature = "full" ) ]
 fn visit_item_impl_mut(&mut self, i: &mut ItemImpl) { visit_item_impl_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
-fn visit_item_kind_mut(&mut self, i: &mut ItemKind) { visit_item_kind_mut(self, i) }
+fn visit_item_mac_mut(&mut self, i: &mut ItemMac) { visit_item_mac_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn visit_item_mod_mut(&mut self, i: &mut ItemMod) { visit_item_mod_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
@@ -1203,77 +1203,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut Item) {
-    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
-    _visitor.visit_item_kind_mut(&mut _i . node);
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_const_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemConst) {
-    _visitor.visit_visibility_mut(&mut _i . vis);
-    // Skipped field _i . const_token;
-    // Skipped field _i . ident;
-    // Skipped field _i . colon_token;
-    _visitor.visit_ty_mut(&mut _i . ty);
-    // Skipped field _i . eq_token;
-    _visitor.visit_expr_mut(&mut _i . expr);
-    // Skipped field _i . semi_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_default_impl_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemDefaultImpl) {
-    _visitor.visit_unsafety_mut(&mut _i . unsafety);
-    // Skipped field _i . impl_token;
-    _visitor.visit_path_mut(&mut _i . path);
-    // Skipped field _i . for_token;
-    // Skipped field _i . dot2_token;
-    // Skipped field _i . brace_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_enum_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemEnum) {
-    _visitor.visit_visibility_mut(&mut _i . vis);
-    // Skipped field _i . enum_token;
-    // Skipped field _i . ident;
-    _visitor.visit_generics_mut(&mut _i . generics);
-    // Skipped field _i . brace_token;
-    for mut el in (_i . variants).iter_mut() { let mut it = el.item_mut(); _visitor.visit_variant_mut(&mut it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_extern_crate_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemExternCrate) {
-    _visitor.visit_visibility_mut(&mut _i . vis);
-    // Skipped field _i . extern_token;
-    // Skipped field _i . crate_token;
-    // Skipped field _i . ident;
-    // Skipped field _i . rename;
-    // Skipped field _i . semi_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_fn_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemFn) {
-    _visitor.visit_visibility_mut(&mut _i . vis);
-    _visitor.visit_constness_mut(&mut _i . constness);
-    _visitor.visit_unsafety_mut(&mut _i . unsafety);
-    if let Some(ref mut it) = _i . abi { _visitor.visit_abi_mut(&mut * it) };
-    _visitor.visit_fn_decl_mut(&mut _i . decl);
-    // Skipped field _i . ident;
-    _visitor.visit_block_mut(&mut _i . block);
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_foreign_mod_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemForeignMod) {
-    _visitor.visit_abi_mut(&mut _i . abi);
-    // Skipped field _i . brace_token;
-    for mut it in (_i . items).iter_mut() { _visitor.visit_foreign_item_mut(&mut it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_impl_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemImpl) {
-    _visitor.visit_defaultness_mut(&mut _i . defaultness);
-    _visitor.visit_unsafety_mut(&mut _i . unsafety);
-    // Skipped field _i . impl_token;
-    _visitor.visit_generics_mut(&mut _i . generics);
-    // Skipped field _i . trait_;
-    _visitor.visit_ty_mut(&mut _i . self_ty);
-    // Skipped field _i . brace_token;
-    for mut it in (_i . items).iter_mut() { _visitor.visit_impl_item_mut(&mut it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_item_kind_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemKind) {
-    use ::ItemKind::*;
+    use ::Item::*;
     match *_i {
         ExternCrate(ref mut _binding_0, ) => {
             _visitor.visit_item_extern_crate_mut(&mut * _binding_0);
@@ -1318,12 +1248,90 @@
             _visitor.visit_item_impl_mut(&mut * _binding_0);
         }
         Mac(ref mut _binding_0, ) => {
-            _visitor.visit_mac_mut(&mut * _binding_0);
+            _visitor.visit_item_mac_mut(&mut * _binding_0);
         }
     }
 }
 # [ cfg ( feature = "full" ) ]
+pub fn visit_item_const_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemConst) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_visibility_mut(&mut _i . vis);
+    // Skipped field _i . const_token;
+    // Skipped field _i . ident;
+    // Skipped field _i . colon_token;
+    _visitor.visit_ty_mut(&mut _i . ty);
+    // Skipped field _i . eq_token;
+    _visitor.visit_expr_mut(&mut _i . expr);
+    // Skipped field _i . semi_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_default_impl_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemDefaultImpl) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_unsafety_mut(&mut _i . unsafety);
+    // Skipped field _i . impl_token;
+    _visitor.visit_path_mut(&mut _i . path);
+    // Skipped field _i . for_token;
+    // Skipped field _i . dot2_token;
+    // Skipped field _i . brace_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_enum_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemEnum) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_visibility_mut(&mut _i . vis);
+    // Skipped field _i . enum_token;
+    // Skipped field _i . ident;
+    _visitor.visit_generics_mut(&mut _i . generics);
+    // Skipped field _i . brace_token;
+    for mut el in (_i . variants).iter_mut() { let mut it = el.item_mut(); _visitor.visit_variant_mut(&mut it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_extern_crate_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemExternCrate) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_visibility_mut(&mut _i . vis);
+    // Skipped field _i . extern_token;
+    // Skipped field _i . crate_token;
+    // Skipped field _i . ident;
+    // Skipped field _i . rename;
+    // Skipped field _i . semi_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_fn_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemFn) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_visibility_mut(&mut _i . vis);
+    _visitor.visit_constness_mut(&mut _i . constness);
+    _visitor.visit_unsafety_mut(&mut _i . unsafety);
+    if let Some(ref mut it) = _i . abi { _visitor.visit_abi_mut(&mut * it) };
+    _visitor.visit_fn_decl_mut(&mut _i . decl);
+    // Skipped field _i . ident;
+    _visitor.visit_block_mut(&mut _i . block);
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_foreign_mod_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemForeignMod) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_abi_mut(&mut _i . abi);
+    // Skipped field _i . brace_token;
+    for mut it in (_i . items).iter_mut() { _visitor.visit_foreign_item_mut(&mut it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_impl_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemImpl) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+    _visitor.visit_defaultness_mut(&mut _i . defaultness);
+    _visitor.visit_unsafety_mut(&mut _i . unsafety);
+    // Skipped field _i . impl_token;
+    _visitor.visit_generics_mut(&mut _i . generics);
+    // Skipped field _i . trait_;
+    _visitor.visit_ty_mut(&mut _i . self_ty);
+    // Skipped field _i . brace_token;
+    for mut it in (_i . items).iter_mut() { _visitor.visit_impl_item_mut(&mut it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_item_mac_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemMac) {
+    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_item_mod_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemMod) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     // Skipped field _i . mod_token;
     // Skipped field _i . ident;
@@ -1332,6 +1340,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_static_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemStatic) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     // Skipped field _i . static_token;
     _visitor.visit_mutability_mut(&mut _i . mutbl);
@@ -1344,6 +1353,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_struct_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemStruct) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     // Skipped field _i . struct_token;
     // Skipped field _i . ident;
@@ -1353,6 +1363,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_trait_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemTrait) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     _visitor.visit_unsafety_mut(&mut _i . unsafety);
     // Skipped field _i . trait_token;
@@ -1365,6 +1376,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_ty_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemTy) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     // Skipped field _i . type_token;
     // Skipped field _i . ident;
@@ -1375,6 +1387,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_union_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemUnion) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     // Skipped field _i . union_token;
     // Skipped field _i . ident;
@@ -1383,6 +1396,7 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_item_use_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ItemUse) {
+    for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     // Skipped field _i . use_token;
     _visitor.visit_view_path_mut(&mut _i . path);
diff --git a/src/item.rs b/src/item.rs
index e9ccd32..cf71fcc 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -1,20 +1,14 @@
 use super::*;
 use delimited::Delimited;
 
-ast_struct! {
-    /// Things that can appear directly inside of a module.
-    pub struct Item {
-        pub attrs: Vec<Attribute>,
-        pub node: ItemKind,
-    }
-}
-
 ast_enum_of_structs! {
-    pub enum ItemKind {
+    /// Things that can appear directly inside of a module.
+    pub enum Item {
         /// An `extern crate` item, with optional original crate name.
         ///
         /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
         pub ExternCrate(ItemExternCrate {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub extern_token: tokens::Extern,
             pub crate_token: tokens::Crate,
@@ -26,6 +20,7 @@
         ///
         /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
         pub Use(ItemUse {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub use_token: tokens::Use,
             pub path: Box<ViewPath>,
@@ -35,6 +30,7 @@
         ///
         /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
         pub Static(ItemStatic {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub static_token: tokens::Static,
             pub mutbl: Mutability,
@@ -49,6 +45,7 @@
         ///
         /// E.g. `const FOO: i32 = 42;`
         pub Const(ItemConst {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub const_token: tokens::Const,
             pub ident: Ident,
@@ -62,6 +59,7 @@
         ///
         /// E.g. `fn foo(bar: usize) -> usize { .. }`
         pub Fn(ItemFn {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub constness: Constness,
             pub unsafety: Unsafety,
@@ -74,6 +72,7 @@
         ///
         /// E.g. `mod foo;` or `mod foo { .. }`
         pub Mod(ItemMod {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub mod_token: tokens::Mod,
             pub ident: Ident,
@@ -84,6 +83,7 @@
         ///
         /// E.g. `extern {}` or `extern "C" {}`
         pub ForeignMod(ItemForeignMod {
+            pub attrs: Vec<Attribute>,
             pub abi: Abi,
             pub brace_token: tokens::Brace,
             pub items: Vec<ForeignItem>,
@@ -92,6 +92,7 @@
         ///
         /// E.g. `type Foo = Bar<u8>;`
         pub Ty(ItemTy {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub type_token: tokens::Type,
             pub ident: Ident,
@@ -104,6 +105,7 @@
         ///
         /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
         pub Enum(ItemEnum {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub enum_token: tokens::Enum,
             pub ident: Ident,
@@ -115,6 +117,7 @@
         ///
         /// E.g. `struct Foo<A> { x: A }`
         pub Struct(ItemStruct {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub struct_token: tokens::Struct,
             pub ident: Ident,
@@ -126,6 +129,7 @@
         ///
         /// E.g. `union Foo<A, B> { x: A, y: B }`
         pub Union(ItemUnion {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub union_token: tokens::Union,
             pub ident: Ident,
@@ -136,6 +140,7 @@
         ///
         /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
         pub Trait(ItemTrait {
+            pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub unsafety: Unsafety,
             pub trait_token: tokens::Trait,
@@ -150,6 +155,7 @@
         ///
         /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
         pub DefaultImpl(ItemDefaultImpl {
+            pub attrs: Vec<Attribute>,
             pub unsafety: Unsafety,
             pub impl_token: tokens::Impl,
             pub path: Path,
@@ -161,6 +167,7 @@
         ///
         /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
         pub Impl(ItemImpl {
+            pub attrs: Vec<Attribute>,
             pub defaultness: Defaultness,
             pub unsafety: Unsafety,
             pub impl_token: tokens::Impl,
@@ -175,7 +182,10 @@
         /// A macro invocation (which includes macro definition).
         ///
         /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
-        pub Mac(Mac),
+        pub Mac(ItemMac {
+            pub attrs: Vec<Attribute>,
+            pub mac: Mac,
+        }),
     }
 
     do_not_generate_to_tokens
@@ -183,30 +193,29 @@
 
 impl From<DeriveInput> for Item {
     fn from(input: DeriveInput) -> Item {
-        Item {
-            attrs: input.attrs,
-            node: match input.body {
-                Body::Enum(data) => {
-                    ItemEnum {
-                        vis: input.vis,
-                        enum_token: data.enum_token,
-                        ident: input.ident,
-                        generics: input.generics,
-                        brace_token: data.brace_token,
-                        variants: data.variants,
-                    }.into()
-                }
-                Body::Struct(data) => {
-                    ItemStruct {
-                        vis: input.vis,
-                        struct_token: data.struct_token,
-                        ident: input.ident,
-                        generics: input.generics,
-                        data: data.data,
-                        semi_token: data.semi_token,
-                    }.into()
-                }
-            },
+        match input.body {
+            Body::Enum(data) => {
+                Item::Enum(ItemEnum {
+                    attrs: input.attrs,
+                    vis: input.vis,
+                    enum_token: data.enum_token,
+                    ident: input.ident,
+                    generics: input.generics,
+                    brace_token: data.brace_token,
+                    variants: data.variants,
+                })
+            }
+            Body::Struct(data) => {
+                Item::Struct(ItemStruct {
+                    attrs: input.attrs,
+                    vis: input.vis,
+                    struct_token: data.struct_token,
+                    ident: input.ident,
+                    generics: input.generics,
+                    data: data.data,
+                    semi_token: data.semi_token,
+                })
+            }
         }
     }
 }
@@ -488,15 +497,15 @@
         ident: option!(syn!(Ident)) >>
         body: call!(::TokenTree::parse_delimited) >>
         cond!(!body.is_braced(), syn!(Semi)) >>
-        (Item {
+        (Item::Mac(ItemMac {
             attrs: attrs,
-            node: ItemKind::Mac(Mac {
+            mac: Mac {
                 path: what,
                 bang_token: bang,
                 ident: ident,
                 tokens: vec![body],
-            }),
-        })
+            },
+        }))
     ));
 
     named!(item_extern_crate -> Item, do_parse!(
@@ -507,17 +516,15 @@
         ident: syn!(Ident) >>
         rename: option!(tuple!(syn!(As), syn!(Ident))) >>
         semi: syn!(Semi) >>
-        (Item {
+        (Item::ExternCrate(ItemExternCrate {
             attrs: attrs,
-            node: ItemExternCrate {
-                vis: vis,
-                extern_token: extern_,
-                crate_token: crate_,
-                ident: ident,
-                rename: rename,
-                semi_token: semi,
-            }.into(),
-        })
+            vis: vis,
+            extern_token: extern_,
+            crate_token: crate_,
+            ident: ident,
+            rename: rename,
+            semi_token: semi,
+        }))
     ));
 
     named!(item_use -> Item, do_parse!(
@@ -526,15 +533,13 @@
         use_: syn!(Use) >>
         what: syn!(ViewPath) >>
         semi: syn!(Semi) >>
-        (Item {
+        (Item::Use(ItemUse {
             attrs: attrs,
-            node: ItemUse {
-                vis: vis,
-                use_token: use_,
-                path: Box::new(what),
-                semi_token: semi,
-            }.into(),
-        })
+            vis: vis,
+            use_token: use_,
+            path: Box::new(what),
+            semi_token: semi,
+        }))
     ));
 
     impl Synom for ViewPath {
@@ -648,20 +653,18 @@
         eq: syn!(Eq) >>
         value: syn!(Expr) >>
         semi: syn!(Semi) >>
-        (Item {
+        (Item::Static(ItemStatic {
             attrs: attrs,
-            node: ItemStatic {
-                vis: vis,
-                static_token: static_,
-                mutbl: mutability,
-                ident: ident,
-                colon_token: colon,
-                ty: Box::new(ty),
-                eq_token: eq,
-                expr: Box::new(value),
-                semi_token: semi,
-            }.into(),
-        })
+            vis: vis,
+            static_token: static_,
+            mutbl: mutability,
+            ident: ident,
+            colon_token: colon,
+            ty: Box::new(ty),
+            eq_token: eq,
+            expr: Box::new(value),
+            semi_token: semi,
+        }))
     ));
 
     named!(item_const -> Item, do_parse!(
@@ -674,19 +677,17 @@
         eq: syn!(Eq) >>
         value: syn!(Expr) >>
         semi: syn!(Semi) >>
-        (Item {
+        (Item::Const(ItemConst {
             attrs: attrs,
-            node: ItemConst {
-                vis: vis,
-                const_token: const_,
-                ident: ident,
-                colon_token: colon,
-                ty: Box::new(ty),
-                eq_token: eq,
-                expr: Box::new(value),
-                semi_token: semi,
-            }.into(),
-        })
+            vis: vis,
+            const_token: const_,
+            ident: ident,
+            colon_token: colon,
+            ty: Box::new(ty),
+            eq_token: eq,
+            expr: Box::new(value),
+            semi_token: semi,
+        }))
     ));
 
     named!(item_fn -> Item, do_parse!(
@@ -705,36 +706,34 @@
             many0!(call!(Attribute::parse_inner)),
             call!(Block::parse_within)
         )) >>
-        (Item {
+        (Item::Fn(ItemFn {
             attrs: {
                 let mut attrs = outer_attrs;
                 attrs.extend((inner_attrs_stmts.0).0);
                 attrs
             },
-            node: ItemFn {
-                vis: vis,
-                constness: constness,
-                unsafety: unsafety,
-                abi: abi,
-                decl: Box::new(FnDecl {
-                    dot_tokens: None,
-                    fn_token: fn_,
-                    paren_token: inputs.1,
-                    inputs: inputs.0,
-                    output: ret,
-                    variadic: false,
-                    generics: Generics {
-                        where_clause: where_clause,
-                        .. generics
-                    },
-                }),
-                ident: ident,
-                block: Box::new(Block {
-                    brace_token: inner_attrs_stmts.1,
-                    stmts: (inner_attrs_stmts.0).1,
-                }),
-            }.into(),
-        })
+            vis: vis,
+            constness: constness,
+            unsafety: unsafety,
+            abi: abi,
+            decl: Box::new(FnDecl {
+                dot_tokens: None,
+                fn_token: fn_,
+                paren_token: inputs.1,
+                inputs: inputs.0,
+                output: ret,
+                variadic: false,
+                generics: Generics {
+                    where_clause: where_clause,
+                    .. generics
+                },
+            }),
+            ident: ident,
+            block: Box::new(Block {
+                brace_token: inner_attrs_stmts.1,
+                stmts: (inner_attrs_stmts.0).1,
+            }),
+        }))
     ));
 
     impl Synom for FnArg {
@@ -801,34 +800,30 @@
                 None,
             )}
         ) >>
-        (Item {
+        (Item::Mod(ItemMod {
             attrs: {
                 let mut attrs = outer_attrs;
                 attrs.extend(content_semi.0);
                 attrs
             },
-            node: ItemMod {
-                vis: vis,
-                mod_token: mod_,
-                ident: ident,
-                content: content_semi.1,
-                semi: content_semi.2,
-            }.into(),
-        })
+            vis: vis,
+            mod_token: mod_,
+            ident: ident,
+            content: content_semi.1,
+            semi: content_semi.2,
+        }))
     ));
 
     named!(item_foreign_mod -> Item, do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
         abi: syn!(Abi) >>
         items: braces!(many0!(syn!(ForeignItem))) >>
-        (Item {
+        (Item::ForeignMod(ItemForeignMod {
             attrs: attrs,
-            node: ItemForeignMod {
-                abi: abi,
-                brace_token: items.1,
-                items: items.0,
-            }.into(),
-        })
+            abi: abi,
+            brace_token: items.1,
+            items: items.0,
+        }))
     ));
 
     impl Synom for ForeignItem {
@@ -913,21 +908,19 @@
         eq: syn!(Eq) >>
         ty: syn!(Ty) >>
         semi: syn!(Semi) >>
-        (Item {
+        (Item::Ty(ItemTy {
             attrs: attrs,
-            node: ItemTy {
-                vis: vis,
-                type_token: type_,
-                ident: ident,
-                generics: Generics {
-                    where_clause: where_clause,
-                    ..generics
-                },
-                eq_token: eq,
-                ty: Box::new(ty),
-                semi_token: semi,
-            }.into(),
-        })
+            vis: vis,
+            type_token: type_,
+            ident: ident,
+            generics: Generics {
+                where_clause: where_clause,
+                ..generics
+            },
+            eq_token: eq,
+            ty: Box::new(ty),
+            semi_token: semi,
+        }))
     ));
 
     named!(item_struct_or_enum -> Item, map!(syn!(DeriveInput), Into::into));
@@ -941,19 +934,17 @@
         where_clause: syn!(WhereClause) >>
         fields: braces!(call!(Delimited::parse_terminated_with,
                               Field::parse_struct)) >>
-        (Item {
+        (Item::Union(ItemUnion {
             attrs: attrs,
-            node: ItemUnion {
-                vis: vis,
-                union_token: union_,
-                ident: ident,
-                generics: Generics {
-                    where_clause: where_clause,
-                    .. generics
-                },
-                data: VariantData::Struct(fields.0, fields.1),
-            }.into(),
-        })
+            vis: vis,
+            union_token: union_,
+            ident: ident,
+            generics: Generics {
+                where_clause: where_clause,
+                .. generics
+            },
+            data: VariantData::Struct(fields.0, fields.1),
+        }))
     ));
 
     named!(item_trait -> Item, do_parse!(
@@ -969,23 +960,21 @@
         ) >>
         where_clause: syn!(WhereClause) >>
         body: braces!(many0!(syn!(TraitItem))) >>
-        (Item {
+        (Item::Trait(ItemTrait {
             attrs: attrs,
-            node: ItemTrait {
-                vis: vis,
-                unsafety: unsafety,
-                trait_token: trait_,
-                ident: ident,
-                generics: Generics {
-                    where_clause: where_clause,
-                    .. generics
-                },
-                colon_token: colon,
-                supertraits: bounds.unwrap_or_default(),
-                brace_token: body.1,
-                items: body.0,
-            }.into(),
-        })
+            vis: vis,
+            unsafety: unsafety,
+            trait_token: trait_,
+            ident: ident,
+            generics: Generics {
+                where_clause: where_clause,
+                .. generics
+            },
+            colon_token: colon,
+            supertraits: bounds.unwrap_or_default(),
+            brace_token: body.1,
+            items: body.0,
+        }))
     ));
 
     named!(item_default_impl -> Item, do_parse!(
@@ -996,17 +985,15 @@
         for_: syn!(For) >>
         dot2: syn!(Dot2) >>
         braces: braces!(epsilon!()) >>
-        (Item {
+        (Item::DefaultImpl(ItemDefaultImpl {
             attrs: attrs,
-            node: ItemDefaultImpl {
-                unsafety: unsafety,
-                impl_token: impl_,
-                path: path,
-                for_token: for_,
-                dot2_token: dot2,
-                brace_token: braces.1,
-            }.into(),
-        })
+            unsafety: unsafety,
+            impl_token: impl_,
+            path: path,
+            for_token: for_,
+            dot2_token: dot2,
+            brace_token: braces.1,
+        }))
     ));
 
     impl Synom for TraitItem {
@@ -1152,22 +1139,20 @@
         self_ty: syn!(Ty) >>
         where_clause: syn!(WhereClause) >>
         body: braces!(many0!(syn!(ImplItem))) >>
-        (Item {
+        (Item::Impl(ItemImpl {
             attrs: attrs,
-            node: ItemImpl {
-                defaultness: defaultness,
-                unsafety: unsafety,
-                impl_token: impl_,
-                generics: Generics {
-                    where_clause: where_clause,
-                    .. generics
-                },
-                trait_: polarity_path,
-                self_ty: Box::new(self_ty),
-                brace_token: body.1,
-                items: body.0,
-            }.into(),
-        })
+            defaultness: defaultness,
+            unsafety: unsafety,
+            impl_token: impl_,
+            generics: Generics {
+                where_clause: where_clause,
+                .. generics
+            },
+            trait_: polarity_path,
+            self_ty: Box::new(self_ty),
+            brace_token: body.1,
+            items: body.0,
+        }))
     ));
 
     impl Synom for ImplItem {
@@ -1328,9 +1313,9 @@
 
     impl ToTokens for Item {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            tokens.append_all(self.attrs.outer());
-            match self.node {
-                ItemKind::ExternCrate(ref item) => {
+            match *self {
+                Item::ExternCrate(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.extern_token.to_tokens(tokens);
                     item.crate_token.to_tokens(tokens);
@@ -1341,13 +1326,15 @@
                     }
                     item.semi_token.to_tokens(tokens);
                 }
-                ItemKind::Use(ref item) => {
+                Item::Use(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.use_token.to_tokens(tokens);
                     item.path.to_tokens(tokens);
                     item.semi_token.to_tokens(tokens);
                 }
-                ItemKind::Static(ref item) => {
+                Item::Static(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.static_token.to_tokens(tokens);
                     item.mutbl.to_tokens(tokens);
@@ -1358,7 +1345,8 @@
                     item.expr.to_tokens(tokens);
                     item.semi_token.to_tokens(tokens);
                 }
-                ItemKind::Const(ref item) => {
+                Item::Const(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.const_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
@@ -1368,37 +1356,41 @@
                     item.expr.to_tokens(tokens);
                     item.semi_token.to_tokens(tokens);
                 }
-                ItemKind::Fn(ref item) => {
+                Item::Fn(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.constness.to_tokens(tokens);
                     item.unsafety.to_tokens(tokens);
                     item.abi.to_tokens(tokens);
                     NamedDecl(&item.decl, item.ident).to_tokens(tokens);
                     item.block.brace_token.surround(tokens, |tokens| {
-                        tokens.append_all(self.attrs.inner());
+                        tokens.append_all(item.attrs.inner());
                         tokens.append_all(&item.block.stmts);
                     });
                 }
-                ItemKind::Mod(ref item) => {
+                Item::Mod(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.mod_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
                     if let Some((ref brace, ref items)) = item.content {
                         brace.surround(tokens, |tokens| {
-                            tokens.append_all(self.attrs.inner());
+                            tokens.append_all(item.attrs.inner());
                             tokens.append_all(items);
                         });
                     } else {
                         TokensOrDefault(&item.semi).to_tokens(tokens);
                     }
                 }
-                ItemKind::ForeignMod(ref item) => {
+                Item::ForeignMod(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.abi.to_tokens(tokens);
                     item.brace_token.surround(tokens, |tokens| {
                         tokens.append_all(&item.items);
                     });
                 }
-                ItemKind::Ty(ref item) => {
+                Item::Ty(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.type_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
@@ -1408,7 +1400,8 @@
                     item.ty.to_tokens(tokens);
                     item.semi_token.to_tokens(tokens);
                 }
-                ItemKind::Enum(ref item) => {
+                Item::Enum(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.enum_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
@@ -1418,7 +1411,8 @@
                         item.variants.to_tokens(tokens);
                     });
                 }
-                ItemKind::Struct(ref item) => {
+                Item::Struct(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.struct_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
@@ -1439,7 +1433,8 @@
                         }
                     }
                 }
-                ItemKind::Union(ref item) => {
+                Item::Union(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.union_token.to_tokens(tokens);
                     item.ident.to_tokens(tokens);
@@ -1449,7 +1444,8 @@
                     // non-VariantData::Struct Variant in Union?
                     item.data.to_tokens(tokens);
                 }
-                ItemKind::Trait(ref item) => {
+                Item::Trait(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.vis.to_tokens(tokens);
                     item.unsafety.to_tokens(tokens);
                     item.trait_token.to_tokens(tokens);
@@ -1464,7 +1460,8 @@
                         tokens.append_all(&item.items);
                     });
                 }
-                ItemKind::DefaultImpl(ref item) => {
+                Item::DefaultImpl(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.unsafety.to_tokens(tokens);
                     item.impl_token.to_tokens(tokens);
                     item.path.to_tokens(tokens);
@@ -1472,7 +1469,8 @@
                     item.dot2_token.to_tokens(tokens);
                     item.brace_token.surround(tokens, |_tokens| {});
                 }
-                ItemKind::Impl(ref item) => {
+                Item::Impl(ref item) => {
+                    tokens.append_all(item.attrs.outer());
                     item.defaultness.to_tokens(tokens);
                     item.unsafety.to_tokens(tokens);
                     item.impl_token.to_tokens(tokens);
@@ -1488,12 +1486,13 @@
                         tokens.append_all(&item.items);
                     });
                 }
-                ItemKind::Mac(ref mac) => {
-                    mac.path.to_tokens(tokens);
-                    mac.bang_token.to_tokens(tokens);
-                    mac.ident.to_tokens(tokens);
-                    tokens.append_all(&mac.tokens);
-                    if !mac.is_braced() {
+                Item::Mac(ref item) => {
+                    tokens.append_all(item.attrs.outer());
+                    item.mac.path.to_tokens(tokens);
+                    item.mac.bang_token.to_tokens(tokens);
+                    item.mac.ident.to_tokens(tokens);
+                    tokens.append_all(&item.mac.tokens);
+                    if !item.mac.is_braced() {
                         tokens::Semi::default().to_tokens(tokens);
                     }
                 }
diff --git a/src/lib.rs b/src/lib.rs
index 2e20825..132f8dc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -53,9 +53,9 @@
 mod item;
 #[cfg(feature = "full")]
 pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ItemForeignMod,
-               ImplItem, ImplItemKind, ImplPolarity, Item, ItemKind, MethodSig, PathListItem,
+               ImplItem, ImplItemKind, ImplPolarity, Item, MethodSig, PathListItem,
                TraitItem, TraitItemKind, ViewPath, ItemExternCrate, ItemUse,
-               ItemStatic, ItemConst, ItemFn, ItemMod, ItemTy, ItemEnum,
+               ItemStatic, ItemConst, ItemFn, ItemMac, ItemMod, ItemTy, ItemEnum,
                ItemStruct, ItemUnion, ItemTrait, ItemDefaultImpl, ItemImpl,
                PathSimple, PathGlob, PathList, ForeignItemFn, ForeignItemStatic,
                TraitItemConst, TraitItemMethod, TraitItemType,
diff --git a/syn_codegen/src/main.rs b/syn_codegen/src/main.rs
index 4567545..aab20b6 100644
--- a/syn_codegen/src/main.rs
+++ b/syn_codegen/src/main.rs
@@ -16,7 +16,7 @@
 extern crate inflections;
 
 use quote::{Tokens, ToTokens};
-use syn::{ItemKind, Attribute, DeriveInput, Ident};
+use syn::{Item, Attribute, DeriveInput, Ident};
 
 use std::io::{self, Read, Write};
 use std::fs::File;
@@ -90,17 +90,17 @@
 
     // Collect all of the interesting AstItems declared in this file or submodules.
     'items: for item in &file.items {
-        match item.node {
-            ItemKind::Mod(ref module) => {
+        match *item {
+            Item::Mod(ref item) => {
                 // Don't inspect inline modules.
-                if module.content.is_some() {
+                if item.content.is_some() {
                     continue;
                 }
 
                 // We don't want to try to load the generated rust files and
                 // parse them, so we ignore them here.
                 for name in IGNORED_MODS {
-                    if module.ident.as_ref() == *name {
+                    if item.ident.as_ref() == *name {
                         continue 'items;
                     }
                 }
@@ -111,26 +111,26 @@
 
                 // Look up the submodule file, and recursively parse it.
                 // XXX: Only handles same-directory .rs file submodules.
-                let path = parent.join(&format!("{}.rs", module.ident.as_ref()));
+                let path = parent.join(&format!("{}.rs", item.ident.as_ref()));
                 load_file(path, features, lookup)?;
             }
-            ItemKind::Mac(ref mac) => {
+            Item::Mac(ref item) => {
                 // Lookip any #[cfg()] attributes directly on the macro
                 // invocation, and add them to the feature set.
                 let features = get_features(&item.attrs, features.clone());
 
                 // Try to parse the AstItem declaration out of the item.
-                let found = if path_eq(&mac.path, &"ast_struct".into()) {
+                let found = if path_eq(&item.mac.path, &"ast_struct".into()) {
                     syn::parse_tokens::<parsing::AstStruct>(
-                        mac.tokens[0].clone().into_tokens()
+                        item.mac.tokens[0].clone().into_tokens()
                     ).map_err(|_| io::ErrorKind::Other)?.0
-                } else if path_eq(&mac.path, &"ast_enum".into()) {
+                } else if path_eq(&item.mac.path, &"ast_enum".into()) {
                     syn::parse_tokens::<parsing::AstEnum>(
-                        mac.tokens[0].clone().into_tokens()
+                        item.mac.tokens[0].clone().into_tokens()
                     ).map_err(|_| io::ErrorKind::Other)?.0
-                } else if path_eq(&mac.path, &"ast_enum_of_structs".into()) {
+                } else if path_eq(&item.mac.path, &"ast_enum_of_structs".into()) {
                     syn::parse_tokens::<parsing::AstEnumOfStructs>(
-                        mac.tokens[0].clone().into_tokens()
+                        item.mac.tokens[0].clone().into_tokens()
                     ).map_err(|_| io::ErrorKind::Other)?.0
                 } else {
                     continue
diff --git a/tests/test_expr.rs b/tests/test_expr.rs
index 14c0cae..5967aa6 100644
--- a/tests/test_expr.rs
+++ b/tests/test_expr.rs
@@ -88,11 +88,11 @@
 
     let actual: File = syn::parse_str(raw).unwrap();
 
-    assert_let!(ItemKind::Struct(ItemStruct { ref ident, .. }) = actual.items[0].node; {
+    assert_let!(Item::Struct(ItemStruct { ref ident, .. }) = actual.items[0]; {
         assert_eq!(ident, "catch");
     });
 
-    assert_let!(Item { node: ItemKind::Fn(ItemFn { ref block, .. }), .. } = actual.items[1]; {
+    assert_let!(Item::Fn(ItemFn { ref block, .. }) = actual.items[1]; {
         assert_let!(Stmt::Local(ref local) = block.stmts[0]; {
             assert_let!(Local { init: Some(ref init_expr), .. } = **local; {
                 assert_let!(Expr { node: ExprKind::Catch(..), .. } = **init_expr);