about summary refs log tree commit diff
path: root/src/librustc_front
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-03-29 08:50:44 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-04-06 09:01:55 +0300
commit8b0937293bdb70ab4a5efed02b90a71af2b234f6 (patch)
tree7db24b3a02e775cdce37e5373e2e08d56b23aaa5 /src/librustc_front
parent772c600d4d6f39daa6d07d1a60ee0df3d3426978 (diff)
downloadrust-8b0937293bdb70ab4a5efed02b90a71af2b234f6.tar.gz
rust-8b0937293bdb70ab4a5efed02b90a71af2b234f6.zip
rustc: move rustc_front to rustc::hir.
Diffstat (limited to 'src/librustc_front')
-rw-r--r--src/librustc_front/Cargo.toml15
-rw-r--r--src/librustc_front/fold.rs1151
-rw-r--r--src/librustc_front/hir.rs1458
-rw-r--r--src/librustc_front/intravisit.rs837
-rw-r--r--src/librustc_front/lib.rs58
-rw-r--r--src/librustc_front/lowering.rs2149
-rw-r--r--src/librustc_front/print/pprust.rs2413
-rw-r--r--src/librustc_front/util.rs362
8 files changed, 0 insertions, 8443 deletions
diff --git a/src/librustc_front/Cargo.toml b/src/librustc_front/Cargo.toml
deleted file mode 100644
index bf40cdbd330..00000000000
--- a/src/librustc_front/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_front"
-version = "0.0.0"
-
-[lib]
-name = "rustc_front"
-path = "lib.rs"
-crate-type = ["dylib"]
-
-[dependencies]
-log = { path = "../liblog" }
-syntax = { path = "../libsyntax" }
-serialize = { path = "../libserialize" }
-rustc_bitflags = { path = "../librustc_bitflags" }
diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs
deleted file mode 100644
index e65f2fc37de..00000000000
--- a/src/librustc_front/fold.rs
+++ /dev/null
@@ -1,1151 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A Folder represents an HIR->HIR fold; it accepts a HIR piece,
-//! and returns a piece of the same type.
-
-use hir::*;
-use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem};
-use syntax::ast::MetaItemKind;
-use syntax::attr::ThinAttributesExt;
-use hir;
-use syntax::codemap::{respan, Span, Spanned};
-use syntax::ptr::P;
-use syntax::parse::token;
-use syntax::util::move_map::MoveMap;
-
-pub trait Folder : Sized {
-    // Any additions to this trait should happen in form
-    // of a call to a public `noop_*` function that only calls
-    // out to the folder again, not other `noop_*` functions.
-    //
-    // This is a necessary API workaround to the problem of not
-    // being able to call out to the super default method
-    // in an overridden default method.
-
-    fn fold_crate(&mut self, c: Crate) -> Crate {
-        noop_fold_crate(c, self)
-    }
-
-    fn fold_meta_items(&mut self, meta_items: HirVec<P<MetaItem>>) -> HirVec<P<MetaItem>> {
-        noop_fold_meta_items(meta_items, self)
-    }
-
-    fn fold_meta_item(&mut self, meta_item: P<MetaItem>) -> P<MetaItem> {
-        noop_fold_meta_item(meta_item, self)
-    }
-
-    fn fold_view_path(&mut self, view_path: P<ViewPath>) -> P<ViewPath> {
-        noop_fold_view_path(view_path, self)
-    }
-
-    fn fold_foreign_item(&mut self, ni: ForeignItem) -> ForeignItem {
-        noop_fold_foreign_item(ni, self)
-    }
-
-    fn fold_item(&mut self, i: Item) -> Item {
-        noop_fold_item(i, self)
-    }
-
-    fn fold_item_id(&mut self, i: ItemId) -> ItemId {
-        noop_fold_item_id(i, self)
-    }
-
-    fn fold_struct_field(&mut self, sf: StructField) -> StructField {
-        noop_fold_struct_field(sf, self)
-    }
-
-    fn fold_item_underscore(&mut self, i: Item_) -> Item_ {
-        noop_fold_item_underscore(i, self)
-    }
-
-    fn fold_trait_item(&mut self, i: TraitItem) -> TraitItem {
-        noop_fold_trait_item(i, self)
-    }
-
-    fn fold_impl_item(&mut self, i: ImplItem) -> ImplItem {
-        noop_fold_impl_item(i, self)
-    }
-
-    fn fold_fn_decl(&mut self, d: P<FnDecl>) -> P<FnDecl> {
-        noop_fold_fn_decl(d, self)
-    }
-
-    fn fold_block(&mut self, b: P<Block>) -> P<Block> {
-        noop_fold_block(b, self)
-    }
-
-    fn fold_stmt(&mut self, s: Stmt) -> Stmt {
-        noop_fold_stmt(s, self)
-    }
-
-    fn fold_arm(&mut self, a: Arm) -> Arm {
-        noop_fold_arm(a, self)
-    }
-
-    fn fold_pat(&mut self, p: P<Pat>) -> P<Pat> {
-        noop_fold_pat(p, self)
-    }
-
-    fn fold_decl(&mut self, d: P<Decl>) -> P<Decl> {
-        noop_fold_decl(d, self)
-    }
-
-    fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
-        e.map(|e| noop_fold_expr(e, self))
-    }
-
-    fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
-        noop_fold_ty(t, self)
-    }
-
-    fn fold_ty_binding(&mut self, t: TypeBinding) -> TypeBinding {
-        noop_fold_ty_binding(t, self)
-    }
-
-    fn fold_mod(&mut self, m: Mod) -> Mod {
-        noop_fold_mod(m, self)
-    }
-
-    fn fold_foreign_mod(&mut self, nm: ForeignMod) -> ForeignMod {
-        noop_fold_foreign_mod(nm, self)
-    }
-
-    fn fold_variant(&mut self, v: Variant) -> Variant {
-        noop_fold_variant(v, self)
-    }
-
-    fn fold_name(&mut self, n: Name) -> Name {
-        noop_fold_name(n, self)
-    }
-
-    fn fold_ident(&mut self, i: Ident) -> Ident {
-        noop_fold_ident(i, self)
-    }
-
-    fn fold_usize(&mut self, i: usize) -> usize {
-        noop_fold_usize(i, self)
-    }
-
-    fn fold_path(&mut self, p: Path) -> Path {
-        noop_fold_path(p, self)
-    }
-
-    fn fold_path_parameters(&mut self, p: PathParameters) -> PathParameters {
-        noop_fold_path_parameters(p, self)
-    }
-
-    fn fold_angle_bracketed_parameter_data(&mut self,
-                                           p: AngleBracketedParameterData)
-                                           -> AngleBracketedParameterData {
-        noop_fold_angle_bracketed_parameter_data(p, self)
-    }
-
-    fn fold_parenthesized_parameter_data(&mut self,
-                                         p: ParenthesizedParameterData)
-                                         -> ParenthesizedParameterData {
-        noop_fold_parenthesized_parameter_data(p, self)
-    }
-
-    fn fold_local(&mut self, l: P<Local>) -> P<Local> {
-        noop_fold_local(l, self)
-    }
-
-    fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf {
-        noop_fold_explicit_self(es, self)
-    }
-
-    fn fold_explicit_self_underscore(&mut self, es: ExplicitSelf_) -> ExplicitSelf_ {
-        noop_fold_explicit_self_underscore(es, self)
-    }
-
-    fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime {
-        noop_fold_lifetime(l, self)
-    }
-
-    fn fold_lifetime_def(&mut self, l: LifetimeDef) -> LifetimeDef {
-        noop_fold_lifetime_def(l, self)
-    }
-
-    fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> {
-        noop_fold_attribute(at, self)
-    }
-
-    fn fold_arg(&mut self, a: Arg) -> Arg {
-        noop_fold_arg(a, self)
-    }
-
-    fn fold_generics(&mut self, generics: Generics) -> Generics {
-        noop_fold_generics(generics, self)
-    }
-
-    fn fold_trait_ref(&mut self, p: TraitRef) -> TraitRef {
-        noop_fold_trait_ref(p, self)
-    }
-
-    fn fold_poly_trait_ref(&mut self, p: PolyTraitRef) -> PolyTraitRef {
-        noop_fold_poly_trait_ref(p, self)
-    }
-
-    fn fold_variant_data(&mut self, vdata: VariantData) -> VariantData {
-        noop_fold_variant_data(vdata, self)
-    }
-
-    fn fold_lifetimes(&mut self, lts: HirVec<Lifetime>) -> HirVec<Lifetime> {
-        noop_fold_lifetimes(lts, self)
-    }
-
-    fn fold_lifetime_defs(&mut self, lts: HirVec<LifetimeDef>) -> HirVec<LifetimeDef> {
-        noop_fold_lifetime_defs(lts, self)
-    }
-
-    fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
-        noop_fold_ty_param(tp, self)
-    }
-
-    fn fold_ty_params(&mut self, tps: HirVec<TyParam>) -> HirVec<TyParam> {
-        noop_fold_ty_params(tps, self)
-    }
-
-    fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> {
-        noop_fold_opt_lifetime(o_lt, self)
-    }
-
-    fn fold_opt_bounds(&mut self,
-                       b: Option<TyParamBounds>)
-                       -> Option<TyParamBounds> {
-        noop_fold_opt_bounds(b, self)
-    }
-
-    fn fold_bounds(&mut self, b: TyParamBounds) -> TyParamBounds {
-        noop_fold_bounds(b, self)
-    }
-
-    fn fold_ty_param_bound(&mut self, tpb: TyParamBound) -> TyParamBound {
-        noop_fold_ty_param_bound(tpb, self)
-    }
-
-    fn fold_mt(&mut self, mt: MutTy) -> MutTy {
-        noop_fold_mt(mt, self)
-    }
-
-    fn fold_field(&mut self, field: Field) -> Field {
-        noop_fold_field(field, self)
-    }
-
-    fn fold_where_clause(&mut self, where_clause: WhereClause) -> WhereClause {
-        noop_fold_where_clause(where_clause, self)
-    }
-
-    fn fold_where_predicate(&mut self, where_predicate: WherePredicate) -> WherePredicate {
-        noop_fold_where_predicate(where_predicate, self)
-    }
-
-    /// called for the `id` on each declaration
-    fn new_id(&mut self, i: NodeId) -> NodeId {
-        i
-    }
-
-    /// called for ids that are references (e.g., ItemDef)
-    fn map_id(&mut self, i: NodeId) -> NodeId {
-        i
-    }
-
-    fn new_span(&mut self, sp: Span) -> Span {
-        sp
-    }
-}
-
-pub fn noop_fold_meta_items<T: Folder>(meta_items: HirVec<P<MetaItem>>,
-                                       fld: &mut T)
-                                       -> HirVec<P<MetaItem>> {
-    meta_items.move_map(|x| fld.fold_meta_item(x))
-}
-
-pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> {
-    view_path.map(|Spanned { node, span }| {
-        Spanned {
-            node: match node {
-                ViewPathSimple(name, path) => {
-                    ViewPathSimple(name, fld.fold_path(path))
-                }
-                ViewPathGlob(path) => {
-                    ViewPathGlob(fld.fold_path(path))
-                }
-                ViewPathList(path, path_list_idents) => {
-                    ViewPathList(fld.fold_path(path),
-                                 path_list_idents.move_map(|path_list_ident| {
-                                     Spanned {
-                                         node: match path_list_ident.node {
-                                             PathListIdent { id, name, rename } => PathListIdent {
-                                                 id: fld.new_id(id),
-                                                 name: name,
-                                                 rename: rename,
-                                             },
-                                             PathListMod { id, rename } => PathListMod {
-                                                 id: fld.new_id(id),
-                                                 rename: rename,
-                                             },
-                                         },
-                                         span: fld.new_span(path_list_ident.span),
-                                     }
-                                 }))
-                }
-            },
-            span: fld.new_span(span),
-        }
-    })
-}
-
-pub fn fold_attrs<T: Folder>(attrs: HirVec<Attribute>, fld: &mut T) -> HirVec<Attribute> {
-    attrs.move_flat_map(|x| fld.fold_attribute(x))
-}
-
-pub fn noop_fold_arm<T: Folder>(Arm { attrs, pats, guard, body }: Arm, fld: &mut T) -> Arm {
-    Arm {
-        attrs: fold_attrs(attrs, fld),
-        pats: pats.move_map(|x| fld.fold_pat(x)),
-        guard: guard.map(|x| fld.fold_expr(x)),
-        body: fld.fold_expr(body),
-    }
-}
-
-pub fn noop_fold_decl<T: Folder>(d: P<Decl>, fld: &mut T) -> P<Decl> {
-    d.map(|Spanned { node, span }| {
-        match node {
-            DeclLocal(l) => Spanned {
-                node: DeclLocal(fld.fold_local(l)),
-                span: fld.new_span(span),
-            },
-            DeclItem(it) => Spanned {
-                node: DeclItem(fld.fold_item_id(it)),
-                span: fld.new_span(span),
-            },
-        }
-    })
-}
-
-pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding {
-    TypeBinding {
-        id: fld.new_id(b.id),
-        name: b.name,
-        ty: fld.fold_ty(b.ty),
-        span: fld.new_span(b.span),
-    }
-}
-
-pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
-    t.map(|Ty { id, node, span }| {
-        Ty {
-            id: fld.new_id(id),
-            node: match node {
-                TyInfer => node,
-                TyVec(ty) => TyVec(fld.fold_ty(ty)),
-                TyPtr(mt) => TyPtr(fld.fold_mt(mt)),
-                TyRptr(region, mt) => {
-                    TyRptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt))
-                }
-                TyBareFn(f) => {
-                    TyBareFn(f.map(|BareFnTy { lifetimes, unsafety, abi, decl }| {
-                        BareFnTy {
-                            lifetimes: fld.fold_lifetime_defs(lifetimes),
-                            unsafety: unsafety,
-                            abi: abi,
-                            decl: fld.fold_fn_decl(decl),
-                        }
-                    }))
-                }
-                TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
-                TyPath(qself, path) => {
-                    let qself = qself.map(|QSelf { ty, position }| {
-                        QSelf {
-                            ty: fld.fold_ty(ty),
-                            position: position,
-                        }
-                    });
-                    TyPath(qself, fld.fold_path(path))
-                }
-                TyObjectSum(ty, bounds) => {
-                    TyObjectSum(fld.fold_ty(ty), fld.fold_bounds(bounds))
-                }
-                TyFixedLengthVec(ty, e) => {
-                    TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e))
-                }
-                TyTypeof(expr) => {
-                    TyTypeof(fld.fold_expr(expr))
-                }
-                TyPolyTraitRef(bounds) => {
-                    TyPolyTraitRef(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
-                }
-            },
-            span: fld.new_span(span),
-        }
-    })
-}
-
-pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod { abi, items }: ForeignMod,
-                                        fld: &mut T)
-                                        -> ForeignMod {
-    ForeignMod {
-        abi: abi,
-        items: items.move_map(|x| fld.fold_foreign_item(x)),
-    }
-}
-
-pub fn noop_fold_variant<T: Folder>(v: Variant, fld: &mut T) -> Variant {
-    Spanned {
-        node: Variant_ {
-            name: v.node.name,
-            attrs: fold_attrs(v.node.attrs, fld),
-            data: fld.fold_variant_data(v.node.data),
-            disr_expr: v.node.disr_expr.map(|e| fld.fold_expr(e)),
-        },
-        span: fld.new_span(v.span),
-    }
-}
-
-pub fn noop_fold_name<T: Folder>(n: Name, _: &mut T) -> Name {
-    n
-}
-
-pub fn noop_fold_ident<T: Folder>(i: Ident, _: &mut T) -> Ident {
-    i
-}
-
-pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
-    i
-}
-
-pub fn noop_fold_path<T: Folder>(Path { global, segments, span }: Path, fld: &mut T) -> Path {
-    Path {
-        global: global,
-        segments: segments.move_map(|PathSegment { identifier, parameters }| {
-            PathSegment {
-                identifier: fld.fold_ident(identifier),
-                parameters: fld.fold_path_parameters(parameters),
-            }
-        }),
-        span: fld.new_span(span),
-    }
-}
-
-pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters,
-                                            fld: &mut T)
-                                            -> PathParameters {
-    match path_parameters {
-        AngleBracketedParameters(data) =>
-            AngleBracketedParameters(fld.fold_angle_bracketed_parameter_data(data)),
-        ParenthesizedParameters(data) =>
-            ParenthesizedParameters(fld.fold_parenthesized_parameter_data(data)),
-    }
-}
-
-pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedParameterData,
-                                                           fld: &mut T)
-                                                           -> AngleBracketedParameterData {
-    let AngleBracketedParameterData { lifetimes, types, bindings } = data;
-    AngleBracketedParameterData {
-        lifetimes: fld.fold_lifetimes(lifetimes),
-        types: types.move_map(|ty| fld.fold_ty(ty)),
-        bindings: bindings.move_map(|b| fld.fold_ty_binding(b)),
-    }
-}
-
-pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData,
-                                                         fld: &mut T)
-                                                         -> ParenthesizedParameterData {
-    let ParenthesizedParameterData { inputs, output, span } = data;
-    ParenthesizedParameterData {
-        inputs: inputs.move_map(|ty| fld.fold_ty(ty)),
-        output: output.map(|ty| fld.fold_ty(ty)),
-        span: fld.new_span(span),
-    }
-}
-
-pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
-    l.map(|Local { id, pat, ty, init, span, attrs }| {
-        Local {
-            id: fld.new_id(id),
-            ty: ty.map(|t| fld.fold_ty(t)),
-            pat: fld.fold_pat(pat),
-            init: init.map(|e| fld.fold_expr(e)),
-            span: fld.new_span(span),
-            attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), fld).into()),
-        }
-    })
-}
-
-pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> {
-    let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at;
-    Some(Spanned {
-        node: Attribute_ {
-            id: id,
-            style: style,
-            value: fld.fold_meta_item(value),
-            is_sugared_doc: is_sugared_doc,
-        },
-        span: fld.new_span(span),
-    })
-}
-
-pub fn noop_fold_explicit_self_underscore<T: Folder>(es: ExplicitSelf_,
-                                                     fld: &mut T)
-                                                     -> ExplicitSelf_ {
-    match es {
-        SelfStatic | SelfValue(_) => es,
-        SelfRegion(lifetime, m, name) => {
-            SelfRegion(fld.fold_opt_lifetime(lifetime), m, name)
-        }
-        SelfExplicit(typ, name) => {
-            SelfExplicit(fld.fold_ty(typ), name)
-        }
-    }
-}
-
-pub fn noop_fold_explicit_self<T: Folder>(Spanned { span, node }: ExplicitSelf,
-                                          fld: &mut T)
-                                          -> ExplicitSelf {
-    Spanned {
-        node: fld.fold_explicit_self_underscore(node),
-        span: fld.new_span(span),
-    }
-}
-
-pub fn noop_fold_meta_item<T: Folder>(mi: P<MetaItem>, fld: &mut T) -> P<MetaItem> {
-    mi.map(|Spanned { node, span }| {
-        Spanned {
-            node: match node {
-                MetaItemKind::Word(id) => MetaItemKind::Word(id),
-                MetaItemKind::List(id, mis) => {
-                    MetaItemKind::List(id, mis.move_map(|e| fld.fold_meta_item(e)))
-                }
-                MetaItemKind::NameValue(id, s) => MetaItemKind::NameValue(id, s),
-            },
-            span: fld.new_span(span),
-        }
-    })
-}
-
-pub fn noop_fold_arg<T: Folder>(Arg { id, pat, ty }: Arg, fld: &mut T) -> Arg {
-    Arg {
-        id: fld.new_id(id),
-        pat: fld.fold_pat(pat),
-        ty: fld.fold_ty(ty),
-    }
-}
-
-pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
-    decl.map(|FnDecl { inputs, output, variadic }| {
-        FnDecl {
-            inputs: inputs.move_map(|x| fld.fold_arg(x)),
-            output: match output {
-                Return(ty) => Return(fld.fold_ty(ty)),
-                DefaultReturn(span) => DefaultReturn(span),
-                NoReturn(span) => NoReturn(span),
-            },
-            variadic: variadic,
-        }
-    })
-}
-
-pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T) -> TyParamBound
-    where T: Folder
-{
-    match tpb {
-        TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier),
-        RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)),
-    }
-}
-
-pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
-    let TyParam {id, name, bounds, default, span} = tp;
-    TyParam {
-        id: fld.new_id(id),
-        name: name,
-        bounds: fld.fold_bounds(bounds),
-        default: default.map(|x| fld.fold_ty(x)),
-        span: span,
-    }
-}
-
-pub fn noop_fold_ty_params<T: Folder>(tps: HirVec<TyParam>,
-                                      fld: &mut T)
-                                      -> HirVec<TyParam> {
-    tps.move_map(|tp| fld.fold_ty_param(tp))
-}
-
-pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime {
-    Lifetime {
-        id: fld.new_id(l.id),
-        name: l.name,
-        span: fld.new_span(l.span),
-    }
-}
-
-pub fn noop_fold_lifetime_def<T: Folder>(l: LifetimeDef, fld: &mut T) -> LifetimeDef {
-    LifetimeDef {
-        lifetime: fld.fold_lifetime(l.lifetime),
-        bounds: fld.fold_lifetimes(l.bounds),
-    }
-}
-
-pub fn noop_fold_lifetimes<T: Folder>(lts: HirVec<Lifetime>, fld: &mut T) -> HirVec<Lifetime> {
-    lts.move_map(|l| fld.fold_lifetime(l))
-}
-
-pub fn noop_fold_lifetime_defs<T: Folder>(lts: HirVec<LifetimeDef>,
-                                          fld: &mut T)
-                                          -> HirVec<LifetimeDef> {
-    lts.move_map(|l| fld.fold_lifetime_def(l))
-}
-
-pub fn noop_fold_opt_lifetime<T: Folder>(o_lt: Option<Lifetime>, fld: &mut T) -> Option<Lifetime> {
-    o_lt.map(|lt| fld.fold_lifetime(lt))
-}
-
-pub fn noop_fold_generics<T: Folder>(Generics { ty_params, lifetimes, where_clause }: Generics,
-                                     fld: &mut T)
-                                     -> Generics {
-    Generics {
-        ty_params: fld.fold_ty_params(ty_params),
-        lifetimes: fld.fold_lifetime_defs(lifetimes),
-        where_clause: fld.fold_where_clause(where_clause),
-    }
-}
-
-pub fn noop_fold_where_clause<T: Folder>(WhereClause { id, predicates }: WhereClause,
-                                         fld: &mut T)
-                                         -> WhereClause {
-    WhereClause {
-        id: fld.new_id(id),
-        predicates: predicates.move_map(|predicate| fld.fold_where_predicate(predicate)),
-    }
-}
-
-pub fn noop_fold_where_predicate<T: Folder>(pred: WherePredicate, fld: &mut T) -> WherePredicate {
-    match pred {
-        hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{bound_lifetimes,
-                                                                     bounded_ty,
-                                                                     bounds,
-                                                                     span}) => {
-            hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                bound_lifetimes: fld.fold_lifetime_defs(bound_lifetimes),
-                bounded_ty: fld.fold_ty(bounded_ty),
-                bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)),
-                span: fld.new_span(span),
-            })
-        }
-        hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{lifetime,
-                                                                       bounds,
-                                                                       span}) => {
-            hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
-                span: fld.new_span(span),
-                lifetime: fld.fold_lifetime(lifetime),
-                bounds: bounds.move_map(|bound| fld.fold_lifetime(bound)),
-            })
-        }
-        hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{id,
-                                                               path,
-                                                               ty,
-                                                               span}) => {
-            hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                id: fld.new_id(id),
-                path: fld.fold_path(path),
-                ty: fld.fold_ty(ty),
-                span: fld.new_span(span),
-            })
-        }
-    }
-}
-
-pub fn noop_fold_variant_data<T: Folder>(vdata: VariantData, fld: &mut T) -> VariantData {
-    match vdata {
-        VariantData::Struct(fields, id) => {
-            VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)),
-                                fld.new_id(id))
-        }
-        VariantData::Tuple(fields, id) => {
-            VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)),
-                               fld.new_id(id))
-        }
-        VariantData::Unit(id) => VariantData::Unit(fld.new_id(id)),
-    }
-}
-
-pub fn noop_fold_trait_ref<T: Folder>(p: TraitRef, fld: &mut T) -> TraitRef {
-    let id = fld.new_id(p.ref_id);
-    let TraitRef {
-        path,
-        ref_id: _,
-    } = p;
-    hir::TraitRef {
-        path: fld.fold_path(path),
-        ref_id: id,
-    }
-}
-
-pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef {
-    hir::PolyTraitRef {
-        bound_lifetimes: fld.fold_lifetime_defs(p.bound_lifetimes),
-        trait_ref: fld.fold_trait_ref(p.trait_ref),
-        span: fld.new_span(p.span),
-    }
-}
-
-pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructField {
-    StructField {
-        span: fld.new_span(f.span),
-        id: fld.new_id(f.id),
-        name: f.name,
-        vis: f.vis,
-        ty: fld.fold_ty(f.ty),
-        attrs: fold_attrs(f.attrs, fld),
-    }
-}
-
-pub fn noop_fold_field<T: Folder>(Field { name, expr, span }: Field, folder: &mut T) -> Field {
-    Field {
-        name: respan(folder.new_span(name.span), folder.fold_name(name.node)),
-        expr: folder.fold_expr(expr),
-        span: folder.new_span(span),
-    }
-}
-
-pub fn noop_fold_mt<T: Folder>(MutTy { ty, mutbl }: MutTy, folder: &mut T) -> MutTy {
-    MutTy {
-        ty: folder.fold_ty(ty),
-        mutbl: mutbl,
-    }
-}
-
-pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>,
-                                       folder: &mut T)
-                                       -> Option<TyParamBounds> {
-    b.map(|bounds| folder.fold_bounds(bounds))
-}
-
-fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T) -> TyParamBounds {
-    bounds.move_map(|bound| folder.fold_ty_param_bound(bound))
-}
-
-pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
-    b.map(|Block { id, stmts, expr, rules, span }| {
-        Block {
-            id: folder.new_id(id),
-            stmts: stmts.move_map(|s| folder.fold_stmt(s)),
-            expr: expr.map(|x| folder.fold_expr(x)),
-            rules: rules,
-            span: folder.new_span(span),
-        }
-    })
-}
-
-pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
-    match i {
-        ItemExternCrate(string) => ItemExternCrate(string),
-        ItemUse(view_path) => {
-            ItemUse(folder.fold_view_path(view_path))
-        }
-        ItemStatic(t, m, e) => {
-            ItemStatic(folder.fold_ty(t), m, folder.fold_expr(e))
-        }
-        ItemConst(t, e) => {
-            ItemConst(folder.fold_ty(t), folder.fold_expr(e))
-        }
-        ItemFn(decl, unsafety, constness, abi, generics, body) => {
-            ItemFn(folder.fold_fn_decl(decl),
-                   unsafety,
-                   constness,
-                   abi,
-                   folder.fold_generics(generics),
-                   folder.fold_block(body))
-        }
-        ItemMod(m) => ItemMod(folder.fold_mod(m)),
-        ItemForeignMod(nm) => ItemForeignMod(folder.fold_foreign_mod(nm)),
-        ItemTy(t, generics) => {
-            ItemTy(folder.fold_ty(t), folder.fold_generics(generics))
-        }
-        ItemEnum(enum_definition, generics) => {
-            ItemEnum(hir::EnumDef {
-                         variants: enum_definition.variants.move_map(|x| folder.fold_variant(x)),
-                     },
-                     folder.fold_generics(generics))
-        }
-        ItemStruct(struct_def, generics) => {
-            let struct_def = folder.fold_variant_data(struct_def);
-            ItemStruct(struct_def, folder.fold_generics(generics))
-        }
-        ItemDefaultImpl(unsafety, ref trait_ref) => {
-            ItemDefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
-        }
-        ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => {
-            let new_impl_items = impl_items
-                .move_map(|item| folder.fold_impl_item(item));
-            let ifce = match ifce {
-                None => None,
-                Some(ref trait_ref) => {
-                    Some(folder.fold_trait_ref((*trait_ref).clone()))
-                }
-            };
-            ItemImpl(unsafety,
-                     polarity,
-                     folder.fold_generics(generics),
-                     ifce,
-                     folder.fold_ty(ty),
-                     new_impl_items)
-        }
-        ItemTrait(unsafety, generics, bounds, items) => {
-            let bounds = folder.fold_bounds(bounds);
-            let items = items.move_map(|item| folder.fold_trait_item(item));
-            ItemTrait(unsafety, folder.fold_generics(generics), bounds, items)
-        }
-    }
-}
-
-pub fn noop_fold_trait_item<T: Folder>(i: TraitItem,
-                                       folder: &mut T)
-                                       -> TraitItem {
-    TraitItem {
-        id: folder.new_id(i.id),
-        name: folder.fold_name(i.name),
-        attrs: fold_attrs(i.attrs, folder),
-        node: match i.node {
-            ConstTraitItem(ty, default) => {
-                ConstTraitItem(folder.fold_ty(ty), default.map(|x| folder.fold_expr(x)))
-            }
-            MethodTraitItem(sig, body) => {
-                MethodTraitItem(noop_fold_method_sig(sig, folder),
-                                body.map(|x| folder.fold_block(x)))
-            }
-            TypeTraitItem(bounds, default) => {
-                TypeTraitItem(folder.fold_bounds(bounds),
-                              default.map(|x| folder.fold_ty(x)))
-            }
-        },
-        span: folder.new_span(i.span),
-    }
-}
-
-pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T) -> ImplItem {
-    ImplItem {
-        id: folder.new_id(i.id),
-        name: folder.fold_name(i.name),
-        attrs: fold_attrs(i.attrs, folder),
-        vis: i.vis,
-        defaultness: i.defaultness,
-        node: match i.node {
-            ImplItemKind::Const(ty, expr) => {
-                ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr))
-            }
-            ImplItemKind::Method(sig, body) => {
-                ImplItemKind::Method(noop_fold_method_sig(sig, folder), folder.fold_block(body))
-            }
-            ImplItemKind::Type(ty) => ImplItemKind::Type(folder.fold_ty(ty)),
-        },
-        span: folder.new_span(i.span),
-    }
-}
-
-pub fn noop_fold_mod<T: Folder>(Mod { inner, item_ids }: Mod, folder: &mut T) -> Mod {
-    Mod {
-        inner: folder.new_span(inner),
-        item_ids: item_ids.move_map(|x| folder.fold_item_id(x)),
-    }
-}
-
-pub fn noop_fold_crate<T: Folder>(Crate { module, attrs, config, span,
-                                          exported_macros, items }: Crate,
-                                  folder: &mut T)
-                                  -> Crate {
-    let config = folder.fold_meta_items(config);
-
-    let crate_mod = folder.fold_item(hir::Item {
-        name: token::special_idents::invalid.name,
-        attrs: attrs,
-        id: DUMMY_NODE_ID,
-        vis: hir::Public,
-        span: span,
-        node: hir::ItemMod(module),
-    });
-
-    let (module, attrs, span) = match crate_mod {
-        hir::Item { attrs, span, node, .. } => {
-            match node {
-                hir::ItemMod(m) => (m, attrs, span),
-                _ => panic!("fold converted a module to not a module"),
-            }
-        }
-    };
-
-    let items = items.into_iter()
-                     .map(|(id, item)| (id, folder.fold_item(item)))
-                     .collect();
-
-    Crate {
-        module: module,
-        attrs: attrs,
-        config: config,
-        span: span,
-        exported_macros: exported_macros,
-        items: items,
-    }
-}
-
-pub fn noop_fold_item_id<T: Folder>(i: ItemId, folder: &mut T) -> ItemId {
-    let id = folder.map_id(i.id);
-    ItemId { id: id }
-}
-
-// fold one item into one item
-pub fn noop_fold_item<T: Folder>(item: Item, folder: &mut T) -> Item {
-    let Item { id, name, attrs, node, vis, span } = item;
-    let id = folder.new_id(id);
-    let node = folder.fold_item_underscore(node);
-    // FIXME: we should update the impl_pretty_name, but it uses pretty printing.
-    // let ident = match node {
-    //     // The node may have changed, recompute the "pretty" impl name.
-    //     ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
-    //         impl_pretty_name(maybe_trait, Some(&**ty))
-    //     }
-    //     _ => ident
-    // };
-
-    Item {
-        id: id,
-        name: folder.fold_name(name),
-        attrs: fold_attrs(attrs, folder),
-        node: node,
-        vis: vis,
-        span: folder.new_span(span),
-    }
-}
-
-pub fn noop_fold_foreign_item<T: Folder>(ni: ForeignItem, folder: &mut T) -> ForeignItem {
-    ForeignItem {
-        id: folder.new_id(ni.id),
-        name: folder.fold_name(ni.name),
-        attrs: fold_attrs(ni.attrs, folder),
-        node: match ni.node {
-            ForeignItemFn(fdec, generics) => {
-                ForeignItemFn(folder.fold_fn_decl(fdec), folder.fold_generics(generics))
-            }
-            ForeignItemStatic(t, m) => {
-                ForeignItemStatic(folder.fold_ty(t), m)
-            }
-        },
-        vis: ni.vis,
-        span: folder.new_span(ni.span),
-    }
-}
-
-pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
-    MethodSig {
-        generics: folder.fold_generics(sig.generics),
-        abi: sig.abi,
-        explicit_self: folder.fold_explicit_self(sig.explicit_self),
-        unsafety: sig.unsafety,
-        constness: sig.constness,
-        decl: folder.fold_fn_decl(sig.decl),
-    }
-}
-
-pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
-    p.map(|Pat { id, node, span }| {
-        Pat {
-            id: folder.new_id(id),
-            node: match node {
-                PatKind::Wild => PatKind::Wild,
-                PatKind::Ident(binding_mode, pth1, sub) => {
-                    PatKind::Ident(binding_mode,
-                             Spanned {
-                                 span: folder.new_span(pth1.span),
-                                 node: folder.fold_ident(pth1.node),
-                             },
-                             sub.map(|x| folder.fold_pat(x)))
-                }
-                PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)),
-                PatKind::TupleStruct(pth, pats) => {
-                    PatKind::TupleStruct(folder.fold_path(pth),
-                            pats.map(|pats| pats.move_map(|x| folder.fold_pat(x))))
-                }
-                PatKind::Path(pth) => {
-                    PatKind::Path(folder.fold_path(pth))
-                }
-                PatKind::QPath(qself, pth) => {
-                    let qself = QSelf { ty: folder.fold_ty(qself.ty), ..qself };
-                    PatKind::QPath(qself, folder.fold_path(pth))
-                }
-                PatKind::Struct(pth, fields, etc) => {
-                    let pth = folder.fold_path(pth);
-                    let fs = fields.move_map(|f| {
-                        Spanned {
-                            span: folder.new_span(f.span),
-                            node: hir::FieldPat {
-                                name: f.node.name,
-                                pat: folder.fold_pat(f.node.pat),
-                                is_shorthand: f.node.is_shorthand,
-                            },
-                        }
-                    });
-                    PatKind::Struct(pth, fs, etc)
-                }
-                PatKind::Tup(elts) => PatKind::Tup(elts.move_map(|x| folder.fold_pat(x))),
-                PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)),
-                PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl),
-                PatKind::Range(e1, e2) => {
-                    PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2))
-                }
-                PatKind::Vec(before, slice, after) => {
-                    PatKind::Vec(before.move_map(|x| folder.fold_pat(x)),
-                           slice.map(|x| folder.fold_pat(x)),
-                           after.move_map(|x| folder.fold_pat(x)))
-                }
-            },
-            span: folder.new_span(span),
-        }
-    })
-}
-
-pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &mut T) -> Expr {
-    Expr {
-        id: folder.new_id(id),
-        node: match node {
-            ExprBox(e) => {
-                ExprBox(folder.fold_expr(e))
-            }
-            ExprVec(exprs) => {
-                ExprVec(exprs.move_map(|x| folder.fold_expr(x)))
-            }
-            ExprRepeat(expr, count) => {
-                ExprRepeat(folder.fold_expr(expr), folder.fold_expr(count))
-            }
-            ExprTup(elts) => ExprTup(elts.move_map(|x| folder.fold_expr(x))),
-            ExprCall(f, args) => {
-                ExprCall(folder.fold_expr(f), args.move_map(|x| folder.fold_expr(x)))
-            }
-            ExprMethodCall(name, tps, args) => {
-                ExprMethodCall(respan(folder.new_span(name.span), folder.fold_name(name.node)),
-                               tps.move_map(|x| folder.fold_ty(x)),
-                               args.move_map(|x| folder.fold_expr(x)))
-            }
-            ExprBinary(binop, lhs, rhs) => {
-                ExprBinary(binop, folder.fold_expr(lhs), folder.fold_expr(rhs))
-            }
-            ExprUnary(binop, ohs) => {
-                ExprUnary(binop, folder.fold_expr(ohs))
-            }
-            ExprLit(l) => ExprLit(l),
-            ExprCast(expr, ty) => {
-                ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
-            }
-            ExprType(expr, ty) => {
-                ExprType(folder.fold_expr(expr), folder.fold_ty(ty))
-            }
-            ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)),
-            ExprIf(cond, tr, fl) => {
-                ExprIf(folder.fold_expr(cond),
-                       folder.fold_block(tr),
-                       fl.map(|x| folder.fold_expr(x)))
-            }
-            ExprWhile(cond, body, opt_ident) => {
-                ExprWhile(folder.fold_expr(cond),
-                          folder.fold_block(body),
-                          opt_ident.map(|i| folder.fold_ident(i)))
-            }
-            ExprLoop(body, opt_ident) => {
-                ExprLoop(folder.fold_block(body),
-                         opt_ident.map(|i| folder.fold_ident(i)))
-            }
-            ExprMatch(expr, arms, source) => {
-                ExprMatch(folder.fold_expr(expr),
-                          arms.move_map(|x| folder.fold_arm(x)),
-                          source)
-            }
-            ExprClosure(capture_clause, decl, body) => {
-                ExprClosure(capture_clause,
-                            folder.fold_fn_decl(decl),
-                            folder.fold_block(body))
-            }
-            ExprBlock(blk) => ExprBlock(folder.fold_block(blk)),
-            ExprAssign(el, er) => {
-                ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
-            }
-            ExprAssignOp(op, el, er) => {
-                ExprAssignOp(op, folder.fold_expr(el), folder.fold_expr(er))
-            }
-            ExprField(el, name) => {
-                ExprField(folder.fold_expr(el),
-                          respan(folder.new_span(name.span), folder.fold_name(name.node)))
-            }
-            ExprTupField(el, index) => {
-                ExprTupField(folder.fold_expr(el),
-                             respan(folder.new_span(index.span), folder.fold_usize(index.node)))
-            }
-            ExprIndex(el, er) => {
-                ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
-            }
-            ExprPath(qself, path) => {
-                let qself = qself.map(|QSelf { ty, position }| {
-                    QSelf {
-                        ty: folder.fold_ty(ty),
-                        position: position,
-                    }
-                });
-                ExprPath(qself, folder.fold_path(path))
-            }
-            ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|label| {
-                respan(folder.new_span(label.span), folder.fold_ident(label.node))
-            })),
-            ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|label| {
-                respan(folder.new_span(label.span), folder.fold_ident(label.node))
-            })),
-            ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
-            ExprInlineAsm(asm, outputs, inputs) => {
-                ExprInlineAsm(asm,
-                              outputs.move_map(|x| folder.fold_expr(x)),
-                              inputs.move_map(|x| folder.fold_expr(x)))
-            }
-            ExprStruct(path, fields, maybe_expr) => {
-                ExprStruct(folder.fold_path(path),
-                           fields.move_map(|x| folder.fold_field(x)),
-                           maybe_expr.map(|x| folder.fold_expr(x)))
-            }
-        },
-        span: folder.new_span(span),
-        attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), folder).into()),
-    }
-}
-
-pub fn noop_fold_stmt<T: Folder>(stmt: Stmt, folder: &mut T) -> Stmt {
-    let span = folder.new_span(stmt.span);
-    match stmt.node {
-        StmtDecl(d, id) => {
-            let id = folder.new_id(id);
-            Spanned {
-                node: StmtDecl(folder.fold_decl(d), id),
-                span: span
-            }
-        }
-        StmtExpr(e, id) => {
-            let id = folder.new_id(id);
-            Spanned {
-                node: StmtExpr(folder.fold_expr(e), id),
-                span: span,
-            }
-        }
-        StmtSemi(e, id) => {
-            let id = folder.new_id(id);
-            Spanned {
-                node: StmtSemi(folder.fold_expr(e), id),
-                span: span,
-            }
-        }
-    }
-}
diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs
deleted file mode 100644
index 86f8635f58d..00000000000
--- a/src/librustc_front/hir.rs
+++ /dev/null
@@ -1,1458 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// The Rust HIR.
-
-pub use self::BindingMode::*;
-pub use self::BinOp_::*;
-pub use self::BlockCheckMode::*;
-pub use self::CaptureClause::*;
-pub use self::Decl_::*;
-pub use self::ExplicitSelf_::*;
-pub use self::Expr_::*;
-pub use self::FunctionRetTy::*;
-pub use self::ForeignItem_::*;
-pub use self::Item_::*;
-pub use self::Mutability::*;
-pub use self::PathListItem_::*;
-pub use self::PrimTy::*;
-pub use self::Stmt_::*;
-pub use self::TraitItem_::*;
-pub use self::Ty_::*;
-pub use self::TyParamBound::*;
-pub use self::UnOp::*;
-pub use self::UnsafeSource::*;
-pub use self::ViewPath_::*;
-pub use self::Visibility::*;
-pub use self::PathParameters::*;
-
-use intravisit::Visitor;
-use std::collections::BTreeMap;
-use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId};
-use syntax::abi::Abi;
-use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
-use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
-use syntax::attr::{ThinAttributes, ThinAttributesExt};
-use syntax::parse::token::InternedString;
-use syntax::ptr::P;
-
-use print::pprust;
-use util;
-
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use serialize::{Encodable, Decodable, Encoder, Decoder};
-
-/// HIR doesn't commit to a concrete storage type and have its own alias for a vector.
-/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar
-/// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead
-/// of `Vec` to avoid keeping extra capacity.
-pub type HirVec<T> = P<[T]>;
-
-macro_rules! hir_vec {
-    ($elem:expr; $n:expr) => (
-        $crate::hir::HirVec::from(vec![$elem; $n])
-    );
-    ($($x:expr),*) => (
-        $crate::hir::HirVec::from(vec![$($x),*])
-    );
-    ($($x:expr,)*) => (vec![$($x),*])
-}
-
-/// Identifier in HIR
-#[derive(Clone, Copy, Eq)]
-pub struct Ident {
-    /// Hygienic name (renamed), should be used by default
-    pub name: Name,
-    /// Unhygienic name (original, not renamed), needed in few places in name resolution
-    pub unhygienic_name: Name,
-}
-
-impl Ident {
-    /// Creates a HIR identifier with both `name` and `unhygienic_name` initialized with
-    /// the argument. Hygiene properties of the created identifier depend entirely on this
-    /// argument. If the argument is a plain interned string `intern("iter")`, then the result
-    /// is unhygienic and can interfere with other entities named "iter". If the argument is
-    /// a "fresh" name created with `gensym("iter")`, then the result is hygienic and can't
-    /// interfere with other entities having the same string as a name.
-    pub fn from_name(name: Name) -> Ident {
-        Ident { name: name, unhygienic_name: name }
-    }
-}
-
-impl PartialEq for Ident {
-    fn eq(&self, other: &Ident) -> bool {
-        self.name == other.name
-    }
-}
-
-impl Hash for Ident {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.name.hash(state)
-    }
-}
-
-impl fmt::Debug for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(&self.name, f)
-    }
-}
-
-impl fmt::Display for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.name, f)
-    }
-}
-
-impl Encodable for Ident {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        self.name.encode(s)
-    }
-}
-
-impl Decodable for Ident {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        Ok(Ident::from_name(Name::decode(d)?))
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
-pub struct Lifetime {
-    pub id: NodeId,
-    pub span: Span,
-    pub name: Name,
-}
-
-impl fmt::Debug for Lifetime {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f,
-               "lifetime({}: {})",
-               self.id,
-               pprust::lifetime_to_string(self))
-    }
-}
-
-/// A lifetime definition, eg `'a: 'b+'c+'d`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct LifetimeDef {
-    pub lifetime: Lifetime,
-    pub bounds: HirVec<Lifetime>,
-}
-
-/// A "Path" is essentially Rust's notion of a name; for instance:
-/// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
-/// along with a bunch of supporting information.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
-pub struct Path {
-    pub span: Span,
-    /// A `::foo` path, is relative to the crate root rather than current
-    /// module (like paths in an import).
-    pub global: bool,
-    /// The segments in the path: the things separated by `::`.
-    pub segments: HirVec<PathSegment>,
-}
-
-impl fmt::Debug for Path {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "path({})", pprust::path_to_string(self))
-    }
-}
-
-impl fmt::Display for Path {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", pprust::path_to_string(self))
-    }
-}
-
-/// A segment of a path: an identifier, an optional lifetime, and a set of
-/// types.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct PathSegment {
-    /// The identifier portion of this path segment.
-    ///
-    /// Hygiene properties of this identifier are worth noting.
-    /// Most path segments are not hygienic and they are not renamed during
-    /// lowering from AST to HIR (see comments to `fn lower_path`). However segments from
-    /// unqualified paths with one segment originating from `ExprPath` (local-variable-like paths)
-    /// can be hygienic, so they are renamed. You should not normally care about this peculiarity
-    /// and just use `identifier.name` unless you modify identifier resolution code
-    /// (`fn resolve_identifier` and other functions called by it in `rustc_resolve`).
-    pub identifier: Ident,
-
-    /// Type/lifetime parameters attached to this path. They come in
-    /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
-    /// this is more than just simple syntactic sugar; the use of
-    /// parens affects the region binding rules, so we preserve the
-    /// distinction.
-    pub parameters: PathParameters,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum PathParameters {
-    /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
-    AngleBracketedParameters(AngleBracketedParameterData),
-    /// The `(A,B)` and `C` in `Foo(A,B) -> C`
-    ParenthesizedParameters(ParenthesizedParameterData),
-}
-
-impl PathParameters {
-    pub fn none() -> PathParameters {
-        AngleBracketedParameters(AngleBracketedParameterData {
-            lifetimes: HirVec::new(),
-            types: HirVec::new(),
-            bindings: HirVec::new(),
-        })
-    }
-
-    pub fn is_empty(&self) -> bool {
-        match *self {
-            AngleBracketedParameters(ref data) => data.is_empty(),
-
-            // Even if the user supplied no types, something like
-            // `X()` is equivalent to `X<(),()>`.
-            ParenthesizedParameters(..) => false,
-        }
-    }
-
-    pub fn has_lifetimes(&self) -> bool {
-        match *self {
-            AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(),
-            ParenthesizedParameters(_) => false,
-        }
-    }
-
-    pub fn has_types(&self) -> bool {
-        match *self {
-            AngleBracketedParameters(ref data) => !data.types.is_empty(),
-            ParenthesizedParameters(..) => true,
-        }
-    }
-
-    /// Returns the types that the user wrote. Note that these do not necessarily map to the type
-    /// parameters in the parenthesized case.
-    pub fn types(&self) -> HirVec<&P<Ty>> {
-        match *self {
-            AngleBracketedParameters(ref data) => {
-                data.types.iter().collect()
-            }
-            ParenthesizedParameters(ref data) => {
-                data.inputs
-                    .iter()
-                    .chain(data.output.iter())
-                    .collect()
-            }
-        }
-    }
-
-    pub fn lifetimes(&self) -> HirVec<&Lifetime> {
-        match *self {
-            AngleBracketedParameters(ref data) => {
-                data.lifetimes.iter().collect()
-            }
-            ParenthesizedParameters(_) => {
-                HirVec::new()
-            }
-        }
-    }
-
-    pub fn bindings(&self) -> HirVec<&TypeBinding> {
-        match *self {
-            AngleBracketedParameters(ref data) => {
-                data.bindings.iter().collect()
-            }
-            ParenthesizedParameters(_) => {
-                HirVec::new()
-            }
-        }
-    }
-}
-
-/// A path like `Foo<'a, T>`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct AngleBracketedParameterData {
-    /// The lifetime parameters for this path segment.
-    pub lifetimes: HirVec<Lifetime>,
-    /// The type parameters for this path segment, if present.
-    pub types: HirVec<P<Ty>>,
-    /// Bindings (equality constraints) on associated types, if present.
-    /// E.g., `Foo<A=Bar>`.
-    pub bindings: HirVec<TypeBinding>,
-}
-
-impl AngleBracketedParameterData {
-    fn is_empty(&self) -> bool {
-        self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty()
-    }
-}
-
-/// A path like `Foo(A,B) -> C`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct ParenthesizedParameterData {
-    /// Overall span
-    pub span: Span,
-
-    /// `(A,B)`
-    pub inputs: HirVec<P<Ty>>,
-
-    /// `C`
-    pub output: Option<P<Ty>>,
-}
-
-/// The AST represents all type param bounds as types.
-/// typeck::collect::compute_bounds matches these against
-/// the "special" built-in traits (see middle::lang_items) and
-/// detects Copy, Send and Sync.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TyParamBound {
-    TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
-    RegionTyParamBound(Lifetime),
-}
-
-/// A modifier on a bound, currently this is only used for `?Sized`, where the
-/// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitBoundModifier {
-    None,
-    Maybe,
-}
-
-pub type TyParamBounds = HirVec<TyParamBound>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TyParam {
-    pub name: Name,
-    pub id: NodeId,
-    pub bounds: TyParamBounds,
-    pub default: Option<P<Ty>>,
-    pub span: Span,
-}
-
-/// Represents lifetimes and type parameters attached to a declaration
-/// of a function, enum, trait, etc.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Generics {
-    pub lifetimes: HirVec<LifetimeDef>,
-    pub ty_params: HirVec<TyParam>,
-    pub where_clause: WhereClause,
-}
-
-impl Generics {
-    pub fn is_lt_parameterized(&self) -> bool {
-        !self.lifetimes.is_empty()
-    }
-    pub fn is_type_parameterized(&self) -> bool {
-        !self.ty_params.is_empty()
-    }
-    pub fn is_parameterized(&self) -> bool {
-        self.is_lt_parameterized() || self.is_type_parameterized()
-    }
-}
-
-/// A `where` clause in a definition
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct WhereClause {
-    pub id: NodeId,
-    pub predicates: HirVec<WherePredicate>,
-}
-
-/// A single predicate in a `where` clause
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum WherePredicate {
-    /// A type binding, eg `for<'c> Foo: Send+Clone+'c`
-    BoundPredicate(WhereBoundPredicate),
-    /// A lifetime predicate, e.g. `'a: 'b+'c`
-    RegionPredicate(WhereRegionPredicate),
-    /// An equality predicate (unsupported)
-    EqPredicate(WhereEqPredicate),
-}
-
-/// A type bound, eg `for<'c> Foo: Send+Clone+'c`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct WhereBoundPredicate {
-    pub span: Span,
-    /// Any lifetimes from a `for` binding
-    pub bound_lifetimes: HirVec<LifetimeDef>,
-    /// The type being bounded
-    pub bounded_ty: P<Ty>,
-    /// Trait and lifetime bounds (`Clone+Send+'static`)
-    pub bounds: TyParamBounds,
-}
-
-/// A lifetime predicate, e.g. `'a: 'b+'c`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct WhereRegionPredicate {
-    pub span: Span,
-    pub lifetime: Lifetime,
-    pub bounds: HirVec<Lifetime>,
-}
-
-/// An equality predicate (unsupported), e.g. `T=int`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct WhereEqPredicate {
-    pub id: NodeId,
-    pub span: Span,
-    pub path: Path,
-    pub ty: P<Ty>,
-}
-
-pub type CrateConfig = HirVec<P<MetaItem>>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
-pub struct Crate {
-    pub module: Mod,
-    pub attrs: HirVec<Attribute>,
-    pub config: CrateConfig,
-    pub span: Span,
-    pub exported_macros: HirVec<MacroDef>,
-
-    // NB: We use a BTreeMap here so that `visit_all_items` iterates
-    // over the ids in increasing order. In principle it should not
-    // matter what order we visit things in, but in *practice* it
-    // does, because it can affect the order in which errors are
-    // detected, which in turn can make compile-fail tests yield
-    // slightly different results.
-    pub items: BTreeMap<NodeId, Item>,
-}
-
-impl Crate {
-    pub fn item(&self, id: NodeId) -> &Item {
-        &self.items[&id]
-    }
-
-    /// Visits all items in the crate in some determinstic (but
-    /// unspecified) order. If you just need to process every item,
-    /// but don't care about nesting, this method is the best choice.
-    ///
-    /// If you do care about nesting -- usually because your algorithm
-    /// follows lexical scoping rules -- then you want a different
-    /// approach. You should override `visit_nested_item` in your
-    /// visitor and then call `intravisit::walk_crate` instead.
-    pub fn visit_all_items<'hir, V:Visitor<'hir>>(&'hir self, visitor: &mut V) {
-        for (_, item) in &self.items {
-            visitor.visit_item(item);
-        }
-    }
-}
-
-/// A macro definition, in this crate or imported from another.
-///
-/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct MacroDef {
-    pub name: Name,
-    pub attrs: HirVec<Attribute>,
-    pub id: NodeId,
-    pub span: Span,
-    pub imported_from: Option<Name>,
-    pub export: bool,
-    pub use_locally: bool,
-    pub allow_internal_unstable: bool,
-    pub body: HirVec<TokenTree>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Block {
-    /// Statements in a block
-    pub stmts: HirVec<Stmt>,
-    /// An expression at the end of the block
-    /// without a semicolon, if any
-    pub expr: Option<P<Expr>>,
-    pub id: NodeId,
-    /// Distinguishes between `unsafe { ... }` and `{ ... }`
-    pub rules: BlockCheckMode,
-    pub span: Span,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
-pub struct Pat {
-    pub id: NodeId,
-    pub node: PatKind,
-    pub span: Span,
-}
-
-impl fmt::Debug for Pat {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
-    }
-}
-
-/// A single field in a struct pattern
-///
-/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
-/// are treated the same as` x: x, y: ref y, z: ref mut z`,
-/// except is_shorthand is true
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct FieldPat {
-    /// The identifier for the field
-    pub name: Name,
-    /// The pattern the field is destructured to
-    pub pat: P<Pat>,
-    pub is_shorthand: bool,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum BindingMode {
-    BindByRef(Mutability),
-    BindByValue(Mutability),
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum PatKind {
-    /// Represents a wildcard pattern (`_`)
-    Wild,
-
-    /// A `PatKind::Ident` may either be a new bound variable,
-    /// or a unit struct/variant pattern, or a const pattern (in the last two cases
-    /// the third field must be `None`).
-    ///
-    /// In the unit or const pattern case, the parser can't determine
-    /// which it is. The resolver determines this, and
-    /// records this pattern's `NodeId` in an auxiliary
-    /// set (of "PatIdents that refer to unit patterns or constants").
-    Ident(BindingMode, Spanned<Ident>, Option<P<Pat>>),
-
-    /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
-    /// The `bool` is `true` in the presence of a `..`.
-    Struct(Path, HirVec<Spanned<FieldPat>>, bool),
-
-    /// A tuple struct/variant pattern `Variant(x, y, z)`.
-    /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
-    TupleStruct(Path, Option<HirVec<P<Pat>>>),
-
-    /// A path pattern.
-    /// Such pattern can be resolved to a unit struct/variant or a constant.
-    Path(Path),
-
-    /// An associated const named using the qualified path `<T>::CONST` or
-    /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
-    /// referred to as simply `T::CONST`, in which case they will end up as
-    /// PatKind::Path, and the resolver will have to sort that out.
-    QPath(QSelf, Path),
-
-    /// A tuple pattern `(a, b)`
-    Tup(HirVec<P<Pat>>),
-    /// A `box` pattern
-    Box(P<Pat>),
-    /// A reference pattern, e.g. `&mut (a, b)`
-    Ref(P<Pat>, Mutability),
-    /// A literal
-    Lit(P<Expr>),
-    /// A range pattern, e.g. `1...2`
-    Range(P<Expr>, P<Expr>),
-    /// `[a, b, ..i, y, z]` is represented as:
-    ///     `PatKind::Vec(box [a, b], Some(i), box [y, z])`
-    Vec(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum Mutability {
-    MutMutable,
-    MutImmutable,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum BinOp_ {
-    /// The `+` operator (addition)
-    BiAdd,
-    /// The `-` operator (subtraction)
-    BiSub,
-    /// The `*` operator (multiplication)
-    BiMul,
-    /// The `/` operator (division)
-    BiDiv,
-    /// The `%` operator (modulus)
-    BiRem,
-    /// The `&&` operator (logical and)
-    BiAnd,
-    /// The `||` operator (logical or)
-    BiOr,
-    /// The `^` operator (bitwise xor)
-    BiBitXor,
-    /// The `&` operator (bitwise and)
-    BiBitAnd,
-    /// The `|` operator (bitwise or)
-    BiBitOr,
-    /// The `<<` operator (shift left)
-    BiShl,
-    /// The `>>` operator (shift right)
-    BiShr,
-    /// The `==` operator (equality)
-    BiEq,
-    /// The `<` operator (less than)
-    BiLt,
-    /// The `<=` operator (less than or equal to)
-    BiLe,
-    /// The `!=` operator (not equal to)
-    BiNe,
-    /// The `>=` operator (greater than or equal to)
-    BiGe,
-    /// The `>` operator (greater than)
-    BiGt,
-}
-
-pub type BinOp = Spanned<BinOp_>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum UnOp {
-    /// The `*` operator for dereferencing
-    UnDeref,
-    /// The `!` operator for logical inversion
-    UnNot,
-    /// The `-` operator for negation
-    UnNeg,
-}
-
-/// A statement
-pub type Stmt = Spanned<Stmt_>;
-
-impl fmt::Debug for Stmt_ {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        // Sadness.
-        let spanned = codemap::dummy_spanned(self.clone());
-        write!(f,
-               "stmt({}: {})",
-               util::stmt_id(&spanned),
-               pprust::stmt_to_string(&spanned))
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
-pub enum Stmt_ {
-    /// Could be an item or a local (let) binding:
-    StmtDecl(P<Decl>, NodeId),
-
-    /// Expr without trailing semi-colon (must have unit type):
-    StmtExpr(P<Expr>, NodeId),
-
-    /// Expr with trailing semi-colon (may have any type):
-    StmtSemi(P<Expr>, NodeId),
-}
-
-impl Stmt_ {
-    pub fn attrs(&self) -> &[Attribute] {
-        match *self {
-            StmtDecl(ref d, _) => d.node.attrs(),
-            StmtExpr(ref e, _) |
-            StmtSemi(ref e, _) => e.attrs.as_attr_slice(),
-        }
-    }
-}
-
-// FIXME (pending discussion of #1697, #2178...): local should really be
-// a refinement on pat.
-/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Local {
-    pub pat: P<Pat>,
-    pub ty: Option<P<Ty>>,
-    /// Initializer expression to set the value, if any
-    pub init: Option<P<Expr>>,
-    pub id: NodeId,
-    pub span: Span,
-    pub attrs: ThinAttributes,
-}
-
-pub type Decl = Spanned<Decl_>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Decl_ {
-    /// A local (let) binding:
-    DeclLocal(P<Local>),
-    /// An item binding:
-    DeclItem(ItemId),
-}
-
-impl Decl_ {
-    pub fn attrs(&self) -> &[Attribute] {
-        match *self {
-            DeclLocal(ref l) => l.attrs.as_attr_slice(),
-            DeclItem(_) => &[]
-        }
-    }
-}
-
-/// represents one arm of a 'match'
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Arm {
-    pub attrs: HirVec<Attribute>,
-    pub pats: HirVec<P<Pat>>,
-    pub guard: Option<P<Expr>>,
-    pub body: P<Expr>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Field {
-    pub name: Spanned<Name>,
-    pub expr: P<Expr>,
-    pub span: Span,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum BlockCheckMode {
-    DefaultBlock,
-    UnsafeBlock(UnsafeSource),
-    PushUnsafeBlock(UnsafeSource),
-    PopUnsafeBlock(UnsafeSource),
-    // Within this block (but outside a PopUnstableBlock), we suspend checking of stability.
-    PushUnstableBlock,
-    PopUnstableBlock,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum UnsafeSource {
-    CompilerGenerated,
-    UserProvided,
-}
-
-/// An expression
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
-pub struct Expr {
-    pub id: NodeId,
-    pub node: Expr_,
-    pub span: Span,
-    pub attrs: ThinAttributes,
-}
-
-impl fmt::Debug for Expr {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Expr_ {
-    /// A `box x` expression.
-    ExprBox(P<Expr>),
-    /// An array (`[a, b, c, d]`)
-    ExprVec(HirVec<P<Expr>>),
-    /// A function call
-    ///
-    /// The first field resolves to the function itself,
-    /// and the second field is the list of arguments
-    ExprCall(P<Expr>, HirVec<P<Expr>>),
-    /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
-    ///
-    /// The `Spanned<Name>` is the identifier for the method name.
-    /// The vector of `Ty`s are the ascripted type parameters for the method
-    /// (within the angle brackets).
-    ///
-    /// The first element of the vector of `Expr`s is the expression that evaluates
-    /// to the object on which the method is being called on (the receiver),
-    /// and the remaining elements are the rest of the arguments.
-    ///
-    /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
-    /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
-    ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<P<Expr>>),
-    /// A tuple (`(a, b, c ,d)`)
-    ExprTup(HirVec<P<Expr>>),
-    /// A binary operation (For example: `a + b`, `a * b`)
-    ExprBinary(BinOp, P<Expr>, P<Expr>),
-    /// A unary operation (For example: `!x`, `*x`)
-    ExprUnary(UnOp, P<Expr>),
-    /// A literal (For example: `1`, `"foo"`)
-    ExprLit(P<Lit>),
-    /// A cast (`foo as f64`)
-    ExprCast(P<Expr>, P<Ty>),
-    ExprType(P<Expr>, P<Ty>),
-    /// An `if` block, with an optional else block
-    ///
-    /// `if expr { block } else { expr }`
-    ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
-    /// A while loop, with an optional label
-    ///
-    /// `'label: while expr { block }`
-    ExprWhile(P<Expr>, P<Block>, Option<Ident>),
-    /// Conditionless loop (can be exited with break, continue, or return)
-    ///
-    /// `'label: loop { block }`
-    ExprLoop(P<Block>, Option<Ident>),
-    /// A `match` block, with a source that indicates whether or not it is
-    /// the result of a desugaring, and if so, which kind.
-    ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
-    /// A closure (for example, `move |a, b, c| {a + b + c}`)
-    ExprClosure(CaptureClause, P<FnDecl>, P<Block>),
-    /// A block (`{ ... }`)
-    ExprBlock(P<Block>),
-
-    /// An assignment (`a = foo()`)
-    ExprAssign(P<Expr>, P<Expr>),
-    /// An assignment with an operator
-    ///
-    /// For example, `a += 1`.
-    ExprAssignOp(BinOp, P<Expr>, P<Expr>),
-    /// Access of a named struct field (`obj.foo`)
-    ExprField(P<Expr>, Spanned<Name>),
-    /// Access of an unnamed field of a struct or tuple-struct
-    ///
-    /// For example, `foo.0`.
-    ExprTupField(P<Expr>, Spanned<usize>),
-    /// An indexing operation (`foo[2]`)
-    ExprIndex(P<Expr>, P<Expr>),
-
-    /// Variable reference, possibly containing `::` and/or type
-    /// parameters, e.g. foo::bar::<baz>.
-    ///
-    /// Optionally "qualified",
-    /// e.g. `<HirVec<T> as SomeTrait>::SomeType`.
-    ExprPath(Option<QSelf>, Path),
-
-    /// A referencing operation (`&a` or `&mut a`)
-    ExprAddrOf(Mutability, P<Expr>),
-    /// A `break`, with an optional label to break
-    ExprBreak(Option<Spanned<Ident>>),
-    /// A `continue`, with an optional label
-    ExprAgain(Option<Spanned<Ident>>),
-    /// A `return`, with an optional value to be returned
-    ExprRet(Option<P<Expr>>),
-
-    /// Inline assembly (from `asm!`), with its outputs and inputs.
-    ExprInlineAsm(InlineAsm, Vec<P<Expr>>, Vec<P<Expr>>),
-
-    /// A struct literal expression.
-    ///
-    /// For example, `Foo {x: 1, y: 2}`, or
-    /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
-    ExprStruct(Path, HirVec<Field>, Option<P<Expr>>),
-
-    /// A vector literal constructed from one repeated element.
-    ///
-    /// For example, `[1; 5]`. The first expression is the element
-    /// to be repeated; the second is the number of times to repeat it.
-    ExprRepeat(P<Expr>, P<Expr>),
-}
-
-/// The explicit Self type in a "qualified path". The actual
-/// path, including the trait and the associated item, is stored
-/// separately. `position` represents the index of the associated
-/// item qualified with this Self type.
-///
-///     <HirVec<T> as a::b::Trait>::AssociatedItem
-///      ^~~~~     ~~~~~~~~~~~~~~^
-///      ty        position = 3
-///
-///     <HirVec<T>>::AssociatedItem
-///      ^~~~~    ^
-///      ty       position = 0
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct QSelf {
-    pub ty: P<Ty>,
-    pub position: usize,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum MatchSource {
-    Normal,
-    IfLetDesugar {
-        contains_else_clause: bool,
-    },
-    WhileLetDesugar,
-    ForLoopDesugar,
-    TryDesugar,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum CaptureClause {
-    CaptureByValue,
-    CaptureByRef,
-}
-
-// NB: If you change this, you'll probably want to change the corresponding
-// type structure in middle/ty.rs as well.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct MutTy {
-    pub ty: P<Ty>,
-    pub mutbl: Mutability,
-}
-
-/// Represents a method's signature in a trait declaration,
-/// or in an implementation.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct MethodSig {
-    pub unsafety: Unsafety,
-    pub constness: Constness,
-    pub abi: Abi,
-    pub decl: P<FnDecl>,
-    pub generics: Generics,
-    pub explicit_self: ExplicitSelf,
-}
-
-/// Represents an item declaration within a trait declaration,
-/// possibly including a default implementation. A trait item is
-/// either required (meaning it doesn't have an implementation, just a
-/// signature) or provided (meaning it has a default implementation).
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TraitItem {
-    pub id: NodeId,
-    pub name: Name,
-    pub attrs: HirVec<Attribute>,
-    pub node: TraitItem_,
-    pub span: Span,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitItem_ {
-    ConstTraitItem(P<Ty>, Option<P<Expr>>),
-    MethodTraitItem(MethodSig, Option<P<Block>>),
-    TypeTraitItem(TyParamBounds, Option<P<Ty>>),
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct ImplItem {
-    pub id: NodeId,
-    pub name: Name,
-    pub vis: Visibility,
-    pub defaultness: Defaultness,
-    pub attrs: HirVec<Attribute>,
-    pub node: ImplItemKind,
-    pub span: Span,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum ImplItemKind {
-    Const(P<Ty>, P<Expr>),
-    Method(MethodSig, P<Block>),
-    Type(P<Ty>),
-}
-
-// Bind a type to an associated type: `A=Foo`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TypeBinding {
-    pub id: NodeId,
-    pub name: Name,
-    pub ty: P<Ty>,
-    pub span: Span,
-}
-
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
-pub struct Ty {
-    pub id: NodeId,
-    pub node: Ty_,
-    pub span: Span,
-}
-
-impl fmt::Debug for Ty {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "type({})", pprust::ty_to_string(self))
-    }
-}
-
-/// Not represented directly in the AST, referred to by name through a ty_path.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum PrimTy {
-    TyInt(IntTy),
-    TyUint(UintTy),
-    TyFloat(FloatTy),
-    TyStr,
-    TyBool,
-    TyChar,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct BareFnTy {
-    pub unsafety: Unsafety,
-    pub abi: Abi,
-    pub lifetimes: HirVec<LifetimeDef>,
-    pub decl: P<FnDecl>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-/// The different kinds of types recognized by the compiler
-pub enum Ty_ {
-    TyVec(P<Ty>),
-    /// A fixed length array (`[T; n]`)
-    TyFixedLengthVec(P<Ty>, P<Expr>),
-    /// A raw pointer (`*const T` or `*mut T`)
-    TyPtr(MutTy),
-    /// A reference (`&'a T` or `&'a mut T`)
-    TyRptr(Option<Lifetime>, MutTy),
-    /// A bare function (e.g. `fn(usize) -> bool`)
-    TyBareFn(P<BareFnTy>),
-    /// A tuple (`(A, B, C, D,...)`)
-    TyTup(HirVec<P<Ty>>),
-    /// A path (`module::module::...::Type`), optionally
-    /// "qualified", e.g. `<HirVec<T> as SomeTrait>::SomeType`.
-    ///
-    /// Type parameters are stored in the Path itself
-    TyPath(Option<QSelf>, Path),
-    /// Something like `A+B`. Note that `B` must always be a path.
-    TyObjectSum(P<Ty>, TyParamBounds),
-    /// A type like `for<'a> Foo<&'a Bar>`
-    TyPolyTraitRef(TyParamBounds),
-    /// Unused for now
-    TyTypeof(P<Expr>),
-    /// TyInfer means the type should be inferred instead of it having been
-    /// specified. This can appear anywhere in a type.
-    TyInfer,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct InlineAsmOutput {
-    pub constraint: InternedString,
-    pub is_rw: bool,
-    pub is_indirect: bool,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct InlineAsm {
-    pub asm: InternedString,
-    pub asm_str_style: StrStyle,
-    pub outputs: HirVec<InlineAsmOutput>,
-    pub inputs: HirVec<InternedString>,
-    pub clobbers: HirVec<InternedString>,
-    pub volatile: bool,
-    pub alignstack: bool,
-    pub dialect: AsmDialect,
-    pub expn_id: ExpnId,
-}
-
-/// represents an argument in a function header
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Arg {
-    pub ty: P<Ty>,
-    pub pat: P<Pat>,
-    pub id: NodeId,
-}
-
-impl Arg {
-    pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
-        let path = Spanned {
-            span: span,
-            node: self_ident,
-        };
-        Arg {
-            // HACK(eddyb) fake type for the self argument.
-            ty: P(Ty {
-                id: DUMMY_NODE_ID,
-                node: TyInfer,
-                span: DUMMY_SP,
-            }),
-            pat: P(Pat {
-                id: DUMMY_NODE_ID,
-                node: PatKind::Ident(BindByValue(mutability), path, None),
-                span: span,
-            }),
-            id: DUMMY_NODE_ID,
-        }
-    }
-}
-
-/// Represents the header (not the body) of a function declaration
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct FnDecl {
-    pub inputs: HirVec<Arg>,
-    pub output: FunctionRetTy,
-    pub variadic: bool,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Unsafety {
-    Unsafe,
-    Normal,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Constness {
-    Const,
-    NotConst,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Defaultness {
-    Default,
-    Final,
-}
-
-impl Defaultness {
-    pub fn is_final(&self) -> bool {
-        *self == Defaultness::Final
-    }
-
-    pub fn is_default(&self) -> bool {
-        *self == Defaultness::Default
-    }
-}
-
-impl fmt::Display for Unsafety {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(match *self {
-                              Unsafety::Normal => "normal",
-                              Unsafety::Unsafe => "unsafe",
-                          },
-                          f)
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
-pub enum ImplPolarity {
-    /// `impl Trait for Type`
-    Positive,
-    /// `impl !Trait for Type`
-    Negative,
-}
-
-impl fmt::Debug for ImplPolarity {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            ImplPolarity::Positive => "positive".fmt(f),
-            ImplPolarity::Negative => "negative".fmt(f),
-        }
-    }
-}
-
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum FunctionRetTy {
-    /// Functions with return type `!`that always
-    /// raise an error or exit (i.e. never return to the caller)
-    NoReturn(Span),
-    /// Return type is not specified.
-    ///
-    /// Functions default to `()` and
-    /// closures default to inference. Span points to where return
-    /// type would be inserted.
-    DefaultReturn(Span),
-    /// Everything else
-    Return(P<Ty>),
-}
-
-impl FunctionRetTy {
-    pub fn span(&self) -> Span {
-        match *self {
-            NoReturn(span) => span,
-            DefaultReturn(span) => span,
-            Return(ref ty) => ty.span,
-        }
-    }
-}
-
-/// Represents the kind of 'self' associated with a method
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum ExplicitSelf_ {
-    /// No self
-    SelfStatic,
-    /// `self`
-    SelfValue(Name),
-    /// `&'lt self`, `&'lt mut self`
-    SelfRegion(Option<Lifetime>, Mutability, Name),
-    /// `self: TYPE`
-    SelfExplicit(P<Ty>, Name),
-}
-
-pub type ExplicitSelf = Spanned<ExplicitSelf_>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Mod {
-    /// A span from the first token past `{` to the last token until `}`.
-    /// For `mod foo;`, the inner span ranges from the first token
-    /// to the last token in the external file.
-    pub inner: Span,
-    pub item_ids: HirVec<ItemId>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct ForeignMod {
-    pub abi: Abi,
-    pub items: HirVec<ForeignItem>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct EnumDef {
-    pub variants: HirVec<Variant>,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Variant_ {
-    pub name: Name,
-    pub attrs: HirVec<Attribute>,
-    pub data: VariantData,
-    /// Explicit discriminant, eg `Foo = 1`
-    pub disr_expr: Option<P<Expr>>,
-}
-
-pub type Variant = Spanned<Variant_>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum PathListItem_ {
-    PathListIdent {
-        name: Name,
-        /// renamed in list, eg `use foo::{bar as baz};`
-        rename: Option<Name>,
-        id: NodeId,
-    },
-    PathListMod {
-        /// renamed in list, eg `use foo::{self as baz};`
-        rename: Option<Name>,
-        id: NodeId,
-    },
-}
-
-impl PathListItem_ {
-    pub fn id(&self) -> NodeId {
-        match *self {
-            PathListIdent { id, .. } | PathListMod { id, .. } => id,
-        }
-    }
-
-    pub fn name(&self) -> Option<Name> {
-        match *self {
-            PathListIdent { name, .. } => Some(name),
-            PathListMod { .. } => None,
-        }
-    }
-
-    pub fn rename(&self) -> Option<Name> {
-        match *self {
-            PathListIdent { rename, .. } | PathListMod { rename, .. } => rename,
-        }
-    }
-}
-
-pub type PathListItem = Spanned<PathListItem_>;
-
-pub type ViewPath = Spanned<ViewPath_>;
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum ViewPath_ {
-    /// `foo::bar::baz as quux`
-    ///
-    /// or just
-    ///
-    /// `foo::bar::baz` (with `as baz` implicitly on the right)
-    ViewPathSimple(Name, Path),
-
-    /// `foo::bar::*`
-    ViewPathGlob(Path),
-
-    /// `foo::bar::{a,b,c}`
-    ViewPathList(Path, HirVec<PathListItem>),
-}
-
-/// TraitRef's appear in impls.
-///
-/// resolve maps each TraitRef's ref_id to its defining trait; that's all
-/// that the ref_id is for. The impl_id maps to the "self type" of this impl.
-/// If this impl is an ItemImpl, the impl_id is redundant (it could be the
-/// same as the impl's node id).
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TraitRef {
-    pub path: Path,
-    pub ref_id: NodeId,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct PolyTraitRef {
-    /// The `'a` in `<'a> Foo<&'a T>`
-    pub bound_lifetimes: HirVec<LifetimeDef>,
-
-    /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
-    pub trait_ref: TraitRef,
-
-    pub span: Span,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum Visibility {
-    Public,
-    Inherited,
-}
-
-impl Visibility {
-    pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
-        match self {
-            &Inherited => parent_visibility,
-            &Public => *self,
-        }
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct StructField {
-    pub span: Span,
-    pub name: Name,
-    pub vis: Visibility,
-    pub id: NodeId,
-    pub ty: P<Ty>,
-    pub attrs: HirVec<Attribute>,
-}
-
-impl StructField {
-    // Still necessary in couple of places
-    pub fn is_positional(&self) -> bool {
-        let first = self.name.as_str().as_bytes()[0];
-        first >= b'0' && first <= b'9'
-    }
-}
-
-/// Fields and Ids of enum variants and structs
-///
-/// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
-/// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
-/// One shared Id can be successfully used for these two purposes.
-/// Id of the whole enum lives in `Item`.
-///
-/// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
-/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
-/// the variant itself" from enum variants.
-/// Id of the whole struct lives in `Item`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum VariantData {
-    Struct(HirVec<StructField>, NodeId),
-    Tuple(HirVec<StructField>, NodeId),
-    Unit(NodeId),
-}
-
-impl VariantData {
-    pub fn fields(&self) -> &[StructField] {
-        match *self {
-            VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
-            _ => &[],
-        }
-    }
-    pub fn id(&self) -> NodeId {
-        match *self {
-            VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
-        }
-    }
-    pub fn is_struct(&self) -> bool {
-        if let VariantData::Struct(..) = *self {
-            true
-        } else {
-            false
-        }
-    }
-    pub fn is_tuple(&self) -> bool {
-        if let VariantData::Tuple(..) = *self {
-            true
-        } else {
-            false
-        }
-    }
-    pub fn is_unit(&self) -> bool {
-        if let VariantData::Unit(..) = *self {
-            true
-        } else {
-            false
-        }
-    }
-}
-
-// The bodies for items are stored "out of line", in a separate
-// hashmap in the `Crate`. Here we just record the node-id of the item
-// so it can fetched later.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct ItemId {
-    pub id: NodeId,
-}
-
-//  FIXME (#3300): Should allow items to be anonymous. Right now
-//  we just use dummy names for anon items.
-/// An item
-///
-/// The name might be a dummy name in case of anonymous items
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Item {
-    pub name: Name,
-    pub attrs: HirVec<Attribute>,
-    pub id: NodeId,
-    pub node: Item_,
-    pub vis: Visibility,
-    pub span: Span,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Item_ {
-    /// An`extern crate` item, with optional original crate name,
-    ///
-    /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
-    ItemExternCrate(Option<Name>),
-    /// A `use` or `pub use` item
-    ItemUse(P<ViewPath>),
-
-    /// A `static` item
-    ItemStatic(P<Ty>, Mutability, P<Expr>),
-    /// A `const` item
-    ItemConst(P<Ty>, P<Expr>),
-    /// A function declaration
-    ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
-    /// A module
-    ItemMod(Mod),
-    /// An external module
-    ItemForeignMod(ForeignMod),
-    /// A type alias, e.g. `type Foo = Bar<u8>`
-    ItemTy(P<Ty>, Generics),
-    /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
-    ItemEnum(EnumDef, Generics),
-    /// A struct definition, e.g. `struct Foo<A> {x: A}`
-    ItemStruct(VariantData, Generics),
-    /// Represents a Trait Declaration
-    ItemTrait(Unsafety, Generics, TyParamBounds, HirVec<TraitItem>),
-
-    // Default trait implementations
-    ///
-    /// `impl Trait for .. {}`
-    ItemDefaultImpl(Unsafety, TraitRef),
-    /// An implementation, eg `impl<A> Trait for Foo { .. }`
-    ItemImpl(Unsafety,
-             ImplPolarity,
-             Generics,
-             Option<TraitRef>, // (optional) trait this impl implements
-             P<Ty>, // self
-             HirVec<ImplItem>),
-}
-
-impl Item_ {
-    pub fn descriptive_variant(&self) -> &str {
-        match *self {
-            ItemExternCrate(..) => "extern crate",
-            ItemUse(..) => "use",
-            ItemStatic(..) => "static item",
-            ItemConst(..) => "constant item",
-            ItemFn(..) => "function",
-            ItemMod(..) => "module",
-            ItemForeignMod(..) => "foreign module",
-            ItemTy(..) => "type alias",
-            ItemEnum(..) => "enum",
-            ItemStruct(..) => "struct",
-            ItemTrait(..) => "trait",
-            ItemImpl(..) |
-            ItemDefaultImpl(..) => "item",
-        }
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct ForeignItem {
-    pub name: Name,
-    pub attrs: HirVec<Attribute>,
-    pub node: ForeignItem_,
-    pub id: NodeId,
-    pub span: Span,
-    pub vis: Visibility,
-}
-
-/// An item within an `extern` block
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum ForeignItem_ {
-    /// A foreign function
-    ForeignItemFn(P<FnDecl>, Generics),
-    /// A foreign static item (`static ext: u8`), with optional mutability
-    /// (the boolean is true when mutable)
-    ForeignItemStatic(P<Ty>, bool),
-}
-
-impl ForeignItem_ {
-    pub fn descriptive_variant(&self) -> &str {
-        match *self {
-            ForeignItemFn(..) => "foreign function",
-            ForeignItemStatic(..) => "foreign static item",
-        }
-    }
-}
diff --git a/src/librustc_front/intravisit.rs b/src/librustc_front/intravisit.rs
deleted file mode 100644
index be1cc528d88..00000000000
--- a/src/librustc_front/intravisit.rs
+++ /dev/null
@@ -1,837 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! HIR walker. Each overridden visit method has full control over what
-//! happens with its node, it can do its own traversal of the node's children,
-//! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent
-//! deeper traversal by doing nothing.
-//!
-//! When visiting the HIR, the contents of nested items are NOT visited
-//! by default. This is different from the AST visitor, which does a deep walk.
-//! Hence this module is called `intravisit`; see the method `visit_nested_item`
-//! for more details.
-//!
-//! Note: it is an important invariant that the default visitor walks
-//! the body of a function in "execution order" (more concretely,
-//! reverse post-order with respect to the CFG implied by the AST),
-//! meaning that if AST node A may execute before AST node B, then A
-//! is visited first.  The borrow checker in particular relies on this
-//! property.
-
-use syntax::abi::Abi;
-use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
-use syntax::attr::ThinAttributesExt;
-use syntax::codemap::Span;
-use hir::*;
-
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub enum FnKind<'a> {
-    /// fn foo() or extern "Abi" fn foo()
-    ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, Visibility, &'a [Attribute]),
-
-    /// fn foo(&self)
-    Method(Name, &'a MethodSig, Option<Visibility>, &'a [Attribute]),
-
-    /// |x, y| {}
-    Closure(&'a [Attribute]),
-}
-
-impl<'a> FnKind<'a> {
-    pub fn attrs(&self) -> &'a [Attribute] {
-        match *self {
-            FnKind::ItemFn(_, _, _, _, _, _, attrs) => attrs,
-            FnKind::Method(_, _, _, attrs) => attrs,
-            FnKind::Closure(attrs) => attrs,
-        }
-    }
-}
-
-/// Each method of the Visitor trait is a hook to be potentially
-/// overridden.  Each method's default implementation recursively visits
-/// the substructure of the input via the corresponding `walk` method;
-/// e.g. the `visit_mod` method by default calls `intravisit::walk_mod`.
-///
-/// Note that this visitor does NOT visit nested items by default
-/// (this is why the module is called `intravisit`, to distinguish it
-/// from the AST's `visit` module, which acts differently). If you
-/// simply want to visit all items in the crate in some order, you
-/// should call `Crate::visit_all_items`. Otherwise, see the comment
-/// on `visit_nested_item` for details on how to visit nested items.
-///
-/// If you want to ensure that your code handles every variant
-/// explicitly, you need to override each method.  (And you also need
-/// to monitor future changes to `Visitor` in case a new method with a
-/// new default implementation gets introduced.)
-pub trait Visitor<'v> : Sized {
-    ///////////////////////////////////////////////////////////////////////////
-    // Nested items.
-
-    /// Invoked when a nested item is encountered. By default, does
-    /// nothing. If you want a deep walk, you need to override to
-    /// fetch the item contents. But most of the time, it is easier
-    /// (and better) to invoke `Crate::visit_all_items`, which visits
-    /// all items in the crate in some order (but doesn't respect
-    /// nesting).
-    #[allow(unused_variables)]
-    fn visit_nested_item(&mut self, id: ItemId) {
-    }
-
-    /// Visit the top-level item and (optionally) nested items. See
-    /// `visit_nested_item` for details.
-    fn visit_item(&mut self, i: &'v Item) {
-        walk_item(self, i)
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-
-    fn visit_name(&mut self, _span: Span, _name: Name) {
-        // Nothing to do.
-    }
-    fn visit_ident(&mut self, span: Span, ident: Ident) {
-        walk_ident(self, span, ident);
-    }
-    fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) {
-        walk_mod(self, m)
-    }
-    fn visit_foreign_item(&mut self, i: &'v ForeignItem) {
-        walk_foreign_item(self, i)
-    }
-    fn visit_local(&mut self, l: &'v Local) {
-        walk_local(self, l)
-    }
-    fn visit_block(&mut self, b: &'v Block) {
-        walk_block(self, b)
-    }
-    fn visit_stmt(&mut self, s: &'v Stmt) {
-        walk_stmt(self, s)
-    }
-    fn visit_arm(&mut self, a: &'v Arm) {
-        walk_arm(self, a)
-    }
-    fn visit_pat(&mut self, p: &'v Pat) {
-        walk_pat(self, p)
-    }
-    fn visit_decl(&mut self, d: &'v Decl) {
-        walk_decl(self, d)
-    }
-    fn visit_expr(&mut self, ex: &'v Expr) {
-        walk_expr(self, ex)
-    }
-    fn visit_expr_post(&mut self, _ex: &'v Expr) {
-    }
-    fn visit_ty(&mut self, t: &'v Ty) {
-        walk_ty(self, t)
-    }
-    fn visit_generics(&mut self, g: &'v Generics) {
-        walk_generics(self, g)
-    }
-    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
-        walk_fn(self, fk, fd, b, s)
-    }
-    fn visit_trait_item(&mut self, ti: &'v TraitItem) {
-        walk_trait_item(self, ti)
-    }
-    fn visit_impl_item(&mut self, ii: &'v ImplItem) {
-        walk_impl_item(self, ii)
-    }
-    fn visit_trait_ref(&mut self, t: &'v TraitRef) {
-        walk_trait_ref(self, t)
-    }
-    fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
-        walk_ty_param_bound(self, bounds)
-    }
-    fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
-        walk_poly_trait_ref(self, t, m)
-    }
-    fn visit_variant_data(&mut self,
-                          s: &'v VariantData,
-                          _: Name,
-                          _: &'v Generics,
-                          _: NodeId,
-                          _: Span) {
-        walk_struct_def(self, s)
-    }
-    fn visit_struct_field(&mut self, s: &'v StructField) {
-        walk_struct_field(self, s)
-    }
-    fn visit_enum_def(&mut self,
-                      enum_definition: &'v EnumDef,
-                      generics: &'v Generics,
-                      item_id: NodeId,
-                      _: Span) {
-        walk_enum_def(self, enum_definition, generics, item_id)
-    }
-    fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
-        walk_variant(self, v, g, item_id)
-    }
-    fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
-        walk_lifetime(self, lifetime)
-    }
-    fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
-        walk_lifetime_def(self, lifetime)
-    }
-    fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
-        walk_explicit_self(self, es)
-    }
-    fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
-        walk_path(self, path)
-    }
-    fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
-        walk_path_list_item(self, prefix, item)
-    }
-    fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
-        walk_path_segment(self, path_span, path_segment)
-    }
-    fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
-        walk_path_parameters(self, path_span, path_parameters)
-    }
-    fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
-        walk_assoc_type_binding(self, type_binding)
-    }
-    fn visit_attribute(&mut self, _attr: &'v Attribute) {
-    }
-    fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
-        walk_macro_def(self, macro_def)
-    }
-}
-
-pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
-    for name in opt_name {
-        visitor.visit_name(span, name);
-    }
-}
-
-pub fn walk_opt_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_ident: Option<Ident>) {
-    for ident in opt_ident {
-        visitor.visit_ident(span, ident);
-    }
-}
-
-pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) {
-    visitor.visit_name(span, ident.name);
-}
-
-/// Walks the contents of a crate. See also `Crate::visit_all_items`.
-pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
-    visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
-    walk_list!(visitor, visit_attribute, &krate.attrs);
-    walk_list!(visitor, visit_macro_def, &krate.exported_macros);
-}
-
-pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) {
-    visitor.visit_name(macro_def.span, macro_def.name);
-    walk_opt_name(visitor, macro_def.span, macro_def.imported_from);
-    walk_list!(visitor, visit_attribute, &macro_def.attrs);
-}
-
-pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
-    for &item_id in &module.item_ids {
-        visitor.visit_nested_item(item_id);
-    }
-}
-
-pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
-    visitor.visit_pat(&local.pat);
-    walk_list!(visitor, visit_ty, &local.ty);
-    walk_list!(visitor, visit_expr, &local.init);
-}
-
-pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
-    visitor.visit_name(lifetime.span, lifetime.name);
-}
-
-pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v LifetimeDef) {
-    visitor.visit_lifetime(&lifetime_def.lifetime);
-    walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
-}
-
-pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, explicit_self: &'v ExplicitSelf) {
-    match explicit_self.node {
-        SelfStatic => {}
-        SelfValue(name) => {
-            visitor.visit_name(explicit_self.span, name)
-        }
-        SelfRegion(ref opt_lifetime, _, name) => {
-            visitor.visit_name(explicit_self.span, name);
-            walk_list!(visitor, visit_lifetime, opt_lifetime);
-        }
-        SelfExplicit(ref typ, name) => {
-            visitor.visit_name(explicit_self.span, name);
-            visitor.visit_ty(typ)
-        }
-    }
-}
-
-pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
-                                  trait_ref: &'v PolyTraitRef,
-                                  _modifier: &'v TraitBoundModifier)
-    where V: Visitor<'v>
-{
-    walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes);
-    visitor.visit_trait_ref(&trait_ref.trait_ref);
-}
-
-pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef)
-    where V: Visitor<'v>
-{
-    visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
-}
-
-pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
-    visitor.visit_name(item.span, item.name);
-    match item.node {
-        ItemExternCrate(opt_name) => {
-            walk_opt_name(visitor, item.span, opt_name)
-        }
-        ItemUse(ref vp) => {
-            match vp.node {
-                ViewPathSimple(name, ref path) => {
-                    visitor.visit_name(vp.span, name);
-                    visitor.visit_path(path, item.id);
-                }
-                ViewPathGlob(ref path) => {
-                    visitor.visit_path(path, item.id);
-                }
-                ViewPathList(ref prefix, ref list) => {
-                    if !list.is_empty() {
-                        for item in list {
-                            visitor.visit_path_list_item(prefix, item)
-                        }
-                    } else {
-                        visitor.visit_path(prefix, item.id);
-                    }
-                }
-            }
-        }
-        ItemStatic(ref typ, _, ref expr) |
-        ItemConst(ref typ, ref expr) => {
-            visitor.visit_ty(typ);
-            visitor.visit_expr(expr);
-        }
-        ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
-            visitor.visit_fn(FnKind::ItemFn(item.name,
-                                            generics,
-                                            unsafety,
-                                            constness,
-                                            abi,
-                                            item.vis,
-                                            &item.attrs),
-                             declaration,
-                             body,
-                             item.span,
-                             item.id)
-        }
-        ItemMod(ref module) => {
-            visitor.visit_mod(module, item.span, item.id)
-        }
-        ItemForeignMod(ref foreign_module) => {
-            walk_list!(visitor, visit_foreign_item, &foreign_module.items);
-        }
-        ItemTy(ref typ, ref type_parameters) => {
-            visitor.visit_ty(typ);
-            visitor.visit_generics(type_parameters)
-        }
-        ItemEnum(ref enum_definition, ref type_parameters) => {
-            visitor.visit_generics(type_parameters);
-            visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
-        }
-        ItemDefaultImpl(_, ref trait_ref) => {
-            visitor.visit_trait_ref(trait_ref)
-        }
-        ItemImpl(_, _, ref type_parameters, ref opt_trait_reference, ref typ, ref impl_items) => {
-            visitor.visit_generics(type_parameters);
-            walk_list!(visitor, visit_trait_ref, opt_trait_reference);
-            visitor.visit_ty(typ);
-            walk_list!(visitor, visit_impl_item, impl_items);
-        }
-        ItemStruct(ref struct_definition, ref generics) => {
-            visitor.visit_generics(generics);
-            visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span);
-        }
-        ItemTrait(_, ref generics, ref bounds, ref methods) => {
-            visitor.visit_generics(generics);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
-            walk_list!(visitor, visit_trait_item, methods);
-        }
-    }
-    walk_list!(visitor, visit_attribute, &item.attrs);
-}
-
-pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
-                                         enum_definition: &'v EnumDef,
-                                         generics: &'v Generics,
-                                         item_id: NodeId) {
-    walk_list!(visitor,
-               visit_variant,
-               &enum_definition.variants,
-               generics,
-               item_id);
-}
-
-pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
-                                        variant: &'v Variant,
-                                        generics: &'v Generics,
-                                        item_id: NodeId) {
-    visitor.visit_name(variant.span, variant.node.name);
-    visitor.visit_variant_data(&variant.node.data,
-                               variant.node.name,
-                               generics,
-                               item_id,
-                               variant.span);
-    walk_list!(visitor, visit_expr, &variant.node.disr_expr);
-    walk_list!(visitor, visit_attribute, &variant.node.attrs);
-}
-
-pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
-    match typ.node {
-        TyVec(ref ty) => {
-            visitor.visit_ty(ty)
-        }
-        TyPtr(ref mutable_type) => {
-            visitor.visit_ty(&mutable_type.ty)
-        }
-        TyRptr(ref opt_lifetime, ref mutable_type) => {
-            walk_list!(visitor, visit_lifetime, opt_lifetime);
-            visitor.visit_ty(&mutable_type.ty)
-        }
-        TyTup(ref tuple_element_types) => {
-            walk_list!(visitor, visit_ty, tuple_element_types);
-        }
-        TyBareFn(ref function_declaration) => {
-            walk_fn_decl(visitor, &function_declaration.decl);
-            walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes);
-        }
-        TyPath(ref maybe_qself, ref path) => {
-            if let Some(ref qself) = *maybe_qself {
-                visitor.visit_ty(&qself.ty);
-            }
-            visitor.visit_path(path, typ.id);
-        }
-        TyObjectSum(ref ty, ref bounds) => {
-            visitor.visit_ty(ty);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
-        }
-        TyFixedLengthVec(ref ty, ref expression) => {
-            visitor.visit_ty(ty);
-            visitor.visit_expr(expression)
-        }
-        TyPolyTraitRef(ref bounds) => {
-            walk_list!(visitor, visit_ty_param_bound, bounds);
-        }
-        TyTypeof(ref expression) => {
-            visitor.visit_expr(expression)
-        }
-        TyInfer => {}
-    }
-}
-
-pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
-    for segment in &path.segments {
-        visitor.visit_path_segment(path.span, segment);
-    }
-}
-
-pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V,
-                                               prefix: &'v Path,
-                                               item: &'v PathListItem) {
-    for segment in &prefix.segments {
-        visitor.visit_path_segment(prefix.span, segment);
-    }
-
-    walk_opt_name(visitor, item.span, item.node.name());
-    walk_opt_name(visitor, item.span, item.node.rename());
-}
-
-pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
-                                             path_span: Span,
-                                             segment: &'v PathSegment) {
-    visitor.visit_ident(path_span, segment.identifier);
-    visitor.visit_path_parameters(path_span, &segment.parameters);
-}
-
-pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
-                                                _path_span: Span,
-                                                path_parameters: &'v PathParameters) {
-    match *path_parameters {
-        AngleBracketedParameters(ref data) => {
-            walk_list!(visitor, visit_ty, &data.types);
-            walk_list!(visitor, visit_lifetime, &data.lifetimes);
-            walk_list!(visitor, visit_assoc_type_binding, &data.bindings);
-        }
-        ParenthesizedParameters(ref data) => {
-            walk_list!(visitor, visit_ty, &data.inputs);
-            walk_list!(visitor, visit_ty, &data.output);
-        }
-    }
-}
-
-pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
-                                                   type_binding: &'v TypeBinding) {
-    visitor.visit_name(type_binding.span, type_binding.name);
-    visitor.visit_ty(&type_binding.ty);
-}
-
-pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
-    match pattern.node {
-        PatKind::TupleStruct(ref path, ref opt_children) => {
-            visitor.visit_path(path, pattern.id);
-            if let Some(ref children) = *opt_children {
-                walk_list!(visitor, visit_pat, children);
-            }
-        }
-        PatKind::Path(ref path) => {
-            visitor.visit_path(path, pattern.id);
-        }
-        PatKind::QPath(ref qself, ref path) => {
-            visitor.visit_ty(&qself.ty);
-            visitor.visit_path(path, pattern.id)
-        }
-        PatKind::Struct(ref path, ref fields, _) => {
-            visitor.visit_path(path, pattern.id);
-            for field in fields {
-                visitor.visit_name(field.span, field.node.name);
-                visitor.visit_pat(&field.node.pat)
-            }
-        }
-        PatKind::Tup(ref tuple_elements) => {
-            walk_list!(visitor, visit_pat, tuple_elements);
-        }
-        PatKind::Box(ref subpattern) |
-        PatKind::Ref(ref subpattern, _) => {
-            visitor.visit_pat(subpattern)
-        }
-        PatKind::Ident(_, ref pth1, ref optional_subpattern) => {
-            visitor.visit_ident(pth1.span, pth1.node);
-            walk_list!(visitor, visit_pat, optional_subpattern);
-        }
-        PatKind::Lit(ref expression) => visitor.visit_expr(expression),
-        PatKind::Range(ref lower_bound, ref upper_bound) => {
-            visitor.visit_expr(lower_bound);
-            visitor.visit_expr(upper_bound)
-        }
-        PatKind::Wild => (),
-        PatKind::Vec(ref prepatterns, ref slice_pattern, ref postpatterns) => {
-            walk_list!(visitor, visit_pat, prepatterns);
-            walk_list!(visitor, visit_pat, slice_pattern);
-            walk_list!(visitor, visit_pat, postpatterns);
-        }
-    }
-}
-
-pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) {
-    visitor.visit_name(foreign_item.span, foreign_item.name);
-
-    match foreign_item.node {
-        ForeignItemFn(ref function_declaration, ref generics) => {
-            walk_fn_decl(visitor, function_declaration);
-            visitor.visit_generics(generics)
-        }
-        ForeignItemStatic(ref typ, _) => visitor.visit_ty(typ),
-    }
-
-    walk_list!(visitor, visit_attribute, &foreign_item.attrs);
-}
-
-pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) {
-    match *bound {
-        TraitTyParamBound(ref typ, ref modifier) => {
-            visitor.visit_poly_trait_ref(typ, modifier);
-        }
-        RegionTyParamBound(ref lifetime) => {
-            visitor.visit_lifetime(lifetime);
-        }
-    }
-}
-
-pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
-    for param in &generics.ty_params {
-        visitor.visit_name(param.span, param.name);
-        walk_list!(visitor, visit_ty_param_bound, &param.bounds);
-        walk_list!(visitor, visit_ty, &param.default);
-    }
-    walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
-    for predicate in &generics.where_clause.predicates {
-        match predicate {
-            &WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
-                                                                          ref bounds,
-                                                                          ref bound_lifetimes,
-                                                                          ..}) => {
-                visitor.visit_ty(bounded_ty);
-                walk_list!(visitor, visit_ty_param_bound, bounds);
-                walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
-            }
-            &WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
-                                                                            ref bounds,
-                                                                            ..}) => {
-                visitor.visit_lifetime(lifetime);
-                walk_list!(visitor, visit_lifetime, bounds);
-            }
-            &WherePredicate::EqPredicate(WhereEqPredicate{id,
-                                                                    ref path,
-                                                                    ref ty,
-                                                                    ..}) => {
-                visitor.visit_path(path, id);
-                visitor.visit_ty(ty);
-            }
-        }
-    }
-}
-
-pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) {
-    if let Return(ref output_ty) = *ret_ty {
-        visitor.visit_ty(output_ty)
-    }
-}
-
-pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
-    for argument in &function_declaration.inputs {
-        visitor.visit_pat(&argument.pat);
-        visitor.visit_ty(&argument.ty)
-    }
-    walk_fn_ret_ty(visitor, &function_declaration.output)
-}
-
-pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
-    for argument in &function_declaration.inputs {
-        visitor.visit_ty(&argument.ty)
-    }
-    walk_fn_ret_ty(visitor, &function_declaration.output)
-}
-
-pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) {
-    match function_kind {
-        FnKind::ItemFn(_, generics, _, _, _, _, _) => {
-            visitor.visit_generics(generics);
-        }
-        FnKind::Method(_, sig, _, _) => {
-            visitor.visit_generics(&sig.generics);
-            visitor.visit_explicit_self(&sig.explicit_self);
-        }
-        FnKind::Closure(_) => {}
-    }
-}
-
-pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
-                                   function_kind: FnKind<'v>,
-                                   function_declaration: &'v FnDecl,
-                                   function_body: &'v Block,
-                                   _span: Span) {
-    walk_fn_decl(visitor, function_declaration);
-    walk_fn_kind(visitor, function_kind);
-    visitor.visit_block(function_body)
-}
-
-pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
-    visitor.visit_name(trait_item.span, trait_item.name);
-    walk_list!(visitor, visit_attribute, &trait_item.attrs);
-    match trait_item.node {
-        ConstTraitItem(ref ty, ref default) => {
-            visitor.visit_ty(ty);
-            walk_list!(visitor, visit_expr, default);
-        }
-        MethodTraitItem(ref sig, None) => {
-            visitor.visit_explicit_self(&sig.explicit_self);
-            visitor.visit_generics(&sig.generics);
-            walk_fn_decl(visitor, &sig.decl);
-        }
-        MethodTraitItem(ref sig, Some(ref body)) => {
-            visitor.visit_fn(FnKind::Method(trait_item.name,
-                                            sig,
-                                            None,
-                                            &trait_item.attrs),
-                             &sig.decl,
-                             body,
-                             trait_item.span,
-                             trait_item.id);
-        }
-        TypeTraitItem(ref bounds, ref default) => {
-            walk_list!(visitor, visit_ty_param_bound, bounds);
-            walk_list!(visitor, visit_ty, default);
-        }
-    }
-}
-
-pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
-    visitor.visit_name(impl_item.span, impl_item.name);
-    walk_list!(visitor, visit_attribute, &impl_item.attrs);
-    match impl_item.node {
-        ImplItemKind::Const(ref ty, ref expr) => {
-            visitor.visit_ty(ty);
-            visitor.visit_expr(expr);
-        }
-        ImplItemKind::Method(ref sig, ref body) => {
-            visitor.visit_fn(FnKind::Method(impl_item.name,
-                                            sig,
-                                            Some(impl_item.vis),
-                                            &impl_item.attrs),
-                             &sig.decl,
-                             body,
-                             impl_item.span,
-                             impl_item.id);
-        }
-        ImplItemKind::Type(ref ty) => {
-            visitor.visit_ty(ty);
-        }
-    }
-}
-
-pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
-    walk_list!(visitor, visit_struct_field, struct_definition.fields());
-}
-
-pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
-    visitor.visit_name(struct_field.span, struct_field.name);
-    visitor.visit_ty(&struct_field.ty);
-    walk_list!(visitor, visit_attribute, &struct_field.attrs);
-}
-
-pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
-    walk_list!(visitor, visit_stmt, &block.stmts);
-    walk_list!(visitor, visit_expr, &block.expr);
-}
-
-pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
-    match statement.node {
-        StmtDecl(ref declaration, _) => visitor.visit_decl(declaration),
-        StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => {
-            visitor.visit_expr(expression)
-        }
-    }
-}
-
-pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
-    match declaration.node {
-        DeclLocal(ref local) => visitor.visit_local(local),
-        DeclItem(item) => visitor.visit_nested_item(item),
-    }
-}
-
-pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
-    match expression.node {
-        ExprBox(ref subexpression) => {
-            visitor.visit_expr(subexpression)
-        }
-        ExprVec(ref subexpressions) => {
-            walk_list!(visitor, visit_expr, subexpressions);
-        }
-        ExprRepeat(ref element, ref count) => {
-            visitor.visit_expr(element);
-            visitor.visit_expr(count)
-        }
-        ExprStruct(ref path, ref fields, ref optional_base) => {
-            visitor.visit_path(path, expression.id);
-            for field in fields {
-                visitor.visit_name(field.name.span, field.name.node);
-                visitor.visit_expr(&field.expr)
-            }
-            walk_list!(visitor, visit_expr, optional_base);
-        }
-        ExprTup(ref subexpressions) => {
-            walk_list!(visitor, visit_expr, subexpressions);
-        }
-        ExprCall(ref callee_expression, ref arguments) => {
-            walk_list!(visitor, visit_expr, arguments);
-            visitor.visit_expr(callee_expression)
-        }
-        ExprMethodCall(ref name, ref types, ref arguments) => {
-            visitor.visit_name(name.span, name.node);
-            walk_list!(visitor, visit_expr, arguments);
-            walk_list!(visitor, visit_ty, types);
-        }
-        ExprBinary(_, ref left_expression, ref right_expression) => {
-            visitor.visit_expr(left_expression);
-            visitor.visit_expr(right_expression)
-        }
-        ExprAddrOf(_, ref subexpression) | ExprUnary(_, ref subexpression) => {
-            visitor.visit_expr(subexpression)
-        }
-        ExprLit(_) => {}
-        ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => {
-            visitor.visit_expr(subexpression);
-            visitor.visit_ty(typ)
-        }
-        ExprIf(ref head_expression, ref if_block, ref optional_else) => {
-            visitor.visit_expr(head_expression);
-            visitor.visit_block(if_block);
-            walk_list!(visitor, visit_expr, optional_else);
-        }
-        ExprWhile(ref subexpression, ref block, opt_ident) => {
-            visitor.visit_expr(subexpression);
-            visitor.visit_block(block);
-            walk_opt_ident(visitor, expression.span, opt_ident)
-        }
-        ExprLoop(ref block, opt_ident) => {
-            visitor.visit_block(block);
-            walk_opt_ident(visitor, expression.span, opt_ident)
-        }
-        ExprMatch(ref subexpression, ref arms, _) => {
-            visitor.visit_expr(subexpression);
-            walk_list!(visitor, visit_arm, arms);
-        }
-        ExprClosure(_, ref function_declaration, ref body) => {
-            visitor.visit_fn(FnKind::Closure(expression.attrs.as_attr_slice()),
-                             function_declaration,
-                             body,
-                             expression.span,
-                             expression.id)
-        }
-        ExprBlock(ref block) => visitor.visit_block(block),
-        ExprAssign(ref left_hand_expression, ref right_hand_expression) => {
-            visitor.visit_expr(right_hand_expression);
-            visitor.visit_expr(left_hand_expression)
-        }
-        ExprAssignOp(_, ref left_expression, ref right_expression) => {
-            visitor.visit_expr(right_expression);
-            visitor.visit_expr(left_expression)
-        }
-        ExprField(ref subexpression, ref name) => {
-            visitor.visit_expr(subexpression);
-            visitor.visit_name(name.span, name.node);
-        }
-        ExprTupField(ref subexpression, _) => {
-            visitor.visit_expr(subexpression);
-        }
-        ExprIndex(ref main_expression, ref index_expression) => {
-            visitor.visit_expr(main_expression);
-            visitor.visit_expr(index_expression)
-        }
-        ExprPath(ref maybe_qself, ref path) => {
-            if let Some(ref qself) = *maybe_qself {
-                visitor.visit_ty(&qself.ty);
-            }
-            visitor.visit_path(path, expression.id)
-        }
-        ExprBreak(ref opt_sp_ident) | ExprAgain(ref opt_sp_ident) => {
-            for sp_ident in opt_sp_ident {
-                visitor.visit_ident(sp_ident.span, sp_ident.node);
-            }
-        }
-        ExprRet(ref optional_expression) => {
-            walk_list!(visitor, visit_expr, optional_expression);
-        }
-        ExprInlineAsm(_, ref outputs, ref inputs) => {
-            for output in outputs {
-                visitor.visit_expr(output)
-            }
-            for input in inputs {
-                visitor.visit_expr(input)
-            }
-        }
-    }
-
-    visitor.visit_expr_post(expression)
-}
-
-pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
-    walk_list!(visitor, visit_pat, &arm.pats);
-    walk_list!(visitor, visit_expr, &arm.guard);
-    visitor.visit_expr(&arm.body);
-    walk_list!(visitor, visit_attribute, &arm.attrs);
-}
diff --git a/src/librustc_front/lib.rs b/src/librustc_front/lib.rs
deleted file mode 100644
index b9e3b71cf1a..00000000000
--- a/src/librustc_front/lib.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The Rust compiler.
-//!
-//! # Note
-//!
-//! This API is completely unstable and subject to change.
-
-#![crate_name = "rustc_front"]
-#![unstable(feature = "rustc_private", issue = "27812")]
-#![crate_type = "dylib"]
-#![crate_type = "rlib"]
-#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/nightly/")]
-#![cfg_attr(not(stage0), deny(warnings))]
-
-#![feature(associated_consts)]
-#![feature(box_patterns)]
-#![feature(box_syntax)]
-#![feature(const_fn)]
-#![feature(quote)]
-#![feature(rustc_diagnostic_macros)]
-#![feature(rustc_private)]
-#![feature(slice_patterns)]
-#![feature(staged_api)]
-#![feature(str_char)]
-#![feature(question_mark)]
-
-extern crate serialize;
-#[macro_use]
-extern crate log;
-#[macro_use]
-extern crate syntax;
-#[macro_use]
-#[no_link]
-extern crate rustc_bitflags;
-
-extern crate serialize as rustc_serialize; // used by deriving
-
-#[macro_use]
-pub mod hir;
-pub mod lowering;
-pub mod fold;
-pub mod intravisit;
-pub mod util;
-
-pub mod print {
-    pub mod pprust;
-}
diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs
deleted file mode 100644
index 66b9e217bd3..00000000000
--- a/src/librustc_front/lowering.rs
+++ /dev/null
@@ -1,2149 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Lowers the AST to the HIR.
-//
-// Since the AST and HIR are fairly similar, this is mostly a simple procedure,
-// much like a fold. Where lowering involves a bit more work things get more
-// interesting and there are some invariants you should know about. These mostly
-// concern spans and ids.
-//
-// Spans are assigned to AST nodes during parsing and then are modified during
-// expansion to indicate the origin of a node and the process it went through
-// being expanded. Ids are assigned to AST nodes just before lowering.
-//
-// For the simpler lowering steps, ids and spans should be preserved. Unlike
-// expansion we do not preserve the process of lowering in the spans, so spans
-// should not be modified here. When creating a new node (as opposed to
-// 'folding' an existing one), then you create a new id using `next_id()`.
-//
-// You must ensure that ids are unique. That means that you should only use the
-// id from an AST node in a single HIR node (you can assume that AST node ids
-// are unique). Every new node must have a unique id. Avoid cloning HIR nodes.
-// If you do, you must then set the new node's id to a fresh one.
-//
-// Lowering must be reproducable (the compiler only lowers once, but tools and
-// custom lints may lower an AST node to a HIR node to interact with the
-// compiler). The most interesting bit of this is ids - if you lower an AST node
-// and create new HIR nodes with fresh ids, when re-lowering the same node, you
-// must ensure you get the same ids! To do this, we keep track of the next id
-// when we translate a node which requires new ids. By checking this cache and
-// using node ids starting with the cached id, we ensure ids are reproducible.
-// To use this system, you just need to hold on to a CachedIdSetter object
-// whilst lowering. This is an RAII object that takes care of setting and
-// restoring the cached id, etc.
-//
-// This whole system relies on node ids being incremented one at a time and
-// all increments being for lowering. This means that you should not call any
-// non-lowering function which will use new node ids.
-//
-// We must also cache gensym'ed Idents to ensure that we get the same Ident
-// every time we lower a node with gensym'ed names. One consequence of this is
-// that you can only gensym a name once in a lowering (you don't need to worry
-// about nested lowering though). That's because we cache based on the name and
-// the currently cached node id, which is unique per lowered node.
-//
-// Spans are used for error messages and for tools to map semantics back to
-// source code. It is therefore not as important with spans as ids to be strict
-// about use (you can't break the compiler by screwing up a span). Obviously, a
-// HIR node can only have a single span. But multiple nodes can have the same
-// span and spans don't need to be kept in order, etc. Where code is preserved
-// by lowering, it should have the same span as in the AST. Where HIR nodes are
-// new it is probably best to give a span for the whole AST node being lowered.
-// All nodes should have real spans, don't use dummy spans. Tools are likely to
-// get confused if the spans from leaf AST nodes occur in multiple places
-// in the HIR, especially for multiple identifiers.
-
-use hir;
-
-use std::collections::BTreeMap;
-use std::collections::HashMap;
-use std::iter;
-use syntax::ast::*;
-use syntax::attr::{ThinAttributes, ThinAttributesExt};
-use syntax::errors::Handler;
-use syntax::ext::mtwt;
-use syntax::ptr::P;
-use syntax::codemap::{respan, Spanned, Span};
-use syntax::parse::token;
-use syntax::std_inject;
-use syntax::visit::{self, Visitor};
-
-use std::cell::{Cell, RefCell};
-
-pub struct LoweringContext<'a> {
-    crate_root: Option<&'static str>,
-    // Map AST ids to ids used for expanded nodes.
-    id_cache: RefCell<HashMap<NodeId, NodeId>>,
-    // Use if there are no cached ids for the current node.
-    id_assigner: &'a NodeIdAssigner,
-    // 0 == no cached id. Must be incremented to align with previous id
-    // incrementing.
-    cached_id: Cell<u32>,
-    // Keep track of gensym'ed idents.
-    gensym_cache: RefCell<HashMap<(NodeId, &'static str), hir::Ident>>,
-    // A copy of cached_id, but is also set to an id while a node is lowered for
-    // the first time.
-    gensym_key: Cell<u32>,
-}
-
-impl<'a, 'hir> LoweringContext<'a> {
-    pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContext<'a> {
-        let crate_root = c.and_then(|c| {
-            if std_inject::no_core(c) {
-                None
-            } else if std_inject::no_std(c) {
-                Some("core")
-            } else {
-                Some("std")
-            }
-        });
-
-        LoweringContext {
-            crate_root: crate_root,
-            id_cache: RefCell::new(HashMap::new()),
-            id_assigner: id_assigner,
-            cached_id: Cell::new(0),
-            gensym_cache: RefCell::new(HashMap::new()),
-            gensym_key: Cell::new(0),
-        }
-    }
-
-    fn next_id(&self) -> NodeId {
-        let cached_id = self.cached_id.get();
-        if cached_id == 0 {
-            return self.id_assigner.next_node_id();
-        }
-
-        self.cached_id.set(cached_id + 1);
-        cached_id
-    }
-
-    fn str_to_ident(&self, s: &'static str) -> hir::Ident {
-        let gensym_key = self.gensym_key.get();
-        if gensym_key == 0 {
-            return hir::Ident::from_name(token::gensym(s));
-        }
-
-        let cached = self.gensym_cache.borrow().contains_key(&(gensym_key, s));
-        if cached {
-            self.gensym_cache.borrow()[&(gensym_key, s)]
-        } else {
-            let result = hir::Ident::from_name(token::gensym(s));
-            self.gensym_cache.borrow_mut().insert((gensym_key, s), result);
-            result
-        }
-    }
-
-    // Panics if this LoweringContext's NodeIdAssigner is not able to emit diagnostics.
-    fn diagnostic(&self) -> &Handler {
-        self.id_assigner.diagnostic()
-    }
-}
-
-// Utility fn for setting and unsetting the cached id.
-fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R
-    where OP: FnOnce(&LoweringContext) -> R
-{
-    // Only reset the id if it was previously 0, i.e., was not cached.
-    // If it was cached, we are in a nested node, but our id count will
-    // still count towards the parent's count.
-    let reset_cached_id = lctx.cached_id.get() == 0;
-    // We always reset gensym_key so that if we use the same name in a nested
-    // node and after that node, they get different values.
-    let old_gensym_key = lctx.gensym_key.get();
-
-    {
-        let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut();
-
-        if id_cache.contains_key(&expr_id) {
-            let cached_id = lctx.cached_id.get();
-            if cached_id == 0 {
-                // We're entering a node where we need to track ids, but are not
-                // yet tracking.
-                lctx.cached_id.set(id_cache[&expr_id]);
-            } else {
-                // We're already tracking - check that the tracked id is the same
-                // as the expected id.
-                assert!(cached_id == id_cache[&expr_id], "id mismatch");
-            }
-            lctx.gensym_key.set(id_cache[&expr_id]);
-        } else {
-            // We've never lowered this node before, remember it for next time.
-            let next_id = lctx.id_assigner.peek_node_id();
-            id_cache.insert(expr_id, next_id);
-            lctx.gensym_key.set(next_id);
-            // self.cached_id is not set when we lower a node for the first time,
-            // only on re-lowering.
-        }
-    }
-
-    let result = op(lctx);
-
-    if reset_cached_id {
-        lctx.cached_id.set(0);
-    }
-    lctx.gensym_key.set(old_gensym_key);
-
-    result
-}
-
-pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident {
-    hir::Ident {
-        name: mtwt::resolve(ident),
-        unhygienic_name: ident.name,
-    }
-}
-
-pub fn lower_attrs(_lctx: &LoweringContext, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
-    attrs.clone().into()
-}
-
-pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::ViewPath> {
-    P(Spanned {
-        node: match view_path.node {
-            ViewPathSimple(ident, ref path) => {
-                hir::ViewPathSimple(ident.name, lower_path(lctx, path))
-            }
-            ViewPathGlob(ref path) => {
-                hir::ViewPathGlob(lower_path(lctx, path))
-            }
-            ViewPathList(ref path, ref path_list_idents) => {
-                hir::ViewPathList(lower_path(lctx, path),
-                                  path_list_idents.iter()
-                                                  .map(lower_path_list_item)
-                                                  .collect())
-            }
-        },
-        span: view_path.span,
-    })
-}
-
-fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem {
-    Spanned {
-        node: match path_list_ident.node {
-            PathListItemKind::Ident { id, name, rename } => hir::PathListIdent {
-                id: id,
-                name: name.name,
-                rename: rename.map(|x| x.name),
-            },
-            PathListItemKind::Mod { id, rename } => hir::PathListMod {
-                id: id,
-                rename: rename.map(|x| x.name),
-            },
-        },
-        span: path_list_ident.span,
-    }
-}
-
-pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm {
-    hir::Arm {
-        attrs: lower_attrs(lctx, &arm.attrs),
-        pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(),
-        guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)),
-        body: lower_expr(lctx, &arm.body),
-    }
-}
-
-pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P<hir::Decl> {
-    match d.node {
-        DeclKind::Local(ref l) => P(Spanned {
-            node: hir::DeclLocal(lower_local(lctx, l)),
-            span: d.span,
-        }),
-        DeclKind::Item(ref it) => P(Spanned {
-            node: hir::DeclItem(lower_item_id(lctx, it)),
-            span: d.span,
-        }),
-    }
-}
-
-pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> hir::TypeBinding {
-    hir::TypeBinding {
-        id: b.id,
-        name: b.ident.name,
-        ty: lower_ty(lctx, &b.ty),
-        span: b.span,
-    }
-}
-
-pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P<hir::Ty> {
-    use syntax::ast::TyKind::*;
-    P(hir::Ty {
-        id: t.id,
-        node: match t.node {
-            Infer => hir::TyInfer,
-            Vec(ref ty) => hir::TyVec(lower_ty(lctx, ty)),
-            Ptr(ref mt) => hir::TyPtr(lower_mt(lctx, mt)),
-            Rptr(ref region, ref mt) => {
-                hir::TyRptr(lower_opt_lifetime(lctx, region), lower_mt(lctx, mt))
-            }
-            BareFn(ref f) => {
-                hir::TyBareFn(P(hir::BareFnTy {
-                    lifetimes: lower_lifetime_defs(lctx, &f.lifetimes),
-                    unsafety: lower_unsafety(lctx, f.unsafety),
-                    abi: f.abi,
-                    decl: lower_fn_decl(lctx, &f.decl),
-                }))
-            }
-            Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(lctx, ty)).collect()),
-            Paren(ref ty) => {
-                return lower_ty(lctx, ty);
-            }
-            Path(ref qself, ref path) => {
-                let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
-                    hir::QSelf {
-                        ty: lower_ty(lctx, ty),
-                        position: position,
-                    }
-                });
-                hir::TyPath(qself, lower_path(lctx, path))
-            }
-            ObjectSum(ref ty, ref bounds) => {
-                hir::TyObjectSum(lower_ty(lctx, ty), lower_bounds(lctx, bounds))
-            }
-            FixedLengthVec(ref ty, ref e) => {
-                hir::TyFixedLengthVec(lower_ty(lctx, ty), lower_expr(lctx, e))
-            }
-            Typeof(ref expr) => {
-                hir::TyTypeof(lower_expr(lctx, expr))
-            }
-            PolyTraitRef(ref bounds) => {
-                hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(lctx, b)).collect())
-            }
-            Mac(_) => panic!("TyMac should have been expanded by now."),
-        },
-        span: t.span,
-    })
-}
-
-pub fn lower_foreign_mod(lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod {
-    hir::ForeignMod {
-        abi: fm.abi,
-        items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(),
-    }
-}
-
-pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant {
-    Spanned {
-        node: hir::Variant_ {
-            name: v.node.name.name,
-            attrs: lower_attrs(lctx, &v.node.attrs),
-            data: lower_variant_data(lctx, &v.node.data),
-            disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)),
-        },
-        span: v.span,
-    }
-}
-
-// Path segments are usually unhygienic, hygienic path segments can occur only in
-// identifier-like paths originating from `ExprPath`.
-// Make life simpler for rustc_resolve by renaming only such segments.
-pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path {
-    let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1;
-    hir::Path {
-        global: p.global,
-        segments: p.segments
-                   .iter()
-                   .map(|&PathSegment { identifier, ref parameters }| {
-                       hir::PathSegment {
-                           identifier: if maybe_hygienic {
-                               lower_ident(lctx, identifier)
-                           } else {
-                               hir::Ident::from_name(identifier.name)
-                           },
-                           parameters: lower_path_parameters(lctx, parameters),
-                       }
-                   })
-                   .collect(),
-        span: p.span,
-    }
-}
-
-pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path {
-    lower_path_full(lctx, p, false)
-}
-
-pub fn lower_path_parameters(lctx: &LoweringContext,
-                             path_parameters: &PathParameters)
-                             -> hir::PathParameters {
-    match *path_parameters {
-        PathParameters::AngleBracketed(ref data) =>
-            hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)),
-        PathParameters::Parenthesized(ref data) =>
-            hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)),
-    }
-}
-
-pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext,
-                                            data: &AngleBracketedParameterData)
-                                            -> hir::AngleBracketedParameterData {
-    let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data;
-    hir::AngleBracketedParameterData {
-        lifetimes: lower_lifetimes(lctx, lifetimes),
-        types: types.iter().map(|ty| lower_ty(lctx, ty)).collect(),
-        bindings: bindings.iter().map(|b| lower_ty_binding(lctx, b)).collect(),
-    }
-}
-
-pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext,
-                                          data: &ParenthesizedParameterData)
-                                          -> hir::ParenthesizedParameterData {
-    let &ParenthesizedParameterData { ref inputs, ref output, span } = data;
-    hir::ParenthesizedParameterData {
-        inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(),
-        output: output.as_ref().map(|ty| lower_ty(lctx, ty)),
-        span: span,
-    }
-}
-
-pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P<hir::Local> {
-    P(hir::Local {
-        id: l.id,
-        ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)),
-        pat: lower_pat(lctx, &l.pat),
-        init: l.init.as_ref().map(|e| lower_expr(lctx, e)),
-        span: l.span,
-        attrs: l.attrs.clone(),
-    })
-}
-
-pub fn lower_explicit_self_underscore(lctx: &LoweringContext,
-                                      es: &SelfKind)
-                                      -> hir::ExplicitSelf_ {
-    match *es {
-        SelfKind::Static => hir::SelfStatic,
-        SelfKind::Value(v) => hir::SelfValue(v.name),
-        SelfKind::Region(ref lifetime, m, ident) => {
-            hir::SelfRegion(lower_opt_lifetime(lctx, lifetime),
-                            lower_mutability(lctx, m),
-                            ident.name)
-        }
-        SelfKind::Explicit(ref typ, ident) => {
-            hir::SelfExplicit(lower_ty(lctx, typ), ident.name)
-        }
-    }
-}
-
-pub fn lower_mutability(_lctx: &LoweringContext, m: Mutability) -> hir::Mutability {
-    match m {
-        Mutability::Mutable => hir::MutMutable,
-        Mutability::Immutable => hir::MutImmutable,
-    }
-}
-
-pub fn lower_explicit_self(lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf {
-    Spanned {
-        node: lower_explicit_self_underscore(lctx, &s.node),
-        span: s.span,
-    }
-}
-
-pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg {
-    hir::Arg {
-        id: arg.id,
-        pat: lower_pat(lctx, &arg.pat),
-        ty: lower_ty(lctx, &arg.ty),
-    }
-}
-
-pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P<hir::FnDecl> {
-    P(hir::FnDecl {
-        inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(),
-        output: match decl.output {
-            FunctionRetTy::Ty(ref ty) => hir::Return(lower_ty(lctx, ty)),
-            FunctionRetTy::Default(span) => hir::DefaultReturn(span),
-            FunctionRetTy::None(span) => hir::NoReturn(span),
-        },
-        variadic: decl.variadic,
-    })
-}
-
-pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound {
-    match *tpb {
-        TraitTyParamBound(ref ty, modifier) => {
-            hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty),
-                                   lower_trait_bound_modifier(lctx, modifier))
-        }
-        RegionTyParamBound(ref lifetime) => {
-            hir::RegionTyParamBound(lower_lifetime(lctx, lifetime))
-        }
-    }
-}
-
-pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam {
-    hir::TyParam {
-        id: tp.id,
-        name: tp.ident.name,
-        bounds: lower_bounds(lctx, &tp.bounds),
-        default: tp.default.as_ref().map(|x| lower_ty(lctx, x)),
-        span: tp.span,
-    }
-}
-
-pub fn lower_ty_params(lctx: &LoweringContext,
-                       tps: &P<[TyParam]>)
-                       -> hir::HirVec<hir::TyParam> {
-    tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect()
-}
-
-pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime {
-    hir::Lifetime {
-        id: l.id,
-        name: l.name,
-        span: l.span,
-    }
-}
-
-pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef {
-    hir::LifetimeDef {
-        lifetime: lower_lifetime(lctx, &l.lifetime),
-        bounds: lower_lifetimes(lctx, &l.bounds),
-    }
-}
-
-pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
-    lts.iter().map(|l| lower_lifetime(lctx, l)).collect()
-}
-
-pub fn lower_lifetime_defs(lctx: &LoweringContext,
-                           lts: &Vec<LifetimeDef>)
-                           -> hir::HirVec<hir::LifetimeDef> {
-    lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect()
-}
-
-pub fn lower_opt_lifetime(lctx: &LoweringContext,
-                          o_lt: &Option<Lifetime>)
-                          -> Option<hir::Lifetime> {
-    o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt))
-}
-
-pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics {
-    hir::Generics {
-        ty_params: lower_ty_params(lctx, &g.ty_params),
-        lifetimes: lower_lifetime_defs(lctx, &g.lifetimes),
-        where_clause: lower_where_clause(lctx, &g.where_clause),
-    }
-}
-
-pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause {
-    hir::WhereClause {
-        id: wc.id,
-        predicates: wc.predicates
-                      .iter()
-                      .map(|predicate| lower_where_predicate(lctx, predicate))
-                      .collect(),
-    }
-}
-
-pub fn lower_where_predicate(lctx: &LoweringContext,
-                             pred: &WherePredicate)
-                             -> hir::WherePredicate {
-    match *pred {
-        WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes,
-                                                            ref bounded_ty,
-                                                            ref bounds,
-                                                            span}) => {
-            hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                bound_lifetimes: lower_lifetime_defs(lctx, bound_lifetimes),
-                bounded_ty: lower_ty(lctx, bounded_ty),
-                bounds: bounds.iter().map(|x| lower_ty_param_bound(lctx, x)).collect(),
-                span: span,
-            })
-        }
-        WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
-                                                              ref bounds,
-                                                              span}) => {
-            hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
-                span: span,
-                lifetime: lower_lifetime(lctx, lifetime),
-                bounds: bounds.iter().map(|bound| lower_lifetime(lctx, bound)).collect(),
-            })
-        }
-        WherePredicate::EqPredicate(WhereEqPredicate{ id,
-                                                      ref path,
-                                                      ref ty,
-                                                      span}) => {
-            hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
-                id: id,
-                path: lower_path(lctx, path),
-                ty: lower_ty(lctx, ty),
-                span: span,
-            })
-        }
-    }
-}
-
-pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::VariantData {
-    match *vdata {
-        VariantData::Struct(ref fields, id) => {
-            hir::VariantData::Struct(fields.iter()
-                                           .enumerate()
-                                           .map(|f| lower_struct_field(lctx, f))
-                                           .collect(),
-                                     id)
-        }
-        VariantData::Tuple(ref fields, id) => {
-            hir::VariantData::Tuple(fields.iter()
-                                          .enumerate()
-                                          .map(|f| lower_struct_field(lctx, f))
-                                          .collect(),
-                                    id)
-        }
-        VariantData::Unit(id) => hir::VariantData::Unit(id),
-    }
-}
-
-pub fn lower_trait_ref(lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef {
-    hir::TraitRef {
-        path: lower_path(lctx, &p.path),
-        ref_id: p.ref_id,
-    }
-}
-
-pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef {
-    hir::PolyTraitRef {
-        bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes),
-        trait_ref: lower_trait_ref(lctx, &p.trait_ref),
-        span: p.span,
-    }
-}
-
-pub fn lower_struct_field(lctx: &LoweringContext,
-                          (index, f): (usize, &StructField))
-                          -> hir::StructField {
-    hir::StructField {
-        span: f.span,
-        id: f.node.id,
-        name: f.node.ident().map(|ident| ident.name)
-                            .unwrap_or(token::intern(&index.to_string())),
-        vis: lower_visibility(lctx, f.node.kind.visibility()),
-        ty: lower_ty(lctx, &f.node.ty),
-        attrs: lower_attrs(lctx, &f.node.attrs),
-    }
-}
-
-pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field {
-    hir::Field {
-        name: respan(f.ident.span, f.ident.node.name),
-        expr: lower_expr(lctx, &f.expr),
-        span: f.span,
-    }
-}
-
-pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy {
-    hir::MutTy {
-        ty: lower_ty(lctx, &mt.ty),
-        mutbl: lower_mutability(lctx, mt.mutbl),
-    }
-}
-
-pub fn lower_opt_bounds(lctx: &LoweringContext,
-                        b: &Option<TyParamBounds>)
-                        -> Option<hir::TyParamBounds> {
-    b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds))
-}
-
-fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds {
-    bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect()
-}
-
-pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P<hir::Block> {
-    P(hir::Block {
-        id: b.id,
-        stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(),
-        expr: b.expr.as_ref().map(|ref x| lower_expr(lctx, x)),
-        rules: lower_block_check_mode(lctx, &b.rules),
-        span: b.span,
-    })
-}
-
-pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ {
-    match *i {
-        ItemKind::ExternCrate(string) => hir::ItemExternCrate(string),
-        ItemKind::Use(ref view_path) => {
-            hir::ItemUse(lower_view_path(lctx, view_path))
-        }
-        ItemKind::Static(ref t, m, ref e) => {
-            hir::ItemStatic(lower_ty(lctx, t),
-                            lower_mutability(lctx, m),
-                            lower_expr(lctx, e))
-        }
-        ItemKind::Const(ref t, ref e) => {
-            hir::ItemConst(lower_ty(lctx, t), lower_expr(lctx, e))
-        }
-        ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
-            hir::ItemFn(lower_fn_decl(lctx, decl),
-                        lower_unsafety(lctx, unsafety),
-                        lower_constness(lctx, constness),
-                        abi,
-                        lower_generics(lctx, generics),
-                        lower_block(lctx, body))
-        }
-        ItemKind::Mod(ref m) => hir::ItemMod(lower_mod(lctx, m)),
-        ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(lctx, nm)),
-        ItemKind::Ty(ref t, ref generics) => {
-            hir::ItemTy(lower_ty(lctx, t), lower_generics(lctx, generics))
-        }
-        ItemKind::Enum(ref enum_definition, ref generics) => {
-            hir::ItemEnum(hir::EnumDef {
-                              variants: enum_definition.variants
-                                                       .iter()
-                                                       .map(|x| lower_variant(lctx, x))
-                                                       .collect(),
-                          },
-                          lower_generics(lctx, generics))
-        }
-        ItemKind::Struct(ref struct_def, ref generics) => {
-            let struct_def = lower_variant_data(lctx, struct_def);
-            hir::ItemStruct(struct_def, lower_generics(lctx, generics))
-        }
-        ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
-            hir::ItemDefaultImpl(lower_unsafety(lctx, unsafety),
-                                 lower_trait_ref(lctx, trait_ref))
-        }
-        ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
-            let new_impl_items = impl_items.iter()
-                                           .map(|item| lower_impl_item(lctx, item))
-                                           .collect();
-            let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(lctx, trait_ref));
-            hir::ItemImpl(lower_unsafety(lctx, unsafety),
-                          lower_impl_polarity(lctx, polarity),
-                          lower_generics(lctx, generics),
-                          ifce,
-                          lower_ty(lctx, ty),
-                          new_impl_items)
-        }
-        ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
-            let bounds = lower_bounds(lctx, bounds);
-            let items = items.iter().map(|item| lower_trait_item(lctx, item)).collect();
-            hir::ItemTrait(lower_unsafety(lctx, unsafety),
-                           lower_generics(lctx, generics),
-                           bounds,
-                           items)
-        }
-        ItemKind::Mac(_) => panic!("Shouldn't still be around"),
-    }
-}
-
-pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem {
-    hir::TraitItem {
-        id: i.id,
-        name: i.ident.name,
-        attrs: lower_attrs(lctx, &i.attrs),
-        node: match i.node {
-            TraitItemKind::Const(ref ty, ref default) => {
-                hir::ConstTraitItem(lower_ty(lctx, ty),
-                                    default.as_ref().map(|x| lower_expr(lctx, x)))
-            }
-            TraitItemKind::Method(ref sig, ref body) => {
-                hir::MethodTraitItem(lower_method_sig(lctx, sig),
-                                     body.as_ref().map(|x| lower_block(lctx, x)))
-            }
-            TraitItemKind::Type(ref bounds, ref default) => {
-                hir::TypeTraitItem(lower_bounds(lctx, bounds),
-                                   default.as_ref().map(|x| lower_ty(lctx, x)))
-            }
-        },
-        span: i.span,
-    }
-}
-
-pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem {
-    hir::ImplItem {
-        id: i.id,
-        name: i.ident.name,
-        attrs: lower_attrs(lctx, &i.attrs),
-        vis: lower_visibility(lctx, &i.vis),
-        defaultness: lower_defaultness(lctx, i.defaultness),
-        node: match i.node {
-            ImplItemKind::Const(ref ty, ref expr) => {
-                hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr))
-            }
-            ImplItemKind::Method(ref sig, ref body) => {
-                hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body))
-            }
-            ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)),
-            ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
-        },
-        span: i.span,
-    }
-}
-
-pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod {
-    hir::Mod {
-        inner: m.inner,
-        item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(),
-    }
-}
-
-struct ItemLowerer<'lcx, 'interner: 'lcx> {
-    items: BTreeMap<NodeId, hir::Item>,
-    lctx: &'lcx LoweringContext<'interner>,
-}
-
-impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
-    fn visit_item(&mut self, item: &'lcx Item) {
-        self.items.insert(item.id, lower_item(self.lctx, item));
-        visit::walk_item(self, item);
-    }
-}
-
-pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate {
-    let items = {
-        let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx };
-        visit::walk_crate(&mut item_lowerer, c);
-        item_lowerer.items
-    };
-
-    hir::Crate {
-        module: lower_mod(lctx, &c.module),
-        attrs: lower_attrs(lctx, &c.attrs),
-        config: c.config.clone().into(),
-        span: c.span,
-        exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(),
-        items: items,
-    }
-}
-
-pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef {
-    hir::MacroDef {
-        name: m.ident.name,
-        attrs: lower_attrs(lctx, &m.attrs),
-        id: m.id,
-        span: m.span,
-        imported_from: m.imported_from.map(|x| x.name),
-        export: m.export,
-        use_locally: m.use_locally,
-        allow_internal_unstable: m.allow_internal_unstable,
-        body: m.body.clone().into(),
-    }
-}
-
-pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId {
-    hir::ItemId { id: i.id }
-}
-
-pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item {
-    let node = lower_item_kind(lctx, &i.node);
-
-    hir::Item {
-        id: i.id,
-        name: i.ident.name,
-        attrs: lower_attrs(lctx, &i.attrs),
-        node: node,
-        vis: lower_visibility(lctx, &i.vis),
-        span: i.span,
-    }
-}
-
-pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem {
-    hir::ForeignItem {
-        id: i.id,
-        name: i.ident.name,
-        attrs: lower_attrs(lctx, &i.attrs),
-        node: match i.node {
-            ForeignItemKind::Fn(ref fdec, ref generics) => {
-                hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics))
-            }
-            ForeignItemKind::Static(ref t, m) => {
-                hir::ForeignItemStatic(lower_ty(lctx, t), m)
-            }
-        },
-        vis: lower_visibility(lctx, &i.vis),
-        span: i.span,
-    }
-}
-
-pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig {
-    hir::MethodSig {
-        generics: lower_generics(lctx, &sig.generics),
-        abi: sig.abi,
-        explicit_self: lower_explicit_self(lctx, &sig.explicit_self),
-        unsafety: lower_unsafety(lctx, sig.unsafety),
-        constness: lower_constness(lctx, sig.constness),
-        decl: lower_fn_decl(lctx, &sig.decl),
-    }
-}
-
-pub fn lower_unsafety(_lctx: &LoweringContext, u: Unsafety) -> hir::Unsafety {
-    match u {
-        Unsafety::Unsafe => hir::Unsafety::Unsafe,
-        Unsafety::Normal => hir::Unsafety::Normal,
-    }
-}
-
-pub fn lower_constness(_lctx: &LoweringContext, c: Constness) -> hir::Constness {
-    match c {
-        Constness::Const => hir::Constness::Const,
-        Constness::NotConst => hir::Constness::NotConst,
-    }
-}
-
-pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp {
-    match u {
-        UnOp::Deref => hir::UnDeref,
-        UnOp::Not => hir::UnNot,
-        UnOp::Neg => hir::UnNeg,
-    }
-}
-
-pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp {
-    Spanned {
-        node: match b.node {
-            BinOpKind::Add => hir::BiAdd,
-            BinOpKind::Sub => hir::BiSub,
-            BinOpKind::Mul => hir::BiMul,
-            BinOpKind::Div => hir::BiDiv,
-            BinOpKind::Rem => hir::BiRem,
-            BinOpKind::And => hir::BiAnd,
-            BinOpKind::Or => hir::BiOr,
-            BinOpKind::BitXor => hir::BiBitXor,
-            BinOpKind::BitAnd => hir::BiBitAnd,
-            BinOpKind::BitOr => hir::BiBitOr,
-            BinOpKind::Shl => hir::BiShl,
-            BinOpKind::Shr => hir::BiShr,
-            BinOpKind::Eq => hir::BiEq,
-            BinOpKind::Lt => hir::BiLt,
-            BinOpKind::Le => hir::BiLe,
-            BinOpKind::Ne => hir::BiNe,
-            BinOpKind::Ge => hir::BiGe,
-            BinOpKind::Gt => hir::BiGt,
-        },
-        span: b.span,
-    }
-}
-
-pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
-    P(hir::Pat {
-        id: p.id,
-        node: match p.node {
-            PatKind::Wild => hir::PatKind::Wild,
-            PatKind::Ident(ref binding_mode, pth1, ref sub) => {
-                hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode),
-                              respan(pth1.span, lower_ident(lctx, pth1.node)),
-                              sub.as_ref().map(|x| lower_pat(lctx, x)))
-            }
-            PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)),
-            PatKind::TupleStruct(ref pth, ref pats) => {
-                hir::PatKind::TupleStruct(lower_path(lctx, pth),
-                             pats.as_ref()
-                                 .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect()))
-            }
-            PatKind::Path(ref pth) => {
-                hir::PatKind::Path(lower_path(lctx, pth))
-            }
-            PatKind::QPath(ref qself, ref pth) => {
-                let qself = hir::QSelf {
-                    ty: lower_ty(lctx, &qself.ty),
-                    position: qself.position,
-                };
-                hir::PatKind::QPath(qself, lower_path(lctx, pth))
-            }
-            PatKind::Struct(ref pth, ref fields, etc) => {
-                let pth = lower_path(lctx, pth);
-                let fs = fields.iter()
-                               .map(|f| {
-                                   Spanned {
-                                       span: f.span,
-                                       node: hir::FieldPat {
-                                           name: f.node.ident.name,
-                                           pat: lower_pat(lctx, &f.node.pat),
-                                           is_shorthand: f.node.is_shorthand,
-                                       },
-                                   }
-                               })
-                               .collect();
-                hir::PatKind::Struct(pth, fs, etc)
-            }
-            PatKind::Tup(ref elts) => {
-                hir::PatKind::Tup(elts.iter().map(|x| lower_pat(lctx, x)).collect())
-            }
-            PatKind::Box(ref inner) => hir::PatKind::Box(lower_pat(lctx, inner)),
-            PatKind::Ref(ref inner, mutbl) => {
-                hir::PatKind::Ref(lower_pat(lctx, inner), lower_mutability(lctx, mutbl))
-            }
-            PatKind::Range(ref e1, ref e2) => {
-                hir::PatKind::Range(lower_expr(lctx, e1), lower_expr(lctx, e2))
-            }
-            PatKind::Vec(ref before, ref slice, ref after) => {
-                hir::PatKind::Vec(before.iter().map(|x| lower_pat(lctx, x)).collect(),
-                            slice.as_ref().map(|x| lower_pat(lctx, x)),
-                            after.iter().map(|x| lower_pat(lctx, x)).collect())
-            }
-            PatKind::Mac(_) => panic!("Shouldn't exist here"),
-        },
-        span: p.span,
-    })
-}
-
-pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
-    P(hir::Expr {
-        id: e.id,
-        node: match e.node {
-            // Issue #22181:
-            // Eventually a desugaring for `box EXPR`
-            // (similar to the desugaring above for `in PLACE BLOCK`)
-            // should go here, desugaring
-            //
-            // to:
-            //
-            // let mut place = BoxPlace::make_place();
-            // let raw_place = Place::pointer(&mut place);
-            // let value = $value;
-            // unsafe {
-            //     ::std::ptr::write(raw_place, value);
-            //     Boxed::finalize(place)
-            // }
-            //
-            // But for now there are type-inference issues doing that.
-            ExprKind::Box(ref e) => {
-                hir::ExprBox(lower_expr(lctx, e))
-            }
-
-            // Desugar ExprBox: `in (PLACE) EXPR`
-            ExprKind::InPlace(ref placer, ref value_expr) => {
-                // to:
-                //
-                // let p = PLACE;
-                // let mut place = Placer::make_place(p);
-                // let raw_place = Place::pointer(&mut place);
-                // push_unsafe!({
-                //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
-                //     InPlace::finalize(place)
-                // })
-                return cache_ids(lctx, e.id, |lctx| {
-                    let placer_expr = lower_expr(lctx, placer);
-                    let value_expr = lower_expr(lctx, value_expr);
-
-                    let placer_ident = lctx.str_to_ident("placer");
-                    let place_ident = lctx.str_to_ident("place");
-                    let p_ptr_ident = lctx.str_to_ident("p_ptr");
-
-                    let make_place = ["ops", "Placer", "make_place"];
-                    let place_pointer = ["ops", "Place", "pointer"];
-                    let move_val_init = ["intrinsics", "move_val_init"];
-                    let inplace_finalize = ["ops", "InPlace", "finalize"];
-
-                    let make_call = |lctx: &LoweringContext, p, args| {
-                        let path = core_path(lctx, e.span, p);
-                        let path = expr_path(lctx, path, None);
-                        expr_call(lctx, e.span, path, args, None)
-                    };
-
-                    let mk_stmt_let = |lctx: &LoweringContext, bind, expr| {
-                        stmt_let(lctx, e.span, false, bind, expr, None)
-                    };
-
-                    let mk_stmt_let_mut = |lctx: &LoweringContext, bind, expr| {
-                        stmt_let(lctx, e.span, true, bind, expr, None)
-                    };
-
-                    // let placer = <placer_expr> ;
-                    let s1 = {
-                        let placer_expr = signal_block_expr(lctx,
-                                                            hir_vec![],
-                                                            placer_expr,
-                                                            e.span,
-                                                            hir::PopUnstableBlock,
-                                                            None);
-                        mk_stmt_let(lctx, placer_ident, placer_expr)
-                    };
-
-                    // let mut place = Placer::make_place(placer);
-                    let s2 = {
-                        let placer = expr_ident(lctx, e.span, placer_ident, None);
-                        let call = make_call(lctx, &make_place, hir_vec![placer]);
-                        mk_stmt_let_mut(lctx, place_ident, call)
-                    };
-
-                    // let p_ptr = Place::pointer(&mut place);
-                    let s3 = {
-                        let agent = expr_ident(lctx, e.span, place_ident, None);
-                        let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)];
-                        let call = make_call(lctx, &place_pointer, args);
-                        mk_stmt_let(lctx, p_ptr_ident, call)
-                    };
-
-                    // pop_unsafe!(EXPR));
-                    let pop_unsafe_expr = {
-                        let value_expr = signal_block_expr(lctx,
-                                                           hir_vec![],
-                                                           value_expr,
-                                                           e.span,
-                                                           hir::PopUnstableBlock,
-                                                           None);
-                        signal_block_expr(lctx,
-                                          hir_vec![],
-                                          value_expr,
-                                          e.span,
-                                          hir::PopUnsafeBlock(hir::CompilerGenerated), None)
-                    };
-
-                    // push_unsafe!({
-                    //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
-                    //     InPlace::finalize(place)
-                    // })
-                    let expr = {
-                        let ptr = expr_ident(lctx, e.span, p_ptr_ident, None);
-                        let call_move_val_init =
-                            hir::StmtSemi(
-                                make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
-                                lctx.next_id());
-                        let call_move_val_init = respan(e.span, call_move_val_init);
-
-                        let place = expr_ident(lctx, e.span, place_ident, None);
-                        let call = make_call(lctx, &inplace_finalize, hir_vec![place]);
-                        signal_block_expr(lctx,
-                                          hir_vec![call_move_val_init],
-                                          call,
-                                          e.span,
-                                          hir::PushUnsafeBlock(hir::CompilerGenerated), None)
-                    };
-
-                    signal_block_expr(lctx,
-                                      hir_vec![s1, s2, s3],
-                                      expr,
-                                      e.span,
-                                      hir::PushUnstableBlock,
-                                      e.attrs.clone())
-                });
-            }
-
-            ExprKind::Vec(ref exprs) => {
-                hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect())
-            }
-            ExprKind::Repeat(ref expr, ref count) => {
-                let expr = lower_expr(lctx, expr);
-                let count = lower_expr(lctx, count);
-                hir::ExprRepeat(expr, count)
-            }
-            ExprKind::Tup(ref elts) => {
-                hir::ExprTup(elts.iter().map(|x| lower_expr(lctx, x)).collect())
-            }
-            ExprKind::Call(ref f, ref args) => {
-                let f = lower_expr(lctx, f);
-                hir::ExprCall(f, args.iter().map(|x| lower_expr(lctx, x)).collect())
-            }
-            ExprKind::MethodCall(i, ref tps, ref args) => {
-                let tps = tps.iter().map(|x| lower_ty(lctx, x)).collect();
-                let args = args.iter().map(|x| lower_expr(lctx, x)).collect();
-                hir::ExprMethodCall(respan(i.span, i.node.name), tps, args)
-            }
-            ExprKind::Binary(binop, ref lhs, ref rhs) => {
-                let binop = lower_binop(lctx, binop);
-                let lhs = lower_expr(lctx, lhs);
-                let rhs = lower_expr(lctx, rhs);
-                hir::ExprBinary(binop, lhs, rhs)
-            }
-            ExprKind::Unary(op, ref ohs) => {
-                let op = lower_unop(lctx, op);
-                let ohs = lower_expr(lctx, ohs);
-                hir::ExprUnary(op, ohs)
-            }
-            ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())),
-            ExprKind::Cast(ref expr, ref ty) => {
-                let expr = lower_expr(lctx, expr);
-                hir::ExprCast(expr, lower_ty(lctx, ty))
-            }
-            ExprKind::Type(ref expr, ref ty) => {
-                let expr = lower_expr(lctx, expr);
-                hir::ExprType(expr, lower_ty(lctx, ty))
-            }
-            ExprKind::AddrOf(m, ref ohs) => {
-                let m = lower_mutability(lctx, m);
-                let ohs = lower_expr(lctx, ohs);
-                hir::ExprAddrOf(m, ohs)
-            }
-            // More complicated than you might expect because the else branch
-            // might be `if let`.
-            ExprKind::If(ref cond, ref blk, ref else_opt) => {
-                let else_opt = else_opt.as_ref().map(|els| {
-                    match els.node {
-                        ExprKind::IfLet(..) => {
-                            cache_ids(lctx, e.id, |lctx| {
-                                // wrap the if-let expr in a block
-                                let span = els.span;
-                                let els = lower_expr(lctx, els);
-                                let id = lctx.next_id();
-                                let blk = P(hir::Block {
-                                    stmts: hir_vec![],
-                                    expr: Some(els),
-                                    id: id,
-                                    rules: hir::DefaultBlock,
-                                    span: span,
-                                });
-                                expr_block(lctx, blk, None)
-                            })
-                        }
-                        _ => lower_expr(lctx, els),
-                    }
-                });
-
-                hir::ExprIf(lower_expr(lctx, cond), lower_block(lctx, blk), else_opt)
-            }
-            ExprKind::While(ref cond, ref body, opt_ident) => {
-                hir::ExprWhile(lower_expr(lctx, cond), lower_block(lctx, body),
-                               opt_ident.map(|ident| lower_ident(lctx, ident)))
-            }
-            ExprKind::Loop(ref body, opt_ident) => {
-                hir::ExprLoop(lower_block(lctx, body),
-                              opt_ident.map(|ident| lower_ident(lctx, ident)))
-            }
-            ExprKind::Match(ref expr, ref arms) => {
-                hir::ExprMatch(lower_expr(lctx, expr),
-                               arms.iter().map(|x| lower_arm(lctx, x)).collect(),
-                               hir::MatchSource::Normal)
-            }
-            ExprKind::Closure(capture_clause, ref decl, ref body) => {
-                hir::ExprClosure(lower_capture_clause(lctx, capture_clause),
-                                 lower_fn_decl(lctx, decl),
-                                 lower_block(lctx, body))
-            }
-            ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)),
-            ExprKind::Assign(ref el, ref er) => {
-                hir::ExprAssign(lower_expr(lctx, el), lower_expr(lctx, er))
-            }
-            ExprKind::AssignOp(op, ref el, ref er) => {
-                hir::ExprAssignOp(lower_binop(lctx, op),
-                                  lower_expr(lctx, el),
-                                  lower_expr(lctx, er))
-            }
-            ExprKind::Field(ref el, ident) => {
-                hir::ExprField(lower_expr(lctx, el), respan(ident.span, ident.node.name))
-            }
-            ExprKind::TupField(ref el, ident) => {
-                hir::ExprTupField(lower_expr(lctx, el), ident)
-            }
-            ExprKind::Index(ref el, ref er) => {
-                hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er))
-            }
-            ExprKind::Range(ref e1, ref e2, lims) => {
-                fn make_struct(lctx: &LoweringContext,
-                               ast_expr: &Expr,
-                               path: &[&str],
-                               fields: &[(&str, &P<Expr>)]) -> P<hir::Expr> {
-                    let strs = std_path(lctx, &iter::once(&"ops")
-                                                    .chain(path)
-                                                    .map(|s| *s)
-                                                    .collect::<Vec<_>>());
-
-                    let structpath = path_global(ast_expr.span, strs);
-
-                    let hir_expr = if fields.len() == 0 {
-                        expr_path(lctx,
-                                  structpath,
-                                  ast_expr.attrs.clone())
-                    } else {
-                        expr_struct(lctx,
-                                    ast_expr.span,
-                                    structpath,
-                                    fields.into_iter().map(|&(s, e)| {
-                                        field(token::intern(s),
-                                              signal_block_expr(lctx,
-                                                                hir_vec![],
-                                                                lower_expr(lctx, &**e),
-                                                                e.span,
-                                                                hir::PopUnstableBlock,
-                                                                None),
-                                              ast_expr.span)
-                                    }).collect(),
-                                    None,
-                                    ast_expr.attrs.clone())
-                    };
-
-                    signal_block_expr(lctx,
-                                      hir_vec![],
-                                      hir_expr,
-                                      ast_expr.span,
-                                      hir::PushUnstableBlock,
-                                      None)
-                }
-
-                return cache_ids(lctx, e.id, |lctx| {
-                    use syntax::ast::RangeLimits::*;
-
-                    match (e1, e2, lims) {
-                        (&None,         &None,         HalfOpen) =>
-                            make_struct(lctx, e, &["RangeFull"],
-                                                 &[]),
-
-                        (&Some(ref e1), &None,         HalfOpen) =>
-                            make_struct(lctx, e, &["RangeFrom"],
-                                                 &[("start", e1)]),
-
-                        (&None,         &Some(ref e2), HalfOpen) =>
-                            make_struct(lctx, e, &["RangeTo"],
-                                                 &[("end", e2)]),
-
-                        (&Some(ref e1), &Some(ref e2), HalfOpen) =>
-                            make_struct(lctx, e, &["Range"],
-                                                 &[("start", e1), ("end", e2)]),
-
-                        (&None,         &Some(ref e2), Closed)   =>
-                            make_struct(lctx, e, &["RangeToInclusive"],
-                                                 &[("end", e2)]),
-
-                        (&Some(ref e1), &Some(ref e2), Closed)   =>
-                            make_struct(lctx, e, &["RangeInclusive", "NonEmpty"],
-                                                 &[("start", e1), ("end", e2)]),
-
-                        _ => panic!(lctx.diagnostic().span_fatal(e.span,
-                                                                 "inclusive range with no end"))
-                    }
-                });
-            }
-            ExprKind::Path(ref qself, ref path) => {
-                let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
-                    hir::QSelf {
-                        ty: lower_ty(lctx, ty),
-                        position: position,
-                    }
-                });
-                hir::ExprPath(hir_qself, lower_path_full(lctx, path, qself.is_none()))
-            }
-            ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| {
-                respan(sp_ident.span, lower_ident(lctx, sp_ident.node))
-            })),
-            ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| {
-                respan(sp_ident.span, lower_ident(lctx, sp_ident.node))
-            })),
-            ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(lctx, x))),
-            ExprKind::InlineAsm(InlineAsm {
-                    ref inputs,
-                    ref outputs,
-                    ref asm,
-                    asm_str_style,
-                    ref clobbers,
-                    volatile,
-                    alignstack,
-                    dialect,
-                    expn_id,
-                }) => hir::ExprInlineAsm(hir::InlineAsm {
-                inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
-                outputs: outputs.iter()
-                                .map(|out| {
-                                    hir::InlineAsmOutput {
-                                        constraint: out.constraint.clone(),
-                                        is_rw: out.is_rw,
-                                        is_indirect: out.is_indirect,
-                                    }
-                                })
-                                .collect(),
-                asm: asm.clone(),
-                asm_str_style: asm_str_style,
-                clobbers: clobbers.clone().into(),
-                volatile: volatile,
-                alignstack: alignstack,
-                dialect: dialect,
-                expn_id: expn_id,
-            }, outputs.iter().map(|out| lower_expr(lctx, &out.expr)).collect(),
-               inputs.iter().map(|&(_, ref input)| lower_expr(lctx, input)).collect()),
-            ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
-                hir::ExprStruct(lower_path(lctx, path),
-                                fields.iter().map(|x| lower_field(lctx, x)).collect(),
-                                maybe_expr.as_ref().map(|x| lower_expr(lctx, x)))
-            }
-            ExprKind::Paren(ref ex) => {
-                // merge attributes into the inner expression.
-                return lower_expr(lctx, ex).map(|mut ex| {
-                    ex.attrs.update(|attrs| {
-                        attrs.prepend(e.attrs.clone())
-                    });
-                    ex
-                });
-            }
-
-            // Desugar ExprIfLet
-            // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
-            ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => {
-                // to:
-                //
-                //   match <sub_expr> {
-                //     <pat> => <body>,
-                //     [_ if <else_opt_if_cond> => <else_opt_if_body>,]
-                //     _ => [<else_opt> | ()]
-                //   }
-
-                return cache_ids(lctx, e.id, |lctx| {
-                    // `<pat> => <body>`
-                    let pat_arm = {
-                        let body = lower_block(lctx, body);
-                        let body_expr = expr_block(lctx, body, None);
-                        arm(hir_vec![lower_pat(lctx, pat)], body_expr)
-                    };
-
-                    // `[_ if <else_opt_if_cond> => <else_opt_if_body>,]`
-                    let mut else_opt = else_opt.as_ref().map(|e| lower_expr(lctx, e));
-                    let else_if_arms = {
-                        let mut arms = vec![];
-                        loop {
-                            let else_opt_continue = else_opt.and_then(|els| {
-                                els.and_then(|els| {
-                                    match els.node {
-                                        // else if
-                                        hir::ExprIf(cond, then, else_opt) => {
-                                            let pat_under = pat_wild(lctx, e.span);
-                                            arms.push(hir::Arm {
-                                                attrs: hir_vec![],
-                                                pats: hir_vec![pat_under],
-                                                guard: Some(cond),
-                                                body: expr_block(lctx, then, None),
-                                            });
-                                            else_opt.map(|else_opt| (else_opt, true))
-                                        }
-                                        _ => Some((P(els), false)),
-                                    }
-                                })
-                            });
-                            match else_opt_continue {
-                                Some((e, true)) => {
-                                    else_opt = Some(e);
-                                }
-                                Some((e, false)) => {
-                                    else_opt = Some(e);
-                                    break;
-                                }
-                                None => {
-                                    else_opt = None;
-                                    break;
-                                }
-                            }
-                        }
-                        arms
-                    };
-
-                    let contains_else_clause = else_opt.is_some();
-
-                    // `_ => [<else_opt> | ()]`
-                    let else_arm = {
-                        let pat_under = pat_wild(lctx, e.span);
-                        let else_expr =
-                            else_opt.unwrap_or_else(
-                                || expr_tuple(lctx, e.span, hir_vec![], None));
-                        arm(hir_vec![pat_under], else_expr)
-                    };
-
-                    let mut arms = Vec::with_capacity(else_if_arms.len() + 2);
-                    arms.push(pat_arm);
-                    arms.extend(else_if_arms);
-                    arms.push(else_arm);
-
-                    let sub_expr = lower_expr(lctx, sub_expr);
-                    // add attributes to the outer returned expr node
-                    expr(lctx,
-                         e.span,
-                         hir::ExprMatch(sub_expr,
-                                        arms.into(),
-                                        hir::MatchSource::IfLetDesugar {
-                                            contains_else_clause: contains_else_clause,
-                                        }),
-                         e.attrs.clone())
-                });
-            }
-
-            // Desugar ExprWhileLet
-            // From: `[opt_ident]: while let <pat> = <sub_expr> <body>`
-            ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => {
-                // to:
-                //
-                //   [opt_ident]: loop {
-                //     match <sub_expr> {
-                //       <pat> => <body>,
-                //       _ => break
-                //     }
-                //   }
-
-                return cache_ids(lctx, e.id, |lctx| {
-                    // `<pat> => <body>`
-                    let pat_arm = {
-                        let body = lower_block(lctx, body);
-                        let body_expr = expr_block(lctx, body, None);
-                        arm(hir_vec![lower_pat(lctx, pat)], body_expr)
-                    };
-
-                    // `_ => break`
-                    let break_arm = {
-                        let pat_under = pat_wild(lctx, e.span);
-                        let break_expr = expr_break(lctx, e.span, None);
-                        arm(hir_vec![pat_under], break_expr)
-                    };
-
-                    // `match <sub_expr> { ... }`
-                    let arms = hir_vec![pat_arm, break_arm];
-                    let sub_expr = lower_expr(lctx, sub_expr);
-                    let match_expr = expr(lctx,
-                                          e.span,
-                                          hir::ExprMatch(sub_expr,
-                                                         arms,
-                                                         hir::MatchSource::WhileLetDesugar),
-                                          None);
-
-                    // `[opt_ident]: loop { ... }`
-                    let loop_block = block_expr(lctx, match_expr);
-                    let loop_expr = hir::ExprLoop(loop_block,
-                                                  opt_ident.map(|ident| lower_ident(lctx, ident)));
-                    // add attributes to the outer returned expr node
-                    expr(lctx, e.span, loop_expr, e.attrs.clone())
-                });
-            }
-
-            // Desugar ExprForLoop
-            // From: `[opt_ident]: for <pat> in <head> <body>`
-            ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => {
-                // to:
-                //
-                //   {
-                //     let result = match ::std::iter::IntoIterator::into_iter(<head>) {
-                //       mut iter => {
-                //         [opt_ident]: loop {
-                //           match ::std::iter::Iterator::next(&mut iter) {
-                //             ::std::option::Option::Some(<pat>) => <body>,
-                //             ::std::option::Option::None => break
-                //           }
-                //         }
-                //       }
-                //     };
-                //     result
-                //   }
-
-                return cache_ids(lctx, e.id, |lctx| {
-                    // expand <head>
-                    let head = lower_expr(lctx, head);
-
-                    let iter = lctx.str_to_ident("iter");
-
-                    // `::std::option::Option::Some(<pat>) => <body>`
-                    let pat_arm = {
-                        let body_block = lower_block(lctx, body);
-                        let body_span = body_block.span;
-                        let body_expr = P(hir::Expr {
-                            id: lctx.next_id(),
-                            node: hir::ExprBlock(body_block),
-                            span: body_span,
-                            attrs: None,
-                        });
-                        let pat = lower_pat(lctx, pat);
-                        let some_pat = pat_some(lctx, e.span, pat);
-
-                        arm(hir_vec![some_pat], body_expr)
-                    };
-
-                    // `::std::option::Option::None => break`
-                    let break_arm = {
-                        let break_expr = expr_break(lctx, e.span, None);
-
-                        arm(hir_vec![pat_none(lctx, e.span)], break_expr)
-                    };
-
-                    // `match ::std::iter::Iterator::next(&mut iter) { ... }`
-                    let match_expr = {
-                        let next_path = {
-                            let strs = std_path(lctx, &["iter", "Iterator", "next"]);
-
-                            path_global(e.span, strs)
-                        };
-                        let iter = expr_ident(lctx, e.span, iter, None);
-                        let ref_mut_iter = expr_mut_addr_of(lctx, e.span, iter, None);
-                        let next_path = expr_path(lctx, next_path, None);
-                        let next_expr = expr_call(lctx,
-                                                  e.span,
-                                                  next_path,
-                                                  hir_vec![ref_mut_iter],
-                                                  None);
-                        let arms = hir_vec![pat_arm, break_arm];
-
-                        expr(lctx,
-                             e.span,
-                             hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
-                             None)
-                    };
-
-                    // `[opt_ident]: loop { ... }`
-                    let loop_block = block_expr(lctx, match_expr);
-                    let loop_expr = hir::ExprLoop(loop_block,
-                                                  opt_ident.map(|ident| lower_ident(lctx, ident)));
-                    let loop_expr = expr(lctx, e.span, loop_expr, None);
-
-                    // `mut iter => { ... }`
-                    let iter_arm = {
-                        let iter_pat = pat_ident_binding_mode(lctx,
-                                                              e.span,
-                                                              iter,
-                                                              hir::BindByValue(hir::MutMutable));
-                        arm(hir_vec![iter_pat], loop_expr)
-                    };
-
-                    // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
-                    let into_iter_expr = {
-                        let into_iter_path = {
-                            let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]);
-
-                            path_global(e.span, strs)
-                        };
-
-                        let into_iter = expr_path(lctx, into_iter_path, None);
-                        expr_call(lctx, e.span, into_iter, hir_vec![head], None)
-                    };
-
-                    let match_expr = expr_match(lctx,
-                                                e.span,
-                                                into_iter_expr,
-                                                hir_vec![iter_arm],
-                                                hir::MatchSource::ForLoopDesugar,
-                                                None);
-
-                    // `{ let _result = ...; _result }`
-                    // underscore prevents an unused_variables lint if the head diverges
-                    let result_ident = lctx.str_to_ident("_result");
-                    let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None);
-                    let result = expr_ident(lctx, e.span, result_ident, None);
-                    let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result));
-                    // add the attributes to the outer returned expr node
-                    expr_block(lctx, block, e.attrs.clone())
-                });
-            }
-
-            // Desugar ExprKind::Try
-            // From: `<expr>?`
-            ExprKind::Try(ref sub_expr) => {
-                // to:
-                //
-                // {
-                //     match <expr> {
-                //         Ok(val) => val,
-                //         Err(err) => {
-                //             return Err(From::from(err))
-                //         }
-                //     }
-                // }
-
-                return cache_ids(lctx, e.id, |lctx| {
-                    // expand <expr>
-                    let sub_expr = lower_expr(lctx, sub_expr);
-
-                    // Ok(val) => val
-                    let ok_arm = {
-                        let val_ident = lctx.str_to_ident("val");
-                        let val_pat = pat_ident(lctx, e.span, val_ident);
-                        let val_expr = expr_ident(lctx, e.span, val_ident, None);
-                        let ok_pat = pat_ok(lctx, e.span, val_pat);
-
-                        arm(hir_vec![ok_pat], val_expr)
-                    };
-
-                    // Err(err) => return Err(From::from(err))
-                    let err_arm = {
-                        let err_ident = lctx.str_to_ident("err");
-                        let from_expr = {
-                            let path = std_path(lctx, &["convert", "From", "from"]);
-                            let path = path_global(e.span, path);
-                            let from = expr_path(lctx, path, None);
-                            let err_expr = expr_ident(lctx, e.span, err_ident, None);
-
-                            expr_call(lctx, e.span, from, hir_vec![err_expr], None)
-                        };
-                        let err_expr = {
-                            let path = std_path(lctx, &["result", "Result", "Err"]);
-                            let path = path_global(e.span, path);
-                            let err_ctor = expr_path(lctx, path, None);
-                            expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None)
-                        };
-                        let err_pat = pat_err(lctx, e.span, pat_ident(lctx, e.span, err_ident));
-                        let ret_expr = expr(lctx, e.span,
-                                            hir::Expr_::ExprRet(Some(err_expr)), None);
-
-                        arm(hir_vec![err_pat], ret_expr)
-                    };
-
-                    expr_match(lctx, e.span, sub_expr, hir_vec![err_arm, ok_arm],
-                               hir::MatchSource::TryDesugar, None)
-                })
-            }
-
-            ExprKind::Mac(_) => panic!("Shouldn't exist here"),
-        },
-        span: e.span,
-        attrs: e.attrs.clone(),
-    })
-}
-
-pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> hir::Stmt {
-    match s.node {
-        StmtKind::Decl(ref d, id) => {
-            Spanned {
-                node: hir::StmtDecl(lower_decl(lctx, d), id),
-                span: s.span,
-            }
-        }
-        StmtKind::Expr(ref e, id) => {
-            Spanned {
-                node: hir::StmtExpr(lower_expr(lctx, e), id),
-                span: s.span,
-            }
-        }
-        StmtKind::Semi(ref e, id) => {
-            Spanned {
-                node: hir::StmtSemi(lower_expr(lctx, e), id),
-                span: s.span,
-            }
-        }
-        StmtKind::Mac(..) => panic!("Shouldn't exist here"),
-    }
-}
-
-pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureBy) -> hir::CaptureClause {
-    match c {
-        CaptureBy::Value => hir::CaptureByValue,
-        CaptureBy::Ref => hir::CaptureByRef,
-    }
-}
-
-pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibility {
-    match *v {
-        Visibility::Public => hir::Public,
-        Visibility::Inherited => hir::Inherited,
-        _ => panic!(lctx.diagnostic().fatal("pub(restricted) is not implemented yet!"))
-    }
-}
-
-pub fn lower_defaultness(_lctx: &LoweringContext, d: Defaultness) -> hir::Defaultness {
-    match d {
-        Defaultness::Default => hir::Defaultness::Default,
-        Defaultness::Final => hir::Defaultness::Final,
-    }
-}
-
-pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode {
-    match *b {
-        BlockCheckMode::Default => hir::DefaultBlock,
-        BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)),
-    }
-}
-
-pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode {
-    match *b {
-        BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)),
-        BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)),
-    }
-}
-
-pub fn lower_unsafe_source(_lctx: &LoweringContext, u: UnsafeSource) -> hir::UnsafeSource {
-    match u {
-        CompilerGenerated => hir::CompilerGenerated,
-        UserProvided => hir::UserProvided,
-    }
-}
-
-pub fn lower_impl_polarity(_lctx: &LoweringContext, i: ImplPolarity) -> hir::ImplPolarity {
-    match i {
-        ImplPolarity::Positive => hir::ImplPolarity::Positive,
-        ImplPolarity::Negative => hir::ImplPolarity::Negative,
-    }
-}
-
-pub fn lower_trait_bound_modifier(_lctx: &LoweringContext,
-                                  f: TraitBoundModifier)
-                                  -> hir::TraitBoundModifier {
-    match f {
-        TraitBoundModifier::None => hir::TraitBoundModifier::None,
-        TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
-    }
-}
-
-// Helper methods for building HIR.
-
-fn arm(pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
-    hir::Arm {
-        attrs: hir_vec![],
-        pats: pats,
-        guard: None,
-        body: expr,
-    }
-}
-
-fn field(name: Name, expr: P<hir::Expr>, span: Span) -> hir::Field {
-    hir::Field {
-        name: Spanned {
-            node: name,
-            span: span,
-        },
-        span: span,
-        expr: expr,
-    }
-}
-
-fn expr_break(lctx: &LoweringContext, span: Span,
-              attrs: ThinAttributes) -> P<hir::Expr> {
-    expr(lctx, span, hir::ExprBreak(None), attrs)
-}
-
-fn expr_call(lctx: &LoweringContext,
-             span: Span,
-             e: P<hir::Expr>,
-             args: hir::HirVec<P<hir::Expr>>,
-             attrs: ThinAttributes)
-             -> P<hir::Expr> {
-    expr(lctx, span, hir::ExprCall(e, args), attrs)
-}
-
-fn expr_ident(lctx: &LoweringContext, span: Span, id: hir::Ident,
-              attrs: ThinAttributes) -> P<hir::Expr> {
-    expr_path(lctx, path_ident(span, id), attrs)
-}
-
-fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P<hir::Expr>,
-                    attrs: ThinAttributes) -> P<hir::Expr> {
-    expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs)
-}
-
-fn expr_path(lctx: &LoweringContext, path: hir::Path,
-             attrs: ThinAttributes) -> P<hir::Expr> {
-    expr(lctx, path.span, hir::ExprPath(None, path), attrs)
-}
-
-fn expr_match(lctx: &LoweringContext,
-              span: Span,
-              arg: P<hir::Expr>,
-              arms: hir::HirVec<hir::Arm>,
-              source: hir::MatchSource,
-              attrs: ThinAttributes)
-              -> P<hir::Expr> {
-    expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs)
-}
-
-fn expr_block(lctx: &LoweringContext, b: P<hir::Block>,
-              attrs: ThinAttributes) -> P<hir::Expr> {
-    expr(lctx, b.span, hir::ExprBlock(b), attrs)
-}
-
-fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec<P<hir::Expr>>,
-              attrs: ThinAttributes) -> P<hir::Expr> {
-    expr(lctx, sp, hir::ExprTup(exprs), attrs)
-}
-
-fn expr_struct(lctx: &LoweringContext,
-               sp: Span,
-               path: hir::Path,
-               fields: hir::HirVec<hir::Field>,
-               e: Option<P<hir::Expr>>,
-               attrs: ThinAttributes) -> P<hir::Expr> {
-    expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs)
-}
-
-fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_,
-        attrs: ThinAttributes) -> P<hir::Expr> {
-    P(hir::Expr {
-        id: lctx.next_id(),
-        node: node,
-        span: span,
-        attrs: attrs,
-    })
-}
-
-fn stmt_let(lctx: &LoweringContext,
-            sp: Span,
-            mutbl: bool,
-            ident: hir::Ident,
-            ex: P<hir::Expr>,
-            attrs: ThinAttributes)
-            -> hir::Stmt {
-    let pat = if mutbl {
-        pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable))
-    } else {
-        pat_ident(lctx, sp, ident)
-    };
-    let local = P(hir::Local {
-        pat: pat,
-        ty: None,
-        init: Some(ex),
-        id: lctx.next_id(),
-        span: sp,
-        attrs: attrs,
-    });
-    let decl = respan(sp, hir::DeclLocal(local));
-    respan(sp, hir::StmtDecl(P(decl), lctx.next_id()))
-}
-
-fn block_expr(lctx: &LoweringContext, expr: P<hir::Expr>) -> P<hir::Block> {
-    block_all(lctx, expr.span, hir::HirVec::new(), Some(expr))
-}
-
-fn block_all(lctx: &LoweringContext,
-             span: Span,
-             stmts: hir::HirVec<hir::Stmt>,
-             expr: Option<P<hir::Expr>>)
-             -> P<hir::Block> {
-    P(hir::Block {
-        stmts: stmts,
-        expr: expr,
-        id: lctx.next_id(),
-        rules: hir::DefaultBlock,
-        span: span,
-    })
-}
-
-fn pat_ok(lctx: &LoweringContext, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-    let ok = std_path(lctx, &["result", "Result", "Ok"]);
-    let path = path_global(span, ok);
-    pat_enum(lctx, span, path, hir_vec![pat])
-}
-
-fn pat_err(lctx: &LoweringContext, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-    let err = std_path(lctx, &["result", "Result", "Err"]);
-    let path = path_global(span, err);
-    pat_enum(lctx, span, path, hir_vec![pat])
-}
-
-fn pat_some(lctx: &LoweringContext, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
-    let some = std_path(lctx, &["option", "Option", "Some"]);
-    let path = path_global(span, some);
-    pat_enum(lctx, span, path, hir_vec![pat])
-}
-
-fn pat_none(lctx: &LoweringContext, span: Span) -> P<hir::Pat> {
-    let none = std_path(lctx, &["option", "Option", "None"]);
-    let path = path_global(span, none);
-    pat_enum(lctx, span, path, hir_vec![])
-}
-
-fn pat_enum(lctx: &LoweringContext,
-            span: Span,
-            path: hir::Path,
-            subpats: hir::HirVec<P<hir::Pat>>)
-            -> P<hir::Pat> {
-    let pt = if subpats.is_empty() {
-        hir::PatKind::Path(path)
-    } else {
-        hir::PatKind::TupleStruct(path, Some(subpats))
-    };
-    pat(lctx, span, pt)
-}
-
-fn pat_ident(lctx: &LoweringContext, span: Span, ident: hir::Ident) -> P<hir::Pat> {
-    pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable))
-}
-
-fn pat_ident_binding_mode(lctx: &LoweringContext,
-                          span: Span,
-                          ident: hir::Ident,
-                          bm: hir::BindingMode)
-                          -> P<hir::Pat> {
-    let pat_ident = hir::PatKind::Ident(bm,
-                                  Spanned {
-                                      span: span,
-                                      node: ident,
-                                  },
-                                  None);
-    pat(lctx, span, pat_ident)
-}
-
-fn pat_wild(lctx: &LoweringContext, span: Span) -> P<hir::Pat> {
-    pat(lctx, span, hir::PatKind::Wild)
-}
-
-fn pat(lctx: &LoweringContext, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
-    P(hir::Pat {
-        id: lctx.next_id(),
-        node: pat,
-        span: span,
-    })
-}
-
-fn path_ident(span: Span, id: hir::Ident) -> hir::Path {
-    path(span, vec![id])
-}
-
-fn path(span: Span, strs: Vec<hir::Ident>) -> hir::Path {
-    path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
-}
-
-fn path_global(span: Span, strs: Vec<hir::Ident>) -> hir::Path {
-    path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
-}
-
-fn path_all(sp: Span,
-            global: bool,
-            mut idents: Vec<hir::Ident>,
-            lifetimes: hir::HirVec<hir::Lifetime>,
-            types: hir::HirVec<P<hir::Ty>>,
-            bindings: hir::HirVec<hir::TypeBinding>)
-            -> hir::Path {
-    let last_identifier = idents.pop().unwrap();
-    let mut segments: Vec<hir::PathSegment> = idents.into_iter()
-                                                    .map(|ident| {
-                                                        hir::PathSegment {
-                                                            identifier: ident,
-                                                            parameters: hir::PathParameters::none(),
-                                                        }
-                                                    })
-                                                    .collect();
-    segments.push(hir::PathSegment {
-        identifier: last_identifier,
-        parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
-            lifetimes: lifetimes,
-            types: types,
-            bindings: bindings,
-        }),
-    });
-    hir::Path {
-        span: sp,
-        global: global,
-        segments: segments.into(),
-    }
-}
-
-fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec<hir::Ident> {
-    let mut v = Vec::new();
-    if let Some(s) = lctx.crate_root {
-        v.push(hir::Ident::from_name(token::intern(s)));
-    }
-    v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s))));
-    return v;
-}
-
-// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
-// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
-fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Path {
-    let idents = std_path(lctx, components);
-    path_global(span, idents)
-}
-
-fn signal_block_expr(lctx: &LoweringContext,
-                     stmts: hir::HirVec<hir::Stmt>,
-                     expr: P<hir::Expr>,
-                     span: Span,
-                     rule: hir::BlockCheckMode,
-                     attrs: ThinAttributes)
-                     -> P<hir::Expr> {
-    let id = lctx.next_id();
-    expr_block(lctx,
-               P(hir::Block {
-                   rules: rule,
-                   span: span,
-                   id: id,
-                   stmts: stmts,
-                   expr: Some(expr),
-               }),
-               attrs)
-}
-
-
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use syntax::ast::{self, NodeId, NodeIdAssigner};
-    use syntax::{parse, codemap};
-    use syntax::fold::Folder;
-    use std::cell::Cell;
-
-    struct MockAssigner {
-        next_id: Cell<NodeId>,
-    }
-
-    impl MockAssigner {
-        fn new() -> MockAssigner {
-            MockAssigner { next_id: Cell::new(0) }
-        }
-    }
-
-    trait FakeExtCtxt {
-        fn call_site(&self) -> codemap::Span;
-        fn cfg(&self) -> ast::CrateConfig;
-        fn ident_of(&self, st: &str) -> ast::Ident;
-        fn name_of(&self, st: &str) -> ast::Name;
-        fn parse_sess(&self) -> &parse::ParseSess;
-    }
-
-    impl FakeExtCtxt for parse::ParseSess {
-        fn call_site(&self) -> codemap::Span {
-            codemap::Span {
-                lo: codemap::BytePos(0),
-                hi: codemap::BytePos(0),
-                expn_id: codemap::NO_EXPANSION,
-            }
-        }
-        fn cfg(&self) -> ast::CrateConfig {
-            Vec::new()
-        }
-        fn ident_of(&self, st: &str) -> ast::Ident {
-            parse::token::str_to_ident(st)
-        }
-        fn name_of(&self, st: &str) -> ast::Name {
-            parse::token::intern(st)
-        }
-        fn parse_sess(&self) -> &parse::ParseSess {
-            self
-        }
-    }
-
-    impl NodeIdAssigner for MockAssigner {
-        fn next_node_id(&self) -> NodeId {
-            let result = self.next_id.get();
-            self.next_id.set(result + 1);
-            result
-        }
-
-        fn peek_node_id(&self) -> NodeId {
-            self.next_id.get()
-        }
-    }
-
-    impl Folder for MockAssigner {
-        fn new_id(&mut self, old_id: NodeId) -> NodeId {
-            assert_eq!(old_id, ast::DUMMY_NODE_ID);
-            self.next_node_id()
-        }
-    }
-
-    #[test]
-    fn test_preserves_ids() {
-        let cx = parse::ParseSess::new();
-        let mut assigner = MockAssigner::new();
-
-        let ast_if_let = quote_expr!(&cx,
-                                     if let Some(foo) = baz {
-                                         bar(foo);
-                                     });
-        let ast_if_let = assigner.fold_expr(ast_if_let);
-        let ast_while_let = quote_expr!(&cx,
-                                        while let Some(foo) = baz {
-                                            bar(foo);
-                                        });
-        let ast_while_let = assigner.fold_expr(ast_while_let);
-        let ast_for = quote_expr!(&cx,
-                                  for i in 0..10 {
-                                      for j in 0..10 {
-                                          foo(i, j);
-                                      }
-                                  });
-        let ast_for = assigner.fold_expr(ast_for);
-        let ast_in = quote_expr!(&cx, in HEAP { foo() });
-        let ast_in = assigner.fold_expr(ast_in);
-
-        let lctx = LoweringContext::new(&assigner, None);
-        let hir1 = lower_expr(&lctx, &ast_if_let);
-        let hir2 = lower_expr(&lctx, &ast_if_let);
-        assert!(hir1 == hir2);
-
-        let hir1 = lower_expr(&lctx, &ast_while_let);
-        let hir2 = lower_expr(&lctx, &ast_while_let);
-        assert!(hir1 == hir2);
-
-        let hir1 = lower_expr(&lctx, &ast_for);
-        let hir2 = lower_expr(&lctx, &ast_for);
-        assert!(hir1 == hir2);
-
-        let hir1 = lower_expr(&lctx, &ast_in);
-        let hir2 = lower_expr(&lctx, &ast_in);
-        assert!(hir1 == hir2);
-    }
-}
diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs
deleted file mode 100644
index 3b8e6763de0..00000000000
--- a/src/librustc_front/print/pprust.rs
+++ /dev/null
@@ -1,2413 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub use self::AnnNode::*;
-
-use syntax::abi::Abi;
-use syntax::ast;
-use syntax::codemap::{self, CodeMap, BytePos, Spanned};
-use syntax::errors;
-use syntax::parse::token::{self, BinOpToken};
-use syntax::parse::lexer::comments;
-use syntax::parse;
-use syntax::print::pp::{self, break_offset, word, space, hardbreak};
-use syntax::print::pp::{Breaks, eof};
-use syntax::print::pp::Breaks::{Consistent, Inconsistent};
-use syntax::print::pprust::{self as ast_pp, PrintState};
-use syntax::ptr::P;
-
-use hir;
-use hir::{Crate, PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
-
-use std::io::{self, Write, Read};
-
-pub enum AnnNode<'a> {
-    NodeName(&'a ast::Name),
-    NodeBlock(&'a hir::Block),
-    NodeItem(&'a hir::Item),
-    NodeSubItem(ast::NodeId),
-    NodeExpr(&'a hir::Expr),
-    NodePat(&'a hir::Pat),
-}
-
-pub trait PpAnn {
-    fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> {
-        Ok(())
-    }
-    fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-#[derive(Copy, Clone)]
-pub struct NoAnn;
-
-impl PpAnn for NoAnn {}
-
-
-pub struct State<'a> {
-    krate: Option<&'a Crate>,
-    pub s: pp::Printer<'a>,
-    cm: Option<&'a CodeMap>,
-    comments: Option<Vec<comments::Comment>>,
-    literals: Option<Vec<comments::Literal>>,
-    cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral,
-    boxes: Vec<pp::Breaks>,
-    ann: &'a (PpAnn + 'a),
-}
-
-impl<'a> PrintState<'a> for State<'a> {
-    fn writer(&mut self) -> &mut pp::Printer<'a> {
-        &mut self.s
-    }
-
-    fn boxes(&mut self) -> &mut Vec<pp::Breaks> {
-        &mut self.boxes
-    }
-
-    fn comments(&mut self) -> &mut Option<Vec<comments::Comment>> {
-        &mut self.comments
-    }
-
-    fn cur_cmnt_and_lit(&mut self) -> &mut ast_pp::CurrentCommentAndLiteral {
-        &mut self.cur_cmnt_and_lit
-    }
-
-    fn literals(&self) -> &Option<Vec<comments::Literal>> {
-        &self.literals
-    }
-}
-
-pub fn rust_printer<'a>(writer: Box<Write + 'a>, krate: Option<&'a Crate>) -> State<'a> {
-    static NO_ANN: NoAnn = NoAnn;
-    rust_printer_annotated(writer, &NO_ANN, krate)
-}
-
-pub fn rust_printer_annotated<'a>(writer: Box<Write + 'a>,
-                                  ann: &'a PpAnn,
-                                  krate: Option<&'a Crate>)
-                                  -> State<'a> {
-    State {
-        krate: krate,
-        s: pp::mk_printer(writer, default_columns),
-        cm: None,
-        comments: None,
-        literals: None,
-        cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral {
-            cur_cmnt: 0,
-            cur_lit: 0,
-        },
-        boxes: Vec::new(),
-        ann: ann,
-    }
-}
-
-#[allow(non_upper_case_globals)]
-pub const indent_unit: usize = 4;
-
-#[allow(non_upper_case_globals)]
-pub const default_columns: usize = 78;
-
-
-/// Requires you to pass an input filename and reader so that
-/// it can scan the input text for comments and literals to
-/// copy forward.
-pub fn print_crate<'a>(cm: &'a CodeMap,
-                       span_diagnostic: &errors::Handler,
-                       krate: &hir::Crate,
-                       filename: String,
-                       input: &mut Read,
-                       out: Box<Write + 'a>,
-                       ann: &'a PpAnn,
-                       is_expanded: bool)
-                       -> io::Result<()> {
-    let mut s = State::new_from_input(cm, span_diagnostic, filename, input,
-                                      out, ann, is_expanded, Some(krate));
-
-    // When printing the AST, we sometimes need to inject `#[no_std]` here.
-    // Since you can't compile the HIR, it's not necessary.
-
-    s.print_mod(&krate.module, &krate.attrs)?;
-    s.print_remaining_comments()?;
-    eof(&mut s.s)
-}
-
-impl<'a> State<'a> {
-    pub fn new_from_input(cm: &'a CodeMap,
-                          span_diagnostic: &errors::Handler,
-                          filename: String,
-                          input: &mut Read,
-                          out: Box<Write + 'a>,
-                          ann: &'a PpAnn,
-                          is_expanded: bool,
-                          krate: Option<&'a Crate>)
-                          -> State<'a> {
-        let (cmnts, lits) = comments::gather_comments_and_literals(span_diagnostic,
-                                                                   filename,
-                                                                   input);
-
-        State::new(cm,
-                   out,
-                   ann,
-                   Some(cmnts),
-                   // If the code is post expansion, don't use the table of
-                   // literals, since it doesn't correspond with the literals
-                   // in the AST anymore.
-                   if is_expanded {
-                       None
-                   } else {
-                       Some(lits)
-                   },
-                   krate)
-    }
-
-    pub fn new(cm: &'a CodeMap,
-               out: Box<Write + 'a>,
-               ann: &'a PpAnn,
-               comments: Option<Vec<comments::Comment>>,
-               literals: Option<Vec<comments::Literal>>,
-               krate: Option<&'a Crate>)
-               -> State<'a> {
-        State {
-            krate: krate,
-            s: pp::mk_printer(out, default_columns),
-            cm: Some(cm),
-            comments: comments.clone(),
-            literals: literals.clone(),
-            cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral {
-                cur_cmnt: 0,
-                cur_lit: 0,
-            },
-            boxes: Vec::new(),
-            ann: ann,
-        }
-    }
-}
-
-pub fn to_string<F>(f: F) -> String
-    where F: FnOnce(&mut State) -> io::Result<()>
-{
-    let mut wr = Vec::new();
-    {
-        let mut printer = rust_printer(Box::new(&mut wr), None);
-        f(&mut printer).unwrap();
-        eof(&mut printer.s).unwrap();
-    }
-    String::from_utf8(wr).unwrap()
-}
-
-pub fn binop_to_string(op: BinOpToken) -> &'static str {
-    match op {
-        token::Plus => "+",
-        token::Minus => "-",
-        token::Star => "*",
-        token::Slash => "/",
-        token::Percent => "%",
-        token::Caret => "^",
-        token::And => "&",
-        token::Or => "|",
-        token::Shl => "<<",
-        token::Shr => ">>",
-    }
-}
-
-pub fn ty_to_string(ty: &hir::Ty) -> String {
-    to_string(|s| s.print_type(ty))
-}
-
-pub fn bounds_to_string(bounds: &[hir::TyParamBound]) -> String {
-    to_string(|s| s.print_bounds("", bounds))
-}
-
-pub fn pat_to_string(pat: &hir::Pat) -> String {
-    to_string(|s| s.print_pat(pat))
-}
-
-pub fn arm_to_string(arm: &hir::Arm) -> String {
-    to_string(|s| s.print_arm(arm))
-}
-
-pub fn expr_to_string(e: &hir::Expr) -> String {
-    to_string(|s| s.print_expr(e))
-}
-
-pub fn lifetime_to_string(e: &hir::Lifetime) -> String {
-    to_string(|s| s.print_lifetime(e))
-}
-
-pub fn stmt_to_string(stmt: &hir::Stmt) -> String {
-    to_string(|s| s.print_stmt(stmt))
-}
-
-pub fn item_to_string(i: &hir::Item) -> String {
-    to_string(|s| s.print_item(i))
-}
-
-pub fn impl_item_to_string(i: &hir::ImplItem) -> String {
-    to_string(|s| s.print_impl_item(i))
-}
-
-pub fn trait_item_to_string(i: &hir::TraitItem) -> String {
-    to_string(|s| s.print_trait_item(i))
-}
-
-pub fn generics_to_string(generics: &hir::Generics) -> String {
-    to_string(|s| s.print_generics(generics))
-}
-
-pub fn where_clause_to_string(i: &hir::WhereClause) -> String {
-    to_string(|s| s.print_where_clause(i))
-}
-
-pub fn fn_block_to_string(p: &hir::FnDecl) -> String {
-    to_string(|s| s.print_fn_block_args(p))
-}
-
-pub fn path_to_string(p: &hir::Path) -> String {
-    to_string(|s| s.print_path(p, false, 0))
-}
-
-pub fn name_to_string(name: ast::Name) -> String {
-    to_string(|s| s.print_name(name))
-}
-
-pub fn fun_to_string(decl: &hir::FnDecl,
-                     unsafety: hir::Unsafety,
-                     constness: hir::Constness,
-                     name: ast::Name,
-                     opt_explicit_self: Option<&hir::ExplicitSelf_>,
-                     generics: &hir::Generics)
-                     -> String {
-    to_string(|s| {
-        s.head("")?;
-        s.print_fn(decl,
-                   unsafety,
-                   constness,
-                   Abi::Rust,
-                   Some(name),
-                   generics,
-                   opt_explicit_self,
-                   hir::Inherited)?;
-        s.end()?; // Close the head box
-        s.end() // Close the outer box
-    })
-}
-
-pub fn block_to_string(blk: &hir::Block) -> String {
-    to_string(|s| {
-        // containing cbox, will be closed by print-block at }
-        s.cbox(indent_unit)?;
-        // head-ibox, will be closed by print-block after {
-        s.ibox(0)?;
-        s.print_block(blk)
-    })
-}
-
-pub fn explicit_self_to_string(explicit_self: &hir::ExplicitSelf_) -> String {
-    to_string(|s| s.print_explicit_self(explicit_self, hir::MutImmutable).map(|_| {}))
-}
-
-pub fn variant_to_string(var: &hir::Variant) -> String {
-    to_string(|s| s.print_variant(var))
-}
-
-pub fn arg_to_string(arg: &hir::Arg) -> String {
-    to_string(|s| s.print_arg(arg, false))
-}
-
-pub fn visibility_qualified(vis: hir::Visibility, s: &str) -> String {
-    match vis {
-        hir::Public => format!("pub {}", s),
-        hir::Inherited => s.to_string(),
-    }
-}
-
-fn needs_parentheses(expr: &hir::Expr) -> bool {
-    match expr.node {
-        hir::ExprAssign(..) |
-        hir::ExprBinary(..) |
-        hir::ExprClosure(..) |
-        hir::ExprAssignOp(..) |
-        hir::ExprCast(..) |
-        hir::ExprType(..) => true,
-        _ => false,
-    }
-}
-
-impl<'a> State<'a> {
-    pub fn cbox(&mut self, u: usize) -> io::Result<()> {
-        self.boxes.push(pp::Breaks::Consistent);
-        pp::cbox(&mut self.s, u)
-    }
-
-    pub fn nbsp(&mut self) -> io::Result<()> {
-        word(&mut self.s, " ")
-    }
-
-    pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
-        word(&mut self.s, w)?;
-        self.nbsp()
-    }
-
-    pub fn head(&mut self, w: &str) -> io::Result<()> {
-        // outer-box is consistent
-        self.cbox(indent_unit)?;
-        // head-box is inconsistent
-        self.ibox(w.len() + 1)?;
-        // keyword that starts the head
-        if !w.is_empty() {
-            self.word_nbsp(w)?;
-        }
-        Ok(())
-    }
-
-    pub fn bopen(&mut self) -> io::Result<()> {
-        word(&mut self.s, "{")?;
-        self.end() // close the head-box
-    }
-
-    pub fn bclose_(&mut self, span: codemap::Span, indented: usize) -> io::Result<()> {
-        self.bclose_maybe_open(span, indented, true)
-    }
-    pub fn bclose_maybe_open(&mut self,
-                             span: codemap::Span,
-                             indented: usize,
-                             close_box: bool)
-                             -> io::Result<()> {
-        self.maybe_print_comment(span.hi)?;
-        self.break_offset_if_not_bol(1, -(indented as isize))?;
-        word(&mut self.s, "}")?;
-        if close_box {
-            self.end()?; // close the outer-box
-        }
-        Ok(())
-    }
-    pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
-        self.bclose_(span, indent_unit)
-    }
-
-    pub fn in_cbox(&self) -> bool {
-        match self.boxes.last() {
-            Some(&last_box) => last_box == pp::Breaks::Consistent,
-            None => false,
-        }
-    }
-    pub fn space_if_not_bol(&mut self) -> io::Result<()> {
-        if !self.is_bol() {
-            space(&mut self.s)?;
-        }
-        Ok(())
-    }
-    pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) -> io::Result<()> {
-        if !self.is_bol() {
-            break_offset(&mut self.s, n, off)
-        } else {
-            if off != 0 && self.s.last_token().is_hardbreak_tok() {
-                // We do something pretty sketchy here: tuck the nonzero
-                // offset-adjustment we were going to deposit along with the
-                // break into the previous hardbreak.
-                self.s.replace_last_token(pp::hardbreak_tok_offset(off));
-            }
-            Ok(())
-        }
-    }
-
-    // Synthesizes a comment that was not textually present in the original source
-    // file.
-    pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
-        word(&mut self.s, "/*")?;
-        space(&mut self.s)?;
-        word(&mut self.s, &text[..])?;
-        space(&mut self.s)?;
-        word(&mut self.s, "*/")
-    }
-
-
-    pub fn commasep_cmnt<T, F, G>(&mut self,
-                                  b: Breaks,
-                                  elts: &[T],
-                                  mut op: F,
-                                  mut get_span: G)
-                                  -> io::Result<()>
-        where F: FnMut(&mut State, &T) -> io::Result<()>,
-              G: FnMut(&T) -> codemap::Span
-    {
-        self.rbox(0, b)?;
-        let len = elts.len();
-        let mut i = 0;
-        for elt in elts {
-            self.maybe_print_comment(get_span(elt).hi)?;
-            op(self, elt)?;
-            i += 1;
-            if i < len {
-                word(&mut self.s, ",")?;
-                self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi))?;
-                self.space_if_not_bol()?;
-            }
-        }
-        self.end()
-    }
-
-    pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<hir::Expr>]) -> io::Result<()> {
-        self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span)
-    }
-
-    pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> {
-        self.print_inner_attributes(attrs)?;
-        for item_id in &_mod.item_ids {
-            self.print_item_id(item_id)?;
-        }
-        Ok(())
-    }
-
-    pub fn print_foreign_mod(&mut self,
-                             nmod: &hir::ForeignMod,
-                             attrs: &[ast::Attribute])
-                             -> io::Result<()> {
-        self.print_inner_attributes(attrs)?;
-        for item in &nmod.items {
-            self.print_foreign_item(item)?;
-        }
-        Ok(())
-    }
-
-    pub fn print_opt_lifetime(&mut self, lifetime: &Option<hir::Lifetime>) -> io::Result<()> {
-        if let Some(l) = *lifetime {
-            self.print_lifetime(&l)?;
-            self.nbsp()?;
-        }
-        Ok(())
-    }
-
-    pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
-        self.maybe_print_comment(ty.span.lo)?;
-        self.ibox(0)?;
-        match ty.node {
-            hir::TyVec(ref ty) => {
-                word(&mut self.s, "[")?;
-                self.print_type(&ty)?;
-                word(&mut self.s, "]")?;
-            }
-            hir::TyPtr(ref mt) => {
-                word(&mut self.s, "*")?;
-                match mt.mutbl {
-                    hir::MutMutable => self.word_nbsp("mut")?,
-                    hir::MutImmutable => self.word_nbsp("const")?,
-                }
-                self.print_type(&mt.ty)?;
-            }
-            hir::TyRptr(ref lifetime, ref mt) => {
-                word(&mut self.s, "&")?;
-                self.print_opt_lifetime(lifetime)?;
-                self.print_mt(mt)?;
-            }
-            hir::TyTup(ref elts) => {
-                self.popen()?;
-                self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty))?;
-                if elts.len() == 1 {
-                    word(&mut self.s, ",")?;
-                }
-                self.pclose()?;
-            }
-            hir::TyBareFn(ref f) => {
-                let generics = hir::Generics {
-                    lifetimes: f.lifetimes.clone(),
-                    ty_params: hir::HirVec::new(),
-                    where_clause: hir::WhereClause {
-                        id: ast::DUMMY_NODE_ID,
-                        predicates: hir::HirVec::new(),
-                    },
-                };
-                self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics, None)?;
-            }
-            hir::TyPath(None, ref path) => {
-                self.print_path(path, false, 0)?;
-            }
-            hir::TyPath(Some(ref qself), ref path) => {
-                self.print_qpath(path, qself, false)?
-            }
-            hir::TyObjectSum(ref ty, ref bounds) => {
-                self.print_type(&ty)?;
-                self.print_bounds("+", &bounds[..])?;
-            }
-            hir::TyPolyTraitRef(ref bounds) => {
-                self.print_bounds("", &bounds[..])?;
-            }
-            hir::TyFixedLengthVec(ref ty, ref v) => {
-                word(&mut self.s, "[")?;
-                self.print_type(&ty)?;
-                word(&mut self.s, "; ")?;
-                self.print_expr(&v)?;
-                word(&mut self.s, "]")?;
-            }
-            hir::TyTypeof(ref e) => {
-                word(&mut self.s, "typeof(")?;
-                self.print_expr(&e)?;
-                word(&mut self.s, ")")?;
-            }
-            hir::TyInfer => {
-                word(&mut self.s, "_")?;
-            }
-        }
-        self.end()
-    }
-
-    pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()> {
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(item.span.lo)?;
-        self.print_outer_attributes(&item.attrs)?;
-        match item.node {
-            hir::ForeignItemFn(ref decl, ref generics) => {
-                self.head("")?;
-                self.print_fn(decl,
-                              hir::Unsafety::Normal,
-                              hir::Constness::NotConst,
-                              Abi::Rust,
-                              Some(item.name),
-                              generics,
-                              None,
-                              item.vis)?;
-                self.end()?; // end head-ibox
-                word(&mut self.s, ";")?;
-                self.end() // end the outer fn box
-            }
-            hir::ForeignItemStatic(ref t, m) => {
-                self.head(&visibility_qualified(item.vis, "static"))?;
-                if m {
-                    self.word_space("mut")?;
-                }
-                self.print_name(item.name)?;
-                self.word_space(":")?;
-                self.print_type(&t)?;
-                word(&mut self.s, ";")?;
-                self.end()?; // end the head-ibox
-                self.end() // end the outer cbox
-            }
-        }
-    }
-
-    fn print_associated_const(&mut self,
-                              name: ast::Name,
-                              ty: &hir::Ty,
-                              default: Option<&hir::Expr>,
-                              vis: hir::Visibility)
-                              -> io::Result<()> {
-        word(&mut self.s, &visibility_qualified(vis, ""))?;
-        self.word_space("const")?;
-        self.print_name(name)?;
-        self.word_space(":")?;
-        self.print_type(ty)?;
-        if let Some(expr) = default {
-            space(&mut self.s)?;
-            self.word_space("=")?;
-            self.print_expr(expr)?;
-        }
-        word(&mut self.s, ";")
-    }
-
-    fn print_associated_type(&mut self,
-                             name: ast::Name,
-                             bounds: Option<&hir::TyParamBounds>,
-                             ty: Option<&hir::Ty>)
-                             -> io::Result<()> {
-        self.word_space("type")?;
-        self.print_name(name)?;
-        if let Some(bounds) = bounds {
-            self.print_bounds(":", bounds)?;
-        }
-        if let Some(ty) = ty {
-            space(&mut self.s)?;
-            self.word_space("=")?;
-            self.print_type(ty)?;
-        }
-        word(&mut self.s, ";")
-    }
-
-    pub fn print_item_id(&mut self, item_id: &hir::ItemId) -> io::Result<()> {
-        if let Some(krate) = self.krate {
-            // skip nested items if krate context was not provided
-            let item = &krate.items[&item_id.id];
-            self.print_item(item)
-        } else {
-            Ok(())
-        }
-    }
-
-    /// Pretty-print an item
-    pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(item.span.lo)?;
-        self.print_outer_attributes(&item.attrs)?;
-        self.ann.pre(self, NodeItem(item))?;
-        match item.node {
-            hir::ItemExternCrate(ref optional_path) => {
-                self.head(&visibility_qualified(item.vis, "extern crate"))?;
-                if let Some(p) = *optional_path {
-                    let val = p.as_str();
-                    if val.contains("-") {
-                        self.print_string(&val, ast::StrStyle::Cooked)?;
-                    } else {
-                        self.print_name(p)?;
-                    }
-                    space(&mut self.s)?;
-                    word(&mut self.s, "as")?;
-                    space(&mut self.s)?;
-                }
-                self.print_name(item.name)?;
-                word(&mut self.s, ";")?;
-                self.end()?; // end inner head-block
-                self.end()?; // end outer head-block
-            }
-            hir::ItemUse(ref vp) => {
-                self.head(&visibility_qualified(item.vis, "use"))?;
-                self.print_view_path(&vp)?;
-                word(&mut self.s, ";")?;
-                self.end()?; // end inner head-block
-                self.end()?; // end outer head-block
-            }
-            hir::ItemStatic(ref ty, m, ref expr) => {
-                self.head(&visibility_qualified(item.vis, "static"))?;
-                if m == hir::MutMutable {
-                    self.word_space("mut")?;
-                }
-                self.print_name(item.name)?;
-                self.word_space(":")?;
-                self.print_type(&ty)?;
-                space(&mut self.s)?;
-                self.end()?; // end the head-ibox
-
-                self.word_space("=")?;
-                self.print_expr(&expr)?;
-                word(&mut self.s, ";")?;
-                self.end()?; // end the outer cbox
-            }
-            hir::ItemConst(ref ty, ref expr) => {
-                self.head(&visibility_qualified(item.vis, "const"))?;
-                self.print_name(item.name)?;
-                self.word_space(":")?;
-                self.print_type(&ty)?;
-                space(&mut self.s)?;
-                self.end()?; // end the head-ibox
-
-                self.word_space("=")?;
-                self.print_expr(&expr)?;
-                word(&mut self.s, ";")?;
-                self.end()?; // end the outer cbox
-            }
-            hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, ref body) => {
-                self.head("")?;
-                self.print_fn(decl,
-                              unsafety,
-                              constness,
-                              abi,
-                              Some(item.name),
-                              typarams,
-                              None,
-                              item.vis)?;
-                word(&mut self.s, " ")?;
-                self.print_block_with_attrs(&body, &item.attrs)?;
-            }
-            hir::ItemMod(ref _mod) => {
-                self.head(&visibility_qualified(item.vis, "mod"))?;
-                self.print_name(item.name)?;
-                self.nbsp()?;
-                self.bopen()?;
-                self.print_mod(_mod, &item.attrs)?;
-                self.bclose(item.span)?;
-            }
-            hir::ItemForeignMod(ref nmod) => {
-                self.head("extern")?;
-                self.word_nbsp(&nmod.abi.to_string())?;
-                self.bopen()?;
-                self.print_foreign_mod(nmod, &item.attrs)?;
-                self.bclose(item.span)?;
-            }
-            hir::ItemTy(ref ty, ref params) => {
-                self.ibox(indent_unit)?;
-                self.ibox(0)?;
-                self.word_nbsp(&visibility_qualified(item.vis, "type"))?;
-                self.print_name(item.name)?;
-                self.print_generics(params)?;
-                self.end()?; // end the inner ibox
-
-                self.print_where_clause(&params.where_clause)?;
-                space(&mut self.s)?;
-                self.word_space("=")?;
-                self.print_type(&ty)?;
-                word(&mut self.s, ";")?;
-                self.end()?; // end the outer ibox
-            }
-            hir::ItemEnum(ref enum_definition, ref params) => {
-                self.print_enum_def(enum_definition, params, item.name, item.span, item.vis)?;
-            }
-            hir::ItemStruct(ref struct_def, ref generics) => {
-                self.head(&visibility_qualified(item.vis, "struct"))?;
-                self.print_struct(struct_def, generics, item.name, item.span, true)?;
-            }
-
-            hir::ItemDefaultImpl(unsafety, ref trait_ref) => {
-                self.head("")?;
-                self.print_visibility(item.vis)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("impl")?;
-                self.print_trait_ref(trait_ref)?;
-                space(&mut self.s)?;
-                self.word_space("for")?;
-                self.word_space("..")?;
-                self.bopen()?;
-                self.bclose(item.span)?;
-            }
-            hir::ItemImpl(unsafety,
-                          polarity,
-                          ref generics,
-                          ref opt_trait,
-                          ref ty,
-                          ref impl_items) => {
-                self.head("")?;
-                self.print_visibility(item.vis)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("impl")?;
-
-                if generics.is_parameterized() {
-                    self.print_generics(generics)?;
-                    space(&mut self.s)?;
-                }
-
-                match polarity {
-                    hir::ImplPolarity::Negative => {
-                        word(&mut self.s, "!")?;
-                    }
-                    _ => {}
-                }
-
-                match opt_trait {
-                    &Some(ref t) => {
-                        self.print_trait_ref(t)?;
-                        space(&mut self.s)?;
-                        self.word_space("for")?;
-                    }
-                    &None => {}
-                }
-
-                self.print_type(&ty)?;
-                self.print_where_clause(&generics.where_clause)?;
-
-                space(&mut self.s)?;
-                self.bopen()?;
-                self.print_inner_attributes(&item.attrs)?;
-                for impl_item in impl_items {
-                    self.print_impl_item(impl_item)?;
-                }
-                self.bclose(item.span)?;
-            }
-            hir::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => {
-                self.head("")?;
-                self.print_visibility(item.vis)?;
-                self.print_unsafety(unsafety)?;
-                self.word_nbsp("trait")?;
-                self.print_name(item.name)?;
-                self.print_generics(generics)?;
-                let mut real_bounds = Vec::with_capacity(bounds.len());
-                for b in bounds.iter() {
-                    if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
-                        space(&mut self.s)?;
-                        self.word_space("for ?")?;
-                        self.print_trait_ref(&ptr.trait_ref)?;
-                    } else {
-                        real_bounds.push(b.clone());
-                    }
-                }
-                self.print_bounds(":", &real_bounds[..])?;
-                self.print_where_clause(&generics.where_clause)?;
-                word(&mut self.s, " ")?;
-                self.bopen()?;
-                for trait_item in trait_items {
-                    self.print_trait_item(trait_item)?;
-                }
-                self.bclose(item.span)?;
-            }
-        }
-        self.ann.post(self, NodeItem(item))
-    }
-
-    fn print_trait_ref(&mut self, t: &hir::TraitRef) -> io::Result<()> {
-        self.print_path(&t.path, false, 0)
-    }
-
-    fn print_formal_lifetime_list(&mut self, lifetimes: &[hir::LifetimeDef]) -> io::Result<()> {
-        if !lifetimes.is_empty() {
-            word(&mut self.s, "for<")?;
-            let mut comma = false;
-            for lifetime_def in lifetimes {
-                if comma {
-                    self.word_space(",")?
-                }
-                self.print_lifetime_def(lifetime_def)?;
-                comma = true;
-            }
-            word(&mut self.s, ">")?;
-        }
-        Ok(())
-    }
-
-    fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> {
-        self.print_formal_lifetime_list(&t.bound_lifetimes)?;
-        self.print_trait_ref(&t.trait_ref)
-    }
-
-    pub fn print_enum_def(&mut self,
-                          enum_definition: &hir::EnumDef,
-                          generics: &hir::Generics,
-                          name: ast::Name,
-                          span: codemap::Span,
-                          visibility: hir::Visibility)
-                          -> io::Result<()> {
-        self.head(&visibility_qualified(visibility, "enum"))?;
-        self.print_name(name)?;
-        self.print_generics(generics)?;
-        self.print_where_clause(&generics.where_clause)?;
-        space(&mut self.s)?;
-        self.print_variants(&enum_definition.variants, span)
-    }
-
-    pub fn print_variants(&mut self,
-                          variants: &[hir::Variant],
-                          span: codemap::Span)
-                          -> io::Result<()> {
-        self.bopen()?;
-        for v in variants {
-            self.space_if_not_bol()?;
-            self.maybe_print_comment(v.span.lo)?;
-            self.print_outer_attributes(&v.node.attrs)?;
-            self.ibox(indent_unit)?;
-            self.print_variant(v)?;
-            word(&mut self.s, ",")?;
-            self.end()?;
-            self.maybe_print_trailing_comment(v.span, None)?;
-        }
-        self.bclose(span)
-    }
-
-    pub fn print_visibility(&mut self, vis: hir::Visibility) -> io::Result<()> {
-        match vis {
-            hir::Public => self.word_nbsp("pub"),
-            hir::Inherited => Ok(()),
-        }
-    }
-
-    pub fn print_struct(&mut self,
-                        struct_def: &hir::VariantData,
-                        generics: &hir::Generics,
-                        name: ast::Name,
-                        span: codemap::Span,
-                        print_finalizer: bool)
-                        -> io::Result<()> {
-        self.print_name(name)?;
-        self.print_generics(generics)?;
-        if !struct_def.is_struct() {
-            if struct_def.is_tuple() {
-                self.popen()?;
-                self.commasep(Inconsistent, struct_def.fields(), |s, field| {
-                    s.print_visibility(field.vis)?;
-                    s.maybe_print_comment(field.span.lo)?;
-                    s.print_type(&field.ty)
-                })?;
-                self.pclose()?;
-            }
-            self.print_where_clause(&generics.where_clause)?;
-            if print_finalizer {
-                word(&mut self.s, ";")?;
-            }
-            self.end()?;
-            self.end() // close the outer-box
-        } else {
-            self.print_where_clause(&generics.where_clause)?;
-            self.nbsp()?;
-            self.bopen()?;
-            self.hardbreak_if_not_bol()?;
-
-            for field in struct_def.fields() {
-                self.hardbreak_if_not_bol()?;
-                self.maybe_print_comment(field.span.lo)?;
-                self.print_outer_attributes(&field.attrs)?;
-                self.print_visibility(field.vis)?;
-                self.print_name(field.name)?;
-                self.word_nbsp(":")?;
-                self.print_type(&field.ty)?;
-                word(&mut self.s, ",")?;
-            }
-
-            self.bclose(span)
-        }
-    }
-
-    pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> {
-        self.head("")?;
-        let generics = ::util::empty_generics();
-        self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?;
-        match v.node.disr_expr {
-            Some(ref d) => {
-                space(&mut self.s)?;
-                self.word_space("=")?;
-                self.print_expr(&d)
-            }
-            _ => Ok(()),
-        }
-    }
-    pub fn print_method_sig(&mut self,
-                            name: ast::Name,
-                            m: &hir::MethodSig,
-                            vis: hir::Visibility)
-                            -> io::Result<()> {
-        self.print_fn(&m.decl,
-                      m.unsafety,
-                      m.constness,
-                      m.abi,
-                      Some(name),
-                      &m.generics,
-                      Some(&m.explicit_self.node),
-                      vis)
-    }
-
-    pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> {
-        self.ann.pre(self, NodeSubItem(ti.id))?;
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(ti.span.lo)?;
-        self.print_outer_attributes(&ti.attrs)?;
-        match ti.node {
-            hir::ConstTraitItem(ref ty, ref default) => {
-                self.print_associated_const(ti.name,
-                                            &ty,
-                                            default.as_ref().map(|expr| &**expr),
-                                            hir::Inherited)?;
-            }
-            hir::MethodTraitItem(ref sig, ref body) => {
-                if body.is_some() {
-                    self.head("")?;
-                }
-                self.print_method_sig(ti.name, sig, hir::Inherited)?;
-                if let Some(ref body) = *body {
-                    self.nbsp()?;
-                    self.print_block_with_attrs(body, &ti.attrs)?;
-                } else {
-                    word(&mut self.s, ";")?;
-                }
-            }
-            hir::TypeTraitItem(ref bounds, ref default) => {
-                self.print_associated_type(ti.name,
-                                           Some(bounds),
-                                           default.as_ref().map(|ty| &**ty))?;
-            }
-        }
-        self.ann.post(self, NodeSubItem(ti.id))
-    }
-
-    pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
-        self.ann.pre(self, NodeSubItem(ii.id))?;
-        self.hardbreak_if_not_bol()?;
-        self.maybe_print_comment(ii.span.lo)?;
-        self.print_outer_attributes(&ii.attrs)?;
-
-        if let hir::Defaultness::Default = ii.defaultness {
-            self.word_nbsp("default")?;
-        }
-
-        match ii.node {
-            hir::ImplItemKind::Const(ref ty, ref expr) => {
-                self.print_associated_const(ii.name, &ty, Some(&expr), ii.vis)?;
-            }
-            hir::ImplItemKind::Method(ref sig, ref body) => {
-                self.head("")?;
-                self.print_method_sig(ii.name, sig, ii.vis)?;
-                self.nbsp()?;
-                self.print_block_with_attrs(body, &ii.attrs)?;
-            }
-            hir::ImplItemKind::Type(ref ty) => {
-                self.print_associated_type(ii.name, None, Some(ty))?;
-            }
-        }
-        self.ann.post(self, NodeSubItem(ii.id))
-    }
-
-    pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
-        self.maybe_print_comment(st.span.lo)?;
-        match st.node {
-            hir::StmtDecl(ref decl, _) => {
-                self.print_decl(&decl)?;
-            }
-            hir::StmtExpr(ref expr, _) => {
-                self.space_if_not_bol()?;
-                self.print_expr(&expr)?;
-            }
-            hir::StmtSemi(ref expr, _) => {
-                self.space_if_not_bol()?;
-                self.print_expr(&expr)?;
-                word(&mut self.s, ";")?;
-            }
-        }
-        if stmt_ends_with_semi(&st.node) {
-            word(&mut self.s, ";")?;
-        }
-        self.maybe_print_trailing_comment(st.span, None)
-    }
-
-    pub fn print_block(&mut self, blk: &hir::Block) -> io::Result<()> {
-        self.print_block_with_attrs(blk, &[])
-    }
-
-    pub fn print_block_unclosed(&mut self, blk: &hir::Block) -> io::Result<()> {
-        self.print_block_unclosed_indent(blk, indent_unit)
-    }
-
-    pub fn print_block_unclosed_indent(&mut self,
-                                       blk: &hir::Block,
-                                       indented: usize)
-                                       -> io::Result<()> {
-        self.print_block_maybe_unclosed(blk, indented, &[], false)
-    }
-
-    pub fn print_block_with_attrs(&mut self,
-                                  blk: &hir::Block,
-                                  attrs: &[ast::Attribute])
-                                  -> io::Result<()> {
-        self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
-    }
-
-    pub fn print_block_maybe_unclosed(&mut self,
-                                      blk: &hir::Block,
-                                      indented: usize,
-                                      attrs: &[ast::Attribute],
-                                      close_box: bool)
-                                      -> io::Result<()> {
-        match blk.rules {
-            hir::UnsafeBlock(..) => self.word_space("unsafe")?,
-            hir::PushUnsafeBlock(..) => self.word_space("push_unsafe")?,
-            hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe")?,
-            hir::PushUnstableBlock => self.word_space("push_unstable")?,
-            hir::PopUnstableBlock => self.word_space("pop_unstable")?,
-            hir::DefaultBlock => (),
-        }
-        self.maybe_print_comment(blk.span.lo)?;
-        self.ann.pre(self, NodeBlock(blk))?;
-        self.bopen()?;
-
-        self.print_inner_attributes(attrs)?;
-
-        for st in &blk.stmts {
-            self.print_stmt(st)?;
-        }
-        match blk.expr {
-            Some(ref expr) => {
-                self.space_if_not_bol()?;
-                self.print_expr(&expr)?;
-                self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi))?;
-            }
-            _ => (),
-        }
-        self.bclose_maybe_open(blk.span, indented, close_box)?;
-        self.ann.post(self, NodeBlock(blk))
-    }
-
-    fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> {
-        match els {
-            Some(_else) => {
-                match _else.node {
-                    // "another else-if"
-                    hir::ExprIf(ref i, ref then, ref e) => {
-                        self.cbox(indent_unit - 1)?;
-                        self.ibox(0)?;
-                        word(&mut self.s, " else if ")?;
-                        self.print_expr(&i)?;
-                        space(&mut self.s)?;
-                        self.print_block(&then)?;
-                        self.print_else(e.as_ref().map(|e| &**e))
-                    }
-                    // "final else"
-                    hir::ExprBlock(ref b) => {
-                        self.cbox(indent_unit - 1)?;
-                        self.ibox(0)?;
-                        word(&mut self.s, " else ")?;
-                        self.print_block(&b)
-                    }
-                    // BLEAH, constraints would be great here
-                    _ => {
-                        panic!("print_if saw if with weird alternative");
-                    }
-                }
-            }
-            _ => Ok(()),
-        }
-    }
-
-    pub fn print_if(&mut self,
-                    test: &hir::Expr,
-                    blk: &hir::Block,
-                    elseopt: Option<&hir::Expr>)
-                    -> io::Result<()> {
-        self.head("if")?;
-        self.print_expr(test)?;
-        space(&mut self.s)?;
-        self.print_block(blk)?;
-        self.print_else(elseopt)
-    }
-
-    pub fn print_if_let(&mut self,
-                        pat: &hir::Pat,
-                        expr: &hir::Expr,
-                        blk: &hir::Block,
-                        elseopt: Option<&hir::Expr>)
-                        -> io::Result<()> {
-        self.head("if let")?;
-        self.print_pat(pat)?;
-        space(&mut self.s)?;
-        self.word_space("=")?;
-        self.print_expr(expr)?;
-        space(&mut self.s)?;
-        self.print_block(blk)?;
-        self.print_else(elseopt)
-    }
-
-
-    fn print_call_post(&mut self, args: &[P<hir::Expr>]) -> io::Result<()> {
-        self.popen()?;
-        self.commasep_exprs(Inconsistent, args)?;
-        self.pclose()
-    }
-
-    pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr) -> io::Result<()> {
-        let needs_par = needs_parentheses(expr);
-        if needs_par {
-            self.popen()?;
-        }
-        self.print_expr(expr)?;
-        if needs_par {
-            self.pclose()?;
-        }
-        Ok(())
-    }
-
-    fn print_expr_vec(&mut self, exprs: &[P<hir::Expr>]) -> io::Result<()> {
-        self.ibox(indent_unit)?;
-        word(&mut self.s, "[")?;
-        self.commasep_exprs(Inconsistent, &exprs[..])?;
-        word(&mut self.s, "]")?;
-        self.end()
-    }
-
-    fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::Expr) -> io::Result<()> {
-        self.ibox(indent_unit)?;
-        word(&mut self.s, "[")?;
-        self.print_expr(element)?;
-        self.word_space(";")?;
-        self.print_expr(count)?;
-        word(&mut self.s, "]")?;
-        self.end()
-    }
-
-    fn print_expr_struct(&mut self,
-                         path: &hir::Path,
-                         fields: &[hir::Field],
-                         wth: &Option<P<hir::Expr>>)
-                         -> io::Result<()> {
-        self.print_path(path, true, 0)?;
-        word(&mut self.s, "{")?;
-        self.commasep_cmnt(Consistent,
-                           &fields[..],
-                           |s, field| {
-                               s.ibox(indent_unit)?;
-                               s.print_name(field.name.node)?;
-                               s.word_space(":")?;
-                               s.print_expr(&field.expr)?;
-                               s.end()
-                           },
-                           |f| f.span)?;
-        match *wth {
-            Some(ref expr) => {
-                self.ibox(indent_unit)?;
-                if !fields.is_empty() {
-                    word(&mut self.s, ",")?;
-                    space(&mut self.s)?;
-                }
-                word(&mut self.s, "..")?;
-                self.print_expr(&expr)?;
-                self.end()?;
-            }
-            _ => if !fields.is_empty() {
-                word(&mut self.s, ",")?
-            },
-        }
-        word(&mut self.s, "}")?;
-        Ok(())
-    }
-
-    fn print_expr_tup(&mut self, exprs: &[P<hir::Expr>]) -> io::Result<()> {
-        self.popen()?;
-        self.commasep_exprs(Inconsistent, &exprs[..])?;
-        if exprs.len() == 1 {
-            word(&mut self.s, ",")?;
-        }
-        self.pclose()
-    }
-
-    fn print_expr_call(&mut self, func: &hir::Expr, args: &[P<hir::Expr>]) -> io::Result<()> {
-        self.print_expr_maybe_paren(func)?;
-        self.print_call_post(args)
-    }
-
-    fn print_expr_method_call(&mut self,
-                              name: Spanned<ast::Name>,
-                              tys: &[P<hir::Ty>],
-                              args: &[P<hir::Expr>])
-                              -> io::Result<()> {
-        let base_args = &args[1..];
-        self.print_expr(&args[0])?;
-        word(&mut self.s, ".")?;
-        self.print_name(name.node)?;
-        if !tys.is_empty() {
-            word(&mut self.s, "::<")?;
-            self.commasep(Inconsistent, tys, |s, ty| s.print_type(&ty))?;
-            word(&mut self.s, ">")?;
-        }
-        self.print_call_post(base_args)
-    }
-
-    fn print_expr_binary(&mut self,
-                         op: hir::BinOp,
-                         lhs: &hir::Expr,
-                         rhs: &hir::Expr)
-                         -> io::Result<()> {
-        self.print_expr(lhs)?;
-        space(&mut self.s)?;
-        self.word_space(::util::binop_to_string(op.node))?;
-        self.print_expr(rhs)
-    }
-
-    fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) -> io::Result<()> {
-        word(&mut self.s, ::util::unop_to_string(op))?;
-        self.print_expr_maybe_paren(expr)
-    }
-
-    fn print_expr_addr_of(&mut self,
-                          mutability: hir::Mutability,
-                          expr: &hir::Expr)
-                          -> io::Result<()> {
-        word(&mut self.s, "&")?;
-        self.print_mutability(mutability)?;
-        self.print_expr_maybe_paren(expr)
-    }
-
-    pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> {
-        self.maybe_print_comment(expr.span.lo)?;
-        self.ibox(indent_unit)?;
-        self.ann.pre(self, NodeExpr(expr))?;
-        match expr.node {
-            hir::ExprBox(ref expr) => {
-                self.word_space("box")?;
-                self.print_expr(expr)?;
-            }
-            hir::ExprVec(ref exprs) => {
-                self.print_expr_vec(&exprs[..])?;
-            }
-            hir::ExprRepeat(ref element, ref count) => {
-                self.print_expr_repeat(&element, &count)?;
-            }
-            hir::ExprStruct(ref path, ref fields, ref wth) => {
-                self.print_expr_struct(path, &fields[..], wth)?;
-            }
-            hir::ExprTup(ref exprs) => {
-                self.print_expr_tup(&exprs[..])?;
-            }
-            hir::ExprCall(ref func, ref args) => {
-                self.print_expr_call(&func, &args[..])?;
-            }
-            hir::ExprMethodCall(name, ref tys, ref args) => {
-                self.print_expr_method_call(name, &tys[..], &args[..])?;
-            }
-            hir::ExprBinary(op, ref lhs, ref rhs) => {
-                self.print_expr_binary(op, &lhs, &rhs)?;
-            }
-            hir::ExprUnary(op, ref expr) => {
-                self.print_expr_unary(op, &expr)?;
-            }
-            hir::ExprAddrOf(m, ref expr) => {
-                self.print_expr_addr_of(m, &expr)?;
-            }
-            hir::ExprLit(ref lit) => {
-                self.print_literal(&lit)?;
-            }
-            hir::ExprCast(ref expr, ref ty) => {
-                self.print_expr(&expr)?;
-                space(&mut self.s)?;
-                self.word_space("as")?;
-                self.print_type(&ty)?;
-            }
-            hir::ExprType(ref expr, ref ty) => {
-                self.print_expr(&expr)?;
-                self.word_space(":")?;
-                self.print_type(&ty)?;
-            }
-            hir::ExprIf(ref test, ref blk, ref elseopt) => {
-                self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?;
-            }
-            hir::ExprWhile(ref test, ref blk, opt_ident) => {
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.name)?;
-                    self.word_space(":")?;
-                }
-                self.head("while")?;
-                self.print_expr(&test)?;
-                space(&mut self.s)?;
-                self.print_block(&blk)?;
-            }
-            hir::ExprLoop(ref blk, opt_ident) => {
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.name)?;
-                    self.word_space(":")?;
-                }
-                self.head("loop")?;
-                space(&mut self.s)?;
-                self.print_block(&blk)?;
-            }
-            hir::ExprMatch(ref expr, ref arms, _) => {
-                self.cbox(indent_unit)?;
-                self.ibox(4)?;
-                self.word_nbsp("match")?;
-                self.print_expr(&expr)?;
-                space(&mut self.s)?;
-                self.bopen()?;
-                for arm in arms {
-                    self.print_arm(arm)?;
-                }
-                self.bclose_(expr.span, indent_unit)?;
-            }
-            hir::ExprClosure(capture_clause, ref decl, ref body) => {
-                self.print_capture_clause(capture_clause)?;
-
-                self.print_fn_block_args(&decl)?;
-                space(&mut self.s)?;
-
-                let default_return = match decl.output {
-                    hir::DefaultReturn(..) => true,
-                    _ => false,
-                };
-
-                if !default_return || !body.stmts.is_empty() || body.expr.is_none() {
-                    self.print_block_unclosed(&body)?;
-                } else {
-                    // we extract the block, so as not to create another set of boxes
-                    match body.expr.as_ref().unwrap().node {
-                        hir::ExprBlock(ref blk) => {
-                            self.print_block_unclosed(&blk)?;
-                        }
-                        _ => {
-                            // this is a bare expression
-                            self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap())?;
-                            self.end()?; // need to close a box
-                        }
-                    }
-                }
-                // a box will be closed by print_expr, but we didn't want an overall
-                // wrapper so we closed the corresponding opening. so create an
-                // empty box to satisfy the close.
-                self.ibox(0)?;
-            }
-            hir::ExprBlock(ref blk) => {
-                // containing cbox, will be closed by print-block at }
-                self.cbox(indent_unit)?;
-                // head-box, will be closed by print-block after {
-                self.ibox(0)?;
-                self.print_block(&blk)?;
-            }
-            hir::ExprAssign(ref lhs, ref rhs) => {
-                self.print_expr(&lhs)?;
-                space(&mut self.s)?;
-                self.word_space("=")?;
-                self.print_expr(&rhs)?;
-            }
-            hir::ExprAssignOp(op, ref lhs, ref rhs) => {
-                self.print_expr(&lhs)?;
-                space(&mut self.s)?;
-                word(&mut self.s, ::util::binop_to_string(op.node))?;
-                self.word_space("=")?;
-                self.print_expr(&rhs)?;
-            }
-            hir::ExprField(ref expr, name) => {
-                self.print_expr(&expr)?;
-                word(&mut self.s, ".")?;
-                self.print_name(name.node)?;
-            }
-            hir::ExprTupField(ref expr, id) => {
-                self.print_expr(&expr)?;
-                word(&mut self.s, ".")?;
-                self.print_usize(id.node)?;
-            }
-            hir::ExprIndex(ref expr, ref index) => {
-                self.print_expr(&expr)?;
-                word(&mut self.s, "[")?;
-                self.print_expr(&index)?;
-                word(&mut self.s, "]")?;
-            }
-            hir::ExprPath(None, ref path) => {
-                self.print_path(path, true, 0)?
-            }
-            hir::ExprPath(Some(ref qself), ref path) => {
-                self.print_qpath(path, qself, true)?
-            }
-            hir::ExprBreak(opt_ident) => {
-                word(&mut self.s, "break")?;
-                space(&mut self.s)?;
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.node.name)?;
-                    space(&mut self.s)?;
-                }
-            }
-            hir::ExprAgain(opt_ident) => {
-                word(&mut self.s, "continue")?;
-                space(&mut self.s)?;
-                if let Some(ident) = opt_ident {
-                    self.print_name(ident.node.name)?;
-                    space(&mut self.s)?
-                }
-            }
-            hir::ExprRet(ref result) => {
-                word(&mut self.s, "return")?;
-                match *result {
-                    Some(ref expr) => {
-                        word(&mut self.s, " ")?;
-                        self.print_expr(&expr)?;
-                    }
-                    _ => (),
-                }
-            }
-            hir::ExprInlineAsm(ref a, ref outputs, ref inputs) => {
-                word(&mut self.s, "asm!")?;
-                self.popen()?;
-                self.print_string(&a.asm, a.asm_str_style)?;
-                self.word_space(":")?;
-
-                let mut out_idx = 0;
-                self.commasep(Inconsistent, &a.outputs, |s, out| {
-                    match out.constraint.slice_shift_char() {
-                        Some(('=', operand)) if out.is_rw => {
-                            s.print_string(&format!("+{}", operand), ast::StrStyle::Cooked)?
-                        }
-                        _ => s.print_string(&out.constraint, ast::StrStyle::Cooked)?,
-                    }
-                    s.popen()?;
-                    s.print_expr(&outputs[out_idx])?;
-                    s.pclose()?;
-                    out_idx += 1;
-                    Ok(())
-                })?;
-                space(&mut self.s)?;
-                self.word_space(":")?;
-
-                let mut in_idx = 0;
-                self.commasep(Inconsistent, &a.inputs, |s, co| {
-                    s.print_string(&co, ast::StrStyle::Cooked)?;
-                    s.popen()?;
-                    s.print_expr(&inputs[in_idx])?;
-                    s.pclose()?;
-                    in_idx += 1;
-                    Ok(())
-                })?;
-                space(&mut self.s)?;
-                self.word_space(":")?;
-
-                self.commasep(Inconsistent, &a.clobbers, |s, co| {
-                    s.print_string(&co, ast::StrStyle::Cooked)?;
-                    Ok(())
-                })?;
-
-                let mut options = vec![];
-                if a.volatile {
-                    options.push("volatile");
-                }
-                if a.alignstack {
-                    options.push("alignstack");
-                }
-                if a.dialect == ast::AsmDialect::Intel {
-                    options.push("intel");
-                }
-
-                if !options.is_empty() {
-                    space(&mut self.s)?;
-                    self.word_space(":")?;
-                    self.commasep(Inconsistent, &options, |s, &co| {
-                        s.print_string(co, ast::StrStyle::Cooked)?;
-                        Ok(())
-                    })?;
-                }
-
-                self.pclose()?;
-            }
-        }
-        self.ann.post(self, NodeExpr(expr))?;
-        self.end()
-    }
-
-    pub fn print_local_decl(&mut self, loc: &hir::Local) -> io::Result<()> {
-        self.print_pat(&loc.pat)?;
-        if let Some(ref ty) = loc.ty {
-            self.word_space(":")?;
-            self.print_type(&ty)?;
-        }
-        Ok(())
-    }
-
-    pub fn print_decl(&mut self, decl: &hir::Decl) -> io::Result<()> {
-        self.maybe_print_comment(decl.span.lo)?;
-        match decl.node {
-            hir::DeclLocal(ref loc) => {
-                self.space_if_not_bol()?;
-                self.ibox(indent_unit)?;
-                self.word_nbsp("let")?;
-
-                self.ibox(indent_unit)?;
-                self.print_local_decl(&loc)?;
-                self.end()?;
-                if let Some(ref init) = loc.init {
-                    self.nbsp()?;
-                    self.word_space("=")?;
-                    self.print_expr(&init)?;
-                }
-                self.end()
-            }
-            hir::DeclItem(ref item) => {
-                self.print_item_id(item)
-            }
-        }
-    }
-
-    pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
-        word(&mut self.s, &i.to_string())
-    }
-
-    pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
-        word(&mut self.s, &name.as_str())?;
-        self.ann.post(self, NodeName(&name))
-    }
-
-    pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) -> io::Result<()> {
-        self.print_local_decl(loc)?;
-        space(&mut self.s)?;
-        self.word_space("in")?;
-        self.print_expr(coll)
-    }
-
-    fn print_path(&mut self,
-                  path: &hir::Path,
-                  colons_before_params: bool,
-                  depth: usize)
-                  -> io::Result<()> {
-        self.maybe_print_comment(path.span.lo)?;
-
-        let mut first = !path.global;
-        for segment in &path.segments[..path.segments.len() - depth] {
-            if first {
-                first = false
-            } else {
-                word(&mut self.s, "::")?
-            }
-
-            self.print_name(segment.identifier.name)?;
-
-            self.print_path_parameters(&segment.parameters, colons_before_params)?;
-        }
-
-        Ok(())
-    }
-
-    fn print_qpath(&mut self,
-                   path: &hir::Path,
-                   qself: &hir::QSelf,
-                   colons_before_params: bool)
-                   -> io::Result<()> {
-        word(&mut self.s, "<")?;
-        self.print_type(&qself.ty)?;
-        if qself.position > 0 {
-            space(&mut self.s)?;
-            self.word_space("as")?;
-            let depth = path.segments.len() - qself.position;
-            self.print_path(&path, false, depth)?;
-        }
-        word(&mut self.s, ">")?;
-        word(&mut self.s, "::")?;
-        let item_segment = path.segments.last().unwrap();
-        self.print_name(item_segment.identifier.name)?;
-        self.print_path_parameters(&item_segment.parameters, colons_before_params)
-    }
-
-    fn print_path_parameters(&mut self,
-                             parameters: &hir::PathParameters,
-                             colons_before_params: bool)
-                             -> io::Result<()> {
-        if parameters.is_empty() {
-            return Ok(());
-        }
-
-        if colons_before_params {
-            word(&mut self.s, "::")?
-        }
-
-        match *parameters {
-            hir::AngleBracketedParameters(ref data) => {
-                word(&mut self.s, "<")?;
-
-                let mut comma = false;
-                for lifetime in &data.lifetimes {
-                    if comma {
-                        self.word_space(",")?
-                    }
-                    self.print_lifetime(lifetime)?;
-                    comma = true;
-                }
-
-                if !data.types.is_empty() {
-                    if comma {
-                        self.word_space(",")?
-                    }
-                    self.commasep(Inconsistent, &data.types, |s, ty| s.print_type(&ty))?;
-                    comma = true;
-                }
-
-                for binding in data.bindings.iter() {
-                    if comma {
-                        self.word_space(",")?
-                    }
-                    self.print_name(binding.name)?;
-                    space(&mut self.s)?;
-                    self.word_space("=")?;
-                    self.print_type(&binding.ty)?;
-                    comma = true;
-                }
-
-                word(&mut self.s, ">")?
-            }
-
-            hir::ParenthesizedParameters(ref data) => {
-                word(&mut self.s, "(")?;
-                self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(&ty))?;
-                word(&mut self.s, ")")?;
-
-                match data.output {
-                    None => {}
-                    Some(ref ty) => {
-                        self.space_if_not_bol()?;
-                        self.word_space("->")?;
-                        self.print_type(&ty)?;
-                    }
-                }
-            }
-        }
-
-        Ok(())
-    }
-
-    pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> {
-        self.maybe_print_comment(pat.span.lo)?;
-        self.ann.pre(self, NodePat(pat))?;
-        // Pat isn't normalized, but the beauty of it
-        // is that it doesn't matter
-        match pat.node {
-            PatKind::Wild => word(&mut self.s, "_")?,
-            PatKind::Ident(binding_mode, ref path1, ref sub) => {
-                match binding_mode {
-                    hir::BindByRef(mutbl) => {
-                        self.word_nbsp("ref")?;
-                        self.print_mutability(mutbl)?;
-                    }
-                    hir::BindByValue(hir::MutImmutable) => {}
-                    hir::BindByValue(hir::MutMutable) => {
-                        self.word_nbsp("mut")?;
-                    }
-                }
-                self.print_name(path1.node.name)?;
-                match *sub {
-                    Some(ref p) => {
-                        word(&mut self.s, "@")?;
-                        self.print_pat(&p)?;
-                    }
-                    None => (),
-                }
-            }
-            PatKind::TupleStruct(ref path, ref args_) => {
-                self.print_path(path, true, 0)?;
-                match *args_ {
-                    None => word(&mut self.s, "(..)")?,
-                    Some(ref args) => {
-                        self.popen()?;
-                        self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&p))?;
-                        self.pclose()?;
-                    }
-                }
-            }
-            PatKind::Path(ref path) => {
-                self.print_path(path, true, 0)?;
-            }
-            PatKind::QPath(ref qself, ref path) => {
-                self.print_qpath(path, qself, false)?;
-            }
-            PatKind::Struct(ref path, ref fields, etc) => {
-                self.print_path(path, true, 0)?;
-                self.nbsp()?;
-                self.word_space("{")?;
-                self.commasep_cmnt(Consistent,
-                                   &fields[..],
-                                   |s, f| {
-                                       s.cbox(indent_unit)?;
-                                       if !f.node.is_shorthand {
-                                           s.print_name(f.node.name)?;
-                                           s.word_nbsp(":")?;
-                                       }
-                                       s.print_pat(&f.node.pat)?;
-                                       s.end()
-                                   },
-                                   |f| f.node.pat.span)?;
-                if etc {
-                    if !fields.is_empty() {
-                        self.word_space(",")?;
-                    }
-                    word(&mut self.s, "..")?;
-                }
-                space(&mut self.s)?;
-                word(&mut self.s, "}")?;
-            }
-            PatKind::Tup(ref elts) => {
-                self.popen()?;
-                self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?;
-                if elts.len() == 1 {
-                    word(&mut self.s, ",")?;
-                }
-                self.pclose()?;
-            }
-            PatKind::Box(ref inner) => {
-                word(&mut self.s, "box ")?;
-                self.print_pat(&inner)?;
-            }
-            PatKind::Ref(ref inner, mutbl) => {
-                word(&mut self.s, "&")?;
-                if mutbl == hir::MutMutable {
-                    word(&mut self.s, "mut ")?;
-                }
-                self.print_pat(&inner)?;
-            }
-            PatKind::Lit(ref e) => self.print_expr(&e)?,
-            PatKind::Range(ref begin, ref end) => {
-                self.print_expr(&begin)?;
-                space(&mut self.s)?;
-                word(&mut self.s, "...")?;
-                self.print_expr(&end)?;
-            }
-            PatKind::Vec(ref before, ref slice, ref after) => {
-                word(&mut self.s, "[")?;
-                self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p))?;
-                if let Some(ref p) = *slice {
-                    if !before.is_empty() {
-                        self.word_space(",")?;
-                    }
-                    if p.node != PatKind::Wild {
-                        self.print_pat(&p)?;
-                    }
-                    word(&mut self.s, "..")?;
-                    if !after.is_empty() {
-                        self.word_space(",")?;
-                    }
-                }
-                self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p))?;
-                word(&mut self.s, "]")?;
-            }
-        }
-        self.ann.post(self, NodePat(pat))
-    }
-
-    fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
-        // I have no idea why this check is necessary, but here it
-        // is :(
-        if arm.attrs.is_empty() {
-            space(&mut self.s)?;
-        }
-        self.cbox(indent_unit)?;
-        self.ibox(0)?;
-        self.print_outer_attributes(&arm.attrs)?;
-        let mut first = true;
-        for p in &arm.pats {
-            if first {
-                first = false;
-            } else {
-                space(&mut self.s)?;
-                self.word_space("|")?;
-            }
-            self.print_pat(&p)?;
-        }
-        space(&mut self.s)?;
-        if let Some(ref e) = arm.guard {
-            self.word_space("if")?;
-            self.print_expr(&e)?;
-            space(&mut self.s)?;
-        }
-        self.word_space("=>")?;
-
-        match arm.body.node {
-            hir::ExprBlock(ref blk) => {
-                // the block will close the pattern's ibox
-                self.print_block_unclosed_indent(&blk, indent_unit)?;
-
-                // If it is a user-provided unsafe block, print a comma after it
-                if let hir::UnsafeBlock(hir::UserProvided) = blk.rules {
-                    word(&mut self.s, ",")?;
-                }
-            }
-            _ => {
-                self.end()?; // close the ibox for the pattern
-                self.print_expr(&arm.body)?;
-                word(&mut self.s, ",")?;
-            }
-        }
-        self.end() // close enclosing cbox
-    }
-
-    // Returns whether it printed anything
-    fn print_explicit_self(&mut self,
-                           explicit_self: &hir::ExplicitSelf_,
-                           mutbl: hir::Mutability)
-                           -> io::Result<bool> {
-        self.print_mutability(mutbl)?;
-        match *explicit_self {
-            hir::SelfStatic => {
-                return Ok(false);
-            }
-            hir::SelfValue(_) => {
-                word(&mut self.s, "self")?;
-            }
-            hir::SelfRegion(ref lt, m, _) => {
-                word(&mut self.s, "&")?;
-                self.print_opt_lifetime(lt)?;
-                self.print_mutability(m)?;
-                word(&mut self.s, "self")?;
-            }
-            hir::SelfExplicit(ref typ, _) => {
-                word(&mut self.s, "self")?;
-                self.word_space(":")?;
-                self.print_type(&typ)?;
-            }
-        }
-        return Ok(true);
-    }
-
-    pub fn print_fn(&mut self,
-                    decl: &hir::FnDecl,
-                    unsafety: hir::Unsafety,
-                    constness: hir::Constness,
-                    abi: Abi,
-                    name: Option<ast::Name>,
-                    generics: &hir::Generics,
-                    opt_explicit_self: Option<&hir::ExplicitSelf_>,
-                    vis: hir::Visibility)
-                    -> io::Result<()> {
-        self.print_fn_header_info(unsafety, constness, abi, vis)?;
-
-        if let Some(name) = name {
-            self.nbsp()?;
-            self.print_name(name)?;
-        }
-        self.print_generics(generics)?;
-        self.print_fn_args_and_ret(decl, opt_explicit_self)?;
-        self.print_where_clause(&generics.where_clause)
-    }
-
-    pub fn print_fn_args(&mut self,
-                         decl: &hir::FnDecl,
-                         opt_explicit_self: Option<&hir::ExplicitSelf_>,
-                         is_closure: bool)
-                         -> io::Result<()> {
-        // It is unfortunate to duplicate the commasep logic, but we want the
-        // self type and the args all in the same box.
-        self.rbox(0, Inconsistent)?;
-        let mut first = true;
-        if let Some(explicit_self) = opt_explicit_self {
-            let m = match explicit_self {
-                &hir::SelfStatic => hir::MutImmutable,
-                _ => match decl.inputs[0].pat.node {
-                    PatKind::Ident(hir::BindByValue(m), _, _) => m,
-                    _ => hir::MutImmutable,
-                },
-            };
-            first = !self.print_explicit_self(explicit_self, m)?;
-        }
-
-        // HACK(eddyb) ignore the separately printed self argument.
-        let args = if first {
-            &decl.inputs[..]
-        } else {
-            &decl.inputs[1..]
-        };
-
-        for arg in args {
-            if first {
-                first = false;
-            } else {
-                self.word_space(",")?;
-            }
-            self.print_arg(arg, is_closure)?;
-        }
-
-        self.end()
-    }
-
-    pub fn print_fn_args_and_ret(&mut self,
-                                 decl: &hir::FnDecl,
-                                 opt_explicit_self: Option<&hir::ExplicitSelf_>)
-                                 -> io::Result<()> {
-        self.popen()?;
-        self.print_fn_args(decl, opt_explicit_self, false)?;
-        if decl.variadic {
-            word(&mut self.s, ", ...")?;
-        }
-        self.pclose()?;
-
-        self.print_fn_output(decl)
-    }
-
-    pub fn print_fn_block_args(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
-        word(&mut self.s, "|")?;
-        self.print_fn_args(decl, None, true)?;
-        word(&mut self.s, "|")?;
-
-        if let hir::DefaultReturn(..) = decl.output {
-            return Ok(());
-        }
-
-        self.space_if_not_bol()?;
-        self.word_space("->")?;
-        match decl.output {
-            hir::Return(ref ty) => {
-                self.print_type(&ty)?;
-                self.maybe_print_comment(ty.span.lo)
-            }
-            hir::DefaultReturn(..) => unreachable!(),
-            hir::NoReturn(span) => {
-                self.word_nbsp("!")?;
-                self.maybe_print_comment(span.lo)
-            }
-        }
-    }
-
-    pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) -> io::Result<()> {
-        match capture_clause {
-            hir::CaptureByValue => self.word_space("move"),
-            hir::CaptureByRef => Ok(()),
-        }
-    }
-
-    pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io::Result<()> {
-        if !bounds.is_empty() {
-            word(&mut self.s, prefix)?;
-            let mut first = true;
-            for bound in bounds {
-                self.nbsp()?;
-                if first {
-                    first = false;
-                } else {
-                    self.word_space("+")?;
-                }
-
-                match *bound {
-                    TraitTyParamBound(ref tref, TraitBoundModifier::None) => {
-                        self.print_poly_trait_ref(tref)
-                    }
-                    TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => {
-                        word(&mut self.s, "?")?;
-                        self.print_poly_trait_ref(tref)
-                    }
-                    RegionTyParamBound(ref lt) => {
-                        self.print_lifetime(lt)
-                    }
-                }?
-            }
-            Ok(())
-        } else {
-            Ok(())
-        }
-    }
-
-    pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
-        self.print_name(lifetime.name)
-    }
-
-    pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<()> {
-        self.print_lifetime(&lifetime.lifetime)?;
-        let mut sep = ":";
-        for v in &lifetime.bounds {
-            word(&mut self.s, sep)?;
-            self.print_lifetime(v)?;
-            sep = "+";
-        }
-        Ok(())
-    }
-
-    pub fn print_generics(&mut self, generics: &hir::Generics) -> io::Result<()> {
-        let total = generics.lifetimes.len() + generics.ty_params.len();
-        if total == 0 {
-            return Ok(());
-        }
-
-        word(&mut self.s, "<")?;
-
-        let mut ints = Vec::new();
-        for i in 0..total {
-            ints.push(i);
-        }
-
-        self.commasep(Inconsistent, &ints[..], |s, &idx| {
-            if idx < generics.lifetimes.len() {
-                let lifetime = &generics.lifetimes[idx];
-                s.print_lifetime_def(lifetime)
-            } else {
-                let idx = idx - generics.lifetimes.len();
-                let param = &generics.ty_params[idx];
-                s.print_ty_param(param)
-            }
-        })?;
-
-        word(&mut self.s, ">")?;
-        Ok(())
-    }
-
-    pub fn print_ty_param(&mut self, param: &hir::TyParam) -> io::Result<()> {
-        self.print_name(param.name)?;
-        self.print_bounds(":", &param.bounds)?;
-        match param.default {
-            Some(ref default) => {
-                space(&mut self.s)?;
-                self.word_space("=")?;
-                self.print_type(&default)
-            }
-            _ => Ok(()),
-        }
-    }
-
-    pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> {
-        if where_clause.predicates.is_empty() {
-            return Ok(());
-        }
-
-        space(&mut self.s)?;
-        self.word_space("where")?;
-
-        for (i, predicate) in where_clause.predicates.iter().enumerate() {
-            if i != 0 {
-                self.word_space(",")?;
-            }
-
-            match predicate {
-                &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bound_lifetimes,
-                                                                              ref bounded_ty,
-                                                                              ref bounds,
-                                                                              ..}) => {
-                    self.print_formal_lifetime_list(bound_lifetimes)?;
-                    self.print_type(&bounded_ty)?;
-                    self.print_bounds(":", bounds)?;
-                }
-                &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
-                                                                                ref bounds,
-                                                                                ..}) => {
-                    self.print_lifetime(lifetime)?;
-                    word(&mut self.s, ":")?;
-
-                    for (i, bound) in bounds.iter().enumerate() {
-                        self.print_lifetime(bound)?;
-
-                        if i != 0 {
-                            word(&mut self.s, ":")?;
-                        }
-                    }
-                }
-                &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref path, ref ty, ..}) => {
-                    self.print_path(path, false, 0)?;
-                    space(&mut self.s)?;
-                    self.word_space("=")?;
-                    self.print_type(&ty)?;
-                }
-            }
-        }
-
-        Ok(())
-    }
-
-    pub fn print_view_path(&mut self, vp: &hir::ViewPath) -> io::Result<()> {
-        match vp.node {
-            hir::ViewPathSimple(name, ref path) => {
-                self.print_path(path, false, 0)?;
-
-                if path.segments.last().unwrap().identifier.name != name {
-                    space(&mut self.s)?;
-                    self.word_space("as")?;
-                    self.print_name(name)?;
-                }
-
-                Ok(())
-            }
-
-            hir::ViewPathGlob(ref path) => {
-                self.print_path(path, false, 0)?;
-                word(&mut self.s, "::*")
-            }
-
-            hir::ViewPathList(ref path, ref segments) => {
-                if path.segments.is_empty() {
-                    word(&mut self.s, "{")?;
-                } else {
-                    self.print_path(path, false, 0)?;
-                    word(&mut self.s, "::{")?;
-                }
-                self.commasep(Inconsistent, &segments[..], |s, w| {
-                    match w.node {
-                        hir::PathListIdent { name, .. } => {
-                            s.print_name(name)
-                        }
-                        hir::PathListMod { .. } => {
-                            word(&mut s.s, "self")
-                        }
-                    }
-                })?;
-                word(&mut self.s, "}")
-            }
-        }
-    }
-
-    pub fn print_mutability(&mut self, mutbl: hir::Mutability) -> io::Result<()> {
-        match mutbl {
-            hir::MutMutable => self.word_nbsp("mut"),
-            hir::MutImmutable => Ok(()),
-        }
-    }
-
-    pub fn print_mt(&mut self, mt: &hir::MutTy) -> io::Result<()> {
-        self.print_mutability(mt.mutbl)?;
-        self.print_type(&mt.ty)
-    }
-
-    pub fn print_arg(&mut self, input: &hir::Arg, is_closure: bool) -> io::Result<()> {
-        self.ibox(indent_unit)?;
-        match input.ty.node {
-            hir::TyInfer if is_closure => self.print_pat(&input.pat)?,
-            _ => {
-                match input.pat.node {
-                    PatKind::Ident(_, ref path1, _) if
-                        path1.node.name ==
-                            parse::token::special_idents::invalid.name => {
-                        // Do nothing.
-                    }
-                    _ => {
-                        self.print_pat(&input.pat)?;
-                        word(&mut self.s, ":")?;
-                        space(&mut self.s)?;
-                    }
-                }
-                self.print_type(&input.ty)?;
-            }
-        }
-        self.end()
-    }
-
-    pub fn print_fn_output(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
-        if let hir::DefaultReturn(..) = decl.output {
-            return Ok(());
-        }
-
-        self.space_if_not_bol()?;
-        self.ibox(indent_unit)?;
-        self.word_space("->")?;
-        match decl.output {
-            hir::NoReturn(_) => self.word_nbsp("!")?,
-            hir::DefaultReturn(..) => unreachable!(),
-            hir::Return(ref ty) => self.print_type(&ty)?,
-        }
-        self.end()?;
-
-        match decl.output {
-            hir::Return(ref output) => self.maybe_print_comment(output.span.lo),
-            _ => Ok(()),
-        }
-    }
-
-    pub fn print_ty_fn(&mut self,
-                       abi: Abi,
-                       unsafety: hir::Unsafety,
-                       decl: &hir::FnDecl,
-                       name: Option<ast::Name>,
-                       generics: &hir::Generics,
-                       opt_explicit_self: Option<&hir::ExplicitSelf_>)
-                       -> io::Result<()> {
-        self.ibox(indent_unit)?;
-        if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
-            word(&mut self.s, "for")?;
-            self.print_generics(generics)?;
-        }
-        let generics = hir::Generics {
-            lifetimes: hir::HirVec::new(),
-            ty_params: hir::HirVec::new(),
-            where_clause: hir::WhereClause {
-                id: ast::DUMMY_NODE_ID,
-                predicates: hir::HirVec::new(),
-            },
-        };
-        self.print_fn(decl,
-                      unsafety,
-                      hir::Constness::NotConst,
-                      abi,
-                      name,
-                      &generics,
-                      opt_explicit_self,
-                      hir::Inherited)?;
-        self.end()
-    }
-
-    pub fn maybe_print_trailing_comment(&mut self,
-                                        span: codemap::Span,
-                                        next_pos: Option<BytePos>)
-                                        -> io::Result<()> {
-        let cm = match self.cm {
-            Some(cm) => cm,
-            _ => return Ok(()),
-        };
-        match self.next_comment() {
-            Some(ref cmnt) => {
-                if (*cmnt).style != comments::Trailing {
-                    return Ok(());
-                }
-                let span_line = cm.lookup_char_pos(span.hi);
-                let comment_line = cm.lookup_char_pos((*cmnt).pos);
-                let mut next = (*cmnt).pos + BytePos(1);
-                match next_pos {
-                    None => (),
-                    Some(p) => next = p,
-                }
-                if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
-                   span_line.line == comment_line.line {
-                    self.print_comment(cmnt)?;
-                    self.cur_cmnt_and_lit.cur_cmnt += 1;
-                }
-            }
-            _ => (),
-        }
-        Ok(())
-    }
-
-    pub fn print_remaining_comments(&mut self) -> io::Result<()> {
-        // If there aren't any remaining comments, then we need to manually
-        // make sure there is a line break at the end.
-        if self.next_comment().is_none() {
-            hardbreak(&mut self.s)?;
-        }
-        loop {
-            match self.next_comment() {
-                Some(ref cmnt) => {
-                    self.print_comment(cmnt)?;
-                    self.cur_cmnt_and_lit.cur_cmnt += 1;
-                }
-                _ => break,
-            }
-        }
-        Ok(())
-    }
-
-    pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
-                                                  opt_abi: Option<Abi>)
-                                                  -> io::Result<()> {
-        match opt_abi {
-            Some(Abi::Rust) => Ok(()),
-            Some(abi) => {
-                self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
-            }
-            None => Ok(()),
-        }
-    }
-
-    pub fn print_extern_opt_abi(&mut self, opt_abi: Option<Abi>) -> io::Result<()> {
-        match opt_abi {
-            Some(abi) => {
-                self.word_nbsp("extern")?;
-                self.word_nbsp(&abi.to_string())
-            }
-            None => Ok(()),
-        }
-    }
-
-    pub fn print_fn_header_info(&mut self,
-                                unsafety: hir::Unsafety,
-                                constness: hir::Constness,
-                                abi: Abi,
-                                vis: hir::Visibility)
-                                -> io::Result<()> {
-        word(&mut self.s, &visibility_qualified(vis, ""))?;
-        self.print_unsafety(unsafety)?;
-
-        match constness {
-            hir::Constness::NotConst => {}
-            hir::Constness::Const => self.word_nbsp("const")?,
-        }
-
-        if abi != Abi::Rust {
-            self.word_nbsp("extern")?;
-            self.word_nbsp(&abi.to_string())?;
-        }
-
-        word(&mut self.s, "fn")
-    }
-
-    pub fn print_unsafety(&mut self, s: hir::Unsafety) -> io::Result<()> {
-        match s {
-            hir::Unsafety::Normal => Ok(()),
-            hir::Unsafety::Unsafe => self.word_nbsp("unsafe"),
-        }
-    }
-}
-
-// Dup'ed from parse::classify, but adapted for the HIR.
-/// Does this expression require a semicolon to be treated
-/// as a statement? The negation of this: 'can this expression
-/// be used as a statement without a semicolon' -- is used
-/// as an early-bail-out in the parser so that, for instance,
-///     if true {...} else {...}
-///      |x| 5
-/// isn't parsed as (if true {...} else {...} | x) | 5
-fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
-    match e.node {
-        hir::ExprIf(..) |
-        hir::ExprMatch(..) |
-        hir::ExprBlock(_) |
-        hir::ExprWhile(..) |
-        hir::ExprLoop(..) => false,
-        _ => true,
-    }
-}
-
-/// this statement requires a semicolon after it.
-/// note that in one case (stmt_semi), we've already
-/// seen the semicolon, and thus don't need another.
-fn stmt_ends_with_semi(stmt: &hir::Stmt_) -> bool {
-    match *stmt {
-        hir::StmtDecl(ref d, _) => {
-            match d.node {
-                hir::DeclLocal(_) => true,
-                hir::DeclItem(_) => false,
-            }
-        }
-        hir::StmtExpr(ref e, _) => {
-            expr_requires_semi_to_be_stmt(&e)
-        }
-        hir::StmtSemi(..) => {
-            false
-        }
-    }
-}
diff --git a/src/librustc_front/util.rs b/src/librustc_front/util.rs
deleted file mode 100644
index f4f9cb75eaf..00000000000
--- a/src/librustc_front/util.rs
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use hir;
-use hir::*;
-use intravisit::{self, Visitor, FnKind};
-use syntax::ast_util;
-use syntax::ast::{Name, NodeId, DUMMY_NODE_ID};
-use syntax::codemap::Span;
-use syntax::ptr::P;
-
-pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool
-    where F: FnMut(&Pat) -> bool
-{
-    // FIXME(#19596) this is a workaround, but there should be a better way
-    fn walk_pat_<G>(pat: &Pat, it: &mut G) -> bool
-        where G: FnMut(&Pat) -> bool
-    {
-        if !it(pat) {
-            return false;
-        }
-
-        match pat.node {
-            PatKind::Ident(_, _, Some(ref p)) => walk_pat_(&p, it),
-            PatKind::Struct(_, ref fields, _) => {
-                fields.iter().all(|field| walk_pat_(&field.node.pat, it))
-            }
-            PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => {
-                s.iter().all(|p| walk_pat_(&p, it))
-            }
-            PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
-                walk_pat_(&s, it)
-            }
-            PatKind::Vec(ref before, ref slice, ref after) => {
-                before.iter().all(|p| walk_pat_(&p, it)) &&
-                slice.iter().all(|p| walk_pat_(&p, it)) &&
-                after.iter().all(|p| walk_pat_(&p, it))
-            }
-            PatKind::Wild |
-            PatKind::Lit(_) |
-            PatKind::Range(_, _) |
-            PatKind::Ident(_, _, _) |
-            PatKind::TupleStruct(..) |
-            PatKind::Path(..) |
-            PatKind::QPath(_, _) => {
-                true
-            }
-        }
-    }
-
-    walk_pat_(pat, &mut it)
-}
-
-pub fn binop_to_string(op: BinOp_) -> &'static str {
-    match op {
-        BiAdd => "+",
-        BiSub => "-",
-        BiMul => "*",
-        BiDiv => "/",
-        BiRem => "%",
-        BiAnd => "&&",
-        BiOr => "||",
-        BiBitXor => "^",
-        BiBitAnd => "&",
-        BiBitOr => "|",
-        BiShl => "<<",
-        BiShr => ">>",
-        BiEq => "==",
-        BiLt => "<",
-        BiLe => "<=",
-        BiNe => "!=",
-        BiGe => ">=",
-        BiGt => ">",
-    }
-}
-
-pub fn stmt_id(s: &Stmt) -> NodeId {
-    match s.node {
-        StmtDecl(_, id) => id,
-        StmtExpr(_, id) => id,
-        StmtSemi(_, id) => id,
-    }
-}
-
-pub fn lazy_binop(b: BinOp_) -> bool {
-    match b {
-        BiAnd => true,
-        BiOr => true,
-        _ => false,
-    }
-}
-
-pub fn is_shift_binop(b: BinOp_) -> bool {
-    match b {
-        BiShl => true,
-        BiShr => true,
-        _ => false,
-    }
-}
-
-pub fn is_comparison_binop(b: BinOp_) -> bool {
-    match b {
-        BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true,
-        BiAnd |
-        BiOr |
-        BiAdd |
-        BiSub |
-        BiMul |
-        BiDiv |
-        BiRem |
-        BiBitXor |
-        BiBitAnd |
-        BiBitOr |
-        BiShl |
-        BiShr => false,
-    }
-}
-
-/// Returns `true` if the binary operator takes its arguments by value
-pub fn is_by_value_binop(b: BinOp_) -> bool {
-    !is_comparison_binop(b)
-}
-
-/// Returns `true` if the unary operator takes its argument by value
-pub fn is_by_value_unop(u: UnOp) -> bool {
-    match u {
-        UnNeg | UnNot => true,
-        _ => false,
-    }
-}
-
-pub fn unop_to_string(op: UnOp) -> &'static str {
-    match op {
-        UnDeref => "*",
-        UnNot => "!",
-        UnNeg => "-",
-    }
-}
-
-pub struct IdVisitor<'a, O: 'a> {
-    operation: &'a mut O,
-
-    // In general, the id visitor visits the contents of an item, but
-    // not including nested trait/impl items, nor other nested items.
-    // The base visitor itself always skips nested items, but not
-    // trait/impl items. This means in particular that if you start by
-    // visiting a trait or an impl, you should not visit the
-    // trait/impl items respectively.  This is handled by setting
-    // `skip_members` to true when `visit_item` is on the stack. This
-    // way, if the user begins by calling `visit_trait_item`, we will
-    // visit the trait item, but if they begin with `visit_item`, we
-    // won't visit the (nested) trait items.
-    skip_members: bool,
-}
-
-impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> {
-    pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> {
-        IdVisitor { operation: operation, skip_members: false }
-    }
-
-    fn visit_generics_helper(&mut self, generics: &Generics) {
-        for type_parameter in generics.ty_params.iter() {
-            self.operation.visit_id(type_parameter.id)
-        }
-        for lifetime in &generics.lifetimes {
-            self.operation.visit_id(lifetime.lifetime.id)
-        }
-    }
-}
-
-impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
-    fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) {
-        self.operation.visit_id(node_id);
-        intravisit::walk_mod(self, module)
-    }
-
-    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
-        self.operation.visit_id(foreign_item.id);
-        intravisit::walk_foreign_item(self, foreign_item)
-    }
-
-    fn visit_item(&mut self, item: &Item) {
-        assert!(!self.skip_members);
-        self.skip_members = true;
-
-        self.operation.visit_id(item.id);
-        match item.node {
-            ItemUse(ref view_path) => {
-                match view_path.node {
-                    ViewPathSimple(_, _) |
-                    ViewPathGlob(_) => {}
-                    ViewPathList(_, ref paths) => {
-                        for path in paths {
-                            self.operation.visit_id(path.node.id())
-                        }
-                    }
-                }
-            }
-            _ => {}
-        }
-        intravisit::walk_item(self, item);
-
-        self.skip_members = false;
-    }
-
-    fn visit_local(&mut self, local: &Local) {
-        self.operation.visit_id(local.id);
-        intravisit::walk_local(self, local)
-    }
-
-    fn visit_block(&mut self, block: &Block) {
-        self.operation.visit_id(block.id);
-        intravisit::walk_block(self, block)
-    }
-
-    fn visit_stmt(&mut self, statement: &Stmt) {
-        self.operation.visit_id(stmt_id(statement));
-        intravisit::walk_stmt(self, statement)
-    }
-
-    fn visit_pat(&mut self, pattern: &Pat) {
-        self.operation.visit_id(pattern.id);
-        intravisit::walk_pat(self, pattern)
-    }
-
-    fn visit_expr(&mut self, expression: &Expr) {
-        self.operation.visit_id(expression.id);
-        intravisit::walk_expr(self, expression)
-    }
-
-    fn visit_ty(&mut self, typ: &Ty) {
-        self.operation.visit_id(typ.id);
-        intravisit::walk_ty(self, typ)
-    }
-
-    fn visit_generics(&mut self, generics: &Generics) {
-        self.visit_generics_helper(generics);
-        intravisit::walk_generics(self, generics)
-    }
-
-    fn visit_fn(&mut self,
-                function_kind: FnKind<'v>,
-                function_declaration: &'v FnDecl,
-                block: &'v Block,
-                span: Span,
-                node_id: NodeId) {
-        self.operation.visit_id(node_id);
-
-        match function_kind {
-            FnKind::ItemFn(_, generics, _, _, _, _, _) => {
-                self.visit_generics_helper(generics)
-            }
-            FnKind::Method(_, sig, _, _) => {
-                self.visit_generics_helper(&sig.generics)
-            }
-            FnKind::Closure(_) => {}
-        }
-
-        for argument in &function_declaration.inputs {
-            self.operation.visit_id(argument.id)
-        }
-
-        intravisit::walk_fn(self, function_kind, function_declaration, block, span);
-    }
-
-    fn visit_struct_field(&mut self, struct_field: &StructField) {
-        self.operation.visit_id(struct_field.id);
-        intravisit::walk_struct_field(self, struct_field)
-    }
-
-    fn visit_variant_data(&mut self,
-                          struct_def: &VariantData,
-                          _: Name,
-                          _: &hir::Generics,
-                          _: NodeId,
-                          _: Span) {
-        self.operation.visit_id(struct_def.id());
-        intravisit::walk_struct_def(self, struct_def);
-    }
-
-    fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
-        if !self.skip_members {
-            self.operation.visit_id(ti.id);
-            intravisit::walk_trait_item(self, ti);
-        }
-    }
-
-    fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
-        if !self.skip_members {
-            self.operation.visit_id(ii.id);
-            intravisit::walk_impl_item(self, ii);
-        }
-    }
-
-    fn visit_lifetime(&mut self, lifetime: &Lifetime) {
-        self.operation.visit_id(lifetime.id);
-    }
-
-    fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
-        self.visit_lifetime(&def.lifetime);
-    }
-
-    fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
-        self.operation.visit_id(trait_ref.ref_id);
-        intravisit::walk_trait_ref(self, trait_ref);
-    }
-}
-
-/// Computes the id range for a single fn body, ignoring nested items.
-pub fn compute_id_range_for_fn_body(fk: FnKind,
-                                    decl: &FnDecl,
-                                    body: &Block,
-                                    sp: Span,
-                                    id: NodeId)
-                                    -> ast_util::IdRange {
-    let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() };
-    let mut id_visitor = IdVisitor::new(&mut visitor);
-    id_visitor.visit_fn(fk, decl, body, sp, id);
-    id_visitor.operation.result
-}
-
-pub fn is_path(e: P<Expr>) -> bool {
-    match e.node {
-        ExprPath(..) => true,
-        _ => false,
-    }
-}
-
-pub fn empty_generics() -> Generics {
-    Generics {
-        lifetimes: HirVec::new(),
-        ty_params: HirVec::new(),
-        where_clause: WhereClause {
-            id: DUMMY_NODE_ID,
-            predicates: HirVec::new(),
-        },
-    }
-}
-
-// convert a span and an identifier to the corresponding
-// 1-segment path
-pub fn ident_to_path(s: Span, ident: Ident) -> Path {
-    hir::Path {
-        span: s,
-        global: false,
-        segments: hir_vec![hir::PathSegment {
-            identifier: ident,
-            parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
-                lifetimes: HirVec::new(),
-                types: HirVec::new(),
-                bindings: HirVec::new(),
-            }),
-        }],
-    }
-}