Rewrite the AST to be a bit more user-friendly

This commit is a relatively large rewrite of the AST that `syn` exposes. The
main change is to expose enums-of-structs rather than
enums-with-huge-tuple-variants. The best example of this is `ItemKind::Fn` which
changed from:

    enum ItemKind {
        Fn(Box<FnDecl>, Unsafety, Constness, Option<Abi>, Generics, Box<Block>),
        ...
    }

to

    enum ItemKind {
        Fn(ItemFn),
        ...
    }

    struct ItemFn {
        decl: Box<FnDecl>,
        unsafety: Unsafety,
        constness: Constness,
        abi: Option<Abi>,
        generics: Generics,
        block: Box<Block>,
    }

This change serves a few purposes:

* It's now much easier to add fields to each variant of the ast, ast struct
  fields tend to be "by default ignored" in most contexts.
* It's much easier to document what each field is, as each field can have
  dedicated documentation.
* There's now canonicalized names for each field (the name of the field) which
  can help match `match` statements more consistent across a codebase.

A downside of this representation is that it can be a little more verbose to
work with in `match` statements and during constructions. Overall though I'd
feel at least that the readability improved significantly despite the extra
words required to do various operations.

Closes #136
diff --git a/src/fold.rs b/src/fold.rs
index def73f2..3a5c763 100644
--- a/src/fold.rs
+++ b/src/fold.rs
@@ -198,59 +198,89 @@
 }
 
 pub fn noop_fold_ty<F: ?Sized + Folder>(folder: &mut F, ty: Ty) -> Ty {
+    use ty::*;
     use Ty::*;
+
     match ty {
-        Slice(inner) => Slice(inner.lift(|v| folder.fold_ty(v))),
-        Paren(inner) => Paren(inner.lift(|v| folder.fold_ty(v))),
-        Ptr(mutable_type) => {
-            let mutable_type_ = *mutable_type;
-            let MutTy { ty, mutability }: MutTy = mutable_type_;
-            Ptr(Box::new(MutTy {
-                             ty: folder.fold_ty(ty),
-                             mutability: mutability,
-                         }))
+        Slice(TySlice { ty }) => {
+            Slice(TySlice {
+                ty: ty.lift(|v| folder.fold_ty(v)),
+            })
         }
-        Rptr(opt_lifetime, mutable_type) => {
-            let mutable_type_ = *mutable_type;
-            let MutTy { ty, mutability }: MutTy = mutable_type_;
-            Rptr(opt_lifetime.map(|l| folder.fold_lifetime(l)),
-                 Box::new(MutTy {
-                              ty: folder.fold_ty(ty),
-                              mutability: mutability,
-                          }))
+        Paren(TyParen { ty }) => {
+            Paren(TyParen {
+                ty: ty.lift(|v| folder.fold_ty(v)),
+            })
         }
-        Never => Never,
-        Infer => Infer,
-        Tup(tuple_element_types) => Tup(tuple_element_types.lift(|x| folder.fold_ty(x))),
-        BareFn(bare_fn) => {
-            let bf_ = *bare_fn;
-            let BareFnTy { unsafety, abi, lifetimes, inputs, output, variadic } = bf_;
-            BareFn(Box::new(BareFnTy {
-                                unsafety: unsafety,
-                                abi: abi,
-                                lifetimes: lifetimes.lift(|l| folder.fold_lifetime_def(l)),
-                                inputs: inputs.lift(|v| {
-                BareFnArg {
-                    name: v.name.map(|n| folder.fold_ident(n)),
-                    ty: folder.fold_ty(v.ty),
-                }
-            }),
-                                output: folder.fold_fn_ret_ty(output),
-                                variadic: variadic,
-                            }))
+        Ptr(TyPtr { ty }) => {
+            let ty = *ty;
+            let MutTy { ty, mutability } = ty;
+            Ptr(TyPtr {
+                ty: Box::new(MutTy {
+                    ty: folder.fold_ty(ty),
+                    mutability: mutability,
+                }),
+            })
         }
-        Path(maybe_qself, path) => {
-            Path(maybe_qself.map(|v| noop_fold_qself(folder, v)),
-                 folder.fold_path(path))
+        Rptr(TyRptr { lifetime, ty }) => {
+            let ty = *ty;
+            let MutTy { ty, mutability } = ty;
+            Rptr(TyRptr {
+                lifetime: lifetime.map(|l| folder.fold_lifetime(l)),
+                ty: Box::new(MutTy {
+                    ty: folder.fold_ty(ty),
+                    mutability: mutability,
+                }),
+            })
         }
-        Array(inner, len) => {
-            Array({
-                      inner.lift(|v| folder.fold_ty(v))
-                  },
-                  folder.fold_const_expr(len))
+        Never(t) => Never(t),
+        Infer(t) => Infer(t),
+        Tup(TyTup { tys }) => {
+            Tup(TyTup {
+                tys: tys.lift(|x| folder.fold_ty(x)),
+            })
         }
-        TraitObject(bounds) => TraitObject(bounds.lift(|v| folder.fold_ty_param_bound(v))),
-        ImplTrait(bounds) => ImplTrait(bounds.lift(|v| folder.fold_ty_param_bound(v))),
+        BareFn(TyBareFn { ty }) => {
+            let ty = *ty;
+            let BareFnTy { unsafety, abi, lifetimes, inputs, output, variadic } = ty;
+            BareFn(TyBareFn {
+                ty: Box::new(BareFnTy {
+                    unsafety: unsafety,
+                    abi: abi,
+                    lifetimes: lifetimes.lift(|l| folder.fold_lifetime_def(l)),
+                    inputs: inputs.lift(|v| {
+                        BareFnArg {
+                            name: v.name.map(|n| folder.fold_ident(n)),
+                            ty: folder.fold_ty(v.ty),
+                        }
+                    }),
+                    output: folder.fold_fn_ret_ty(output),
+                    variadic: variadic,
+                }),
+            })
+        }
+        Path(TyPath { qself, path }) => {
+            Path(TyPath {
+                qself: qself.map(|v| noop_fold_qself(folder, v)),
+                path: folder.fold_path(path),
+            })
+        }
+        Array(TyArray { ty, amt }) => {
+            Array(TyArray {
+                ty: ty.lift(|v| folder.fold_ty(v)),
+                amt: folder.fold_const_expr(amt),
+            })
+        }
+        TraitObject(TyTraitObject { bounds }) => {
+            TraitObject(TyTraitObject {
+                bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+            })
+        }
+        ImplTrait(TyImplTrait { bounds }) => {
+            ImplTrait(TyImplTrait {
+                bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+            })
+        }
         Mac(mac) => Mac(folder.fold_mac(mac)),
     }
 }
@@ -435,29 +465,48 @@
 }
 
 pub fn noop_fold_const_expr<F: ?Sized + Folder>(folder: &mut F, expr: ConstExpr) -> ConstExpr {
-    use ConstExpr::*;
+    use constant::*;
+    use constant::ConstExpr::*;
+
     match expr {
-        Call(f, args) => {
-            Call(f.lift(|e| folder.fold_const_expr(e)),
-                 args.lift(|v| folder.fold_const_expr(v)))
+        Call(ConstCall { func, args }) => {
+            Call(ConstCall {
+                func: func.lift(|e| folder.fold_const_expr(e)),
+                args: args.lift(|v| folder.fold_const_expr(v)),
+            })
         }
-        Binary(op, lhs, rhs) => {
-            Binary(op,
-                   lhs.lift(|e| folder.fold_const_expr(e)),
-                   rhs.lift(|e| folder.fold_const_expr(e)))
+        Binary(ConstBinary { op, left, right }) => {
+            Binary(ConstBinary {
+                op: op,
+                left: left.lift(|e| folder.fold_const_expr(e)),
+                right: right.lift(|e| folder.fold_const_expr(e)),
+            })
         }
-        Unary(op, e) => Unary(op, e.lift(|e| folder.fold_const_expr(e))),
+        Unary(ConstUnary { op, expr }) => {
+            Unary(ConstUnary {
+                op: op,
+                expr: expr.lift(|e| folder.fold_const_expr(e)),
+            })
+        }
         Lit(l) => Lit(folder.fold_lit(l)),
-        Cast(e, ty) => {
-            Cast(e.lift(|e| folder.fold_const_expr(e)),
-                 ty.lift(|v| folder.fold_ty(v)))
+        Cast(ConstCast { expr, ty }) => {
+            Cast(ConstCast {
+                expr: expr.lift(|e| folder.fold_const_expr(e)),
+                ty: ty.lift(|v| folder.fold_ty(v)),
+            })
         }
         Path(p) => Path(folder.fold_path(p)),
-        Index(o, i) => {
-            Index(o.lift(|e| folder.fold_const_expr(e)),
-                  i.lift(|e| folder.fold_const_expr(e)))
+        Index(ConstIndex { expr, index }) => {
+            Index(ConstIndex {
+                expr: expr.lift(|e| folder.fold_const_expr(e)),
+                index: index.lift(|e| folder.fold_const_expr(e)),
+            })
         }
-        Paren(no_op) => Paren(no_op.lift(|e| folder.fold_const_expr(e))),
+        Paren(ConstParen { expr }) => {
+            Paren(ConstParen {
+                expr: expr.lift(|e| folder.fold_const_expr(e)),
+            })
+        }
         Other(e) => Other(noop_fold_other_const_expr(folder, e)),
     }
 }
@@ -537,70 +586,113 @@
 pub fn noop_fold_item<F: ?Sized + Folder>(folder: &mut F,
                                           Item { ident, vis, attrs, node }: Item)
                                           -> Item {
+    use item::*;
     use ItemKind::*;
     Item {
         ident: folder.fold_ident(ident.clone()),
         vis: noop_fold_vis(folder, vis),
         attrs: attrs.lift(|a| folder.fold_attribute(a)),
         node: match node {
-            ExternCrate(name) => ExternCrate(name.map(|i| folder.fold_ident(i))),
-            Use(view_path) => Use(Box::new(folder.fold_view_path(*view_path))),
-            Static(ty, mutability, expr) => {
-                Static(Box::new(folder.fold_ty(*ty)),
-                       mutability,
-                       expr.lift(|e| folder.fold_expr(e)))
+            ExternCrate(ItemExternCrate { original }) => {
+                ExternCrate(ItemExternCrate {
+                    original: original.map(|i| folder.fold_ident(i)),
+                })
             }
-            Const(ty, expr) => {
-                Const(ty.lift(|ty| folder.fold_ty(ty)),
-                      expr.lift(|e| folder.fold_expr(e)))
+            Use(ItemUse { path }) => {
+                Use(ItemUse {
+                    path: Box::new(folder.fold_view_path(*path)),
+                })
             }
-            Fn(fn_decl, unsafety, constness, abi, generics, block) => {
-                Fn(fn_decl.lift(|v| folder.fold_fn_decl(v)),
-                   unsafety,
-                   constness,
-                   abi,
-                   folder.fold_generics(generics),
-                   block.lift(|v| folder.fold_block(v)))
+            Static(ItemStatic { ty, mutbl, expr }) => {
+                Static(ItemStatic {
+                    ty: Box::new(folder.fold_ty(*ty)),
+                    mutbl: mutbl,
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Mod(items) => Mod(items.map(|items| items.lift(|i| folder.fold_item(i)))),
-            ForeignMod(super::ForeignMod { abi, items }) => {
-                ForeignMod(super::ForeignMod {
-                               abi: abi,
-                               items: items.lift(|foreign_item| {
-                                                     folder.fold_foreign_item(foreign_item)
-                                                 }),
-                           })
+            Const(ItemConst { ty, expr }) => {
+                Const(ItemConst {
+                    ty: ty.lift(|ty| folder.fold_ty(ty)),
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Ty(ty, generics) => {
-                Ty(ty.lift(|ty| folder.fold_ty(ty)),
-                   folder.fold_generics(generics))
+            Fn(ItemFn { decl, unsafety, constness, abi, generics, block }) => {
+                Fn(ItemFn {
+                    decl: decl.lift(|v| folder.fold_fn_decl(v)),
+                    unsafety: unsafety,
+                    constness: constness,
+                    abi: abi,
+                    generics: folder.fold_generics(generics),
+                    block: block.lift(|v| folder.fold_block(v)),
+                })
             }
-            Enum(variants, generics) => {
-                Enum(variants.lift(|v| folder.fold_variant(v)),
-                     folder.fold_generics(generics))
+            Mod(ItemMod { items }) => {
+                Mod(ItemMod {
+                    items: items.map(|items| items.lift(|i| folder.fold_item(i))),
+                })
             }
-            Struct(variant_data, generics) => {
-                Struct(folder.fold_variant_data(variant_data),
-                       folder.fold_generics(generics))
+            ForeignMod(ItemForeignMod { abi, items }) => {
+                ForeignMod(ItemForeignMod {
+                    abi: abi,
+                    items: items.lift(|foreign_item| {
+                        folder.fold_foreign_item(foreign_item)
+                    }),
+                })
             }
-            Union(variant_data, generics) => {
-                Union(folder.fold_variant_data(variant_data),
-                      folder.fold_generics(generics))
+            Ty(ItemTy { ty, generics }) => {
+                Ty(ItemTy {
+                    ty: ty.lift(|ty| folder.fold_ty(ty)),
+                    generics: folder.fold_generics(generics),
+                })
             }
-            Trait(unsafety, generics, typbs, trait_items) => {
-                Trait(unsafety,
-                      folder.fold_generics(generics),
-                      typbs.lift(|typb| folder.fold_ty_param_bound(typb)),
-                      trait_items.lift(|ti| folder.fold_trait_item(ti)))
+            Enum(ItemEnum { variants, generics }) => {
+                Enum(ItemEnum {
+                    variants: variants.lift(|v| folder.fold_variant(v)),
+                    generics: folder.fold_generics(generics),
+                })
             }
-            DefaultImpl(unsafety, path) => DefaultImpl(unsafety, folder.fold_path(path)),
-            Impl(unsafety, impl_polarity, generics, path, ty, impl_items) => {
-                Impl(unsafety,
-                     impl_polarity,
-                     folder.fold_generics(generics),
-                     path.map(|p| folder.fold_path(p)),
-                     ty.lift(|ty| folder.fold_ty(ty)),
-                     impl_items.lift(|i| folder.fold_impl_item(i)))
+            Struct(ItemStruct { data, generics }) => {
+                Struct(ItemStruct {
+                    data: folder.fold_variant_data(data),
+                    generics: folder.fold_generics(generics),
+                })
+            }
+            Union(ItemUnion { data, generics }) => {
+                Union(ItemUnion {
+                    data: folder.fold_variant_data(data),
+                    generics: folder.fold_generics(generics),
+                })
+            }
+            Trait(ItemTrait { unsafety, generics, supertraits, items }) => {
+                Trait(ItemTrait {
+                    unsafety: unsafety,
+                    generics: folder.fold_generics(generics),
+                    supertraits: supertraits.lift(|typb| folder.fold_ty_param_bound(typb)),
+                    items: items.lift(|ti| folder.fold_trait_item(ti)),
+                })
+            }
+            DefaultImpl(ItemDefaultImpl { unsafety, path }) => {
+                DefaultImpl(ItemDefaultImpl {
+                    unsafety: unsafety,
+                    path: folder.fold_path(path),
+                })
+            }
+            Impl(ItemImpl {
+                unsafety,
+                polarity,
+                generics,
+                trait_,
+                self_ty,
+                items,
+            }) => {
+                Impl(ItemImpl {
+                    unsafety: unsafety,
+                    polarity: polarity,
+                    generics: folder.fold_generics(generics),
+                    trait_: trait_.map(|p| folder.fold_path(p)),
+                    self_ty: self_ty.lift(|ty| folder.fold_ty(ty)),
+                    items: items.lift(|i| folder.fold_impl_item(i)),
+                })
             }
             Mac(mac) => Mac(folder.fold_mac(mac)),
         },
@@ -609,142 +701,235 @@
 
 #[cfg(feature = "full")]
 pub fn noop_fold_expr<F: ?Sized + Folder>(folder: &mut F, Expr { node, attrs }: Expr) -> Expr {
-    use ExprKind::*;
+    use expr::*;
+    use expr::ExprKind::*;
+
     Expr {
         node: match node {
-            ExprKind::Box(e) => ExprKind::Box(e.lift(|e| folder.fold_expr(e))),
-            InPlace(place, value) => {
-                InPlace(place.lift(|e| folder.fold_expr(e)),
-                        value.lift(|e| folder.fold_expr(e)))
+            Box(ExprBox { expr }) => {
+                Box(ExprBox { expr: expr.lift(|e| folder.fold_expr(e)) })
             }
-            Array(array) => Array(array.lift(|e| folder.fold_expr(e))),
-            Call(function, args) => {
-                Call(function.lift(|e| folder.fold_expr(e)),
-                     args.lift(|e| folder.fold_expr(e)))
+            InPlace(ExprInPlace { place, value }) => {
+                InPlace(ExprInPlace {
+                    place: place.lift(|e| folder.fold_expr(e)),
+                    value: value.lift(|e| folder.fold_expr(e)),
+                })
             }
-            MethodCall(method, tys, args) => {
-                MethodCall(folder.fold_ident(method),
-                           tys.lift(|t| folder.fold_ty(t)),
-                           args.lift(|e| folder.fold_expr(e)))
+            Array(ExprArray { exprs }) => {
+                Array(ExprArray {
+                    exprs: exprs.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Tup(args) => Tup(args.lift(|e| folder.fold_expr(e))),
-            Binary(bop, lhs, rhs) => {
-                Binary(bop,
-                       lhs.lift(|e| folder.fold_expr(e)),
-                       rhs.lift(|e| folder.fold_expr(e)))
+            Call(ExprCall { func, args }) => {
+                Call(ExprCall {
+                    func: func.lift(|e| folder.fold_expr(e)),
+                    args: args.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Unary(uop, e) => Unary(uop, e.lift(|e| folder.fold_expr(e))),
+            MethodCall(ExprMethodCall { method, typarams, args }) => {
+                MethodCall(ExprMethodCall {
+                    method: folder.fold_ident(method),
+                    typarams: typarams.lift(|t| folder.fold_ty(t)),
+                    args: args.lift(|e| folder.fold_expr(e)),
+                })
+            }
+            Tup(ExprTup { args }) => {
+                Tup(ExprTup {
+                    args: args.lift(|e| folder.fold_expr(e)),
+                })
+            }
+            Binary(ExprBinary { op, left, right }) => {
+                Binary(ExprBinary {
+                    op: op,
+                    left: left.lift(|e| folder.fold_expr(e)),
+                    right: right.lift(|e| folder.fold_expr(e)),
+                })
+            }
+            Unary(ExprUnary { op, expr }) => {
+                Unary(ExprUnary {
+                    op: op,
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                })
+            }
             Lit(lit) => Lit(folder.fold_lit(lit)),
-            Cast(e, ty) => {
-                Cast(e.lift(|e| folder.fold_expr(e)),
-                     ty.lift(|t| folder.fold_ty(t)))
+            Cast(ExprCast { expr, ty }) => {
+                Cast(ExprCast {
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    ty: ty.lift(|t| folder.fold_ty(t)),
+                })
             }
-            Type(e, ty) => {
-                Type(e.lift(|e| folder.fold_expr(e)),
-                     ty.lift(|t| folder.fold_ty(t)))
+            Type(ExprType { expr, ty }) => {
+                Type(ExprType {
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    ty: ty.lift(|t| folder.fold_ty(t)),
+                })
             }
-            If(e, if_block, else_block) => {
-                If(e.lift(|e| folder.fold_expr(e)),
-                   folder.fold_block(if_block),
-                   else_block.map(|v| v.lift(|e| folder.fold_expr(e))))
+            If(ExprIf { cond, if_true, if_false }) => {
+                If(ExprIf {
+                    cond: cond.lift(|e| folder.fold_expr(e)),
+                    if_true: folder.fold_block(if_true),
+                    if_false: if_false.map(|v| v.lift(|e| folder.fold_expr(e))),
+                })
             }
-            IfLet(pat, expr, block, else_block) => {
-                IfLet(pat.lift(|p| folder.fold_pat(p)),
-                      expr.lift(|e| folder.fold_expr(e)),
-                      folder.fold_block(block),
-                      else_block.map(|v| v.lift(|e| folder.fold_expr(e))))
+            IfLet(ExprIfLet { pat, expr, if_true, if_false }) => {
+                IfLet(ExprIfLet {
+                    pat: pat.lift(|p| folder.fold_pat(p)),
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    if_true: folder.fold_block(if_true),
+                    if_false: if_false.map(|v| v.lift(|e| folder.fold_expr(e))),
+                })
             }
-            While(e, block, label) => {
-                While(e.lift(|e| folder.fold_expr(e)),
-                      folder.fold_block(block),
-                      label.map(|i| folder.fold_ident(i)))
+            While(ExprWhile { cond, body, label }) => {
+                While(ExprWhile {
+                    cond: cond.lift(|e| folder.fold_expr(e)),
+                    body: folder.fold_block(body),
+                    label: label.map(|i| folder.fold_ident(i)),
+                })
             }
-            WhileLet(pat, expr, block, label) => {
-                WhileLet(pat.lift(|p| folder.fold_pat(p)),
-                         expr.lift(|e| folder.fold_expr(e)),
-                         folder.fold_block(block),
-                         label.map(|i| folder.fold_ident(i)))
+            WhileLet(ExprWhileLet { pat, expr, body, label }) => {
+                WhileLet(ExprWhileLet {
+                    pat: pat.lift(|p| folder.fold_pat(p)),
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    body: folder.fold_block(body),
+                    label: label.map(|i| folder.fold_ident(i)),
+                })
             }
-            ForLoop(pat, expr, block, label) => {
-                ForLoop(pat.lift(|p| folder.fold_pat(p)),
-                        expr.lift(|e| folder.fold_expr(e)),
-                        folder.fold_block(block),
-                        label.map(|i| folder.fold_ident(i)))
+            ForLoop(ExprForLoop { pat, expr, body, label }) => {
+                ForLoop(ExprForLoop {
+                    pat: pat.lift(|p| folder.fold_pat(p)),
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    body: folder.fold_block(body),
+                    label: label.map(|i| folder.fold_ident(i)),
+                })
             }
-            Loop(block, label) => {
-                Loop(folder.fold_block(block),
-                     label.map(|i| folder.fold_ident(i)))
+            Loop(ExprLoop { body, label }) => {
+                Loop(ExprLoop {
+                    body: folder.fold_block(body),
+                    label: label.map(|i| folder.fold_ident(i)),
+                })
             }
-            Match(e, arms) => {
-                Match(e.lift(|e| folder.fold_expr(e)),
-                      arms.lift(|Arm { attrs, pats, guard, body }: Arm| {
-                    Arm {
-                        attrs: attrs.lift(|a| folder.fold_attribute(a)),
-                        pats: pats.lift(|p| folder.fold_pat(p)),
-                        guard: guard.map(|v| v.lift(|e| folder.fold_expr(e))),
-                        body: body.lift(|e| folder.fold_expr(e)),
-                    }
-                }))
+            Match(ExprMatch { expr, arms }) => {
+                Match(ExprMatch {
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    arms: arms.lift(|Arm { attrs, pats, guard, body }: Arm| {
+                        Arm {
+                            attrs: attrs.lift(|a| folder.fold_attribute(a)),
+                            pats: pats.lift(|p| folder.fold_pat(p)),
+                            guard: guard.map(|v| v.lift(|e| folder.fold_expr(e))),
+                            body: body.lift(|e| folder.fold_expr(e)),
+                        }
+                    })
+                })
             }
-            Catch(block) => {
-                Catch(folder.fold_block(block))
+            Catch(ExprCatch { block }) => {
+                Catch(ExprCatch { block: folder.fold_block(block) })
             }
-            Closure(capture_by, fn_decl, expr) => {
-                Closure(capture_by,
-                        fn_decl.lift(|v| folder.fold_fn_decl(v)),
-                        expr.lift(|e| folder.fold_expr(e)))
+            Closure(ExprClosure { capture, decl, body }) => {
+                Closure(ExprClosure {
+                    capture: capture,
+                    decl: decl.lift(|v| folder.fold_fn_decl(v)),
+                    body: body.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Block(unsafety, block) => Block(unsafety, folder.fold_block(block)),
-            Assign(lhs, rhs) => {
-                Assign(lhs.lift(|e| folder.fold_expr(e)),
-                       rhs.lift(|e| folder.fold_expr(e)))
+            Block(ExprBlock { unsafety, block }) => {
+                Block(ExprBlock {
+                    unsafety: unsafety,
+                    block: folder.fold_block(block),
+                })
             }
-            AssignOp(bop, lhs, rhs) => {
-                AssignOp(bop,
-                         lhs.lift(|e| folder.fold_expr(e)),
-                         rhs.lift(|e| folder.fold_expr(e)))
+            Assign(ExprAssign { left, right }) => {
+                Assign(ExprAssign {
+                    left: left.lift(|e| folder.fold_expr(e)),
+                    right: right.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Field(expr, name) => Field(expr.lift(|e| folder.fold_expr(e)), folder.fold_ident(name)),
-            TupField(expr, index) => TupField(expr.lift(|e| folder.fold_expr(e)), index),
-            Index(expr, index) => {
-                Index(expr.lift(|e| folder.fold_expr(e)),
-                      index.lift(|e| folder.fold_expr(e)))
+            AssignOp(ExprAssignOp { op, left, right }) => {
+                AssignOp(ExprAssignOp {
+                    op: op,
+                    left: left.lift(|e| folder.fold_expr(e)),
+                    right: right.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Range(lhs, rhs, limits) => {
-                Range(lhs.map(|v| v.lift(|e| folder.fold_expr(e))),
-                      rhs.map(|v| v.lift(|e| folder.fold_expr(e))),
-                      limits)
+            Field(ExprField { expr, field }) => {
+                Field(ExprField {
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    field: folder.fold_ident(field),
+                })
             }
-            Path(qself, path) => {
-                Path(qself.map(|v| noop_fold_qself(folder, v)),
-                     folder.fold_path(path))
+            TupField(ExprTupField { expr, field }) => {
+                TupField(ExprTupField {
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    field: field,
+                })
             }
-            AddrOf(mutability, expr) => AddrOf(mutability, expr.lift(|e| folder.fold_expr(e))),
-            Break(label, expr) => {
-                Break(label.map(|i| folder.fold_ident(i)),
-                      expr.map(|v| v.lift(|e| folder.fold_expr(e))))
+            Index(ExprIndex { expr, index }) => {
+                Index(ExprIndex {
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    index: index.lift(|e| folder.fold_expr(e)),
+                })
             }
-            Continue(label) => Continue(label.map(|i| folder.fold_ident(i))),
-            Ret(expr) => Ret(expr.map(|v| v.lift(|e| folder.fold_expr(e)))),
-            ExprKind::Mac(mac) => ExprKind::Mac(folder.fold_mac(mac)),
-            Struct(path, fields, expr) => {
-                Struct(folder.fold_path(path),
-                       fields.lift(|FieldValue { ident, expr, is_shorthand, attrs }: FieldValue| {
-                    FieldValue {
-                        ident: folder.fold_ident(ident),
-                        expr: folder.fold_expr(expr),
-                        is_shorthand: is_shorthand,
-                        attrs: attrs.lift(|v| folder.fold_attribute(v)),
-                    }
-                }),
-                       expr.map(|v| v.lift(|e| folder.fold_expr(e))))
+            Range(ExprRange { from, to, limits }) => {
+                Range(ExprRange {
+                    from: from.map(|v| v.lift(|e| folder.fold_expr(e))),
+                    to: to.map(|v| v.lift(|e| folder.fold_expr(e))),
+                    limits: limits,
+                })
             }
-            Repeat(element, number) => {
-                Repeat(element.lift(|e| folder.fold_expr(e)),
-                       number.lift(|e| folder.fold_expr(e)))
+            Path(ExprPath { qself, path }) => {
+                Path(ExprPath {
+                    qself: qself.map(|v| noop_fold_qself(folder, v)),
+                    path: folder.fold_path(path),
+                })
             }
-            Paren(expr) => Paren(expr.lift(|e| folder.fold_expr(e))),
-            Try(expr) => Try(expr.lift(|e| folder.fold_expr(e))),
+            AddrOf(ExprAddrOf { mutbl, expr }) => {
+                AddrOf(ExprAddrOf {
+                    mutbl: mutbl,
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                })
+            }
+            Break(ExprBreak { label, expr }) => {
+                Break(ExprBreak {
+                    label: label.map(|i| folder.fold_ident(i)),
+                    expr: expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+                })
+            }
+            Continue(ExprContinue { label }) => {
+                Continue(ExprContinue {
+                    label: label.map(|i| folder.fold_ident(i)),
+                })
+            }
+            Ret(ExprRet { expr }) => {
+                Ret(ExprRet {
+                    expr: expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+                })
+            }
+            Mac(mac) => Mac(folder.fold_mac(mac)),
+            Struct(ExprStruct { path, fields, rest }) => {
+                Struct(ExprStruct {
+                    path: folder.fold_path(path),
+                    fields: fields.lift(|FieldValue { ident, expr, is_shorthand, attrs }: FieldValue| {
+                        FieldValue {
+                            ident: folder.fold_ident(ident),
+                            expr: folder.fold_expr(expr),
+                            is_shorthand: is_shorthand,
+                            attrs: attrs.lift(|v| folder.fold_attribute(v)),
+                        }
+                    }),
+                    rest: rest.map(|v| v.lift(|e| folder.fold_expr(e))),
+                })
+            }
+            Repeat(ExprRepeat { expr, amt }) => {
+                Repeat(ExprRepeat {
+                    expr: expr.lift(|e| folder.fold_expr(e)),
+                    amt: amt.lift(|e| folder.fold_expr(e)),
+                })
+            }
+            Paren(ExprParen { expr }) => {
+                Paren(ExprParen { expr: expr.lift(|e| folder.fold_expr(e)) })
+            }
+            Try(ExprTry { expr }) => {
+                Try(ExprTry { expr: expr.lift(|e| folder.fold_expr(e)) })
+            }
         },
         attrs: attrs.into_iter().map(|a| folder.fold_attribute(a)).collect(),
     }
@@ -754,16 +939,23 @@
 pub fn noop_fold_foreign_item<F: ?Sized + Folder>(folder: &mut F,
                                          ForeignItem { ident, attrs, node, vis }: ForeignItem)
 -> ForeignItem{
+    use item::*;
+
     ForeignItem {
         ident: folder.fold_ident(ident),
         attrs: attrs.into_iter().map(|a| folder.fold_attribute(a)).collect(),
         node: match node {
-            ForeignItemKind::Fn(fn_dcl, generics) => {
-                ForeignItemKind::Fn(fn_dcl.lift(|v| folder.fold_fn_decl(v)),
-                                    folder.fold_generics(generics))
+            ForeignItemKind::Fn(ForeignItemFn { decl, generics }) => {
+                ForeignItemKind::Fn(ForeignItemFn {
+                    decl: decl.lift(|v| folder.fold_fn_decl(v)),
+                    generics: folder.fold_generics(generics),
+                })
             }
-            ForeignItemKind::Static(ty, mutability) => {
-                ForeignItemKind::Static(ty.lift(|v| folder.fold_ty(v)), mutability)
+            ForeignItemKind::Static(ForeignItemStatic { ty, mutbl }) => {
+                ForeignItemKind::Static(ForeignItemStatic {
+                    ty: ty.lift(|v| folder.fold_ty(v)),
+                    mutbl: mutbl,
+                })
             }
         },
         vis: noop_fold_vis(folder, vis),
@@ -826,13 +1018,26 @@
 
     FnDecl {
         inputs: inputs.lift(|a| {
+            use item::*;
             use FnArg::*;
             match a {
-                SelfRef(lifetime, mutability) => {
-                    SelfRef(lifetime.map(|v| folder.fold_lifetime(v)), mutability)
+                SelfRef(ArgSelfRef { lifetime, mutbl }) => {
+                    SelfRef(ArgSelfRef {
+                        lifetime: lifetime.map(|v| folder.fold_lifetime(v)),
+                        mutbl: mutbl,
+                    })
                 }
-                SelfValue(mutability) => SelfValue(mutability),
-                Captured(pat, ty) => Captured(folder.fold_pat(pat), folder.fold_ty(ty)),
+                SelfValue(ArgSelf { mutbl } ) => {
+                    SelfValue(ArgSelf {
+                        mutbl: mutbl,
+                    })
+                }
+                Captured(ArgCaptured { pat, ty }) => {
+                    Captured(ArgCaptured {
+                        pat: folder.fold_pat(pat),
+                        ty: folder.fold_ty(ty),
+                    })
+                }
                 Ignored(ty) => Ignored(folder.fold_ty(ty)),
             }
         }),
@@ -846,19 +1051,29 @@
 pub fn noop_fold_trait_item<F: ?Sized + Folder>(folder: &mut F,
                                                 TraitItem { ident, attrs, node }: TraitItem)
                                                 -> TraitItem {
+    use item::*;
     use TraitItemKind::*;
     TraitItem {
         ident: folder.fold_ident(ident),
         attrs: attrs.lift(|v| folder.fold_attribute(v)),
         node: match node {
-            Const(ty, expr) => Const(folder.fold_ty(ty), expr.map(|v| folder.fold_expr(v))),
-            Method(sig, block) => {
-                Method(folder.fold_method_sig(sig),
-                       block.map(|v| folder.fold_block(v)))
+            Const(TraitItemConst { ty, default }) => {
+                Const(TraitItemConst {
+                    ty: folder.fold_ty(ty),
+                    default: default.map(|v| folder.fold_expr(v)),
+                })
             }
-            Type(ty_pbs, ty) => {
-                Type(ty_pbs.lift(|v| folder.fold_ty_param_bound(v)),
-                     ty.map(|v| folder.fold_ty(v)))
+            Method(TraitItemMethod { sig, default }) => {
+                Method(TraitItemMethod {
+                    sig: folder.fold_method_sig(sig),
+                    default: default.map(|v| folder.fold_block(v)),
+                })
+            }
+            Type(TraitItemType { bounds, default }) => {
+                Type(TraitItemType {
+                    bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+                    default: default.map(|v| folder.fold_ty(v)),
+                })
             }
             Macro(mac) => Macro(folder.fold_mac(mac)),
         },
@@ -869,16 +1084,32 @@
 pub fn noop_fold_impl_item<F: ?Sized + Folder>(folder: &mut F,
                                       ImplItem { ident, vis, defaultness, attrs, node }: ImplItem)
 -> ImplItem{
+    use item::*;
     use ImplItemKind::*;
+
     ImplItem {
         ident: folder.fold_ident(ident),
         vis: noop_fold_vis(folder, vis),
         defaultness: defaultness,
         attrs: attrs.lift(|v| folder.fold_attribute(v)),
         node: match node {
-            Const(ty, expr) => Const(folder.fold_ty(ty), folder.fold_expr(expr)),
-            Method(sig, block) => Method(folder.fold_method_sig(sig), folder.fold_block(block)),
-            Type(ty) => Type(folder.fold_ty(ty)),
+            Const(ImplItemConst { ty, expr }) => {
+                Const(ImplItemConst {
+                    ty: folder.fold_ty(ty),
+                    expr: folder.fold_expr(expr),
+                })
+            }
+            Method(ImplItemMethod { sig, block }) => {
+                Method(ImplItemMethod {
+                    sig: folder.fold_method_sig(sig),
+                    block: folder.fold_block(block),
+                })
+            }
+            Type(ImplItemType { ty }) => {
+                Type(ImplItemType {
+                    ty: folder.fold_ty(ty),
+                })
+            }
             Macro(mac) => Macro(folder.fold_mac(mac)),
         },
     }
@@ -929,18 +1160,30 @@
 
 #[cfg(feature = "full")]
 pub fn noop_fold_view_path<F: ?Sized + Folder>(folder: &mut F, view_path: ViewPath) -> ViewPath {
+    use item::*;
     use ViewPath::*;
     match view_path {
-        Simple(path, ident) => Simple(folder.fold_path(path), ident.map(|i| folder.fold_ident(i))),
-        Glob(path) => Glob(folder.fold_path(path)),
-        List(path, items) => {
-            List(folder.fold_path(path),
-                 items.lift(|PathListItem { name, rename }: PathListItem| {
-                                PathListItem {
-                                    name: folder.fold_ident(name),
-                                    rename: rename.map(|i| folder.fold_ident(i)),
-                                }
-                            }))
+        Simple(PathSimple { path, rename }) => {
+            Simple(PathSimple {
+                path: folder.fold_path(path),
+                rename: rename.map(|i| folder.fold_ident(i)),
+            })
+        }
+        Glob(PathGlob { path }) => {
+            Glob(PathGlob {
+                path: folder.fold_path(path),
+            })
+        }
+        List(PathList { path, items }) => {
+            List(PathList {
+                path: folder.fold_path(path),
+                items: items.lift(|PathListItem { name, rename }: PathListItem| {
+                    PathListItem {
+                        name: folder.fold_ident(name),
+                        rename: rename.map(|i| folder.fold_ident(i)),
+                    }
+                }),
+            })
         }
     }
 }