about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-07-31 00:04:06 -0700
committerNick Cameron <ncameron@mozilla.com>2015-09-03 10:02:36 +1200
commitfacdf2ebb1dce9400a8c8ef0d85d7d278654effb (patch)
tree3ba46bd98df35b4b5d1bc5f1ba491d14adb6f373 /src/librustc
parentcfd76b364cd01695517467299618ef63f1c0cc07 (diff)
downloadrust-facdf2ebb1dce9400a8c8ef0d85d7d278654effb.tar.gz
rust-facdf2ebb1dce9400a8c8ef0d85d7d278654effb.zip
Add an intital HIR and lowering step
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/front/map/blocks.rs (renamed from src/librustc/ast_map/blocks.rs)37
-rw-r--r--src/librustc/front/map/mod.rs (renamed from src/librustc/ast_map/mod.rs)50
-rw-r--r--src/librustc/lib.rs5
-rw-r--r--src/librustc/lint/context.rs37
-rw-r--r--src/librustc/lint/mod.rs2
-rw-r--r--src/librustc/metadata/creader.rs77
-rw-r--r--src/librustc/metadata/csearch.rs17
-rw-r--r--src/librustc/metadata/cstore.rs4
-rw-r--r--src/librustc/metadata/decoder.rs81
-rw-r--r--src/librustc/metadata/encoder.rs40
-rw-r--r--src/librustc/metadata/inline.rs27
-rw-r--r--src/librustc/metadata/macro_import.rs5
-rw-r--r--src/librustc/metadata/tydecode.rs14
-rw-r--r--src/librustc/metadata/tyencode.rs39
-rw-r--r--src/librustc/middle/astconv_util.rs2
-rw-r--r--src/librustc/middle/astencode.rs66
-rw-r--r--src/librustc/middle/cast.rs2
-rw-r--r--src/librustc/middle/cfg/construct.rs172
-rw-r--r--src/librustc/middle/cfg/graphviz.rs2
-rw-r--r--src/librustc/middle/cfg/mod.rs3
-rw-r--r--src/librustc/middle/check_const.rs183
-rw-r--r--src/librustc/middle/check_loop.rs22
-rw-r--r--src/librustc/middle/check_match.rs168
-rw-r--r--src/librustc/middle/check_rvalues.rs13
-rw-r--r--src/librustc/middle/check_static_recursion.rs53
-rw-r--r--src/librustc/middle/const_eval.rs311
-rw-r--r--src/librustc/middle/dataflow.rs19
-rw-r--r--src/librustc/middle/dead.rs132
-rw-r--r--src/librustc/middle/def.rs3
-rw-r--r--src/librustc/middle/effect.rs39
-rw-r--r--src/librustc/middle/entry.rs39
-rw-r--r--src/librustc/middle/expr_use_visitor.rs198
-rw-r--r--src/librustc/middle/fast_reject.rs8
-rw-r--r--src/librustc/middle/infer/combine.rs6
-rw-r--r--src/librustc/middle/infer/error_reporting.rs256
-rw-r--r--src/librustc/middle/infer/mod.rs7
-rw-r--r--src/librustc/middle/infer/unify_key.rs2
-rw-r--r--src/librustc/middle/intrinsicck.rs12
-rw-r--r--src/librustc/middle/lang_items.rs18
-rw-r--r--src/librustc/middle/liveness.rs244
-rw-r--r--src/librustc/middle/mem_categorization.rs119
-rw-r--r--src/librustc/middle/pat_util.rs87
-rw-r--r--src/librustc/middle/reachable.rs87
-rw-r--r--src/librustc/middle/region.rs110
-rw-r--r--src/librustc/middle/resolve_lifetime.rs134
-rw-r--r--src/librustc/middle/stability.rs59
-rw-r--r--src/librustc/middle/traits/error_reporting.rs2
-rw-r--r--src/librustc/middle/traits/select.rs11
-rw-r--r--src/librustc/middle/ty.rs514
-rw-r--r--src/librustc/middle/ty_fold.rs4
-rw-r--r--src/librustc/middle/ty_relate/mod.rs2
-rw-r--r--src/librustc/middle/weak_lang_items.rs12
-rw-r--r--src/librustc/plugin/build.rs14
-rw-r--r--src/librustc/session/config.rs16
-rw-r--r--src/librustc/util/common.rs24
-rw-r--r--src/librustc/util/ppaux.rs52
56 files changed, 1859 insertions, 1803 deletions
diff --git a/src/librustc/ast_map/blocks.rs b/src/librustc/front/map/blocks.rs
index 8f24d20ebbf..4e16d9e5670 100644
--- a/src/librustc/ast_map/blocks.rs
+++ b/src/librustc/front/map/blocks.rs
@@ -23,12 +23,13 @@
 
 pub use self::Code::*;
 
-use ast_map::{self, Node};
+use front::map::{self, Node};
 use syntax::abi;
-use syntax::ast::{Block, FnDecl, NodeId};
-use syntax::ast;
+use rustc_front::hir::{Block, FnDecl};
+use syntax::ast::{NodeId, Ident};
+use rustc_front::hir as ast;
 use syntax::codemap::Span;
-use syntax::visit::FnKind;
+use rustc_front::visit::FnKind;
 
 /// An FnLikeNode is a Node that is like a fn, in that it has a decl
 /// and a body (as well as a NodeId, a span, etc).
@@ -40,7 +41,7 @@ use syntax::visit::FnKind;
 ///
 /// To construct one, use the `Code::from_node` function.
 #[derive(Copy, Clone)]
-pub struct FnLikeNode<'a> { node: ast_map::Node<'a> }
+pub struct FnLikeNode<'a> { node: map::Node<'a> }
 
 /// MaybeFnLike wraps a method that indicates if an object
 /// corresponds to some FnLikeNode.
@@ -86,7 +87,7 @@ pub enum Code<'a> {
 }
 
 impl<'a> Code<'a> {
-    pub fn id(&self) -> ast::NodeId {
+    pub fn id(&self) -> NodeId {
         match *self {
             FnLikeCode(node) => node.id(),
             BlockCode(block) => block.id,
@@ -95,7 +96,7 @@ impl<'a> Code<'a> {
 
     /// Attempts to construct a Code from presumed FnLike or Block node input.
     pub fn from_node(node: Node) -> Option<Code> {
-        if let ast_map::NodeBlock(block) = node {
+        if let map::NodeBlock(block) = node {
             Some(BlockCode(block))
         } else {
             FnLikeNode::from_node(node).map(|fn_like| FnLikeCode(fn_like))
@@ -106,7 +107,7 @@ impl<'a> Code<'a> {
 /// These are all the components one can extract from a fn item for
 /// use when implementing FnLikeNode operations.
 struct ItemFnParts<'a> {
-    ident:    ast::Ident,
+    ident:    Ident,
     decl:     &'a ast::FnDecl,
     unsafety: ast::Unsafety,
     constness: ast::Constness,
@@ -114,7 +115,7 @@ struct ItemFnParts<'a> {
     vis:      ast::Visibility,
     generics: &'a ast::Generics,
     body:     &'a Block,
-    id:       ast::NodeId,
+    id:       NodeId,
     span:     Span
 }
 
@@ -137,10 +138,10 @@ impl<'a> FnLikeNode<'a> {
     /// Attempts to construct a FnLikeNode from presumed FnLike node input.
     pub fn from_node(node: Node) -> Option<FnLikeNode> {
         let fn_like = match node {
-            ast_map::NodeItem(item) => item.is_fn_like(),
-            ast_map::NodeTraitItem(tm) => tm.is_fn_like(),
-            ast_map::NodeImplItem(_) => true,
-            ast_map::NodeExpr(e) => e.is_fn_like(),
+            map::NodeItem(item) => item.is_fn_like(),
+            map::NodeTraitItem(tm) => tm.is_fn_like(),
+            map::NodeImplItem(_) => true,
+            map::NodeExpr(e) => e.is_fn_like(),
             _ => false
         };
         if fn_like {
@@ -202,7 +203,7 @@ impl<'a> FnLikeNode<'a> {
     fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
         I: FnOnce(ItemFnParts<'a>) -> A,
         M: FnOnce(NodeId,
-                  ast::Ident,
+                  Ident,
                   &'a ast::MethodSig,
                   Option<ast::Visibility>,
                   &'a ast::Block,
@@ -211,7 +212,7 @@ impl<'a> FnLikeNode<'a> {
         C: FnOnce(ClosureParts<'a>) -> A,
     {
         match self.node {
-            ast_map::NodeItem(i) => match i.node {
+            map::NodeItem(i) => match i.node {
                 ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) =>
                     item_fn(ItemFnParts {
                         id: i.id,
@@ -227,13 +228,13 @@ impl<'a> FnLikeNode<'a> {
                     }),
                 _ => panic!("item FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeTraitItem(ti) => match ti.node {
+            map::NodeTraitItem(ti) => match ti.node {
                 ast::MethodTraitItem(ref sig, Some(ref body)) => {
                     method(ti.id, ti.ident, sig, None, body, ti.span)
                 }
                 _ => panic!("trait method FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeImplItem(ii) => {
+            map::NodeImplItem(ii) => {
                 match ii.node {
                     ast::MethodImplItem(ref sig, ref body) => {
                         method(ii.id, ii.ident, sig, Some(ii.vis), body, ii.span)
@@ -243,7 +244,7 @@ impl<'a> FnLikeNode<'a> {
                     }
                 }
             }
-            ast_map::NodeExpr(e) => match e.node {
+            map::NodeExpr(e) => match e.node {
                 ast::ExprClosure(_, ref decl, ref block) =>
                     closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
                 _ => panic!("expr FnLikeNode that is not fn-like"),
diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/front/map/mod.rs
index a212594a326..764f54ce0f0 100644
--- a/src/librustc/ast_map/mod.rs
+++ b/src/librustc/front/map/mod.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -15,14 +15,17 @@ use self::MapEntry::*;
 use metadata::inline::InlinedItem;
 use metadata::inline::InlinedItem as II;
 use middle::def_id::DefId;
+
 use syntax::abi;
-use syntax::ast::*;
-use syntax::ast_util;
-use syntax::codemap::{DUMMY_SP, Span, Spanned};
-use syntax::fold::Folder;
+use syntax::ast::{Name, NodeId, Ident, CRATE_NODE_ID, DUMMY_NODE_ID};
+use syntax::codemap::{Span, Spanned};
 use syntax::parse::token;
-use syntax::print::pprust;
-use syntax::visit::{self, Visitor};
+
+use rustc_front::hir::*;
+use rustc_front::fold::Folder;
+use rustc_front::visit::{self, Visitor};
+use rustc_front::util;
+use rustc_front::print::pprust;
 
 use arena::TypedArena;
 use std::cell::RefCell;
@@ -159,7 +162,7 @@ impl<'ast> Clone for MapEntry<'ast> {
 }
 
 #[derive(Debug)]
-struct InlinedParent {
+pub struct InlinedParent {
     path: Vec<PathElem>,
     ii: InlinedItem
 }
@@ -227,7 +230,7 @@ impl<'ast> MapEntry<'ast> {
 
 /// Stores a crate and any number of inlined items from other crates.
 pub struct Forest {
-    krate: Crate,
+    pub krate: Crate,
     inlined_items: TypedArena<InlinedParent>
 }
 
@@ -246,9 +249,10 @@ impl Forest {
 
 /// Represents a mapping from Node IDs to AST elements and their parent
 /// Node IDs
+#[derive(Clone)]
 pub struct Map<'ast> {
     /// The backing storage for all the AST nodes.
-    forest: &'ast Forest,
+    pub forest: &'ast Forest,
 
     /// NodeIds are sequential integers from 0, so we can be
     /// super-compact by storing them in a vector. Not everything with
@@ -870,7 +874,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
     }
 
     fn visit_stmt(&mut self, stmt: &'ast Stmt) {
-        let id = ast_util::stmt_id(stmt);
+        let id = util::stmt_id(stmt);
         self.insert(id, NodeStmt(stmt));
         let parent_node = self.parent_node;
         self.parent_node = id;
@@ -917,20 +921,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
     }
 }
 
-pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map<'ast> {
-    // Replace the crate with an empty one to take it out.
-    let krate = mem::replace(&mut forest.krate, Crate {
-        module: Mod {
-            inner: DUMMY_SP,
-            items: vec![],
-        },
-        attrs: vec![],
-        config: vec![],
-        exported_macros: vec![],
-        span: DUMMY_SP
-    });
-    forest.krate = IdAndSpanUpdater { fold_ops: fold_ops }.fold_crate(krate);
-
+pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
     let mut collector = NodeCollector {
         map: vec![],
         parent_node: CRATE_NODE_ID,
@@ -974,11 +965,11 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
         II::Item(i) => II::Item(fld.fold_item(i).expect_one("expected one item")),
         II::TraitItem(d, ti) => {
             II::TraitItem(fld.fold_ops.new_def_id(d),
-                          fld.fold_trait_item(ti).expect_one("expected one trait item"))
+                        fld.fold_trait_item(ti).expect_one("expected one trait item"))
         }
         II::ImplItem(d, ii) => {
             II::ImplItem(fld.fold_ops.new_def_id(d),
-                         fld.fold_impl_item(ii).expect_one("expected one impl item"))
+                       fld.fold_impl_item(ii).expect_one("expected one impl item"))
         }
         II::Foreign(i) => II::Foreign(fld.fold_foreign_item(i))
     };
@@ -1064,7 +1055,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 ItemTrait(..) => "trait",
                 ItemImpl(..) => "impl",
                 ItemDefaultImpl(..) => "default impl",
-                ItemMac(..) => "macro"
             };
             format!("{} {}{}", item_str, path_str, id_str)
         }
@@ -1091,10 +1081,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                             map.path_to_string(id),
                             id_str)
                 }
-                MacImplItem(ref mac) => {
-                    format!("method macro {}{}",
-                            pprust::mac_to_string(mac), id_str)
-                }
             }
         }
         Some(NodeTraitItem(ti)) => {
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 07ca6129505..f6a877bafce 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -73,6 +73,7 @@ extern crate graphviz;
 extern crate libc;
 extern crate rustc_llvm;
 extern crate rustc_back;
+extern crate rustc_front;
 extern crate rustc_data_structures;
 extern crate serialize;
 extern crate rbml;
@@ -101,7 +102,9 @@ pub mod back {
     pub use rustc_back::svh;
 }
 
-pub mod ast_map;
+pub mod front {
+    pub mod map;
+}
 
 pub mod middle {
     pub mod astconv_util;
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 144dc15dd8a..f8a06bab3dd 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -283,6 +283,7 @@ macro_rules! run_lints { ($cx:expr, $f:ident, $($args:expr),*) => ({
 
 /// Parse the lint attributes into a vector, with `Err`s for malformed lint
 /// attributes. Writing this as an iterator is an enormous mess.
+// See also the hir version just below.
 pub fn gather_attrs(attrs: &[ast::Attribute])
                     -> Vec<Result<(InternedString, Level, Span), Span>> {
     let mut out = vec!();
@@ -312,6 +313,40 @@ pub fn gather_attrs(attrs: &[ast::Attribute])
     }
     out
 }
+// Copy-pasted from the above function :-(
+pub fn gather_attrs_from_hir(attrs: &[::rustc_front::hir::Attribute])
+                             -> Vec<Result<(InternedString, Level, Span), Span>> {
+    use ::rustc_front::attr::AttrMetaMethods;
+
+    let mut out = vec!();
+    for attr in attrs {
+        let level = match Level::from_str(&attr.name()) {
+            None => continue,
+            Some(lvl) => lvl,
+        };
+
+        ::rustc_front::attr::mark_used(attr);
+
+        let meta = &attr.node.value;
+        let metas = match meta.node {
+            ::rustc_front::hir::MetaList(_, ref metas) => metas,
+            _ => {
+                out.push(Err(meta.span));
+                continue;
+            }
+        };
+
+        for meta in metas {
+            out.push(match meta.node {
+                ::rustc_front::hir::MetaWord(ref lint_name) => {
+                    Ok((lint_name.clone(), level, meta.span))
+                }
+                _ => Err(meta.span),
+            });
+        }
+    }
+    out
+}
 
 /// Emit a lint as a warning or an error (or not at all)
 /// according to `level`.
@@ -696,9 +731,9 @@ impl LintPass for GatherNodeLevels {
 ///
 /// Consumes the `lint_store` field of the `Session`.
 pub fn check_crate(tcx: &ty::ctxt,
+                   krate: &ast::Crate,
                    exported_items: &ExportedItems) {
 
-    let krate = tcx.map.krate();
     let mut cx = Context::new(tcx, krate, exported_items);
 
     // Visit the whole crate.
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index fe893f62702..54b7aa81af3 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -38,7 +38,7 @@ use syntax::visit::FnKind;
 use syntax::ast;
 
 pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs,
-                        GatherNodeLevels};
+                        gather_attrs_from_hir, GatherNodeLevels};
 
 /// Specification of a single lint.
 #[derive(Copy, Clone, Debug)]
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 3f182b4d2b5..d758b253441 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -21,6 +21,7 @@ use metadata::decoder;
 use metadata::loader;
 use metadata::loader::CratePaths;
 use util::nodemap::FnvHashMap;
+use front::map as hir_map;
 
 use std::cell::{RefCell, Cell};
 use std::path::PathBuf;
@@ -29,20 +30,22 @@ use std::fs;
 
 use syntax::ast;
 use syntax::abi;
-use syntax::attr;
-use syntax::attr::AttrMetaMethods;
 use syntax::codemap::{self, Span, mk_sp, Pos};
 use syntax::parse;
+use syntax::attr;
 use syntax::parse::token::InternedString;
-use syntax::visit;
 use syntax::util::small_vector::SmallVector;
-use ast_map;
+use rustc_front::visit;
+use rustc_front::hir;
+use rustc_front::attr as attr_front;
+use rustc_front::attr::AttrMetaMethods;
+use rustc_front::lowering::unlower_attribute;
 use log;
 
 pub struct LocalCrateReader<'a, 'b:'a> {
     sess: &'a Session,
     creader: CrateReader<'a>,
-    ast_map: &'a ast_map::Map<'b>,
+    ast_map: &'a hir_map::Map<'b>,
 }
 
 pub struct CrateReader<'a> {
@@ -52,7 +55,7 @@ pub struct CrateReader<'a> {
 }
 
 impl<'a, 'b, 'v> visit::Visitor<'v> for LocalCrateReader<'a, 'b> {
-    fn visit_item(&mut self, a: &ast::Item) {
+    fn visit_item(&mut self, a: &hir::Item) {
         self.process_item(a);
         visit::walk_item(self, a);
     }
@@ -77,6 +80,11 @@ fn should_link(i: &ast::Item) -> bool {
     !attr::contains_name(&i.attrs, "no_link")
 }
 
+// Dup for the hir
+fn should_link_hir(i: &hir::Item) -> bool {
+    !attr_front::contains_name(&i.attrs, "no_link")
+}
+
 struct CrateInfo {
     ident: String,
     name: String,
@@ -188,6 +196,31 @@ impl<'a> CrateReader<'a> {
         }
     }
 
+    // Dup of the above, but for the hir
+    fn extract_crate_info_hir(&self, i: &hir::Item) -> Option<CrateInfo> {
+        match i.node {
+            hir::ItemExternCrate(ref path_opt) => {
+                debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
+                       i.ident, path_opt);
+                let name = match *path_opt {
+                    Some(name) => {
+                        validate_crate_name(Some(self.sess), &name.as_str(),
+                                            Some(i.span));
+                        name.to_string()
+                    }
+                    None => i.ident.to_string(),
+                };
+                Some(CrateInfo {
+                    ident: i.ident.to_string(),
+                    name: name,
+                    id: i.id,
+                    should_link: should_link_hir(i),
+                })
+            }
+            _ => None
+        }
+    }
+
     fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
                       -> Option<ast::CrateNum> {
         let mut ret = None;
@@ -295,7 +328,7 @@ impl<'a> CrateReader<'a> {
         let attrs = decoder::get_crate_attributes(data);
         for attr in &attrs {
             if &attr.name()[..] == "staged_api" {
-                match attr.node.value.node { ast::MetaWord(_) => return true, _ => (/*pass*/) }
+                match attr.node.value.node { hir::MetaWord(_) => return true, _ => (/*pass*/) }
             }
         }
 
@@ -425,11 +458,11 @@ impl<'a> CrateReader<'a> {
     }
 
     /// Read exported macros.
-    pub fn read_exported_macros(&mut self, krate: &ast::Item) -> Vec<ast::MacroDef> {
-        let ci = self.extract_crate_info(krate).unwrap();
-        let ekrate = self.read_extension_crate(krate.span, &ci);
+    pub fn read_exported_macros(&mut self, item: &ast::Item) -> Vec<ast::MacroDef> {
+        let ci = self.extract_crate_info(item).unwrap();
+        let ekrate = self.read_extension_crate(item.span, &ci);
 
-        let source_name = format!("<{} macros>", krate.ident);
+        let source_name = format!("<{} macros>", item.ident);
         let mut macros = vec![];
         decoder::each_exported_macro(ekrate.metadata.as_slice(),
                                      &*self.sess.cstore.intr,
@@ -449,10 +482,10 @@ impl<'a> CrateReader<'a> {
                 p.abort_if_errors();
                 macros.push(ast::MacroDef {
                     ident: name.ident(),
-                    attrs: attrs,
+                    attrs: attrs.iter().map(|a| unlower_attribute(a)).collect(),
                     id: ast::DUMMY_NODE_ID,
                     span: span,
-                    imported_from: Some(krate.ident),
+                    imported_from: Some(item.ident),
                     // overridden in plugin/load.rs
                     export: false,
                     use_locally: false,
@@ -639,7 +672,7 @@ impl<'a> CrateReader<'a> {
 }
 
 impl<'a, 'b> LocalCrateReader<'a, 'b> {
-    pub fn new(sess: &'a Session, map: &'a ast_map::Map<'b>) -> LocalCrateReader<'a, 'b> {
+    pub fn new(sess: &'a Session, map: &'a hir_map::Map<'b>) -> LocalCrateReader<'a, 'b> {
         LocalCrateReader {
             sess: sess,
             creader: CrateReader::new(sess),
@@ -650,7 +683,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
     // Traverses an AST, reading all the information about use'd crates and
     // extern libraries necessary for later resolving, typechecking, linking,
     // etc.
-    pub fn read_crates(&mut self, krate: &ast::Crate) {
+    pub fn read_crates(&mut self, krate: &hir::Crate) {
         self.process_crate(krate);
         visit::walk_crate(self, krate);
         self.creader.inject_allocator_crate();
@@ -665,7 +698,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
         self.creader.register_statically_included_foreign_items();
     }
 
-    fn process_crate(&self, c: &ast::Crate) {
+    fn process_crate(&self, c: &hir::Crate) {
         for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
             match a.value_str() {
                 Some(ref linkarg) => self.sess.cstore.add_used_link_args(&linkarg),
@@ -674,14 +707,14 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
         }
     }
 
-    fn process_item(&mut self, i: &ast::Item) {
+    fn process_item(&mut self, i: &hir::Item) {
         match i.node {
-            ast::ItemExternCrate(_) => {
-                if !should_link(i) {
+            hir::ItemExternCrate(_) => {
+                if !should_link_hir(i) {
                     return;
                 }
 
-                match self.creader.extract_crate_info(i) {
+                match self.creader.extract_crate_info_hir(i) {
                     Some(info) => {
                         let (cnum, cmeta, _) = self.creader.resolve_crate(&None,
                                                               &info.ident,
@@ -698,12 +731,12 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
                     None => ()
                 }
             }
-            ast::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm),
+            hir::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm),
             _ => { }
         }
     }
 
-    fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
+    fn process_foreign_mod(&mut self, i: &hir::Item, fm: &hir::ForeignMod) {
         if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic || fm.abi == abi::PlatformIntrinsic {
             return;
         }
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 79d98880164..91c7ac48918 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -10,7 +10,7 @@
 
 // Searching for information from the cstore
 
-use ast_map;
+use front::map as ast_map;
 use metadata::common::*;
 use metadata::cstore;
 use metadata::decoder;
@@ -23,7 +23,8 @@ use rbml;
 use rbml::reader;
 use std::rc::Rc;
 use syntax::ast;
-use syntax::attr;
+use rustc_front::attr;
+use rustc_front::hir;
 use syntax::diagnostic::expect;
 
 use std::collections::hash_map::HashMap;
@@ -32,7 +33,7 @@ use std::collections::hash_map::HashMap;
 pub struct MethodInfo {
     pub name: ast::Name,
     pub def_id: DefId,
-    pub vis: ast::Visibility,
+    pub vis: hir::Visibility,
 }
 
 pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String {
@@ -55,7 +56,7 @@ pub fn each_lang_item<F>(cstore: &cstore::CStore,
 pub fn each_child_of_item<F>(cstore: &cstore::CStore,
                              def_id: DefId,
                              callback: F) where
-    F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
+    F: FnMut(decoder::DefLike, ast::Name, hir::Visibility),
 {
     let crate_data = cstore.get_crate_data(def_id.krate);
     let get_crate_data = |cnum| {
@@ -72,7 +73,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore,
 pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
                                        cnum: ast::CrateNum,
                                        callback: F) where
-    F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
+    F: FnMut(decoder::DefLike, ast::Name, hir::Visibility),
 {
     let crate_data = cstore.get_crate_data(cnum);
     let get_crate_data = |cnum| {
@@ -190,7 +191,7 @@ pub fn get_methods_if_impl(cstore: &cstore::CStore,
 
 pub fn get_item_attrs(cstore: &cstore::CStore,
                       def_id: DefId)
-                      -> Vec<ast::Attribute> {
+                      -> Vec<hir::Attribute> {
     let cdata = cstore.get_crate_data(def_id.krate);
     decoder::get_item_attrs(&*cdata, def_id.node)
 }
@@ -201,7 +202,7 @@ pub fn get_struct_field_names(cstore: &cstore::CStore, def: DefId) -> Vec<ast::N
 }
 
 pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId) -> HashMap<ast::NodeId,
-        Vec<ast::Attribute>> {
+        Vec<hir::Attribute>> {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_struct_field_attrs(&*cdata)
 }
@@ -269,7 +270,7 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: DefId,
 
 pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
                                def: DefId)
-                               -> Option<ast::ImplPolarity>
+                               -> Option<hir::ImplPolarity>
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index 9179a0a1871..838f78163f0 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -27,12 +27,12 @@ use std::rc::Rc;
 use std::path::PathBuf;
 use flate::Bytes;
 use syntax::ast;
-use syntax::attr;
+use rustc_front::attr;
 use syntax::codemap;
 use syntax::parse::token;
 use syntax::parse::token::IdentInterner;
 use syntax::util::small_vector::SmallVector;
-use ast_map;
+use front::map as ast_map;
 
 // A map from external crate numbers (as decoded from some crate file) to
 // local crate numbers (as generated during this session). Each external
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index bceccc622af..5991b79896b 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -15,7 +15,10 @@
 pub use self::DefLike::*;
 use self::Family::*;
 
-use ast_map;
+use front::map as ast_map;
+use rustc_front::print::pprust;
+use rustc_front::hir;
+
 use back::svh::Svh;
 use metadata::cstore::crate_metadata;
 use metadata::common::*;
@@ -45,15 +48,15 @@ use std::str;
 use rbml::reader;
 use rbml;
 use serialize::Decodable;
-use syntax::abi;
-use syntax::attr;
+use rustc_front::attr;
 use syntax::parse::token::{IdentInterner, special_idents};
 use syntax::parse::token;
-use syntax::print::pprust;
 use syntax::ast;
+use syntax::abi;
 use syntax::codemap;
 use syntax::ptr::P;
 
+
 pub type Cmd<'a> = &'a crate_metadata;
 
 // A function that takes a def_id relative to the crate being searched and
@@ -158,26 +161,26 @@ fn item_family(item: rbml::Doc) -> Family {
     }
 }
 
-fn item_visibility(item: rbml::Doc) -> ast::Visibility {
+fn item_visibility(item: rbml::Doc) -> hir::Visibility {
     match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
-        None => ast::Public,
+        None => hir::Public,
         Some(visibility_doc) => {
             match reader::doc_as_u8(visibility_doc) as char {
-                'y' => ast::Public,
-                'i' => ast::Inherited,
+                'y' => hir::Public,
+                'i' => hir::Inherited,
                 _ => panic!("unknown visibility character")
             }
         }
     }
 }
 
-fn fn_constness(item: rbml::Doc) -> ast::Constness {
+fn fn_constness(item: rbml::Doc) -> hir::Constness {
     match reader::maybe_get_doc(item, tag_items_data_item_constness) {
-        None => ast::Constness::NotConst,
+        None => hir::Constness::NotConst,
         Some(constness_doc) => {
             match reader::doc_as_u8(constness_doc) as char {
-                'c' => ast::Constness::Const,
-                'n' => ast::Constness::NotConst,
+                'c' => hir::Constness::Const,
+                'n' => hir::Constness::NotConst,
                 _ => panic!("unknown constness character")
             }
         }
@@ -343,12 +346,12 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
     }
 }
 
-fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
+fn parse_unsafety(item_doc: rbml::Doc) -> hir::Unsafety {
     let unsafety_doc = reader::get_doc(item_doc, tag_unsafety);
     if reader::doc_as_u8(unsafety_doc) != 0 {
-        ast::Unsafety::Unsafe
+        hir::Unsafety::Unsafe
     } else {
-        ast::Unsafety::Normal
+        hir::Unsafety::Normal
     }
 }
 
@@ -357,12 +360,12 @@ fn parse_paren_sugar(item_doc: rbml::Doc) -> bool {
     reader::doc_as_u8(paren_sugar_doc) != 0
 }
 
-fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
+fn parse_polarity(item_doc: rbml::Doc) -> hir::ImplPolarity {
     let polarity_doc = reader::get_doc(item_doc, tag_polarity);
     if reader::doc_as_u8(polarity_doc) != 0 {
-        ast::ImplPolarity::Negative
+        hir::ImplPolarity::Negative
     } else {
-        ast::ImplPolarity::Positive
+        hir::ImplPolarity::Positive
     }
 }
 
@@ -560,7 +563,7 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
 
 pub fn get_impl_polarity<'tcx>(cdata: Cmd,
                                id: ast::NodeId)
-                               -> Option<ast::ImplPolarity>
+                               -> Option<hir::ImplPolarity>
 {
     let item_doc = lookup_item(id, cdata.data());
     let fam = item_family(item_doc);
@@ -633,7 +636,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
                                      item_doc: rbml::Doc,
                                      mut get_crate_data: G,
                                      mut callback: F) where
-    F: FnMut(DefLike, ast::Name, ast::Visibility),
+    F: FnMut(DefLike, ast::Name, hir::Visibility),
     G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
 {
     // Iterate over all children.
@@ -722,7 +725,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
             let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
             // These items have a public visibility because they're part of
             // a public re-export.
-            callback(def_like, token::intern(name), ast::Public);
+            callback(def_like, token::intern(name), hir::Public);
         }
     }
 }
@@ -733,7 +736,7 @@ pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
                                id: ast::NodeId,
                                get_crate_data: G,
                                callback: F) where
-    F: FnMut(DefLike, ast::Name, ast::Visibility),
+    F: FnMut(DefLike, ast::Name, hir::Visibility),
     G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
 {
     // Find the item.
@@ -756,7 +759,7 @@ pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
                                           cdata: Cmd,
                                           get_crate_data: G,
                                           callback: F) where
-    F: FnMut(DefLike, ast::Name, ast::Visibility),
+    F: FnMut(DefLike, ast::Name, hir::Visibility),
     G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
 {
     let root_doc = rbml::Doc::new(cdata.data());
@@ -810,10 +813,10 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
 }
 
 fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
-    fn get_mutability(ch: u8) -> ast::Mutability {
+    fn get_mutability(ch: u8) -> hir::Mutability {
         match ch as char {
-            'i' => ast::MutImmutable,
-            'm' => ast::MutMutable,
+            'i' => hir::MutImmutable,
+            'm' => hir::MutMutable,
             _ => panic!("unknown mutability character: `{}`", ch as char),
         }
     }
@@ -1074,7 +1077,7 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
 
 pub fn get_item_attrs(cdata: Cmd,
                       orig_node_id: ast::NodeId)
-                      -> Vec<ast::Attribute> {
+                      -> Vec<hir::Attribute> {
     // The attributes for a tuple struct are attached to the definition, not the ctor;
     // we assume that someone passing in a tuple struct ctor is actually wanting to
     // look at the definition
@@ -1084,7 +1087,7 @@ pub fn get_item_attrs(cdata: Cmd,
     get_attributes(item)
 }
 
-pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attribute>> {
+pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<hir::Attribute>> {
     let data = rbml::Doc::new(cdata.data());
     let fields = reader::get_doc(data, tag_struct_fields);
     reader::tagged_docs(fields, tag_struct_field).map(|field| {
@@ -1094,10 +1097,10 @@ pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attri
     }).collect()
 }
 
-fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
+fn struct_field_family_to_visibility(family: Family) -> hir::Visibility {
     match family {
-      PublicField => ast::Public,
-      InheritedField => ast::Inherited,
+      PublicField => hir::Public,
+      InheritedField => hir::Inherited,
       _ => panic!()
     }
 }
@@ -1113,7 +1116,7 @@ pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId)
     })).collect()
 }
 
-fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
+fn get_meta_items(md: rbml::Doc) -> Vec<P<hir::MetaItem>> {
     reader::tagged_docs(md, tag_meta_item_word).map(|meta_item_doc| {
         let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
         let n = token::intern_and_get_ident(nd.as_str_slice());
@@ -1134,7 +1137,7 @@ fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
     })).collect()
 }
 
-fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
+fn get_attributes(md: rbml::Doc) -> Vec<hir::Attribute> {
     match reader::maybe_get_doc(md, tag_attributes) {
         Some(attrs_d) => {
             reader::tagged_docs(attrs_d, tag_attribute).map(|attr_doc| {
@@ -1147,9 +1150,9 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
                 assert_eq!(meta_items.len(), 1);
                 let meta_item = meta_items.into_iter().nth(0).unwrap();
                 codemap::Spanned {
-                    node: ast::Attribute_ {
+                    node: hir::Attribute_ {
                         id: attr::mk_attr_id(),
-                        style: ast::AttrOuter,
+                        style: hir::AttrOuter,
                         value: meta_item,
                         is_sugared_doc: is_sugared_doc,
                     },
@@ -1173,7 +1176,7 @@ fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
     write!(out, "\n\n")
 }
 
-pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
+pub fn get_crate_attributes(data: &[u8]) -> Vec<hir::Attribute> {
     get_attributes(rbml::Doc::new(data))
 }
 
@@ -1371,7 +1374,7 @@ pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
 }
 
 pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
-    F: FnMut(ast::Name, Vec<ast::Attribute>, String) -> bool,
+    F: FnMut(ast::Name, Vec<hir::Attribute>, String) -> bool,
 {
     let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs);
     for macro_doc in reader::tagged_docs(macros, tag_macro_def) {
@@ -1453,8 +1456,8 @@ pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
 pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool {
     let item_doc = lookup_item(id, cdata.data());
     match fn_constness(item_doc) {
-        ast::Constness::Const => true,
-        ast::Constness::NotConst => false,
+        hir::Constness::Const => true,
+        hir::Constness::NotConst => false,
     }
 }
 
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 3f59d70642d..8085c643f19 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -13,7 +13,6 @@
 #![allow(unused_must_use)] // everything is just a MemWriter, can't fail
 #![allow(non_camel_case_types)]
 
-use ast_map::{self, LinkedPath, PathElem, PathElems};
 use back::svh::Svh;
 use session::config;
 use metadata::common::*;
@@ -35,17 +34,20 @@ use std::io::prelude::*;
 use std::io::{Cursor, SeekFrom};
 use std::rc::Rc;
 use syntax::abi;
-use syntax::ast::{self, NodeId};
-use syntax::attr;
-use syntax::attr::AttrMetaMethods;
+use syntax::ast::{NodeId, Name, CRATE_NODE_ID, CrateNum};
 use syntax::diagnostic::SpanHandler;
 use syntax::parse::token::special_idents;
-use syntax::print::pprust;
-use syntax::visit::Visitor;
-use syntax::visit;
 use syntax;
 use rbml::writer::Encoder;
 
+use rustc_front::hir as ast;
+use rustc_front::visit::Visitor;
+use rustc_front::visit;
+use rustc_front::attr;
+use rustc_front::attr::AttrMetaMethods;
+use front::map::{LinkedPath, PathElem, PathElems};
+use front::map as ast_map;
+
 pub type EncodeInlinedItem<'a> =
     Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
 
@@ -72,11 +74,11 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     pub reachable: &'a NodeSet,
 }
 
-fn encode_name(rbml_w: &mut Encoder, name: ast::Name) {
+fn encode_name(rbml_w: &mut Encoder, name: Name) {
     rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str());
 }
 
-fn encode_impl_type_basename(rbml_w: &mut Encoder, name: ast::Name) {
+fn encode_impl_type_basename(rbml_w: &mut Encoder, name: Name) {
     rbml_w.wr_tagged_str(tag_item_impl_type_basename, &name.as_str());
 }
 
@@ -130,7 +132,7 @@ fn encode_item_variances(rbml_w: &mut Encoder,
 
 fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder,
                                              ecx: &EncodeContext<'a, 'tcx>,
-                                             id: ast::NodeId) {
+                                             id: NodeId) {
     encode_bounds_and_type(rbml_w,
                            ecx,
                            &ecx.tcx.lookup_item_type(DefId::local(id)),
@@ -343,7 +345,7 @@ fn encode_path<PI: Iterator<Item=PathElem>>(rbml_w: &mut Encoder, path: PI) {
 fn encode_reexported_static_method(rbml_w: &mut Encoder,
                                    exp: &def::Export,
                                    method_def_id: DefId,
-                                   method_name: ast::Name) {
+                                   method_name: Name) {
     debug!("(encode reexported static method) {}::{}",
             exp.name, method_name);
     rbml_w.start_tag(tag_items_data_item_reexport);
@@ -500,7 +502,7 @@ fn encode_info_for_mod(ecx: &EncodeContext,
                        attrs: &[ast::Attribute],
                        id: NodeId,
                        path: PathElems,
-                       name: ast::Name,
+                       name: Name,
                        vis: ast::Visibility) {
     rbml_w.start_tag(tag_items_data_item);
     encode_def_id(rbml_w, DefId::local(id));
@@ -655,7 +657,7 @@ fn encode_info_for_struct<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 
 fn encode_info_for_struct_ctor(ecx: &EncodeContext,
                                rbml_w: &mut Encoder,
-                               name: ast::Name,
+                               name: Name,
                                ctor_id: NodeId,
                                index: &mut Vec<entry<i64>>,
                                struct_id: NodeId) {
@@ -1475,7 +1477,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
             rbml_w.end_tag();
         }
       }
-      ast::ItemExternCrate(_) | ast::ItemUse(_) |ast::ItemMac(..) => {
+      ast::ItemExternCrate(_) | ast::ItemUse(_) => {
         // these are encoded separately
       }
     }
@@ -1588,14 +1590,14 @@ fn encode_info_for_items(ecx: &EncodeContext,
     let mut index = Vec::new();
     rbml_w.start_tag(tag_items_data);
     index.push(entry {
-        val: ast::CRATE_NODE_ID as i64,
+        val: CRATE_NODE_ID as i64,
         pos: rbml_w.mark_stable_position(),
     });
     encode_info_for_mod(ecx,
                         rbml_w,
                         &krate.module,
                         &[],
-                        ast::CRATE_NODE_ID,
+                        CRATE_NODE_ID,
                         [].iter().cloned().chain(LinkedPath::empty()),
                         syntax::parse::token::special_idents::invalid.name,
                         ast::Public);
@@ -1727,7 +1729,7 @@ fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
     rbml_w.wr_tagged_u8(tag_defaulted_trait, byte);
 }
 
-fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
+fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[Name]) {
     rbml_w.start_tag(tag_associated_type_names);
     for &name in names {
         rbml_w.wr_tagged_str(tag_associated_type_name, &name.as_str());
@@ -1745,7 +1747,7 @@ fn encode_polarity(rbml_w: &mut Encoder, polarity: ast::ImplPolarity) {
 
 fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
     fn get_ordered_deps(cstore: &cstore::CStore)
-                        -> Vec<(ast::CrateNum, Rc<cstore::crate_metadata>)> {
+                        -> Vec<(CrateNum, Rc<cstore::crate_metadata>)> {
         // Pull the cnums and name,vers,hash out of cstore
         let mut deps = Vec::new();
         cstore.iter_crate_data(|cnum, val| {
@@ -1856,7 +1858,7 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
         encode_attributes(rbml_w, &def.attrs);
 
         rbml_w.wr_tagged_str(tag_macro_def_body,
-                             &pprust::tts_to_string(&def.body));
+                             &::syntax::print::pprust::tts_to_string(&def.body));
 
         rbml_w.end_tag();
     }
diff --git a/src/librustc/metadata/inline.rs b/src/librustc/metadata/inline.rs
index b311784def8..a5ca68e4350 100644
--- a/src/librustc/metadata/inline.rs
+++ b/src/librustc/metadata/inline.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 use middle::def_id::DefId;
-use syntax::ast;
-use syntax::ast_util::{IdRange, IdRangeComputingVisitor,
-                       IdVisitor, IdVisitingOperation};
+use rustc_front::hir;
+use rustc_front::util::IdVisitor;
+use syntax::ast_util::{IdRange, IdRangeComputingVisitor, IdVisitingOperation};
 use syntax::ptr::P;
-use syntax::visit::Visitor;
+use rustc_front::visit::Visitor;
 use self::InlinedItem::*;
 
 /// The data we save and restore about an inlined item or method.  This is not
@@ -21,18 +21,18 @@ use self::InlinedItem::*;
 /// that we trans.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum InlinedItem {
-    Item(P<ast::Item>),
-    TraitItem(DefId /* impl id */, P<ast::TraitItem>),
-    ImplItem(DefId /* impl id */, P<ast::ImplItem>),
-    Foreign(P<ast::ForeignItem>),
+    Item(P<hir::Item>),
+    TraitItem(DefId /* impl id */, P<hir::TraitItem>),
+    ImplItem(DefId /* impl id */, P<hir::ImplItem>),
+    Foreign(P<hir::ForeignItem>),
 }
 
-/// A borrowed version of `ast::InlinedItem`.
+/// A borrowed version of `hir::InlinedItem`.
 pub enum InlinedItemRef<'a> {
-    Item(&'a ast::Item),
-    TraitItem(DefId, &'a ast::TraitItem),
-    ImplItem(DefId, &'a ast::ImplItem),
-    Foreign(&'a ast::ForeignItem)
+    Item(&'a hir::Item),
+    TraitItem(DefId, &'a hir::TraitItem),
+    ImplItem(DefId, &'a hir::ImplItem),
+    Foreign(&'a hir::ForeignItem)
 }
 
 impl InlinedItem {
@@ -62,4 +62,3 @@ impl InlinedItem {
         visitor.result()
     }
 }
-
diff --git a/src/librustc/metadata/macro_import.rs b/src/librustc/metadata/macro_import.rs
index 08975bab600..527f5919e2d 100644
--- a/src/librustc/metadata/macro_import.rs
+++ b/src/librustc/metadata/macro_import.rs
@@ -14,13 +14,14 @@ use session::Session;
 use metadata::creader::CrateReader;
 
 use std::collections::{HashSet, HashMap};
-use syntax::ast;
-use syntax::attr;
 use syntax::codemap::Span;
 use syntax::parse::token;
+use syntax::ast;
+use syntax::attr;
 use syntax::visit;
 use syntax::visit::Visitor;
 use syntax::attr::AttrMetaMethods;
+use rustc_front::attr::AttrMetaMethods as FrontAttrMetaMethods;
 
 struct MacroLoader<'a> {
     sess: &'a Session,
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 0c802356af1..643cf132de2 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -18,6 +18,8 @@
 
 pub use self::DefIdSource::*;
 
+use rustc_front::hir;
+
 use middle::def_id::DefId;
 use middle::region;
 use middle::subst;
@@ -467,10 +469,10 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
         }
     }
 
-    fn parse_mutability(&mut self) -> ast::Mutability {
+    fn parse_mutability(&mut self) -> hir::Mutability {
         match self.peek() {
-            'm' => { self.next(); ast::MutMutable }
-            _ => { ast::MutImmutable }
+            'm' => { self.next(); hir::MutMutable }
+            _ => { hir::MutImmutable }
         }
     }
 
@@ -742,10 +744,10 @@ fn parse_defid(buf: &[u8]) -> DefId {
     DefId { krate: crate_num, node: def_num }
 }
 
-fn parse_unsafety(c: char) -> ast::Unsafety {
+fn parse_unsafety(c: char) -> hir::Unsafety {
     match c {
-        'u' => ast::Unsafety::Unsafe,
-        'n' => ast::Unsafety::Normal,
+        'u' => hir::Unsafety::Unsafe,
+        'n' => hir::Unsafety::Normal,
         _ => panic!("parse_unsafety: bad unsafety {}", c)
     }
 }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 70345dc8bad..d7554c4cf75 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -24,8 +24,9 @@ use middle::ty::ParamTy;
 use middle::ty::{self, Ty};
 use util::nodemap::FnvHashMap;
 
+use rustc_front::hir;
+
 use syntax::abi::Abi;
-use syntax::ast;
 use syntax::diagnostic::SpanHandler;
 
 use rbml::writer::Encoder;
@@ -64,26 +65,26 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
         ty::TyChar => mywrite!(w, "c"),
         ty::TyInt(t) => {
             match t {
-                ast::TyIs => mywrite!(w, "is"),
-                ast::TyI8 => mywrite!(w, "MB"),
-                ast::TyI16 => mywrite!(w, "MW"),
-                ast::TyI32 => mywrite!(w, "ML"),
-                ast::TyI64 => mywrite!(w, "MD")
+                hir::TyIs => mywrite!(w, "is"),
+                hir::TyI8 => mywrite!(w, "MB"),
+                hir::TyI16 => mywrite!(w, "MW"),
+                hir::TyI32 => mywrite!(w, "ML"),
+                hir::TyI64 => mywrite!(w, "MD")
             }
         }
         ty::TyUint(t) => {
             match t {
-                ast::TyUs => mywrite!(w, "us"),
-                ast::TyU8 => mywrite!(w, "Mb"),
-                ast::TyU16 => mywrite!(w, "Mw"),
-                ast::TyU32 => mywrite!(w, "Ml"),
-                ast::TyU64 => mywrite!(w, "Md")
+                hir::TyUs => mywrite!(w, "us"),
+                hir::TyU8 => mywrite!(w, "Mb"),
+                hir::TyU16 => mywrite!(w, "Mw"),
+                hir::TyU32 => mywrite!(w, "Ml"),
+                hir::TyU64 => mywrite!(w, "Md")
             }
         }
         ty::TyFloat(t) => {
             match t {
-                ast::TyF32 => mywrite!(w, "Mf"),
-                ast::TyF64 => mywrite!(w, "MF"),
+                hir::TyF32 => mywrite!(w, "Mf"),
+                hir::TyF64 => mywrite!(w, "MF"),
             }
         }
         ty::TyEnum(def, substs) => {
@@ -179,10 +180,10 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
     }
 }
 
-fn enc_mutability(w: &mut Encoder, mt: ast::Mutability) {
+fn enc_mutability(w: &mut Encoder, mt: hir::Mutability) {
     match mt {
-        ast::MutImmutable => (),
-        ast::MutMutable => mywrite!(w, "m"),
+        hir::MutImmutable => (),
+        hir::MutMutable => mywrite!(w, "m"),
     }
 }
 
@@ -314,10 +315,10 @@ pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
     enc_substs(w, cx, s.substs);
 }
 
-fn enc_unsafety(w: &mut Encoder, p: ast::Unsafety) {
+fn enc_unsafety(w: &mut Encoder, p: hir::Unsafety) {
     match p {
-        ast::Unsafety::Normal => mywrite!(w, "n"),
-        ast::Unsafety::Unsafe => mywrite!(w, "u"),
+        hir::Unsafety::Normal => mywrite!(w, "n"),
+        hir::Unsafety::Unsafe => mywrite!(w, "u"),
     }
 }
 
diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs
index fb0131f258d..1700efe23e9 100644
--- a/src/librustc/middle/astconv_util.rs
+++ b/src/librustc/middle/astconv_util.rs
@@ -16,7 +16,7 @@
 
 use middle::def;
 use middle::ty::{self, Ty};
-use syntax::ast;
+use rustc_front::hir as ast;
 
 pub const NO_REGIONS: usize = 1;
 pub const NO_TPS: usize = 2;
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 4ea55d2d4e4..4d921c007c6 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -12,7 +12,11 @@
 // FIXME: remove this after snapshot, and Results are handled
 #![allow(unused_must_use)]
 
-use ast_map;
+use front::map as ast_map;
+use rustc_front::hir;
+use rustc_front::fold;
+use rustc_front::fold::Folder;
+
 use metadata::common as c;
 use metadata::cstore as cstore;
 use session::Session;
@@ -33,11 +37,9 @@ use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::{self, Ty};
 
-use syntax::{ast, ast_util, codemap, fold};
+use syntax::{ast, ast_util, codemap};
 use syntax::codemap::Span;
-use syntax::fold::Folder;
 use syntax::ptr::P;
-use syntax;
 
 use std::cell::Cell;
 use std::io::SeekFrom;
@@ -53,7 +55,8 @@ use serialize::EncoderHelpers;
 
 #[cfg(test)] use std::io::Cursor;
 #[cfg(test)] use syntax::parse;
-#[cfg(test)] use syntax::print::pprust;
+#[cfg(test)] use rustc_front::print::pprust;
+#[cfg(test)] use rustc_front::lowering::lower_item;
 
 struct DecodeContext<'a, 'b, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
@@ -166,7 +169,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
         match *ii {
           InlinedItem::Item(ref i) => {
             debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<",
-                   syntax::print::pprust::item_to_string(&**i));
+                   ::rustc_front::print::pprust::item_to_string(&**i));
           }
           _ => { }
         }
@@ -360,18 +363,17 @@ fn encode_ast(rbml_w: &mut Encoder, item: &InlinedItem) {
 struct NestedItemsDropper;
 
 impl Folder for NestedItemsDropper {
-    fn fold_block(&mut self, blk: P<ast::Block>) -> P<ast::Block> {
-        blk.and_then(|ast::Block {id, stmts, expr, rules, span, ..}| {
+    fn fold_block(&mut self, blk: P<hir::Block>) -> P<hir::Block> {
+        blk.and_then(|hir::Block {id, stmts, expr, rules, span, ..}| {
             let stmts_sans_items = stmts.into_iter().filter_map(|stmt| {
                 let use_stmt = match stmt.node {
-                    ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
-                    ast::StmtDecl(ref decl, _) => {
+                    hir::StmtExpr(_, _) | hir::StmtSemi(_, _) => true,
+                    hir::StmtDecl(ref decl, _) => {
                         match decl.node {
-                            ast::DeclLocal(_) => true,
-                            ast::DeclItem(_) => false,
+                            hir::DeclLocal(_) => true,
+                            hir::DeclItem(_) => false,
                         }
                     }
-                    ast::StmtMac(..) => panic!("unexpanded macro in astencode")
                 };
                 if use_stmt {
                     Some(stmt)
@@ -379,7 +381,7 @@ impl Folder for NestedItemsDropper {
                     None
                 }
             }).collect();
-            let blk_sans_items = P(ast::Block {
+            let blk_sans_items = P(hir::Block {
                 stmts: stmts_sans_items,
                 expr: expr,
                 id: id,
@@ -488,7 +490,7 @@ fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) {
 trait rbml_decoder_helper {
     fn read_freevar_entry(&mut self, dcx: &DecodeContext)
                           -> ty::Freevar;
-    fn read_capture_mode(&mut self) -> ast::CaptureClause;
+    fn read_capture_mode(&mut self) -> hir::CaptureClause;
 }
 
 impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
@@ -498,8 +500,8 @@ impl<'a> rbml_decoder_helper for reader::Decoder<'a> {
         fv.tr(dcx)
     }
 
-    fn read_capture_mode(&mut self) -> ast::CaptureClause {
-        let cm: ast::CaptureClause = Decodable::decode(self).unwrap();
+    fn read_capture_mode(&mut self) -> hir::CaptureClause {
+        let cm: hir::CaptureClause = Decodable::decode(self).unwrap();
         cm
     }
 }
@@ -1304,7 +1306,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                             this.read_enum_variant_arg(0, |this| {
                                 Ok(this.read_region(dcx))
                             }).unwrap();
-                        let m: ast::Mutability =
+                        let m: hir::Mutability =
                             this.read_enum_variant_arg(1, |this| {
                                 Decodable::decode(this)
                             }).unwrap();
@@ -1312,7 +1314,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                         ty::AutoPtr(dcx.tcx.mk_region(r), m)
                     }
                     1 => {
-                        let m: ast::Mutability =
+                        let m: hir::Mutability =
                             this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
 
                         ty::AutoUnsafe(m)
@@ -1506,14 +1508,14 @@ fn decode_side_tables(dcx: &DecodeContext,
 // Testing of astencode_gen
 
 #[cfg(test)]
-fn encode_item_ast(rbml_w: &mut Encoder, item: &ast::Item) {
+fn encode_item_ast(rbml_w: &mut Encoder, item: &hir::Item) {
     rbml_w.start_tag(c::tag_tree as usize);
     (*item).encode(rbml_w);
     rbml_w.end_tag();
 }
 
 #[cfg(test)]
-fn decode_item_ast(par_doc: rbml::Doc) -> ast::Item {
+fn decode_item_ast(par_doc: rbml::Doc) -> hir::Item {
     let chi_doc = par_doc.get(c::tag_tree as usize);
     let mut d = reader::Decoder::new(chi_doc);
     Decodable::decode(&mut d).unwrap()
@@ -1553,8 +1555,7 @@ fn mk_ctxt() -> parse::ParseSess {
 }
 
 #[cfg(test)]
-fn roundtrip(in_item: Option<P<ast::Item>>) {
-    let in_item = in_item.unwrap();
+fn roundtrip(in_item: P<hir::Item>) {
     let mut wr = Cursor::new(Vec::new());
     encode_item_ast(&mut Encoder::new(&mut wr), &*in_item);
     let rbml_doc = rbml::Doc::new(wr.get_ref());
@@ -1566,28 +1567,28 @@ fn roundtrip(in_item: Option<P<ast::Item>>) {
 #[test]
 fn test_basic() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(&cx,
+    roundtrip(lower_item(&quote_item!(&cx,
         fn foo() {}
-    ));
+    ).unwrap()));
 }
 
 #[test]
 fn test_smalltalk() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(&cx,
+    roundtrip(lower_item(&quote_item!(&cx,
         fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed.
-    ));
+    ).unwrap()));
 }
 
 #[test]
 fn test_more() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(&cx,
+    roundtrip(lower_item(&quote_item!(&cx,
         fn foo(x: usize, y: usize) -> usize {
             let z = x + y;
             return z;
         }
-    ));
+    ).unwrap()));
 }
 
 #[test]
@@ -1599,13 +1600,14 @@ fn test_simplification() {
             return alist {eq_fn: eq_int, data: Vec::new()};
         }
     ).unwrap();
-    let item_in = InlinedItemRef::Item(&*item);
+    let hir_item = lower_item(&item);
+    let item_in = InlinedItemRef::Item(&hir_item);
     let item_out = simplify_ast(item_in);
-    let item_exp = InlinedItem::Item(quote_item!(&cx,
+    let item_exp = InlinedItem::Item(lower_item(&quote_item!(&cx,
         fn new_int_alist<B>() -> alist<isize, B> {
             return alist {eq_fn: eq_int, data: Vec::new()};
         }
-    ).unwrap());
+    ).unwrap()));
     match (item_out, item_exp) {
       (InlinedItem::Item(item_out), InlinedItem::Item(item_exp)) => {
         assert!(pprust::item_to_string(&*item_out) ==
diff --git a/src/librustc/middle/cast.rs b/src/librustc/middle/cast.rs
index 8233b6b2b2b..8cb4f941a22 100644
--- a/src/librustc/middle/cast.rs
+++ b/src/librustc/middle/cast.rs
@@ -13,7 +13,7 @@
 
 use middle::ty::{self, Ty};
 
-use syntax::ast;
+use rustc_front::hir as ast;
 
 /// Types that are represented as ints.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index 91e35c0679b..4d79867e5d2 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -14,9 +14,10 @@ use middle::def;
 use middle::pat_util;
 use middle::ty;
 use syntax::ast;
-use syntax::ast_util;
 use syntax::ptr::P;
 
+use rustc_front::hir;
+
 struct CFGBuilder<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
     graph: CFGGraph,
@@ -32,7 +33,7 @@ struct LoopScope {
 }
 
 pub fn construct(tcx: &ty::ctxt,
-                 blk: &ast::Block) -> CFG {
+                 blk: &hir::Block) -> CFG {
     let mut graph = graph::Graph::new();
     let entry = graph.add_node(CFGNodeData::Entry);
 
@@ -58,7 +59,7 @@ pub fn construct(tcx: &ty::ctxt,
 }
 
 impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
-    fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
+    fn block(&mut self, blk: &hir::Block, pred: CFGIndex) -> CFGIndex {
         let mut stmts_exit = pred;
         for stmt in &blk.stmts {
             stmts_exit = self.stmt(&**stmt, stmts_exit);
@@ -69,95 +70,87 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         self.add_ast_node(blk.id, &[expr_exit])
     }
 
-    fn stmt(&mut self, stmt: &ast::Stmt, pred: CFGIndex) -> CFGIndex {
+    fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex {
         match stmt.node {
-            ast::StmtDecl(ref decl, id) => {
+            hir::StmtDecl(ref decl, id) => {
                 let exit = self.decl(&**decl, pred);
                 self.add_ast_node(id, &[exit])
             }
 
-            ast::StmtExpr(ref expr, id) | ast::StmtSemi(ref expr, id) => {
+            hir::StmtExpr(ref expr, id) | hir::StmtSemi(ref expr, id) => {
                 let exit = self.expr(&**expr, pred);
                 self.add_ast_node(id, &[exit])
             }
-
-            ast::StmtMac(..) => {
-                self.tcx.sess.span_bug(stmt.span, "unexpanded macro");
-            }
         }
     }
 
-    fn decl(&mut self, decl: &ast::Decl, pred: CFGIndex) -> CFGIndex {
+    fn decl(&mut self, decl: &hir::Decl, pred: CFGIndex) -> CFGIndex {
         match decl.node {
-            ast::DeclLocal(ref local) => {
+            hir::DeclLocal(ref local) => {
                 let init_exit = self.opt_expr(&local.init, pred);
                 self.pat(&*local.pat, init_exit)
             }
 
-            ast::DeclItem(_) => {
+            hir::DeclItem(_) => {
                 pred
             }
         }
     }
 
-    fn pat(&mut self, pat: &ast::Pat, pred: CFGIndex) -> CFGIndex {
+    fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
         match pat.node {
-            ast::PatIdent(_, _, None) |
-            ast::PatEnum(_, None) |
-            ast::PatQPath(..) |
-            ast::PatLit(..) |
-            ast::PatRange(..) |
-            ast::PatWild(_) => {
+            hir::PatIdent(_, _, None) |
+            hir::PatEnum(_, None) |
+            hir::PatQPath(..) |
+            hir::PatLit(..) |
+            hir::PatRange(..) |
+            hir::PatWild(_) => {
                 self.add_ast_node(pat.id, &[pred])
             }
 
-            ast::PatBox(ref subpat) |
-            ast::PatRegion(ref subpat, _) |
-            ast::PatIdent(_, _, Some(ref subpat)) => {
+            hir::PatBox(ref subpat) |
+            hir::PatRegion(ref subpat, _) |
+            hir::PatIdent(_, _, Some(ref subpat)) => {
                 let subpat_exit = self.pat(&**subpat, pred);
                 self.add_ast_node(pat.id, &[subpat_exit])
             }
 
-            ast::PatEnum(_, Some(ref subpats)) |
-            ast::PatTup(ref subpats) => {
+            hir::PatEnum(_, Some(ref subpats)) |
+            hir::PatTup(ref subpats) => {
                 let pats_exit = self.pats_all(subpats.iter(), pred);
                 self.add_ast_node(pat.id, &[pats_exit])
             }
 
-            ast::PatStruct(_, ref subpats, _) => {
+            hir::PatStruct(_, ref subpats, _) => {
                 let pats_exit =
                     self.pats_all(subpats.iter().map(|f| &f.node.pat), pred);
                 self.add_ast_node(pat.id, &[pats_exit])
             }
 
-            ast::PatVec(ref pre, ref vec, ref post) => {
+            hir::PatVec(ref pre, ref vec, ref post) => {
                 let pre_exit = self.pats_all(pre.iter(), pred);
                 let vec_exit = self.pats_all(vec.iter(), pre_exit);
                 let post_exit = self.pats_all(post.iter(), vec_exit);
                 self.add_ast_node(pat.id, &[post_exit])
             }
-
-            ast::PatMac(_) => {
-                self.tcx.sess.span_bug(pat.span, "unexpanded macro");
-            }
         }
     }
 
-    fn pats_all<'b, I: Iterator<Item=&'b P<ast::Pat>>>(&mut self,
+    fn pats_all<'b, I: Iterator<Item=&'b P<hir::Pat>>>(&mut self,
                                           pats: I,
                                           pred: CFGIndex) -> CFGIndex {
         //! Handles case where all of the patterns must match.
         pats.fold(pred, |pred, pat| self.pat(&**pat, pred))
     }
 
-    fn expr(&mut self, expr: &ast::Expr, pred: CFGIndex) -> CFGIndex {
+    fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex {
         match expr.node {
-            ast::ExprBlock(ref blk) => {
+            hir::ExprBlock(ref blk) => {
                 let blk_exit = self.block(&**blk, pred);
                 self.add_ast_node(expr.id, &[blk_exit])
             }
 
-            ast::ExprIf(ref cond, ref then, None) => {
+            hir::ExprIf(ref cond, ref then, None) => {
                 //
                 //     [pred]
                 //       |
@@ -177,7 +170,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_ast_node(expr.id, &[cond_exit, then_exit])      // 3,4
             }
 
-            ast::ExprIf(ref cond, ref then, Some(ref otherwise)) => {
+            hir::ExprIf(ref cond, ref then, Some(ref otherwise)) => {
                 //
                 //     [pred]
                 //       |
@@ -198,11 +191,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_ast_node(expr.id, &[then_exit, else_exit])      // 4, 5
             }
 
-            ast::ExprIfLet(..) => {
-                self.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
-            }
-
-            ast::ExprWhile(ref cond, ref body, _) => {
+            hir::ExprWhile(ref cond, ref body, _) => {
                 //
                 //         [pred]
                 //           |
@@ -235,15 +224,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 expr_exit
             }
 
-            ast::ExprWhileLet(..) => {
-                self.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
-            }
-
-            ast::ExprForLoop(..) => {
-                self.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
-            }
-
-            ast::ExprLoop(ref body, _) => {
+            hir::ExprLoop(ref body, _) => {
                 //
                 //     [pred]
                 //       |
@@ -271,11 +252,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 expr_exit
             }
 
-            ast::ExprMatch(ref discr, ref arms, _) => {
+            hir::ExprMatch(ref discr, ref arms, _) => {
                 self.match_(expr.id, &discr, &arms, pred)
             }
 
-            ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
+            hir::ExprBinary(op, ref l, ref r) if ::rustc_front::util::lazy_binop(op.node) => {
                 //
                 //     [pred]
                 //       |
@@ -295,14 +276,14 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_ast_node(expr.id, &[l_exit, r_exit])            // 3,4
             }
 
-            ast::ExprRet(ref v) => {
+            hir::ExprRet(ref v) => {
                 let v_exit = self.opt_expr(v, pred);
                 let b = self.add_ast_node(expr.id, &[v_exit]);
                 self.add_returning_edge(expr, b);
                 self.add_unreachable_node()
             }
 
-            ast::ExprBreak(label) => {
+            hir::ExprBreak(label) => {
                 let loop_scope = self.find_scope(expr, label);
                 let b = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, b,
@@ -310,7 +291,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_unreachable_node()
             }
 
-            ast::ExprAgain(label) => {
+            hir::ExprAgain(label) => {
                 let loop_scope = self.find_scope(expr, label);
                 let a = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, a,
@@ -318,68 +299,68 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_unreachable_node()
             }
 
-            ast::ExprVec(ref elems) => {
+            hir::ExprVec(ref elems) => {
                 self.straightline(expr, pred, elems.iter().map(|e| &**e))
             }
 
-            ast::ExprCall(ref func, ref args) => {
+            hir::ExprCall(ref func, ref args) => {
                 self.call(expr, pred, &**func, args.iter().map(|e| &**e))
             }
 
-            ast::ExprMethodCall(_, _, ref args) => {
+            hir::ExprMethodCall(_, _, ref args) => {
                 self.call(expr, pred, &*args[0], args[1..].iter().map(|e| &**e))
             }
 
-            ast::ExprIndex(ref l, ref r) |
-            ast::ExprBinary(_, ref l, ref r) if self.tcx.is_method_call(expr.id) => {
+            hir::ExprIndex(ref l, ref r) |
+            hir::ExprBinary(_, ref l, ref r) if self.tcx.is_method_call(expr.id) => {
                 self.call(expr, pred, &**l, Some(&**r).into_iter())
             }
 
-            ast::ExprRange(ref start, ref end) => {
+            hir::ExprRange(ref start, ref end) => {
                 let fields = start.as_ref().map(|e| &**e).into_iter()
                     .chain(end.as_ref().map(|e| &**e));
                 self.straightline(expr, pred, fields)
             }
 
-            ast::ExprUnary(_, ref e) if self.tcx.is_method_call(expr.id) => {
-                self.call(expr, pred, &**e, None::<ast::Expr>.iter())
+            hir::ExprUnary(_, ref e) if self.tcx.is_method_call(expr.id) => {
+                self.call(expr, pred, &**e, None::<hir::Expr>.iter())
             }
 
-            ast::ExprTup(ref exprs) => {
+            hir::ExprTup(ref exprs) => {
                 self.straightline(expr, pred, exprs.iter().map(|e| &**e))
             }
 
-            ast::ExprStruct(_, ref fields, ref base) => {
+            hir::ExprStruct(_, ref fields, ref base) => {
                 let field_cfg = self.straightline(expr, pred, fields.iter().map(|f| &*f.expr));
                 self.opt_expr(base, field_cfg)
             }
 
-            ast::ExprRepeat(ref elem, ref count) => {
+            hir::ExprRepeat(ref elem, ref count) => {
                 self.straightline(expr, pred, [elem, count].iter().map(|&e| &**e))
             }
 
-            ast::ExprAssign(ref l, ref r) |
-            ast::ExprAssignOp(_, ref l, ref r) => {
+            hir::ExprAssign(ref l, ref r) |
+            hir::ExprAssignOp(_, ref l, ref r) => {
                 self.straightline(expr, pred, [r, l].iter().map(|&e| &**e))
             }
 
-            ast::ExprBox(Some(ref l), ref r) |
-            ast::ExprIndex(ref l, ref r) |
-            ast::ExprBinary(_, ref l, ref r) => { // NB: && and || handled earlier
+            hir::ExprBox(Some(ref l), ref r) |
+            hir::ExprIndex(ref l, ref r) |
+            hir::ExprBinary(_, ref l, ref r) => { // NB: && and || handled earlier
                 self.straightline(expr, pred, [l, r].iter().map(|&e| &**e))
             }
 
-            ast::ExprBox(None, ref e) |
-            ast::ExprAddrOf(_, ref e) |
-            ast::ExprCast(ref e, _) |
-            ast::ExprUnary(_, ref e) |
-            ast::ExprParen(ref e) |
-            ast::ExprField(ref e, _) |
-            ast::ExprTupField(ref e, _) => {
+            hir::ExprBox(None, ref e) |
+            hir::ExprAddrOf(_, ref e) |
+            hir::ExprCast(ref e, _) |
+            hir::ExprUnary(_, ref e) |
+            hir::ExprParen(ref e) |
+            hir::ExprField(ref e, _) |
+            hir::ExprTupField(ref e, _) => {
                 self.straightline(expr, pred, Some(&**e).into_iter())
             }
 
-            ast::ExprInlineAsm(ref inline_asm) => {
+            hir::ExprInlineAsm(ref inline_asm) => {
                 let inputs = inline_asm.inputs.iter();
                 let outputs = inline_asm.outputs.iter();
                 let post_inputs = self.exprs(inputs.map(|a| {
@@ -395,19 +376,18 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_ast_node(expr.id, &[post_outputs])
             }
 
-            ast::ExprMac(..) |
-            ast::ExprClosure(..) |
-            ast::ExprLit(..) |
-            ast::ExprPath(..) => {
-                self.straightline(expr, pred, None::<ast::Expr>.iter())
+            hir::ExprClosure(..) |
+            hir::ExprLit(..) |
+            hir::ExprPath(..) => {
+                self.straightline(expr, pred, None::<hir::Expr>.iter())
             }
         }
     }
 
-    fn call<'b, I: Iterator<Item=&'b ast::Expr>>(&mut self,
-            call_expr: &ast::Expr,
+    fn call<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
+            call_expr: &hir::Expr,
             pred: CFGIndex,
-            func_or_rcvr: &ast::Expr,
+            func_or_rcvr: &hir::Expr,
             args: I) -> CFGIndex {
         let method_call = ty::MethodCall::expr(call_expr.id);
         let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) {
@@ -424,7 +404,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         }
     }
 
-    fn exprs<'b, I: Iterator<Item=&'b ast::Expr>>(&mut self,
+    fn exprs<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
                                              exprs: I,
                                              pred: CFGIndex) -> CFGIndex {
         //! Constructs graph for `exprs` evaluated in order
@@ -432,14 +412,14 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     }
 
     fn opt_expr(&mut self,
-                opt_expr: &Option<P<ast::Expr>>,
+                opt_expr: &Option<P<hir::Expr>>,
                 pred: CFGIndex) -> CFGIndex {
         //! Constructs graph for `opt_expr` evaluated, if Some
         opt_expr.iter().fold(pred, |p, e| self.expr(&**e, p))
     }
 
-    fn straightline<'b, I: Iterator<Item=&'b ast::Expr>>(&mut self,
-                    expr: &ast::Expr,
+    fn straightline<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
+                    expr: &hir::Expr,
                     pred: CFGIndex,
                     subexprs: I) -> CFGIndex {
         //! Handles case of an expression that evaluates `subexprs` in order
@@ -448,8 +428,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         self.add_ast_node(expr.id, &[subexprs_exit])
     }
 
-    fn match_(&mut self, id: ast::NodeId, discr: &ast::Expr,
-              arms: &[ast::Arm], pred: CFGIndex) -> CFGIndex {
+    fn match_(&mut self, id: ast::NodeId, discr: &hir::Expr,
+              arms: &[hir::Arm], pred: CFGIndex) -> CFGIndex {
         // The CFG for match expression is quite complex, so no ASCII
         // art for it (yet).
         //
@@ -579,7 +559,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     }
 
     fn add_exiting_edge(&mut self,
-                        from_expr: &ast::Expr,
+                        from_expr: &hir::Expr,
                         from_index: CFGIndex,
                         to_loop: LoopScope,
                         to_index: CFGIndex) {
@@ -594,7 +574,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     }
 
     fn add_returning_edge(&mut self,
-                          _from_expr: &ast::Expr,
+                          _from_expr: &hir::Expr,
                           from_index: CFGIndex) {
         let mut data = CFGEdgeData {
             exiting_scopes: vec!(),
@@ -606,7 +586,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     }
 
     fn find_scope(&self,
-                  expr: &ast::Expr,
+                  expr: &hir::Expr,
                   label: Option<ast::Ident>) -> LoopScope {
         if label.is_none() {
             return *self.loop_scopes.last().unwrap();
diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs
index 76050671cc4..8fa2dac2da1 100644
--- a/src/librustc/middle/cfg/graphviz.rs
+++ b/src/librustc/middle/cfg/graphviz.rs
@@ -18,7 +18,7 @@ use graphviz as dot;
 
 use syntax::ast;
 
-use ast_map;
+use front::map as ast_map;
 use middle::cfg;
 
 pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);
diff --git a/src/librustc/middle/cfg/mod.rs b/src/librustc/middle/cfg/mod.rs
index c33caaa3c03..ac84d3dec94 100644
--- a/src/librustc/middle/cfg/mod.rs
+++ b/src/librustc/middle/cfg/mod.rs
@@ -14,6 +14,7 @@
 use rustc_data_structures::graph;
 use middle::ty;
 use syntax::ast;
+use rustc_front::hir;
 
 mod construct;
 pub mod graphviz;
@@ -58,7 +59,7 @@ pub type CFGEdge = graph::Edge<CFGEdgeData>;
 
 impl CFG {
     pub fn new(tcx: &ty::ctxt,
-               blk: &ast::Block) -> CFG {
+               blk: &hir::Block) -> CFG {
         construct::construct(tcx, blk)
     }
 
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 47b61767f10..ad9cbfcf4c0 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -36,9 +36,10 @@ use middle::traits;
 use middle::ty::{self, Ty};
 use util::nodemap::NodeMap;
 
+use rustc_front::hir;
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::visit::{self, FnKind, Visitor};
+use rustc_front::visit::{self, FnKind, Visitor};
 
 use std::collections::hash_map::Entry;
 use std::cmp::Ordering;
@@ -96,7 +97,7 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
     mode: Mode,
     qualif: ConstQualif,
-    rvalue_borrows: NodeMap<ast::Mutability>
+    rvalue_borrows: NodeMap<hir::Mutability>
 }
 
 impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
@@ -125,7 +126,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
         f(&mut euv::ExprUseVisitor::new(self, &infcx))
     }
 
-    fn global_expr(&mut self, mode: Mode, expr: &ast::Expr) -> ConstQualif {
+    fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif {
         assert!(mode != Mode::Var);
         match self.tcx.const_qualif_map.borrow_mut().entry(expr.id) {
             Entry::Occupied(entry) => return *entry.get(),
@@ -143,8 +144,8 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
 
     fn fn_like(&mut self,
                fk: FnKind,
-               fd: &ast::FnDecl,
-               b: &ast::Block,
+               fd: &hir::FnDecl,
+               b: &hir::Block,
                s: Span,
                fn_id: ast::NodeId)
                -> ConstQualif {
@@ -157,11 +158,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
         }
 
         let mode = match fk {
-            FnKind::ItemFn(_, _, _, ast::Constness::Const, _, _) => {
+            FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _) => {
                 Mode::ConstFn
             }
             FnKind::Method(_, m, _) => {
-                if m.constness == ast::Constness::Const {
+                if m.constness == hir::Constness::Const {
                     Mode::ConstFn
                 } else {
                     Mode::Var
@@ -174,7 +175,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
         if mode == Mode::ConstFn {
             for arg in &fd.inputs {
                 match arg.pat.node {
-                    ast::PatIdent(ast::BindByValue(ast::MutImmutable), _, None) => {}
+                    hir::PatIdent(hir::BindByValue(hir::MutImmutable), _, None) => {}
                     _ => {
                         span_err!(self.tcx.sess, arg.pat.span, E0022,
                                   "arguments of constant functions can only \
@@ -204,7 +205,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
 
     /// Returns true if the call is to a const fn or method.
     fn handle_const_fn_call(&mut self,
-                            expr: &ast::Expr,
+                            expr: &hir::Expr,
                             def_id: DefId,
                             ret_ty: Ty<'tcx>)
                             -> bool {
@@ -246,12 +247,12 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
         }
     }
 
-    fn record_borrow(&mut self, id: ast::NodeId, mutbl: ast::Mutability) {
+    fn record_borrow(&mut self, id: ast::NodeId, mutbl: hir::Mutability) {
         match self.rvalue_borrows.entry(id) {
             Entry::Occupied(mut entry) => {
                 // Merge the two borrows, taking the most demanding
                 // one, mutability-wise.
-                if mutbl == ast::MutMutable {
+                if mutbl == hir::MutMutable {
                     entry.insert(mutbl);
                 }
             }
@@ -270,7 +271,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
         }
     }
 
-    fn check_static_mut_type(&self, e: &ast::Expr) {
+    fn check_static_mut_type(&self, e: &hir::Expr) {
         let node_ty = self.tcx.node_id_to_type(e.id);
         let tcontents = node_ty.type_contents(self.tcx);
 
@@ -286,7 +287,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
                  "mutable statics are not allowed to have {}", suffix);
     }
 
-    fn check_static_type(&self, e: &ast::Expr) {
+    fn check_static_type(&self, e: &hir::Expr) {
         let ty = self.tcx.node_id_to_type(e.id);
         let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false);
         let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
@@ -302,21 +303,21 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item) {
+    fn visit_item(&mut self, i: &hir::Item) {
         debug!("visit_item(item={})", self.tcx.map.node_to_string(i.id));
         match i.node {
-            ast::ItemStatic(_, ast::MutImmutable, ref expr) => {
+            hir::ItemStatic(_, hir::MutImmutable, ref expr) => {
                 self.check_static_type(&**expr);
                 self.global_expr(Mode::Static, &**expr);
             }
-            ast::ItemStatic(_, ast::MutMutable, ref expr) => {
+            hir::ItemStatic(_, hir::MutMutable, ref expr) => {
                 self.check_static_mut_type(&**expr);
                 self.global_expr(Mode::StaticMut, &**expr);
             }
-            ast::ItemConst(_, ref expr) => {
+            hir::ItemConst(_, ref expr) => {
                 self.global_expr(Mode::Const, &**expr);
             }
-            ast::ItemEnum(ref enum_definition, _) => {
+            hir::ItemEnum(ref enum_definition, _) => {
                 for var in &enum_definition.variants {
                     if let Some(ref ex) = var.node.disr_expr {
                         self.global_expr(Mode::Const, &**ex);
@@ -329,9 +330,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
+    fn visit_trait_item(&mut self, t: &'v hir::TraitItem) {
         match t.node {
-            ast::ConstTraitItem(_, ref default) => {
+            hir::ConstTraitItem(_, ref default) => {
                 if let Some(ref expr) = *default {
                     self.global_expr(Mode::Const, &*expr);
                 } else {
@@ -342,9 +343,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_impl_item(&mut self, i: &'v ast::ImplItem) {
+    fn visit_impl_item(&mut self, i: &'v hir::ImplItem) {
         match i.node {
-            ast::ConstImplItem(_, ref expr) => {
+            hir::ConstImplItem(_, ref expr) => {
                 self.global_expr(Mode::Const, &*expr);
             }
             _ => self.with_mode(Mode::Var, |v| visit::walk_impl_item(v, i)),
@@ -353,19 +354,19 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
 
     fn visit_fn(&mut self,
                 fk: FnKind<'v>,
-                fd: &'v ast::FnDecl,
-                b: &'v ast::Block,
+                fd: &'v hir::FnDecl,
+                b: &'v hir::Block,
                 s: Span,
                 fn_id: ast::NodeId) {
         self.fn_like(fk, fd, b, s, fn_id);
     }
 
-    fn visit_pat(&mut self, p: &ast::Pat) {
+    fn visit_pat(&mut self, p: &hir::Pat) {
         match p.node {
-            ast::PatLit(ref lit) => {
+            hir::PatLit(ref lit) => {
                 self.global_expr(Mode::Const, &**lit);
             }
-            ast::PatRange(ref start, ref end) => {
+            hir::PatRange(ref start, ref end) => {
                 self.global_expr(Mode::Const, &**start);
                 self.global_expr(Mode::Const, &**end);
 
@@ -386,24 +387,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_block(&mut self, block: &ast::Block) {
+    fn visit_block(&mut self, block: &hir::Block) {
         // Check all statements in the block
         for stmt in &block.stmts {
             let span = match stmt.node {
-                ast::StmtDecl(ref decl, _) => {
+                hir::StmtDecl(ref decl, _) => {
                     match decl.node {
-                        ast::DeclLocal(_) => decl.span,
+                        hir::DeclLocal(_) => decl.span,
 
                         // Item statements are allowed
-                        ast::DeclItem(_) => continue
+                        hir::DeclItem(_) => continue
                     }
                 }
-                ast::StmtExpr(ref expr, _) => expr.span,
-                ast::StmtSemi(ref semi, _) => semi.span,
-                ast::StmtMac(..) => {
-                    self.tcx.sess.span_bug(stmt.span, "unexpanded statement \
-                                                       macro in const?!")
-                }
+                hir::StmtExpr(ref expr, _) => expr.span,
+                hir::StmtSemi(ref semi, _) => semi.span,
             };
             self.add_qualif(ConstQualif::NOT_CONST);
             if self.mode != Mode::Var {
@@ -415,7 +412,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
         visit::walk_block(self, block);
     }
 
-    fn visit_expr(&mut self, ex: &ast::Expr) {
+    fn visit_expr(&mut self, ex: &hir::Expr) {
         let mut outer = self.qualif;
         self.qualif = ConstQualif::empty();
 
@@ -425,7 +422,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
 
         // Special-case some expressions to avoid certain flags bubbling up.
         match ex.node {
-            ast::ExprCall(ref callee, ref args) => {
+            hir::ExprCall(ref callee, ref args) => {
                 for arg in args {
                     self.visit_expr(&**arg)
                 }
@@ -436,7 +433,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                 let added = self.qualif - inner;
                 self.qualif = inner | (added - ConstQualif::NON_ZERO_SIZED);
             }
-            ast::ExprRepeat(ref element, _) => {
+            hir::ExprRepeat(ref element, _) => {
                 self.visit_expr(&**element);
                 // The count is checked elsewhere (typeck).
                 let count = match node_ty.sty {
@@ -448,14 +445,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                     self.qualif.remove(ConstQualif::NON_ZERO_SIZED | ConstQualif::PREFER_IN_PLACE);
                 }
             }
-            ast::ExprMatch(ref discr, ref arms, _) => {
+            hir::ExprMatch(ref discr, ref arms, _) => {
                 // Compute the most demanding borrow from all the arms'
                 // patterns and set that on the discriminator.
                 let mut borrow = None;
                 for pat in arms.iter().flat_map(|arm| &arm.pats) {
                     let pat_borrow = self.rvalue_borrows.remove(&pat.id);
                     match (borrow, pat_borrow) {
-                        (None, _) | (_, Some(ast::MutMutable)) => {
+                        (None, _) | (_, Some(hir::MutMutable)) => {
                             borrow = pat_borrow;
                         }
                         _ => {}
@@ -467,9 +464,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                 visit::walk_expr(self, ex);
             }
             // Division by zero and overflow checking.
-            ast::ExprBinary(op, _, _) => {
+            hir::ExprBinary(op, _, _) => {
                 visit::walk_expr(self, ex);
-                let div_or_rem = op.node == ast::BiDiv || op.node == ast::BiRem;
+                let div_or_rem = op.node == hir::BiDiv || op.node == hir::BiRem;
                 match node_ty.sty {
                     ty::TyUint(_) | ty::TyInt(_) if div_or_rem => {
                         if !self.qualif.intersects(ConstQualif::NOT_CONST) {
@@ -492,7 +489,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
 
         // Handle borrows on (or inside the autorefs of) this expression.
         match self.rvalue_borrows.remove(&ex.id) {
-            Some(ast::MutImmutable) => {
+            Some(hir::MutImmutable) => {
                 // Constants cannot be borrowed if they contain interior mutability as
                 // it means that our "silent insertion of statics" could change
                 // initializer values (very bad).
@@ -514,7 +511,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                     self.add_qualif(ConstQualif::HAS_STATIC_BORROWS);
                 }
             }
-            Some(ast::MutMutable) => {
+            Some(hir::MutMutable) => {
                 // `&mut expr` means expr could be mutated, unless it's zero-sized.
                 if self.qualif.intersects(ConstQualif::NON_ZERO_SIZED) {
                     if self.mode == Mode::Var {
@@ -545,7 +542,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
 /// of a const/static item, it is qualified for promotion
 /// instead of producing errors.
 fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
-                        e: &ast::Expr, node_ty: Ty<'tcx>) {
+                        e: &hir::Expr, node_ty: Ty<'tcx>) {
     match node_ty.sty {
         ty::TyStruct(def, _) |
         ty::TyEnum(def, _) if def.has_dtor() => {
@@ -561,27 +558,27 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
 
     let method_call = ty::MethodCall::expr(e.id);
     match e.node {
-        ast::ExprUnary(..) |
-        ast::ExprBinary(..) |
-        ast::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => {
+        hir::ExprUnary(..) |
+        hir::ExprBinary(..) |
+        hir::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => {
             v.add_qualif(ConstQualif::NOT_CONST);
             if v.mode != Mode::Var {
                 span_err!(v.tcx.sess, e.span, E0011,
                             "user-defined operators are not allowed in {}s", v.msg());
             }
         }
-        ast::ExprBox(..) |
-        ast::ExprUnary(ast::UnUniq, _) => {
+        hir::ExprBox(..) |
+        hir::ExprUnary(hir::UnUniq, _) => {
             v.add_qualif(ConstQualif::NOT_CONST);
             if v.mode != Mode::Var {
                 span_err!(v.tcx.sess, e.span, E0010,
                           "allocations are not allowed in {}s", v.msg());
             }
         }
-        ast::ExprUnary(op, ref inner) => {
+        hir::ExprUnary(op, ref inner) => {
             match v.tcx.node_id_to_type(inner.id).sty {
                 ty::TyRawPtr(_) => {
-                    assert!(op == ast::UnDeref);
+                    assert!(op == hir::UnDeref);
 
                     v.add_qualif(ConstQualif::NOT_CONST);
                     if v.mode != Mode::Var {
@@ -592,12 +589,12 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 _ => {}
             }
         }
-        ast::ExprBinary(op, ref lhs, _) => {
+        hir::ExprBinary(op, ref lhs, _) => {
             match v.tcx.node_id_to_type(lhs.id).sty {
                 ty::TyRawPtr(_) => {
-                    assert!(op.node == ast::BiEq || op.node == ast::BiNe ||
-                            op.node == ast::BiLe || op.node == ast::BiLt ||
-                            op.node == ast::BiGe || op.node == ast::BiGt);
+                    assert!(op.node == hir::BiEq || op.node == hir::BiNe ||
+                            op.node == hir::BiLe || op.node == hir::BiLt ||
+                            op.node == hir::BiGe || op.node == hir::BiGt);
 
                     v.add_qualif(ConstQualif::NOT_CONST);
                     if v.mode != Mode::Var {
@@ -608,7 +605,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 _ => {}
             }
         }
-        ast::ExprCast(ref from, _) => {
+        hir::ExprCast(ref from, _) => {
             debug!("Checking const cast(id={})", from.id);
             match v.tcx.cast_kinds.borrow().get(&from.id) {
                 None => v.tcx.sess.span_bug(e.span, "no kind for cast"),
@@ -622,7 +619,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 _ => {}
             }
         }
-        ast::ExprPath(..) => {
+        hir::ExprPath(..) => {
             let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
             match def {
                 Some(def::DefVariant(_, _, _)) => {
@@ -677,12 +674,12 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 }
             }
         }
-        ast::ExprCall(ref callee, _) => {
+        hir::ExprCall(ref callee, _) => {
             let mut callee = &**callee;
             loop {
                 callee = match callee.node {
-                    ast::ExprParen(ref inner) => &**inner,
-                    ast::ExprBlock(ref block) => match block.expr {
+                    hir::ExprParen(ref inner) => &**inner,
+                    hir::ExprBlock(ref block) => match block.expr {
                         Some(ref tail) => &**tail,
                         None => break
                     },
@@ -720,7 +717,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 }
             }
         }
-        ast::ExprMethodCall(..) => {
+        hir::ExprMethodCall(..) => {
             let method = v.tcx.tables.borrow().method_map[&method_call];
             let is_const = match v.tcx.impl_or_trait_item(method.def_id).container() {
                 ty::ImplContainer(_) => v.handle_const_fn_call(e, method.def_id, node_ty),
@@ -735,23 +732,23 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 }
             }
         }
-        ast::ExprStruct(..) => {
+        hir::ExprStruct(..) => {
             let did = v.tcx.def_map.borrow().get(&e.id).map(|def| def.def_id());
             if did == v.tcx.lang_items.unsafe_cell_type() {
                 v.add_qualif(ConstQualif::MUTABLE_MEM);
             }
         }
 
-        ast::ExprLit(_) |
-        ast::ExprAddrOf(..) => {
+        hir::ExprLit(_) |
+        hir::ExprAddrOf(..) => {
             v.add_qualif(ConstQualif::NON_ZERO_SIZED);
         }
 
-        ast::ExprRepeat(..) => {
+        hir::ExprRepeat(..) => {
             v.add_qualif(ConstQualif::PREFER_IN_PLACE);
         }
 
-        ast::ExprClosure(..) => {
+        hir::ExprClosure(..) => {
             // Paths in constant contexts cannot refer to local variables,
             // as there are none, and thus closures can't have upvars there.
             if v.tcx.with_freevars(e.id, |fv| !fv.is_empty()) {
@@ -761,38 +758,34 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             }
         }
 
-        ast::ExprBlock(_) |
-        ast::ExprIndex(..) |
-        ast::ExprField(..) |
-        ast::ExprTupField(..) |
-        ast::ExprVec(_) |
-        ast::ExprParen(..) |
-        ast::ExprTup(..) => {}
+        hir::ExprBlock(_) |
+        hir::ExprIndex(..) |
+        hir::ExprField(..) |
+        hir::ExprTupField(..) |
+        hir::ExprVec(_) |
+        hir::ExprParen(..) |
+        hir::ExprTup(..) => {}
 
         // Conditional control flow (possible to implement).
-        ast::ExprMatch(..) |
-        ast::ExprIf(..) |
-        ast::ExprIfLet(..) |
+        hir::ExprMatch(..) |
+        hir::ExprIf(..) |
 
         // Loops (not very meaningful in constants).
-        ast::ExprWhile(..) |
-        ast::ExprWhileLet(..) |
-        ast::ExprForLoop(..) |
-        ast::ExprLoop(..) |
+        hir::ExprWhile(..) |
+        hir::ExprLoop(..) |
 
         // More control flow (also not very meaningful).
-        ast::ExprBreak(_) |
-        ast::ExprAgain(_) |
-        ast::ExprRet(_) |
+        hir::ExprBreak(_) |
+        hir::ExprAgain(_) |
+        hir::ExprRet(_) |
 
         // Miscellaneous expressions that could be implemented.
-        ast::ExprRange(..) |
+        hir::ExprRange(..) |
 
         // Expressions with side-effects.
-        ast::ExprAssign(..) |
-        ast::ExprAssignOp(..) |
-        ast::ExprInlineAsm(_) |
-        ast::ExprMac(_) => {
+        hir::ExprAssign(..) |
+        hir::ExprAssignOp(..) |
+        hir::ExprInlineAsm(_) => {
             v.add_qualif(ConstQualif::NOT_CONST);
             if v.mode != Mode::Var {
                 span_err!(v.tcx.sess, e.span, E0019,
@@ -803,7 +796,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
 }
 
 /// Check the adjustments of an expression
-fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &ast::Expr) {
+fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr) {
     match v.tcx.tables.borrow().adjustments.get(&e.id) {
         None | Some(&ty::AdjustReifyFnPointer) | Some(&ty::AdjustUnsafeFnPointer) => {}
         Some(&ty::AdjustDerefRef(ty::AutoDerefRef { autoderefs, .. })) => {
@@ -891,7 +884,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
                         break;
                     }
                     let mutbl = bk.to_mutbl_lossy();
-                    if mutbl == ast::MutMutable && self.mode == Mode::StaticMut {
+                    if mutbl == hir::MutMutable && self.mode == Mode::StaticMut {
                         // Mutable slices are the only `&mut` allowed in
                         // globals, but only in `static mut`, nowhere else.
                         // FIXME: This exception is really weird... there isn't
@@ -940,12 +933,12 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
               _mode: euv::MutateMode) {}
 
     fn matched_pat(&mut self,
-                   _: &ast::Pat,
+                   _: &hir::Pat,
                    _: mc::cmt,
                    _: euv::MatchMode) {}
 
     fn consume_pat(&mut self,
-                   _consume_pat: &ast::Pat,
+                   _consume_pat: &hir::Pat,
                    _cmt: mc::cmt,
                    _mode: euv::ConsumeMode) {}
 }
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index bf6829d9676..1e85190ef38 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -11,10 +11,10 @@ use self::Context::*;
 
 use session::Session;
 
-use syntax::ast;
 use syntax::codemap::Span;
-use syntax::visit::Visitor;
-use syntax::visit;
+use rustc_front::visit::Visitor;
+use rustc_front::visit;
+use rustc_front::hir;
 
 #[derive(Clone, Copy, PartialEq)]
 enum Context {
@@ -27,29 +27,29 @@ struct CheckLoopVisitor<'a> {
     cx: Context
 }
 
-pub fn check_crate(sess: &Session, krate: &ast::Crate) {
+pub fn check_crate(sess: &Session, krate: &hir::Crate) {
     visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate)
 }
 
 impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
-    fn visit_item(&mut self, i: &ast::Item) {
+    fn visit_item(&mut self, i: &hir::Item) {
         self.with_context(Normal, |v| visit::walk_item(v, i));
     }
 
-    fn visit_expr(&mut self, e: &ast::Expr) {
+    fn visit_expr(&mut self, e: &hir::Expr) {
         match e.node {
-            ast::ExprWhile(ref e, ref b, _) => {
+            hir::ExprWhile(ref e, ref b, _) => {
                 self.visit_expr(&**e);
                 self.with_context(Loop, |v| v.visit_block(&**b));
             }
-            ast::ExprLoop(ref b, _) => {
+            hir::ExprLoop(ref b, _) => {
                 self.with_context(Loop, |v| v.visit_block(&**b));
             }
-            ast::ExprClosure(_, _, ref b) => {
+            hir::ExprClosure(_, _, ref b) => {
                 self.with_context(Closure, |v| v.visit_block(&**b));
             }
-            ast::ExprBreak(_) => self.require_loop("break", e.span),
-            ast::ExprAgain(_) => self.require_loop("continue", e.span),
+            hir::ExprBreak(_) => self.require_loop("break", e.span),
+            hir::ExprAgain(_) => self.require_loop("continue", e.span),
             _ => visit::walk_expr(self, e)
         }
     }
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 332ccb03729..d0111860b44 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -31,18 +31,23 @@ use std::cmp::Ordering;
 use std::fmt;
 use std::iter::{range_inclusive, FromIterator, IntoIterator, repeat};
 use std::slice;
-use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
+
+use rustc_front::hir;
+use rustc_front::hir::Pat;
+use rustc_front::visit::{self, Visitor, FnKind};
+use rustc_front::util as front_util;
+
+use syntax::ast::{self, DUMMY_NODE_ID, NodeId};
 use syntax::ast_util;
 use syntax::codemap::{Span, Spanned, DUMMY_SP};
-use syntax::fold::{Folder, noop_fold_pat};
-use syntax::print::pprust::pat_to_string;
+use rustc_front::fold::{Folder, noop_fold_pat};
+use rustc_front::print::pprust::pat_to_string;
 use syntax::ptr::P;
-use syntax::visit::{self, Visitor, FnKind};
 use util::nodemap::FnvHashMap;
 
 pub const DUMMY_WILD_PAT: &'static Pat = &Pat {
     id: DUMMY_NODE_ID,
-    node: ast::PatWild(ast::PatWildSingle),
+    node: hir::PatWild(hir::PatWildSingle),
     span: DUMMY_SP
 };
 
@@ -137,14 +142,14 @@ enum WitnessPreference {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
-    fn visit_expr(&mut self, ex: &ast::Expr) {
+    fn visit_expr(&mut self, ex: &hir::Expr) {
         check_expr(self, ex);
     }
-    fn visit_local(&mut self, l: &ast::Local) {
+    fn visit_local(&mut self, l: &hir::Local) {
         check_local(self, l);
     }
-    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
-                b: &'v ast::Block, s: Span, n: NodeId) {
+    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
+                b: &'v hir::Block, s: Span, n: NodeId) {
         check_fn(self, fk, fd, b, s, n);
     }
 }
@@ -157,10 +162,10 @@ pub fn check_crate(tcx: &ty::ctxt) {
     tcx.sess.abort_if_errors();
 }
 
-fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
+fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
     visit::walk_expr(cx, ex);
     match ex.node {
-        ast::ExprMatch(ref scrut, ref arms, source) => {
+        hir::ExprMatch(ref scrut, ref arms, source) => {
             for arm in arms {
                 // First, check legality of move bindings.
                 check_legality_of_move_bindings(cx,
@@ -180,7 +185,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
                 (arm.pats.iter().map(|pat| {
                     static_inliner.fold_pat((*pat).clone())
                 }).collect(), arm.guard.as_ref().map(|e| &**e))
-            }).collect::<Vec<(Vec<P<Pat>>, Option<&ast::Expr>)>>();
+            }).collect::<Vec<(Vec<P<Pat>>, Option<&hir::Expr>)>>();
 
             // Bail out early if inlining failed.
             if static_inliner.failed {
@@ -231,9 +236,9 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
 }
 
 fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) {
-    ast_util::walk_pat(pat, |p| {
+    front_util::walk_pat(pat, |p| {
         match p.node {
-            ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => {
+            hir::PatIdent(hir::BindByValue(hir::MutImmutable), ident, None) => {
                 let pat_ty = cx.tcx.pat_ty(p);
                 if let ty::TyEnum(edef, _) = pat_ty.sty {
                     let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
@@ -262,8 +267,8 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
 
 // Check that we do not match against a static NaN (#6804)
 fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
-    ast_util::walk_pat(pat, |p| {
-        if let ast::PatLit(ref expr) = p.node {
+    front_util::walk_pat(pat, |p| {
+        if let hir::PatLit(ref expr) = p.node {
             match eval_const_expr_partial(cx.tcx, &**expr, ExprTypeChecked) {
                 Ok(ConstVal::Float(f)) if f.is_nan() => {
                     span_warn!(cx.tcx.sess, p.span, E0003,
@@ -290,8 +295,8 @@ fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
 
 // Check for unreachable patterns
 fn check_arms(cx: &MatchCheckCtxt,
-              arms: &[(Vec<P<Pat>>, Option<&ast::Expr>)],
-              source: ast::MatchSource) {
+              arms: &[(Vec<P<Pat>>, Option<&hir::Expr>)],
+              source: hir::MatchSource) {
     let mut seen = Matrix(vec![]);
     let mut printed_if_let_err = false;
     for &(ref pats, guard) in arms {
@@ -301,7 +306,7 @@ fn check_arms(cx: &MatchCheckCtxt,
             match is_useful(cx, &seen, &v[..], LeaveOutWitness) {
                 NotUseful => {
                     match source {
-                        ast::MatchSource::IfLetDesugar { .. } => {
+                        hir::MatchSource::IfLetDesugar { .. } => {
                             if printed_if_let_err {
                                 // we already printed an irrefutable if-let pattern error.
                                 // We don't want two, that's just confusing.
@@ -315,7 +320,7 @@ fn check_arms(cx: &MatchCheckCtxt,
                             }
                         },
 
-                        ast::MatchSource::WhileLetDesugar => {
+                        hir::MatchSource::WhileLetDesugar => {
                             // find the first arm pattern so we can use its span
                             let &(ref first_arm_pats, _) = &arms[0];
                             let first_pat = &first_arm_pats[0];
@@ -323,7 +328,7 @@ fn check_arms(cx: &MatchCheckCtxt,
                             span_err!(cx.tcx.sess, span, E0165, "irrefutable while-let pattern");
                         },
 
-                        ast::MatchSource::ForLoopDesugar => {
+                        hir::MatchSource::ForLoopDesugar => {
                             // this is a bug, because on `match iter.next()` we cover
                             // `Some(<head>)` and `None`. It's impossible to have an unreachable
                             // pattern
@@ -331,7 +336,7 @@ fn check_arms(cx: &MatchCheckCtxt,
                             cx.tcx.sess.span_bug(pat.span, "unreachable for-loop pattern")
                         },
 
-                        ast::MatchSource::Normal => {
+                        hir::MatchSource::Normal => {
                             span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern")
                         },
                     }
@@ -350,12 +355,12 @@ fn check_arms(cx: &MatchCheckCtxt,
 
 fn raw_pat<'a>(p: &'a Pat) -> &'a Pat {
     match p.node {
-        ast::PatIdent(_, _, Some(ref s)) => raw_pat(&**s),
+        hir::PatIdent(_, _, Some(ref s)) => raw_pat(&**s),
         _ => p
     }
 }
 
-fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast::MatchSource) {
+fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: hir::MatchSource) {
     match is_useful(cx, matrix, &[DUMMY_WILD_PAT], ConstructWitness) {
         UsefulWithWitness(pats) => {
             let witness = match &pats[..] {
@@ -364,10 +369,10 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast:
                 _ => unreachable!()
             };
             match source {
-                ast::MatchSource::ForLoopDesugar => {
+                hir::MatchSource::ForLoopDesugar => {
                     // `witness` has the form `Some(<head>)`, peel off the `Some`
                     let witness = match witness.node {
-                        ast::PatEnum(_, Some(ref pats)) => match &pats[..] {
+                        hir::PatEnum(_, Some(ref pats)) => match &pats[..] {
                             [ref pat] => &**pat,
                             _ => unreachable!(),
                         },
@@ -394,14 +399,14 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast:
     }
 }
 
-fn const_val_to_expr(value: &ConstVal) -> P<ast::Expr> {
+fn const_val_to_expr(value: &ConstVal) -> P<hir::Expr> {
     let node = match value {
-        &ConstVal::Bool(b) => ast::LitBool(b),
+        &ConstVal::Bool(b) => hir::LitBool(b),
         _ => unreachable!()
     };
-    P(ast::Expr {
+    P(hir::Expr {
         id: 0,
-        node: ast::ExprLit(P(Spanned { node: node, span: DUMMY_SP })),
+        node: hir::ExprLit(P(Spanned { node: node, span: DUMMY_SP })),
         span: DUMMY_SP
     })
 }
@@ -440,7 +445,7 @@ impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> {
 impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
     fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
         return match pat.node {
-            ast::PatIdent(..) | ast::PatEnum(..) | ast::PatQPath(..) => {
+            hir::PatIdent(..) | hir::PatEnum(..) | hir::PatQPath(..) => {
                 let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
                 match def {
                     Some(DefAssociatedConst(did)) |
@@ -469,8 +474,8 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
             _ => noop_fold_pat(pat, self)
         };
 
-        fn record_renamings(const_expr: &ast::Expr,
-                            substituted_pat: &ast::Pat,
+        fn record_renamings(const_expr: &hir::Expr,
+                            substituted_pat: &hir::Pat,
                             renaming_map: &mut FnvHashMap<(NodeId, Span), NodeId>) {
             let mut renaming_recorder = RenamingRecorder {
                 substituted_node_id: substituted_pat.id,
@@ -478,7 +483,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
                 renaming_map: renaming_map,
             };
 
-            let mut id_visitor = ast_util::IdVisitor {
+            let mut id_visitor = front_util::IdVisitor {
                 operation: &mut renaming_recorder,
                 pass_through_items: true,
                 visited_outermost: false,
@@ -507,26 +512,26 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
     let pats_len = pats.len();
     let mut pats = pats.into_iter().map(|p| P((*p).clone()));
     let pat = match left_ty.sty {
-        ty::TyTuple(_) => ast::PatTup(pats.collect()),
+        ty::TyTuple(_) => hir::PatTup(pats.collect()),
 
         ty::TyEnum(adt, _) | ty::TyStruct(adt, _)  => {
             let v = adt.variant_of_ctor(ctor);
             if let VariantKind::Dict = v.kind() {
                 let field_pats: Vec<_> = v.fields.iter()
                     .zip(pats)
-                    .filter(|&(_, ref pat)| pat.node != ast::PatWild(ast::PatWildSingle))
+                    .filter(|&(_, ref pat)| pat.node != hir::PatWild(hir::PatWildSingle))
                     .map(|(field, pat)| Spanned {
                         span: DUMMY_SP,
-                        node: ast::FieldPat {
+                        node: hir::FieldPat {
                             ident: ast::Ident::new(field.name),
                             pat: pat,
                             is_shorthand: false,
                         }
                     }).collect();
                 let has_more_fields = field_pats.len() < pats_len;
-                ast::PatStruct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
+                hir::PatStruct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
             } else {
-                ast::PatEnum(def_to_path(cx.tcx, v.did), Some(pats.collect()))
+                hir::PatEnum(def_to_path(cx.tcx, v.did), Some(pats.collect()))
             }
         }
 
@@ -535,40 +540,40 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
                ty::TyArray(_, n) => match ctor {
                     &Single => {
                         assert_eq!(pats_len, n);
-                        ast::PatVec(pats.collect(), None, vec!())
+                        hir::PatVec(pats.collect(), None, vec!())
                     },
                     _ => unreachable!()
                 },
                 ty::TySlice(_) => match ctor {
                     &Slice(n) => {
                         assert_eq!(pats_len, n);
-                        ast::PatVec(pats.collect(), None, vec!())
+                        hir::PatVec(pats.collect(), None, vec!())
                     },
                     _ => unreachable!()
                 },
-                ty::TyStr => ast::PatWild(ast::PatWildSingle),
+                ty::TyStr => hir::PatWild(hir::PatWildSingle),
 
                 _ => {
                     assert_eq!(pats_len, 1);
-                    ast::PatRegion(pats.nth(0).unwrap(), mutbl)
+                    hir::PatRegion(pats.nth(0).unwrap(), mutbl)
                 }
             }
         }
 
         ty::TyArray(_, len) => {
             assert_eq!(pats_len, len);
-            ast::PatVec(pats.collect(), None, vec![])
+            hir::PatVec(pats.collect(), None, vec![])
         }
 
         _ => {
             match *ctor {
-                ConstantValue(ref v) => ast::PatLit(const_val_to_expr(v)),
-                _ => ast::PatWild(ast::PatWildSingle),
+                ConstantValue(ref v) => hir::PatLit(const_val_to_expr(v)),
+                _ => hir::PatWild(hir::PatWildSingle),
             }
         }
     };
 
-    P(ast::Pat {
+    P(hir::Pat {
         id: 0,
         node: pat,
         span: DUMMY_SP
@@ -658,7 +663,7 @@ fn is_useful(cx: &MatchCheckCtxt,
         let left_ty = cx.tcx.pat_ty(&*real_pat);
 
         match real_pat.node {
-            ast::PatIdent(ast::BindByRef(..), _, _) => {
+            hir::PatIdent(hir::BindByRef(..), _, _) => {
                 left_ty.builtin_deref(false).unwrap().ty
             }
             _ => left_ty,
@@ -666,7 +671,7 @@ fn is_useful(cx: &MatchCheckCtxt,
     };
 
     let max_slice_length = rows.iter().filter_map(|row| match row[0].node {
-        ast::PatVec(ref before, _, ref after) => Some(before.len() + after.len()),
+        hir::PatVec(ref before, _, ref after) => Some(before.len() + after.len()),
         _ => None
     }).max().map_or(0, |v| v + 1);
 
@@ -747,7 +752,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
                     left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
     let pat = raw_pat(p);
     match pat.node {
-        ast::PatIdent(..) =>
+        hir::PatIdent(..) =>
             match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
                 Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
@@ -756,7 +761,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
                 Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!()
             },
-        ast::PatEnum(..) =>
+        hir::PatEnum(..) =>
             match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
                 Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
@@ -764,10 +769,10 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
                 Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
-        ast::PatQPath(..) =>
+        hir::PatQPath(..) =>
             cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                             been rewritten"),
-        ast::PatStruct(..) =>
+        hir::PatStruct(..) =>
             match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
                 Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
@@ -775,11 +780,11 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
                 Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
-        ast::PatLit(ref expr) =>
+        hir::PatLit(ref expr) =>
             vec!(ConstantValue(eval_const_expr(cx.tcx, &**expr))),
-        ast::PatRange(ref lo, ref hi) =>
+        hir::PatRange(ref lo, ref hi) =>
             vec!(ConstantRange(eval_const_expr(cx.tcx, &**lo), eval_const_expr(cx.tcx, &**hi))),
-        ast::PatVec(ref before, ref slice, ref after) =>
+        hir::PatVec(ref before, ref slice, ref after) =>
             match left_ty.sty {
                 ty::TyArray(_, _) => vec!(Single),
                 _                      => if slice.is_some() {
@@ -790,12 +795,10 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
                     vec!(Slice(before.len() + after.len()))
                 }
             },
-        ast::PatBox(_) | ast::PatTup(_) | ast::PatRegion(..) =>
+        hir::PatBox(_) | hir::PatTup(_) | hir::PatRegion(..) =>
             vec!(Single),
-        ast::PatWild(_) =>
+        hir::PatWild(_) =>
             vec!(),
-        ast::PatMac(_) =>
-            cx.tcx.sess.bug("unexpanded macro")
     }
 }
 
@@ -857,10 +860,10 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         id: pat_id, ref node, span: pat_span
     } = raw_pat(r[col]);
     let head: Option<Vec<&Pat>> = match *node {
-        ast::PatWild(_) =>
+        hir::PatWild(_) =>
             Some(vec![DUMMY_WILD_PAT; arity]),
 
-        ast::PatIdent(_, _, _) => {
+        hir::PatIdent(_, _, _) => {
             let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
             match opt_def {
                 Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
@@ -875,7 +878,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
             }
         }
 
-        ast::PatEnum(_, ref args) => {
+        hir::PatEnum(_, ref args) => {
             let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
             match def {
                 DefConst(..) | DefAssociatedConst(..) =>
@@ -892,12 +895,12 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
             }
         }
 
-        ast::PatQPath(_, _) => {
+        hir::PatQPath(_, _) => {
             cx.tcx.sess.span_bug(pat_span, "const pattern should've \
                                             been rewritten")
         }
 
-        ast::PatStruct(_, ref pattern_fields, _) => {
+        hir::PatStruct(_, ref pattern_fields, _) => {
             let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
             let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
             let variant = adt.variant_of_ctor(constructor);
@@ -914,13 +917,13 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
             }
         }
 
-        ast::PatTup(ref args) =>
+        hir::PatTup(ref args) =>
             Some(args.iter().map(|p| &**p).collect()),
 
-        ast::PatBox(ref inner) | ast::PatRegion(ref inner, _) =>
+        hir::PatBox(ref inner) | hir::PatRegion(ref inner, _) =>
             Some(vec![&**inner]),
 
-        ast::PatLit(ref expr) => {
+        hir::PatLit(ref expr) => {
             let expr_value = eval_const_expr(cx.tcx, &**expr);
             match range_covered_by_constructor(constructor, &expr_value, &expr_value) {
                 Some(true) => Some(vec![]),
@@ -932,7 +935,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
             }
         }
 
-        ast::PatRange(ref from, ref to) => {
+        hir::PatRange(ref from, ref to) => {
             let from_value = eval_const_expr(cx.tcx, &**from);
             let to_value = eval_const_expr(cx.tcx, &**to);
             match range_covered_by_constructor(constructor, &from_value, &to_value) {
@@ -945,7 +948,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
             }
         }
 
-        ast::PatVec(ref before, ref slice, ref after) => {
+        hir::PatVec(ref before, ref slice, ref after) => {
             match *constructor {
                 // Fixed-length vectors.
                 Single => {
@@ -976,11 +979,6 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
                 _ => None
             }
         }
-
-        ast::PatMac(_) => {
-            span_err!(cx.tcx.sess, pat_span, E0300, "unexpanded macro");
-            None
-        }
     };
     head.map(|mut head| {
         head.push_all(&r[..col]);
@@ -989,7 +987,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
     })
 }
 
-fn check_local(cx: &mut MatchCheckCtxt, loc: &ast::Local) {
+fn check_local(cx: &mut MatchCheckCtxt, loc: &hir::Local) {
     visit::walk_local(cx, loc);
 
     let pat = StaticInliner::new(cx.tcx, None).fold_pat(loc.pat.clone());
@@ -1002,8 +1000,8 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &ast::Local) {
 
 fn check_fn(cx: &mut MatchCheckCtxt,
             kind: FnKind,
-            decl: &ast::FnDecl,
-            body: &ast::Block,
+            decl: &hir::FnDecl,
+            body: &hir::Block,
             sp: Span,
             fn_id: NodeId) {
     match kind {
@@ -1060,10 +1058,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
     for pat in pats {
         pat_bindings(def_map, &**pat, |bm, _, span, _path| {
             match bm {
-                ast::BindByRef(_) => {
+                hir::BindByRef(_) => {
                     by_ref_span = Some(span);
                 }
-                ast::BindByValue(_) => {
+                hir::BindByValue(_) => {
                 }
             }
         })
@@ -1085,10 +1083,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
     };
 
     for pat in pats {
-        ast_util::walk_pat(&**pat, |p| {
+        front_util::walk_pat(&**pat, |p| {
             if pat_is_binding(def_map, &*p) {
                 match p.node {
-                    ast::PatIdent(ast::BindByValue(_), _, ref sub) => {
+                    hir::PatIdent(hir::BindByValue(_), _, ref sub) => {
                         let pat_ty = tcx.node_id_to_type(p.id);
                         //FIXME: (@jroesch) this code should be floated up as well
                         let infcx = infer::new_infer_ctxt(cx.tcx,
@@ -1099,7 +1097,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
                             check_move(p, sub.as_ref().map(|p| &**p));
                         }
                     }
-                    ast::PatIdent(ast::BindByRef(_), _, _) => {
+                    hir::PatIdent(hir::BindByRef(_), _, _) => {
                     }
                     _ => {
                         cx.tcx.sess.span_bug(
@@ -1119,7 +1117,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
 /// Ensures that a pattern guard doesn't borrow by mutable reference or
 /// assign.
 fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
-                                         guard: &ast::Expr) {
+                                         guard: &hir::Expr) {
     let mut checker = MutationChecker {
         cx: cx,
     };
@@ -1188,7 +1186,7 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
         }
 
         match pat.node {
-            ast::PatIdent(_, _, Some(_)) => {
+            hir::PatIdent(_, _, Some(_)) => {
                 let bindings_were_allowed = self.bindings_allowed;
                 self.bindings_allowed = false;
                 visit::walk_pat(self, pat);
diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs
index c9017432473..5659a18e500 100644
--- a/src/librustc/middle/check_rvalues.rs
+++ b/src/librustc/middle/check_rvalues.rs
@@ -18,11 +18,12 @@ use middle::ty::ParameterEnvironment;
 use middle::ty;
 
 use syntax::ast;
+use rustc_front::hir;
 use syntax::codemap::Span;
-use syntax::visit;
+use rustc_front::visit;
 
 pub fn check_crate(tcx: &ty::ctxt,
-                   krate: &ast::Crate) {
+                   krate: &hir::Crate) {
     let mut rvcx = RvalueContext { tcx: tcx };
     visit::walk_crate(&mut rvcx, krate);
 }
@@ -34,8 +35,8 @@ struct RvalueContext<'a, 'tcx: 'a> {
 impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
     fn visit_fn(&mut self,
                 fk: visit::FnKind<'v>,
-                fd: &'v ast::FnDecl,
-                b: &'v ast::Block,
+                fd: &'v hir::FnDecl,
+                b: &'v hir::Block,
                 s: Span,
                 fn_id: ast::NodeId) {
         {
@@ -73,12 +74,12 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> {
     }
 
     fn matched_pat(&mut self,
-                   _matched_pat: &ast::Pat,
+                   _matched_pat: &hir::Pat,
                    _cmt: mc::cmt,
                    _mode: euv::MatchMode) {}
 
     fn consume_pat(&mut self,
-                   _consume_pat: &ast::Pat,
+                   _consume_pat: &hir::Pat,
                    _cmt: mc::cmt,
                    _mode: euv::ConsumeMode) {
     }
diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs
index 41a9fea3e9a..84ea6902ca5 100644
--- a/src/librustc/middle/check_static_recursion.rs
+++ b/src/librustc/middle/check_static_recursion.rs
@@ -11,7 +11,7 @@
 // This compiler pass detects constants that refer to themselves
 // recursively.
 
-use ast_map;
+use front::map as ast_map;
 use session::Session;
 use middle::def::{DefStatic, DefConst, DefAssociatedConst, DefVariant, DefMap};
 use util::nodemap::NodeMap;
@@ -19,8 +19,9 @@ use util::nodemap::NodeMap;
 use syntax::{ast};
 use syntax::codemap::Span;
 use syntax::feature_gate::emit_feature_err;
-use syntax::visit::Visitor;
-use syntax::visit;
+use rustc_front::visit::Visitor;
+use rustc_front::visit;
+use rustc_front::hir;
 
 use std::cell::RefCell;
 
@@ -32,19 +33,19 @@ struct CheckCrateVisitor<'a, 'ast: 'a> {
     // variant definitions with the discriminant expression that applies to
     // each one. If the variant uses the default values (starting from `0`),
     // then `None` is stored.
-    discriminant_map: RefCell<NodeMap<Option<&'ast ast::Expr>>>,
+    discriminant_map: RefCell<NodeMap<Option<&'ast hir::Expr>>>,
 }
 
 impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
-    fn visit_item(&mut self, it: &'ast ast::Item) {
+    fn visit_item(&mut self, it: &'ast hir::Item) {
         match it.node {
-            ast::ItemStatic(..) |
-            ast::ItemConst(..) => {
+            hir::ItemStatic(..) |
+            hir::ItemConst(..) => {
                 let mut recursion_visitor =
                     CheckItemRecursionVisitor::new(self, &it.span);
                 recursion_visitor.visit_item(it);
             },
-            ast::ItemEnum(ref enum_def, ref generics) => {
+            hir::ItemEnum(ref enum_def, ref generics) => {
                 // We could process the whole enum, but handling the variants
                 // with discriminant expressions one by one gives more specific,
                 // less redundant output.
@@ -62,9 +63,9 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
         visit::walk_item(self, it)
     }
 
-    fn visit_trait_item(&mut self, ti: &'ast ast::TraitItem) {
+    fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
         match ti.node {
-            ast::ConstTraitItem(_, ref default) => {
+            hir::ConstTraitItem(_, ref default) => {
                 if let Some(_) = *default {
                     let mut recursion_visitor =
                         CheckItemRecursionVisitor::new(self, &ti.span);
@@ -76,9 +77,9 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
         visit::walk_trait_item(self, ti)
     }
 
-    fn visit_impl_item(&mut self, ii: &'ast ast::ImplItem) {
+    fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
         match ii.node {
-            ast::ConstImplItem(..) => {
+            hir::ConstImplItem(..) => {
                 let mut recursion_visitor =
                     CheckItemRecursionVisitor::new(self, &ii.span);
                 recursion_visitor.visit_impl_item(ii);
@@ -90,7 +91,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
 }
 
 pub fn check_crate<'ast>(sess: &Session,
-                         krate: &'ast ast::Crate,
+                         krate: &'ast hir::Crate,
                          def_map: &DefMap,
                          ast_map: &ast_map::Map<'ast>) {
     let mut visitor = CheckCrateVisitor {
@@ -108,7 +109,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
     sess: &'a Session,
     ast_map: &'a ast_map::Map<'ast>,
     def_map: &'a DefMap,
-    discriminant_map: &'a RefCell<NodeMap<Option<&'ast ast::Expr>>>,
+    discriminant_map: &'a RefCell<NodeMap<Option<&'ast hir::Expr>>>,
     idstack: Vec<ast::NodeId>,
 }
 
@@ -129,7 +130,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
         if self.idstack.iter().any(|&x| x == id) {
             let any_static = self.idstack.iter().any(|&x| {
                 if let ast_map::NodeItem(item) = self.ast_map.get(x) {
-                    if let ast::ItemStatic(..) = item.node {
+                    if let hir::ItemStatic(..) = item.node {
                         true
                     } else {
                         false
@@ -161,7 +162,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
     // So for every variant, we need to track whether there is an expression
     // somewhere in the enum definition that controls its discriminant. We do
     // this by starting from the end and searching backward.
-    fn populate_enum_discriminants(&self, enum_definition: &'ast ast::EnumDef) {
+    fn populate_enum_discriminants(&self, enum_definition: &'ast hir::EnumDef) {
         // Get the map, and return if we already processed this enum or if it
         // has no variants.
         let mut discriminant_map = self.discriminant_map.borrow_mut();
@@ -195,18 +196,18 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
 }
 
 impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
-    fn visit_item(&mut self, it: &'ast ast::Item) {
+    fn visit_item(&mut self, it: &'ast hir::Item) {
         self.with_item_id_pushed(it.id, |v| visit::walk_item(v, it));
     }
 
-    fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef,
-                      generics: &'ast ast::Generics) {
+    fn visit_enum_def(&mut self, enum_definition: &'ast hir::EnumDef,
+                      generics: &'ast hir::Generics) {
         self.populate_enum_discriminants(enum_definition);
         visit::walk_enum_def(self, enum_definition, generics);
     }
 
-    fn visit_variant(&mut self, variant: &'ast ast::Variant,
-                     _: &'ast ast::Generics) {
+    fn visit_variant(&mut self, variant: &'ast hir::Variant,
+                     _: &'ast hir::Generics) {
         let variant_id = variant.node.id;
         let maybe_expr;
         if let Some(get_expr) = self.discriminant_map.borrow().get(&variant_id) {
@@ -225,17 +226,17 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
         }
     }
 
-    fn visit_trait_item(&mut self, ti: &'ast ast::TraitItem) {
+    fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
         self.with_item_id_pushed(ti.id, |v| visit::walk_trait_item(v, ti));
     }
 
-    fn visit_impl_item(&mut self, ii: &'ast ast::ImplItem) {
+    fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
         self.with_item_id_pushed(ii.id, |v| visit::walk_impl_item(v, ii));
     }
 
-    fn visit_expr(&mut self, e: &'ast ast::Expr) {
+    fn visit_expr(&mut self, e: &'ast hir::Expr) {
         match e.node {
-            ast::ExprPath(..) => {
+            hir::ExprPath(..) => {
                 match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
                     Some(DefStatic(def_id, _)) |
                     Some(DefAssociatedConst(def_id)) |
@@ -261,7 +262,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
                     // the whole enum definition to see what expression that
                     // might be (if any).
                     Some(DefVariant(enum_id, variant_id, false)) if enum_id.is_local() => {
-                        if let ast::ItemEnum(ref enum_def, ref generics) =
+                        if let hir::ItemEnum(ref enum_def, ref generics) =
                                self.ast_map.expect_item(enum_id.local_id()).node {
                             self.populate_enum_discriminants(enum_def);
                             let variant = self.ast_map.expect_variant(variant_id.local_id());
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 35057037fba..039a9e55523 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -14,8 +14,8 @@ use self::ConstVal::*;
 use self::ErrKind::*;
 use self::EvalHint::*;
 
-use ast_map;
-use ast_map::blocks::FnLikeNode;
+use front::map as ast_map;
+use front::map::blocks::FnLikeNode;
 use metadata::csearch;
 use metadata::inline::InlinedItem;
 use middle::{astencode, def, infer, subst, traits};
@@ -25,11 +25,14 @@ use middle::ty::{self, Ty};
 use middle::astconv_util::ast_ty_to_prim_ty;
 use util::num::ToPrimitive;
 
-use syntax::ast::{self, Expr};
-use syntax::codemap::{self, Span};
+use syntax::ast;
+use rustc_front::hir::Expr;
+use rustc_front::hir;
+use rustc_front::visit::FnKind;
+use syntax::codemap::Span;
 use syntax::parse::token::InternedString;
 use syntax::ptr::P;
-use syntax::visit::FnKind;
+use syntax::codemap;
 
 use std::borrow::{Cow, IntoCow};
 use std::num::wrapping::OverflowingOps;
@@ -56,7 +59,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
                             enum_def: DefId,
                             variant_def: DefId)
                             -> Option<&'a Expr> {
-    fn variant_expr<'a>(variants: &'a [P<ast::Variant>], id: ast::NodeId)
+    fn variant_expr<'a>(variants: &'a [P<hir::Variant>], id: ast::NodeId)
                         -> Option<&'a Expr> {
         for variant in variants {
             if variant.node.id == id {
@@ -70,7 +73,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
         match tcx.map.find(enum_def.node) {
             None => None,
             Some(ast_map::NodeItem(it)) => match it.node {
-                ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
+                hir::ItemEnum(hir::EnumDef { ref variants }, _) => {
                     variant_expr(&variants[..], variant_def.node)
                 }
                 _ => None
@@ -88,7 +91,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
         let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
             Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
             csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
-                ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
+                hir::ItemEnum(hir::EnumDef { ref variants }, _) => {
                     // NOTE this doesn't do the right thing, it compares inlined
                     // NodeId's to the original variant_def's NodeId, but they
                     // come from different crates, so they will likely never match.
@@ -112,13 +115,13 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
         match tcx.map.find(def_id.node) {
             None => None,
             Some(ast_map::NodeItem(it)) => match it.node {
-                ast::ItemConst(_, ref const_expr) => {
+                hir::ItemConst(_, ref const_expr) => {
                     Some(&*const_expr)
                 }
                 _ => None
             },
             Some(ast_map::NodeTraitItem(ti)) => match ti.node {
-                ast::ConstTraitItem(_, _) => {
+                hir::ConstTraitItem(_, _) => {
                     match maybe_ref_id {
                         // If we have a trait item, and we know the expression
                         // that's the source of the obligation to resolve it,
@@ -144,7 +147,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
                 _ => None
             },
             Some(ast_map::NodeImplItem(ii)) => match ii.node {
-                ast::ConstImplItem(_, ref expr) => {
+                hir::ConstImplItem(_, ref expr) => {
                     Some(&*expr)
                 }
                 _ => None
@@ -163,11 +166,11 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
         let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
             Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
             csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
-                ast::ItemConst(_, ref const_expr) => Some(const_expr.id),
+                hir::ItemConst(_, ref const_expr) => Some(const_expr.id),
                 _ => None
             },
             csearch::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
-                ast::ConstTraitItem(_, _) => {
+                hir::ConstTraitItem(_, _) => {
                     used_ref_id = true;
                     match maybe_ref_id {
                         // As mentioned in the comments above for in-crate
@@ -186,7 +189,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
                 _ => None
             },
             csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref ii)) => match ii.node {
-                ast::ConstImplItem(_, ref expr) => Some(expr.id),
+                hir::ConstImplItem(_, ref expr) => Some(expr.id),
                 _ => None
             },
             _ => None
@@ -246,11 +249,11 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
     };
 
     match fn_like.kind() {
-        FnKind::ItemFn(_, _, _, ast::Constness::Const, _, _) => {
+        FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _) => {
             Some(fn_like)
         }
         FnKind::Method(_, m, _) => {
-            if m.constness == ast::Constness::Const {
+            if m.constness == hir::Constness::Const {
                 Some(fn_like)
             } else {
                 None
@@ -288,12 +291,12 @@ impl ConstVal {
     }
 }
 
-pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat> {
+pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat> {
     let pat = match expr.node {
-        ast::ExprTup(ref exprs) =>
-            ast::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
+        hir::ExprTup(ref exprs) =>
+            hir::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
 
-        ast::ExprCall(ref callee, ref args) => {
+        hir::ExprCall(ref callee, ref args) => {
             let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
             if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
                entry.insert(def);
@@ -304,33 +307,33 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
                 _ => unreachable!()
             };
             let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect();
-            ast::PatEnum(path, Some(pats))
+            hir::PatEnum(path, Some(pats))
         }
 
-        ast::ExprStruct(ref path, ref fields, None) => {
+        hir::ExprStruct(ref path, ref fields, None) => {
             let field_pats = fields.iter().map(|field| codemap::Spanned {
                 span: codemap::DUMMY_SP,
-                node: ast::FieldPat {
+                node: hir::FieldPat {
                     ident: field.ident.node,
                     pat: const_expr_to_pat(tcx, &*field.expr, span),
                     is_shorthand: false,
                 },
             }).collect();
-            ast::PatStruct(path.clone(), field_pats, false)
+            hir::PatStruct(path.clone(), field_pats, false)
         }
 
-        ast::ExprVec(ref exprs) => {
+        hir::ExprVec(ref exprs) => {
             let pats = exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect();
-            ast::PatVec(pats, None, vec![])
+            hir::PatVec(pats, None, vec![])
         }
 
-        ast::ExprPath(_, ref path) => {
+        hir::ExprPath(_, ref path) => {
             let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
             match opt_def {
                 Some(def::DefStruct(..)) =>
-                    ast::PatStruct(path.clone(), vec![], false),
+                    hir::PatStruct(path.clone(), vec![], false),
                 Some(def::DefVariant(..)) =>
-                    ast::PatEnum(path.clone(), None),
+                    hir::PatEnum(path.clone(), None),
                 _ => {
                     match lookup_const(tcx, expr) {
                         Some(actual) => return const_expr_to_pat(tcx, actual, span),
@@ -340,9 +343,9 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
             }
         }
 
-        _ => ast::PatLit(P(expr.clone()))
+        _ => hir::PatLit(P(expr.clone()))
     };
-    P(ast::Pat { id: expr.id, node: pat, span: span })
+    P(hir::Pat { id: expr.id, node: pat, span: span })
 }
 
 pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> ConstVal {
@@ -363,10 +366,10 @@ pub struct ConstEvalErr {
 pub enum ErrKind {
     CannotCast,
     CannotCastTo(&'static str),
-    InvalidOpForBools(ast::BinOp_),
-    InvalidOpForFloats(ast::BinOp_),
-    InvalidOpForIntUint(ast::BinOp_),
-    InvalidOpForUintInt(ast::BinOp_),
+    InvalidOpForBools(hir::BinOp_),
+    InvalidOpForFloats(hir::BinOp_),
+    InvalidOpForIntUint(hir::BinOp_),
+    InvalidOpForUintInt(hir::BinOp_),
     NegateOn(ConstVal),
     NotOn(ConstVal),
 
@@ -463,35 +466,35 @@ pub enum IntTy { I8, I16, I32, I64 }
 pub enum UintTy { U8, U16, U32, U64 }
 
 impl IntTy {
-    pub fn from(tcx: &ty::ctxt, t: ast::IntTy) -> IntTy {
-        let t = if let ast::TyIs = t {
+    pub fn from(tcx: &ty::ctxt, t: hir::IntTy) -> IntTy {
+        let t = if let hir::TyIs = t {
             tcx.sess.target.int_type
         } else {
             t
         };
         match t {
-            ast::TyIs => unreachable!(),
-            ast::TyI8  => IntTy::I8,
-            ast::TyI16 => IntTy::I16,
-            ast::TyI32 => IntTy::I32,
-            ast::TyI64 => IntTy::I64,
+            hir::TyIs => unreachable!(),
+            hir::TyI8  => IntTy::I8,
+            hir::TyI16 => IntTy::I16,
+            hir::TyI32 => IntTy::I32,
+            hir::TyI64 => IntTy::I64,
         }
     }
 }
 
 impl UintTy {
-    pub fn from(tcx: &ty::ctxt, t: ast::UintTy) -> UintTy {
-        let t = if let ast::TyUs = t {
+    pub fn from(tcx: &ty::ctxt, t: hir::UintTy) -> UintTy {
+        let t = if let hir::TyUs = t {
             tcx.sess.target.uint_type
         } else {
             t
         };
         match t {
-            ast::TyUs => unreachable!(),
-            ast::TyU8  => UintTy::U8,
-            ast::TyU16 => UintTy::U16,
-            ast::TyU32 => UintTy::U32,
-            ast::TyU64 => UintTy::U64,
+            hir::TyUs => unreachable!(),
+            hir::TyU8  => UintTy::U8,
+            hir::TyU16 => UintTy::U16,
+            hir::TyU32 => UintTy::U32,
+            hir::TyU64 => UintTy::U64,
         }
     }
 }
@@ -769,7 +772,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
     });
 
     let result = match e.node {
-      ast::ExprUnary(ast::UnNeg, ref inner) => {
+      hir::ExprUnary(hir::UnNeg, ref inner) => {
         match try!(eval_const_expr_partial(tcx, &**inner, ty_hint)) {
           Float(f) => Float(-f),
           Int(n) =>  try!(const_int_checked_neg(n, e, expr_int_type)),
@@ -779,7 +782,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
           const_val => signal!(e, NegateOn(const_val)),
         }
       }
-      ast::ExprUnary(ast::UnNot, ref inner) => {
+      hir::ExprUnary(hir::UnNot, ref inner) => {
         match try!(eval_const_expr_partial(tcx, &**inner, ty_hint)) {
           Int(i) => Int(!i),
           Uint(i) => const_uint_not(i, expr_uint_type),
@@ -787,9 +790,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
           const_val => signal!(e, NotOn(const_val)),
         }
       }
-      ast::ExprBinary(op, ref a, ref b) => {
+      hir::ExprBinary(op, ref a, ref b) => {
         let b_ty = match op.node {
-            ast::BiShl | ast::BiShr => {
+            hir::BiShl | hir::BiShr => {
                 if let ExprTypeChecked = ty_hint {
                     ExprTypeChecked
                 } else {
@@ -802,84 +805,84 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                try!(eval_const_expr_partial(tcx, &**b, b_ty))) {
           (Float(a), Float(b)) => {
             match op.node {
-              ast::BiAdd => Float(a + b),
-              ast::BiSub => Float(a - b),
-              ast::BiMul => Float(a * b),
-              ast::BiDiv => Float(a / b),
-              ast::BiRem => Float(a % b),
-              ast::BiEq => fromb(a == b),
-              ast::BiLt => fromb(a < b),
-              ast::BiLe => fromb(a <= b),
-              ast::BiNe => fromb(a != b),
-              ast::BiGe => fromb(a >= b),
-              ast::BiGt => fromb(a > b),
+              hir::BiAdd => Float(a + b),
+              hir::BiSub => Float(a - b),
+              hir::BiMul => Float(a * b),
+              hir::BiDiv => Float(a / b),
+              hir::BiRem => Float(a % b),
+              hir::BiEq => fromb(a == b),
+              hir::BiLt => fromb(a < b),
+              hir::BiLe => fromb(a <= b),
+              hir::BiNe => fromb(a != b),
+              hir::BiGe => fromb(a >= b),
+              hir::BiGt => fromb(a > b),
               _ => signal!(e, InvalidOpForFloats(op.node))
             }
           }
           (Int(a), Int(b)) => {
             match op.node {
-              ast::BiAdd => try!(const_int_checked_add(a,b,e,expr_int_type)),
-              ast::BiSub => try!(const_int_checked_sub(a,b,e,expr_int_type)),
-              ast::BiMul => try!(const_int_checked_mul(a,b,e,expr_int_type)),
-              ast::BiDiv => try!(const_int_checked_div(a,b,e,expr_int_type)),
-              ast::BiRem => try!(const_int_checked_rem(a,b,e,expr_int_type)),
-              ast::BiAnd | ast::BiBitAnd => Int(a & b),
-              ast::BiOr | ast::BiBitOr => Int(a | b),
-              ast::BiBitXor => Int(a ^ b),
-              ast::BiShl => try!(const_int_checked_shl(a,b,e,expr_int_type)),
-              ast::BiShr => try!(const_int_checked_shr(a,b,e,expr_int_type)),
-              ast::BiEq => fromb(a == b),
-              ast::BiLt => fromb(a < b),
-              ast::BiLe => fromb(a <= b),
-              ast::BiNe => fromb(a != b),
-              ast::BiGe => fromb(a >= b),
-              ast::BiGt => fromb(a > b)
+              hir::BiAdd => try!(const_int_checked_add(a,b,e,expr_int_type)),
+              hir::BiSub => try!(const_int_checked_sub(a,b,e,expr_int_type)),
+              hir::BiMul => try!(const_int_checked_mul(a,b,e,expr_int_type)),
+              hir::BiDiv => try!(const_int_checked_div(a,b,e,expr_int_type)),
+              hir::BiRem => try!(const_int_checked_rem(a,b,e,expr_int_type)),
+              hir::BiAnd | hir::BiBitAnd => Int(a & b),
+              hir::BiOr | hir::BiBitOr => Int(a | b),
+              hir::BiBitXor => Int(a ^ b),
+              hir::BiShl => try!(const_int_checked_shl(a,b,e,expr_int_type)),
+              hir::BiShr => try!(const_int_checked_shr(a,b,e,expr_int_type)),
+              hir::BiEq => fromb(a == b),
+              hir::BiLt => fromb(a < b),
+              hir::BiLe => fromb(a <= b),
+              hir::BiNe => fromb(a != b),
+              hir::BiGe => fromb(a >= b),
+              hir::BiGt => fromb(a > b)
             }
           }
           (Uint(a), Uint(b)) => {
             match op.node {
-              ast::BiAdd => try!(const_uint_checked_add(a,b,e,expr_uint_type)),
-              ast::BiSub => try!(const_uint_checked_sub(a,b,e,expr_uint_type)),
-              ast::BiMul => try!(const_uint_checked_mul(a,b,e,expr_uint_type)),
-              ast::BiDiv => try!(const_uint_checked_div(a,b,e,expr_uint_type)),
-              ast::BiRem => try!(const_uint_checked_rem(a,b,e,expr_uint_type)),
-              ast::BiAnd | ast::BiBitAnd => Uint(a & b),
-              ast::BiOr | ast::BiBitOr => Uint(a | b),
-              ast::BiBitXor => Uint(a ^ b),
-              ast::BiShl => try!(const_uint_checked_shl(a,b,e,expr_uint_type)),
-              ast::BiShr => try!(const_uint_checked_shr(a,b,e,expr_uint_type)),
-              ast::BiEq => fromb(a == b),
-              ast::BiLt => fromb(a < b),
-              ast::BiLe => fromb(a <= b),
-              ast::BiNe => fromb(a != b),
-              ast::BiGe => fromb(a >= b),
-              ast::BiGt => fromb(a > b),
+              hir::BiAdd => try!(const_uint_checked_add(a,b,e,expr_uint_type)),
+              hir::BiSub => try!(const_uint_checked_sub(a,b,e,expr_uint_type)),
+              hir::BiMul => try!(const_uint_checked_mul(a,b,e,expr_uint_type)),
+              hir::BiDiv => try!(const_uint_checked_div(a,b,e,expr_uint_type)),
+              hir::BiRem => try!(const_uint_checked_rem(a,b,e,expr_uint_type)),
+              hir::BiAnd | hir::BiBitAnd => Uint(a & b),
+              hir::BiOr | hir::BiBitOr => Uint(a | b),
+              hir::BiBitXor => Uint(a ^ b),
+              hir::BiShl => try!(const_uint_checked_shl(a,b,e,expr_uint_type)),
+              hir::BiShr => try!(const_uint_checked_shr(a,b,e,expr_uint_type)),
+              hir::BiEq => fromb(a == b),
+              hir::BiLt => fromb(a < b),
+              hir::BiLe => fromb(a <= b),
+              hir::BiNe => fromb(a != b),
+              hir::BiGe => fromb(a >= b),
+              hir::BiGt => fromb(a > b),
             }
           }
           // shifts can have any integral type as their rhs
           (Int(a), Uint(b)) => {
             match op.node {
-              ast::BiShl => try!(const_int_checked_shl_via_uint(a,b,e,expr_int_type)),
-              ast::BiShr => try!(const_int_checked_shr_via_uint(a,b,e,expr_int_type)),
+              hir::BiShl => try!(const_int_checked_shl_via_uint(a,b,e,expr_int_type)),
+              hir::BiShr => try!(const_int_checked_shr_via_uint(a,b,e,expr_int_type)),
               _ => signal!(e, InvalidOpForIntUint(op.node)),
             }
           }
           (Uint(a), Int(b)) => {
             match op.node {
-              ast::BiShl => try!(const_uint_checked_shl_via_int(a,b,e,expr_uint_type)),
-              ast::BiShr => try!(const_uint_checked_shr_via_int(a,b,e,expr_uint_type)),
+              hir::BiShl => try!(const_uint_checked_shl_via_int(a,b,e,expr_uint_type)),
+              hir::BiShr => try!(const_uint_checked_shr_via_int(a,b,e,expr_uint_type)),
               _ => signal!(e, InvalidOpForUintInt(op.node)),
             }
           }
           (Bool(a), Bool(b)) => {
             Bool(match op.node {
-              ast::BiAnd => a && b,
-              ast::BiOr => a || b,
-              ast::BiBitXor => a ^ b,
-              ast::BiBitAnd => a & b,
-              ast::BiBitOr => a | b,
-              ast::BiEq => a == b,
-              ast::BiNe => a != b,
+              hir::BiAnd => a && b,
+              hir::BiOr => a || b,
+              hir::BiBitXor => a ^ b,
+              hir::BiBitAnd => a & b,
+              hir::BiBitOr => a | b,
+              hir::BiEq => a == b,
+              hir::BiNe => a != b,
               _ => signal!(e, InvalidOpForBools(op.node)),
              })
           }
@@ -887,7 +890,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
           _ => signal!(e, MiscBinaryOp),
         }
       }
-      ast::ExprCast(ref base, ref target_ty) => {
+      hir::ExprCast(ref base, ref target_ty) => {
         let ety = ety.or_else(|| ast_ty_to_prim_ty(tcx, &**target_ty))
                 .unwrap_or_else(|| {
                     tcx.sess.span_fatal(target_ty.span,
@@ -912,14 +915,14 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
         }
       }
-      ast::ExprPath(..) => {
+      hir::ExprPath(..) => {
           let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
           let (const_expr, const_ty) = match opt_def {
               Some(def::DefConst(def_id)) => {
                   if def_id.is_local() {
                       match tcx.map.find(def_id.node) {
                           Some(ast_map::NodeItem(it)) => match it.node {
-                              ast::ItemConst(ref ty, ref expr) => {
+                              hir::ItemConst(ref ty, ref expr) => {
                                   (Some(&**expr), Some(&**ty))
                               }
                               _ => (None, None)
@@ -935,7 +938,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                       match tcx.impl_or_trait_item(def_id).container() {
                           ty::TraitContainer(trait_id) => match tcx.map.find(def_id.node) {
                               Some(ast_map::NodeTraitItem(ti)) => match ti.node {
-                                  ast::ConstTraitItem(ref ty, _) => {
+                                  hir::ConstTraitItem(ref ty, _) => {
                                       if let ExprTypeChecked = ty_hint {
                                           let substs = tcx.node_id_item_substs(e.id).substs;
                                           (resolve_trait_associated_const(tcx,
@@ -953,7 +956,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                           },
                           ty::ImplContainer(_) => match tcx.map.find(def_id.node) {
                               Some(ast_map::NodeImplItem(ii)) => match ii.node {
-                                  ast::ConstImplItem(ref ty, ref expr) => {
+                                  hir::ConstImplItem(ref ty, ref expr) => {
                                       (Some(&**expr), Some(&**ty))
                                   }
                                   _ => (None, None)
@@ -990,19 +993,19 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
           };
           try!(eval_const_expr_partial(tcx, const_expr, item_hint))
       }
-      ast::ExprLit(ref lit) => {
+      hir::ExprLit(ref lit) => {
           lit_to_const(&**lit, ety)
       }
-      ast::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ty_hint)),
-      ast::ExprBlock(ref block) => {
+      hir::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ty_hint)),
+      hir::ExprBlock(ref block) => {
         match block.expr {
             Some(ref expr) => try!(eval_const_expr_partial(tcx, &**expr, ty_hint)),
             None => Int(0)
         }
       }
-      ast::ExprTup(_) => Tuple(e.id),
-      ast::ExprStruct(..) => Struct(e.id),
-      ast::ExprTupField(ref base, index) => {
+      hir::ExprTup(_) => Tuple(e.id),
+      hir::ExprStruct(..) => Struct(e.id),
+      hir::ExprTupField(ref base, index) => {
         let base_hint = if let ExprTypeChecked = ty_hint {
             ExprTypeChecked
         } else {
@@ -1010,7 +1013,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
         };
         if let Ok(c) = eval_const_expr_partial(tcx, base, base_hint) {
             if let Tuple(tup_id) = c {
-                if let ast::ExprTup(ref fields) = tcx.map.expect_expr(tup_id).node {
+                if let hir::ExprTup(ref fields) = tcx.map.expect_expr(tup_id).node {
                     if index.node < fields.len() {
                         return eval_const_expr_partial(tcx, &fields[index.node], base_hint)
                     } else {
@@ -1026,7 +1029,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             signal!(base, NonConstPath)
         }
       }
-      ast::ExprField(ref base, field_name) => {
+      hir::ExprField(ref base, field_name) => {
         // Get the base expression if it is a struct and it is constant
         let base_hint = if let ExprTypeChecked = ty_hint {
             ExprTypeChecked
@@ -1035,7 +1038,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
         };
         if let Ok(c) = eval_const_expr_partial(tcx, base, base_hint) {
             if let Struct(struct_id) = c {
-                if let ast::ExprStruct(_, ref fields, _) = tcx.map.expect_expr(struct_id).node {
+                if let hir::ExprStruct(_, ref fields, _) = tcx.map.expect_expr(struct_id).node {
                     // Check that the given field exists and evaluate it
                     // if the idents are compared run-pass/issue-19244 fails
                     if let Some(f) = fields.iter().find(|f| f.ident.node.name
@@ -1061,7 +1064,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
 }
 
 fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
-                                                ti: &'tcx ast::TraitItem,
+                                                ti: &'tcx hir::TraitItem,
                                                 trait_id: DefId,
                                                 rcvr_substs: subst::Substs<'tcx>)
                                                 -> Option<&'tcx Expr>
@@ -1110,7 +1113,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
                      .iter().find(|ic| ic.name == ti.ident.name) {
                 Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
                 None => match ti.node {
-                    ast::ConstTraitItem(_, Some(ref expr)) => Some(&*expr),
+                    hir::ConstTraitItem(_, Some(ref expr)) => Some(&*expr),
                     _ => None,
                 },
             }
@@ -1138,60 +1141,60 @@ fn cast_const<'tcx>(tcx: &ty::ctxt<'tcx>, val: ConstVal, ty: Ty) -> CastResult {
 
     // Issue #23890: If isize/usize, then dispatch to appropriate target representation type
     match (&ty.sty, tcx.sess.target.int_type, tcx.sess.target.uint_type) {
-        (&ty::TyInt(ast::TyIs), ast::TyI32, _) => return convert_val!(i32, Int, i64),
-        (&ty::TyInt(ast::TyIs), ast::TyI64, _) => return convert_val!(i64, Int, i64),
-        (&ty::TyInt(ast::TyIs), _, _) => panic!("unexpected target.int_type"),
+        (&ty::TyInt(hir::TyIs), hir::TyI32, _) => return convert_val!(i32, Int, i64),
+        (&ty::TyInt(hir::TyIs), hir::TyI64, _) => return convert_val!(i64, Int, i64),
+        (&ty::TyInt(hir::TyIs), _, _) => panic!("unexpected target.int_type"),
 
-        (&ty::TyUint(ast::TyUs), _, ast::TyU32) => return convert_val!(u32, Uint, u64),
-        (&ty::TyUint(ast::TyUs), _, ast::TyU64) => return convert_val!(u64, Uint, u64),
-        (&ty::TyUint(ast::TyUs), _, _) => panic!("unexpected target.uint_type"),
+        (&ty::TyUint(hir::TyUs), _, hir::TyU32) => return convert_val!(u32, Uint, u64),
+        (&ty::TyUint(hir::TyUs), _, hir::TyU64) => return convert_val!(u64, Uint, u64),
+        (&ty::TyUint(hir::TyUs), _, _) => panic!("unexpected target.uint_type"),
 
         _ => {}
     }
 
     match ty.sty {
-        ty::TyInt(ast::TyIs) => unreachable!(),
-        ty::TyUint(ast::TyUs) => unreachable!(),
+        ty::TyInt(hir::TyIs) => unreachable!(),
+        ty::TyUint(hir::TyUs) => unreachable!(),
 
-        ty::TyInt(ast::TyI8) => convert_val!(i8, Int, i64),
-        ty::TyInt(ast::TyI16) => convert_val!(i16, Int, i64),
-        ty::TyInt(ast::TyI32) => convert_val!(i32, Int, i64),
-        ty::TyInt(ast::TyI64) => convert_val!(i64, Int, i64),
+        ty::TyInt(hir::TyI8) => convert_val!(i8, Int, i64),
+        ty::TyInt(hir::TyI16) => convert_val!(i16, Int, i64),
+        ty::TyInt(hir::TyI32) => convert_val!(i32, Int, i64),
+        ty::TyInt(hir::TyI64) => convert_val!(i64, Int, i64),
 
-        ty::TyUint(ast::TyU8) => convert_val!(u8, Uint, u64),
-        ty::TyUint(ast::TyU16) => convert_val!(u16, Uint, u64),
-        ty::TyUint(ast::TyU32) => convert_val!(u32, Uint, u64),
-        ty::TyUint(ast::TyU64) => convert_val!(u64, Uint, u64),
+        ty::TyUint(hir::TyU8) => convert_val!(u8, Uint, u64),
+        ty::TyUint(hir::TyU16) => convert_val!(u16, Uint, u64),
+        ty::TyUint(hir::TyU32) => convert_val!(u32, Uint, u64),
+        ty::TyUint(hir::TyU64) => convert_val!(u64, Uint, u64),
 
-        ty::TyFloat(ast::TyF32) => convert_val!(f32, Float, f64),
-        ty::TyFloat(ast::TyF64) => convert_val!(f64, Float, f64),
+        ty::TyFloat(hir::TyF32) => convert_val!(f32, Float, f64),
+        ty::TyFloat(hir::TyF64) => convert_val!(f64, Float, f64),
         _ => Err(ErrKind::CannotCast),
     }
 }
 
-fn lit_to_const(lit: &ast::Lit, ty_hint: Option<Ty>) -> ConstVal {
+fn lit_to_const(lit: &hir::Lit, ty_hint: Option<Ty>) -> ConstVal {
     match lit.node {
-        ast::LitStr(ref s, _) => Str((*s).clone()),
-        ast::LitBinary(ref data) => {
+        hir::LitStr(ref s, _) => Str((*s).clone()),
+        hir::LitBinary(ref data) => {
             Binary(data.clone())
         }
-        ast::LitByte(n) => Uint(n as u64),
-        ast::LitChar(n) => Uint(n as u64),
-        ast::LitInt(n, ast::SignedIntLit(_, ast::Plus)) => Int(n as i64),
-        ast::LitInt(n, ast::UnsuffixedIntLit(ast::Plus)) => {
+        hir::LitByte(n) => Uint(n as u64),
+        hir::LitChar(n) => Uint(n as u64),
+        hir::LitInt(n, hir::SignedIntLit(_, hir::Plus)) => Int(n as i64),
+        hir::LitInt(n, hir::UnsuffixedIntLit(hir::Plus)) => {
             match ty_hint.map(|ty| &ty.sty) {
                 Some(&ty::TyUint(_)) => Uint(n),
                 _ => Int(n as i64)
             }
         }
-        ast::LitInt(n, ast::SignedIntLit(_, ast::Minus)) |
-        ast::LitInt(n, ast::UnsuffixedIntLit(ast::Minus)) => Int(-(n as i64)),
-        ast::LitInt(n, ast::UnsignedIntLit(_)) => Uint(n),
-        ast::LitFloat(ref n, _) |
-        ast::LitFloatUnsuffixed(ref n) => {
+        hir::LitInt(n, hir::SignedIntLit(_, hir::Minus)) |
+        hir::LitInt(n, hir::UnsuffixedIntLit(hir::Minus)) => Int(-(n as i64)),
+        hir::LitInt(n, hir::UnsignedIntLit(_)) => Uint(n),
+        hir::LitFloat(ref n, _) |
+        hir::LitFloatUnsuffixed(ref n) => {
             Float(n.parse::<f64>().unwrap() as f64)
         }
-        ast::LitBool(b) => Bool(b)
+        hir::LitBool(b) => Bool(b)
     }
 }
 
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index dea769197aa..14ba241f62b 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -23,9 +23,12 @@ use std::io;
 use std::usize;
 use syntax::ast;
 use syntax::ast_util::IdRange;
-use syntax::visit;
-use syntax::print::{pp, pprust};
+use syntax::print::pp;
 use util::nodemap::NodeMap;
+use rustc_front::hir;
+use rustc_front::visit;
+use rustc_front::print::pprust;
+
 
 #[derive(Copy, Clone, Debug)]
 pub enum EntryOrExit {
@@ -158,7 +161,7 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
     }
 }
 
-fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
+fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
                          cfg: &cfg::CFG) -> NodeMap<Vec<CFGIndex>> {
     let mut index = NodeMap();
 
@@ -181,7 +184,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
     return index;
 
     fn add_entries_from_fn_decl(index: &mut NodeMap<Vec<CFGIndex>>,
-                                decl: &ast::FnDecl,
+                                decl: &hir::FnDecl,
                                 entry: CFGIndex) {
         //! add mappings from the ast nodes for the formal bindings to
         //! the entry-node in the graph.
@@ -192,7 +195,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
         let mut formals = Formals { entry: entry, index: index };
         visit::walk_fn_decl(&mut formals, decl);
         impl<'a, 'v> visit::Visitor<'v> for Formals<'a> {
-            fn visit_pat(&mut self, p: &ast::Pat) {
+            fn visit_pat(&mut self, p: &hir::Pat) {
                 self.index.entry(p.id).or_insert(vec![]).push(self.entry);
                 visit::walk_pat(self, p)
             }
@@ -222,7 +225,7 @@ pub enum KillFrom {
 impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
     pub fn new(tcx: &'a ty::ctxt<'tcx>,
                analysis_name: &'static str,
-               decl: Option<&ast::FnDecl>,
+               decl: Option<&hir::FnDecl>,
                cfg: &cfg::CFG,
                oper: O,
                id_range: IdRange,
@@ -495,7 +498,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
 
 impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
 //                                ^^^^^^^^^^^^^ only needed for pretty printing
-    pub fn propagate(&mut self, cfg: &cfg::CFG, blk: &ast::Block) {
+    pub fn propagate(&mut self, cfg: &cfg::CFG, blk: &hir::Block) {
         //! Performs the data flow analysis.
 
         if self.bits_per_id == 0 {
@@ -528,7 +531,7 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
     }
 
     fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>,
-                           blk: &ast::Block) -> io::Result<()> {
+                           blk: &hir::Block) -> io::Result<()> {
         let mut ps = pprust::rust_printer_annotated(wr, self);
         try!(ps.cbox(pprust::indent_unit));
         try!(ps.ibox(0));
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index ca82427477b..ed9ca48b39c 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -12,7 +12,11 @@
 // closely. The idea is that all reachable symbols are live, codes called
 // from live codes are live, and everything else is dead.
 
-use ast_map;
+use front::map as ast_map;
+use rustc_front::hir;
+use rustc_front::visit::{self, Visitor};
+use rustc_front::attr::{self, AttrMetaMethods};
+
 use middle::{def, pat_util, privacy, ty};
 use middle::def_id::{DefId};
 use lint;
@@ -20,8 +24,6 @@ use util::nodemap::NodeSet;
 
 use std::collections::HashSet;
 use syntax::{ast, codemap};
-use syntax::attr::{self, AttrMetaMethods};
-use syntax::visit::{self, Visitor};
 
 // Any local node that may call something in its body block should be
 // explored. For example, if it's a live NodeItem that is a
@@ -109,7 +111,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         self.check_def_id(method.def_id);
     }
 
-    fn handle_field_access(&mut self, lhs: &ast::Expr, name: ast::Name) {
+    fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
         if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
             self.live_symbols.insert(def.struct_variant().field_named(name).did.node);
         } else {
@@ -117,14 +119,14 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         }
     }
 
-    fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: usize) {
+    fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
         if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
             self.live_symbols.insert(def.struct_variant().fields[idx].did.node);
         }
     }
 
-    fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
-                                  pats: &[codemap::Spanned<ast::FieldPat>]) {
+    fn handle_field_pattern_match(&mut self, lhs: &hir::Pat,
+                                  pats: &[codemap::Spanned<hir::FieldPat>]) {
         let def = self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def();
         let pat_ty = self.tcx.node_id_to_type(lhs.id);
         let variant = match pat_ty.sty {
@@ -132,7 +134,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
             _ => self.tcx.sess.span_bug(lhs.span, "non-ADT in struct pattern")
         };
         for pat in pats {
-            if let ast::PatWild(ast::PatWildSingle) = pat.node.pat.node {
+            if let hir::PatWild(hir::PatWildSingle) = pat.node.pat.node {
                 continue;
             }
             self.live_symbols.insert(variant.field_named(pat.node.ident.name).did.node);
@@ -166,7 +168,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         match *node {
             ast_map::NodeItem(item) => {
                 match item.node {
-                    ast::ItemStruct(..) => {
+                    hir::ItemStruct(..) => {
                         self.struct_has_extern_repr = item.attrs.iter().any(|attr| {
                             attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
                                 .contains(&attr::ReprExtern)
@@ -174,14 +176,14 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
                         visit::walk_item(self, &*item);
                     }
-                    ast::ItemEnum(..) => {
-                        self.inherited_pub_visibility = item.vis == ast::Public;
+                    hir::ItemEnum(..) => {
+                        self.inherited_pub_visibility = item.vis == hir::Public;
                         visit::walk_item(self, &*item);
                     }
-                    ast::ItemFn(..)
-                    | ast::ItemTy(..)
-                    | ast::ItemStatic(..)
-                    | ast::ItemConst(..) => {
+                    hir::ItemFn(..)
+                    | hir::ItemTy(..)
+                    | hir::ItemStatic(..)
+                    | hir::ItemConst(..) => {
                         visit::walk_item(self, &*item);
                     }
                     _ => ()
@@ -205,13 +207,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
 
-    fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident,
-                        _: &ast::Generics, _: ast::NodeId) {
+    fn visit_struct_def(&mut self, def: &hir::StructDef, _: ast::Ident,
+                        _: &hir::Generics, _: ast::NodeId) {
         let has_extern_repr = self.struct_has_extern_repr;
         let inherited_pub_visibility = self.inherited_pub_visibility;
         let live_fields = def.fields.iter().filter(|f| {
             has_extern_repr || inherited_pub_visibility || match f.node.kind {
-                ast::NamedField(_, ast::Public) => true,
+                hir::NamedField(_, hir::Public) => true,
                 _ => false
             }
         });
@@ -220,15 +222,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
         visit::walk_struct_def(self, def);
     }
 
-    fn visit_expr(&mut self, expr: &ast::Expr) {
+    fn visit_expr(&mut self, expr: &hir::Expr) {
         match expr.node {
-            ast::ExprMethodCall(..) => {
+            hir::ExprMethodCall(..) => {
                 self.lookup_and_handle_method(expr.id);
             }
-            ast::ExprField(ref lhs, ref ident) => {
+            hir::ExprField(ref lhs, ref ident) => {
                 self.handle_field_access(&**lhs, ident.node.name);
             }
-            ast::ExprTupField(ref lhs, idx) => {
+            hir::ExprTupField(ref lhs, idx) => {
                 self.handle_tup_field_access(&**lhs, idx.node);
             }
             _ => ()
@@ -237,7 +239,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
         visit::walk_expr(self, expr);
     }
 
-    fn visit_arm(&mut self, arm: &ast::Arm) {
+    fn visit_arm(&mut self, arm: &hir::Arm) {
         if arm.pats.len() == 1 {
             let pat = &*arm.pats[0];
             let variants = pat_util::necessary_variants(&self.tcx.def_map, pat);
@@ -254,10 +256,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_pat(&mut self, pat: &ast::Pat) {
+    fn visit_pat(&mut self, pat: &hir::Pat) {
         let def_map = &self.tcx.def_map;
         match pat.node {
-            ast::PatStruct(_, ref fields, _) => {
+            hir::PatStruct(_, ref fields, _) => {
                 self.handle_field_pattern_match(pat, fields);
             }
             _ if pat_util::pat_is_const(def_map, pat) => {
@@ -272,24 +274,24 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
         self.ignore_non_const_paths = false;
     }
 
-    fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
+    fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
         self.lookup_and_handle_definition(&id);
         visit::walk_path(self, path);
     }
 
-    fn visit_item(&mut self, _: &ast::Item) {
+    fn visit_item(&mut self, _: &hir::Item) {
         // Do not recurse into items. These items will be added to the
         // worklist and recursed into manually if necessary.
     }
 }
 
-fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
+fn has_allow_dead_code_or_lang_attr(attrs: &[hir::Attribute]) -> bool {
     if attr::contains_name(attrs, "lang") {
         return true;
     }
 
     let dead_code = lint::builtin::DEAD_CODE.name_lower();
-    for attr in lint::gather_attrs(attrs) {
+    for attr in lint::gather_attrs_from_hir(attrs) {
         match attr {
             Ok((ref name, lint::Allow, _))
                 if &name[..] == dead_code => return true,
@@ -317,20 +319,20 @@ struct LifeSeeder {
 }
 
 impl<'v> Visitor<'v> for LifeSeeder {
-    fn visit_item(&mut self, item: &ast::Item) {
+    fn visit_item(&mut self, item: &hir::Item) {
         let allow_dead_code = has_allow_dead_code_or_lang_attr(&item.attrs);
         if allow_dead_code {
             self.worklist.push(item.id);
         }
         match item.node {
-            ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
+            hir::ItemEnum(ref enum_def, _) if allow_dead_code => {
                 self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
             }
-            ast::ItemTrait(_, _, _, ref trait_items) => {
+            hir::ItemTrait(_, _, _, ref trait_items) => {
                 for trait_item in trait_items {
                     match trait_item.node {
-                        ast::ConstTraitItem(_, Some(_)) |
-                        ast::MethodTraitItem(_, Some(_)) => {
+                        hir::ConstTraitItem(_, Some(_)) |
+                        hir::MethodTraitItem(_, Some(_)) => {
                             if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
                                 self.worklist.push(trait_item.id);
                             }
@@ -339,18 +341,17 @@ impl<'v> Visitor<'v> for LifeSeeder {
                     }
                 }
             }
-            ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
+            hir::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
                 for impl_item in impl_items {
                     match impl_item.node {
-                        ast::ConstImplItem(..) |
-                        ast::MethodImplItem(..) => {
+                        hir::ConstImplItem(..) |
+                        hir::MethodImplItem(..) => {
                             if opt_trait.is_some() ||
                                     has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
                                 self.worklist.push(impl_item.id);
                             }
                         }
-                        ast::TypeImplItem(_) => {}
-                        ast::MacImplItem(_) => panic!("unexpanded macro")
+                        hir::TypeImplItem(_) => {}
                     }
                 }
             }
@@ -363,7 +364,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
 fn create_and_seed_worklist(tcx: &ty::ctxt,
                             exported_items: &privacy::ExportedItems,
                             reachable_symbols: &NodeSet,
-                            krate: &ast::Crate) -> Vec<ast::NodeId> {
+                            krate: &hir::Crate) -> Vec<ast::NodeId> {
     let mut worklist = Vec::new();
 
     // Preferably, we would only need to seed the worklist with reachable
@@ -401,7 +402,7 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
 fn find_live(tcx: &ty::ctxt,
              exported_items: &privacy::ExportedItems,
              reachable_symbols: &NodeSet,
-             krate: &ast::Crate)
+             krate: &hir::Crate)
              -> Box<HashSet<ast::NodeId>> {
     let worklist = create_and_seed_worklist(tcx, exported_items,
                                             reachable_symbols, krate);
@@ -410,9 +411,9 @@ fn find_live(tcx: &ty::ctxt,
     symbol_visitor.live_symbols
 }
 
-fn get_struct_ctor_id(item: &ast::Item) -> Option<ast::NodeId> {
+fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
     match item.node {
-        ast::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
+        hir::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
         _ => None
     }
 }
@@ -423,20 +424,20 @@ struct DeadVisitor<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
-    fn should_warn_about_item(&mut self, item: &ast::Item) -> bool {
+    fn should_warn_about_item(&mut self, item: &hir::Item) -> bool {
         let should_warn = match item.node {
-            ast::ItemStatic(..)
-            | ast::ItemConst(..)
-            | ast::ItemFn(..)
-            | ast::ItemEnum(..)
-            | ast::ItemStruct(..) => true,
+            hir::ItemStatic(..)
+            | hir::ItemConst(..)
+            | hir::ItemFn(..)
+            | hir::ItemEnum(..)
+            | hir::ItemStruct(..) => true,
             _ => false
         };
         let ctor_id = get_struct_ctor_id(item);
         should_warn && !self.symbol_is_live(item.id, ctor_id)
     }
 
-    fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
+    fn should_warn_about_field(&mut self, node: &hir::StructField_) -> bool {
         let is_named = node.ident().is_some();
         let field_type = self.tcx.node_id_to_type(node.id);
         let is_marker_field = match field_type.ty_to_def_id() {
@@ -449,7 +450,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
             && !has_allow_dead_code_or_lang_attr(&node.attrs)
     }
 
-    fn should_warn_about_variant(&mut self, variant: &ast::Variant_) -> bool {
+    fn should_warn_about_variant(&mut self, variant: &hir::Variant_) -> bool {
         !self.symbol_is_live(variant.id, None)
             && !has_allow_dead_code_or_lang_attr(&variant.attrs)
     }
@@ -509,7 +510,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item) {
+    fn visit_item(&mut self, item: &hir::Item) {
         if self.should_warn_about_item(item) {
             self.warn_dead_code(
                 item.id,
@@ -519,7 +520,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
             );
         } else {
             match item.node {
-                ast::ItemEnum(ref enum_def, _) => {
+                hir::ItemEnum(ref enum_def, _) => {
                     for variant in &enum_def.variants {
                         if self.should_warn_about_variant(&variant.node) {
                             self.warn_dead_code(variant.node.id, variant.span,
@@ -533,14 +534,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
         visit::walk_item(self, item);
     }
 
-    fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
+    fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) {
         if !self.symbol_is_live(fi.id, None) {
             self.warn_dead_code(fi.id, fi.span, fi.ident.name, fi.node.descriptive_variant());
         }
         visit::walk_foreign_item(self, fi);
     }
 
-    fn visit_struct_field(&mut self, field: &ast::StructField) {
+    fn visit_struct_field(&mut self, field: &hir::StructField) {
         if self.should_warn_about_field(&field.node) {
             self.warn_dead_code(field.node.id, field.span,
                                 field.node.ident().unwrap().name, "struct field");
@@ -549,39 +550,38 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
         visit::walk_struct_field(self, field);
     }
 
-    fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
+    fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
         match impl_item.node {
-            ast::ConstImplItem(_, ref expr) => {
+            hir::ConstImplItem(_, ref expr) => {
                 if !self.symbol_is_live(impl_item.id, None) {
                     self.warn_dead_code(impl_item.id, impl_item.span,
                                         impl_item.ident.name, "associated const");
                 }
                 visit::walk_expr(self, expr)
             }
-            ast::MethodImplItem(_, ref body) => {
+            hir::MethodImplItem(_, ref body) => {
                 if !self.symbol_is_live(impl_item.id, None) {
                     self.warn_dead_code(impl_item.id, impl_item.span,
                                         impl_item.ident.name, "method");
                 }
                 visit::walk_block(self, body)
             }
-            ast::TypeImplItem(..) |
-            ast::MacImplItem(..) => {}
+            hir::TypeImplItem(..) => {}
         }
     }
 
     // Overwrite so that we don't warn the trait item itself.
-    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+    fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
         match trait_item.node {
-            ast::ConstTraitItem(_, Some(ref expr)) => {
+            hir::ConstTraitItem(_, Some(ref expr)) => {
                 visit::walk_expr(self, expr)
             }
-            ast::MethodTraitItem(_, Some(ref body)) => {
+            hir::MethodTraitItem(_, Some(ref body)) => {
                 visit::walk_block(self, body)
             }
-            ast::ConstTraitItem(_, None) |
-            ast::MethodTraitItem(_, None) |
-            ast::TypeTraitItem(..) => {}
+            hir::ConstTraitItem(_, None) |
+            hir::MethodTraitItem(_, None) |
+            hir::TypeTraitItem(..) => {}
         }
     }
 }
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index ca08a97e811..2930dd67f45 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -15,6 +15,7 @@ use middle::privacy::LastPrivate;
 use middle::subst::ParamSpace;
 use util::nodemap::NodeMap;
 use syntax::ast;
+use rustc_front::hir;
 
 use std::cell::RefCell;
 
@@ -33,7 +34,7 @@ pub enum Def {
     DefTy(DefId, bool /* is_enum */),
     DefAssociatedTy(DefId /* trait */, DefId),
     DefTrait(DefId),
-    DefPrimTy(ast::PrimTy),
+    DefPrimTy(hir::PrimTy),
     DefTyParam(ParamSpace, u32, DefId, ast::Name),
     DefUse(DefId),
     DefUpvar(ast::NodeId,  // id of closed over local
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index f78ec28c7f0..d1e1434dad8 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -18,8 +18,9 @@ use middle::ty::MethodCall;
 
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::visit;
-use syntax::visit::{FnKind, Visitor};
+use rustc_front::hir;
+use rustc_front::visit;
+use rustc_front::visit::{FnKind, Visitor};
 
 #[derive(Copy, Clone)]
 struct UnsafeContext {
@@ -42,7 +43,7 @@ enum RootUnsafeContext {
 
 fn type_is_unsafe_function(ty: Ty) -> bool {
     match ty.sty {
-        ty::TyBareFn(_, ref f) => f.unsafety == ast::Unsafety::Unsafe,
+        ty::TyBareFn(_, ref f) => f.unsafety == hir::Unsafety::Unsafe,
         _ => false,
     }
 }
@@ -75,14 +76,14 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
-    fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v ast::FnDecl,
-                block: &'v ast::Block, span: Span, _: ast::NodeId) {
+    fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl,
+                block: &'v hir::Block, span: Span, _: ast::NodeId) {
 
         let (is_item_fn, is_unsafe_fn) = match fn_kind {
             FnKind::ItemFn(_, _, unsafety, _, _, _) =>
-                (true, unsafety == ast::Unsafety::Unsafe),
+                (true, unsafety == hir::Unsafety::Unsafe),
             FnKind::Method(_, sig, _) =>
-                (true, sig.unsafety == ast::Unsafety::Unsafe),
+                (true, sig.unsafety == hir::Unsafety::Unsafe),
             _ => (false, false),
         };
 
@@ -98,11 +99,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
         self.unsafe_context = old_unsafe_context
     }
 
-    fn visit_block(&mut self, block: &ast::Block) {
+    fn visit_block(&mut self, block: &hir::Block) {
         let old_unsafe_context = self.unsafe_context;
         match block.rules {
-            ast::DefaultBlock => {}
-            ast::UnsafeBlock(source) => {
+            hir::DefaultBlock => {}
+            hir::UnsafeBlock(source) => {
                 // By default only the outermost `unsafe` block is
                 // "used" and so nested unsafe blocks are pointless
                 // (the inner ones are unnecessary and we actually
@@ -118,15 +119,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
                 // external blocks (e.g. `unsafe { println("") }`,
                 // expands to `unsafe { ... unsafe { ... } }` where
                 // the inner one is compiler generated).
-                if self.unsafe_context.root == SafeContext || source == ast::CompilerGenerated {
+                if self.unsafe_context.root == SafeContext || source == hir::CompilerGenerated {
                     self.unsafe_context.root = UnsafeBlock(block.id)
                 }
             }
-            ast::PushUnsafeBlock(..) => {
+            hir::PushUnsafeBlock(..) => {
                 self.unsafe_context.push_unsafe_count =
                     self.unsafe_context.push_unsafe_count.checked_add(1).unwrap();
             }
-            ast::PopUnsafeBlock(..) => {
+            hir::PopUnsafeBlock(..) => {
                 self.unsafe_context.push_unsafe_count =
                     self.unsafe_context.push_unsafe_count.checked_sub(1).unwrap();
             }
@@ -137,9 +138,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
         self.unsafe_context = old_unsafe_context
     }
 
-    fn visit_expr(&mut self, expr: &ast::Expr) {
+    fn visit_expr(&mut self, expr: &hir::Expr) {
         match expr.node {
-            ast::ExprMethodCall(_, _, _) => {
+            hir::ExprMethodCall(_, _, _) => {
                 let method_call = MethodCall::expr(expr.id);
                 let base_type = self.tcx.tables.borrow().method_map[&method_call].ty;
                 debug!("effect: method call case, base type is {:?}",
@@ -149,7 +150,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
                                         "invocation of unsafe method")
                 }
             }
-            ast::ExprCall(ref base, _) => {
+            hir::ExprCall(ref base, _) => {
                 let base_type = self.tcx.node_id_to_type(base.id);
                 debug!("effect: call case, base type is {:?}",
                         base_type);
@@ -157,7 +158,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
                     self.require_unsafe(expr.span, "call to unsafe function")
                 }
             }
-            ast::ExprUnary(ast::UnDeref, ref base) => {
+            hir::ExprUnary(hir::UnDeref, ref base) => {
                 let base_type = self.tcx.node_id_to_type(base.id);
                 debug!("effect: unary case, base type is {:?}",
                         base_type);
@@ -165,10 +166,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
                     self.require_unsafe(expr.span, "dereference of raw pointer")
                 }
             }
-            ast::ExprInlineAsm(..) => {
+            hir::ExprInlineAsm(..) => {
                 self.require_unsafe(expr.span, "use of inline assembly");
             }
-            ast::ExprPath(..) => {
+            hir::ExprPath(..) => {
                 if let def::DefStatic(_, true) = self.tcx.resolve_expr(expr) {
                     self.require_unsafe(expr.span, "use of mutable static");
                 }
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 8cdd4f7fe74..e32a9b280f3 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -9,15 +9,15 @@
 // except according to those terms.
 
 
-use ast_map;
+use front::map as ast_map;
 use session::{config, Session};
-use syntax;
-use syntax::ast::{NodeId, Item};
-use syntax::attr;
+use syntax::ast::NodeId;
+use rustc_front::hir::{Item, ItemFn};
+use rustc_front::attr;
 use syntax::codemap::Span;
 use syntax::entry::EntryPointType;
-use syntax::visit;
-use syntax::visit::Visitor;
+use rustc_front::visit;
+use rustc_front::visit::Visitor;
 
 struct EntryContext<'a> {
     session: &'a Session,
@@ -76,8 +76,33 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
     configure_main(&mut ctxt);
 }
 
+// Beware, this is duplicated in libsyntax/entry.rs, make sure to keep
+// them in sync.
+fn entry_point_type(item: &Item, depth: usize) -> EntryPointType {
+    match item.node {
+        ItemFn(..) => {
+            if attr::contains_name(&item.attrs, "start") {
+                EntryPointType::Start
+            } else if attr::contains_name(&item.attrs, "main") {
+                EntryPointType::MainAttr
+            } else if item.ident.name == "main" {
+                if depth == 1 {
+                    // This is a top-level function so can be 'main'
+                    EntryPointType::MainNamed
+                } else {
+                    EntryPointType::OtherMain
+                }
+            } else {
+                EntryPointType::None
+            }
+        }
+        _ => EntryPointType::None,
+    }
+}
+
+
 fn find_item(item: &Item, ctxt: &mut EntryContext) {
-    match syntax::entry::entry_point_type(item, ctxt.depth) {
+    match entry_point_type(item, ctxt.depth) {
         EntryPointType::MainNamed => {
             if ctxt.main_fn.is_none() {
                 ctxt.main_fn = Some((item.id, item.span));
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index d8f3ff3d9cb..15f37d434d2 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -26,7 +26,9 @@ use middle::infer;
 use middle::mem_categorization as mc;
 use middle::ty;
 
-use syntax::{ast, ast_util};
+use rustc_front::hir;
+
+use syntax::ast;
 use syntax::ptr::P;
 use syntax::codemap::Span;
 
@@ -57,14 +59,14 @@ pub trait Delegate<'tcx> {
     // same input pattern structure (though of `consume_pat` can be
     // called on a subpart of an input passed to `matched_pat).
     fn matched_pat(&mut self,
-                   matched_pat: &ast::Pat,
+                   matched_pat: &hir::Pat,
                    cmt: mc::cmt<'tcx>,
                    mode: MatchMode);
 
     // The value found at `cmt` is either copied or moved via the
     // pattern binding `consume_pat`, depending on mode.
     fn consume_pat(&mut self,
-                   consume_pat: &ast::Pat,
+                   consume_pat: &hir::Pat,
                    cmt: mc::cmt<'tcx>,
                    mode: ConsumeMode);
 
@@ -277,23 +279,25 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                typer: &'t infer::InferCtxt<'a, 'tcx>)
                -> ExprUseVisitor<'d,'t,'a,'tcx>
     {
-        ExprUseVisitor {
+        let result = ExprUseVisitor {
             typer: typer,
             mc: mc::MemCategorizationContext::new(typer),
             delegate: delegate,
-        }
+        };
+
+        result
     }
 
     pub fn walk_fn(&mut self,
-                   decl: &ast::FnDecl,
-                   body: &ast::Block) {
+                   decl: &hir::FnDecl,
+                   body: &hir::Block) {
         self.walk_arg_patterns(decl, body);
         self.walk_block(body);
     }
 
     fn walk_arg_patterns(&mut self,
-                         decl: &ast::FnDecl,
-                         body: &ast::Block) {
+                         decl: &hir::FnDecl,
+                         body: &hir::Block) {
         for arg in &decl.inputs {
             let arg_ty = return_if_err!(self.typer.node_ty(arg.pat.id));
 
@@ -323,13 +327,13 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         self.delegate.consume(consume_id, consume_span, cmt, mode);
     }
 
-    fn consume_exprs(&mut self, exprs: &Vec<P<ast::Expr>>) {
+    fn consume_exprs(&mut self, exprs: &Vec<P<hir::Expr>>) {
         for expr in exprs {
             self.consume_expr(&**expr);
         }
     }
 
-    pub fn consume_expr(&mut self, expr: &ast::Expr) {
+    pub fn consume_expr(&mut self, expr: &hir::Expr) {
         debug!("consume_expr(expr={:?})", expr);
 
         let cmt = return_if_err!(self.mc.cat_expr(expr));
@@ -338,8 +342,8 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     }
 
     fn mutate_expr(&mut self,
-                   assignment_expr: &ast::Expr,
-                   expr: &ast::Expr,
+                   assignment_expr: &hir::Expr,
+                   expr: &hir::Expr,
                    mode: MutateMode) {
         let cmt = return_if_err!(self.mc.cat_expr(expr));
         self.delegate.mutate(assignment_expr.id, assignment_expr.span, cmt, mode);
@@ -347,7 +351,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     }
 
     fn borrow_expr(&mut self,
-                   expr: &ast::Expr,
+                   expr: &hir::Expr,
                    r: ty::Region,
                    bk: ty::BorrowKind,
                    cause: LoanCause) {
@@ -363,37 +367,37 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         self.walk_expr(expr)
     }
 
-    fn select_from_expr(&mut self, expr: &ast::Expr) {
+    fn select_from_expr(&mut self, expr: &hir::Expr) {
         self.walk_expr(expr)
     }
 
-    pub fn walk_expr(&mut self, expr: &ast::Expr) {
+    pub fn walk_expr(&mut self, expr: &hir::Expr) {
         debug!("walk_expr(expr={:?})", expr);
 
         self.walk_adjustment(expr);
 
         match expr.node {
-            ast::ExprParen(ref subexpr) => {
+            hir::ExprParen(ref subexpr) => {
                 self.walk_expr(&**subexpr)
             }
 
-            ast::ExprPath(..) => { }
+            hir::ExprPath(..) => { }
 
-            ast::ExprUnary(ast::UnDeref, ref base) => {      // *base
+            hir::ExprUnary(hir::UnDeref, ref base) => {      // *base
                 if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
                     self.select_from_expr(&**base);
                 }
             }
 
-            ast::ExprField(ref base, _) => {         // base.f
+            hir::ExprField(ref base, _) => {         // base.f
                 self.select_from_expr(&**base);
             }
 
-            ast::ExprTupField(ref base, _) => {         // base.<n>
+            hir::ExprTupField(ref base, _) => {         // base.<n>
                 self.select_from_expr(&**base);
             }
 
-            ast::ExprIndex(ref lhs, ref rhs) => {       // lhs[rhs]
+            hir::ExprIndex(ref lhs, ref rhs) => {       // lhs[rhs]
                 if !self.walk_overloaded_operator(expr,
                                                   &**lhs,
                                                   vec![&**rhs],
@@ -403,29 +407,29 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             }
 
-            ast::ExprRange(ref start, ref end) => {
+            hir::ExprRange(ref start, ref end) => {
                 start.as_ref().map(|e| self.consume_expr(&**e));
                 end.as_ref().map(|e| self.consume_expr(&**e));
             }
 
-            ast::ExprCall(ref callee, ref args) => {    // callee(args)
+            hir::ExprCall(ref callee, ref args) => {    // callee(args)
                 self.walk_callee(expr, &**callee);
                 self.consume_exprs(args);
             }
 
-            ast::ExprMethodCall(_, _, ref args) => { // callee.m(args)
+            hir::ExprMethodCall(_, _, ref args) => { // callee.m(args)
                 self.consume_exprs(args);
             }
 
-            ast::ExprStruct(_, ref fields, ref opt_with) => {
+            hir::ExprStruct(_, ref fields, ref opt_with) => {
                 self.walk_struct_expr(expr, fields, opt_with);
             }
 
-            ast::ExprTup(ref exprs) => {
+            hir::ExprTup(ref exprs) => {
                 self.consume_exprs(exprs);
             }
 
-            ast::ExprIf(ref cond_expr, ref then_blk, ref opt_else_expr) => {
+            hir::ExprIf(ref cond_expr, ref then_blk, ref opt_else_expr) => {
                 self.consume_expr(&**cond_expr);
                 self.walk_block(&**then_blk);
                 if let Some(ref else_expr) = *opt_else_expr {
@@ -433,11 +437,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             }
 
-            ast::ExprIfLet(..) => {
-                self.tcx().sess.span_bug(expr.span, "non-desugared ExprIfLet");
-            }
-
-            ast::ExprMatch(ref discr, ref arms, _) => {
+            hir::ExprMatch(ref discr, ref arms, _) => {
                 let discr_cmt = return_if_err!(self.mc.cat_expr(&**discr));
                 self.borrow_expr(&**discr, ty::ReEmpty, ty::ImmBorrow, MatchDiscriminant);
 
@@ -449,11 +449,11 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             }
 
-            ast::ExprVec(ref exprs) => {
+            hir::ExprVec(ref exprs) => {
                 self.consume_exprs(exprs);
             }
 
-            ast::ExprAddrOf(m, ref base) => {   // &base
+            hir::ExprAddrOf(m, ref base) => {   // &base
                 // make sure that the thing we are pointing out stays valid
                 // for the lifetime `scope_r` of the resulting ptr:
                 let expr_ty = return_if_err!(self.typer.node_ty(expr.id));
@@ -463,7 +463,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             }
 
-            ast::ExprInlineAsm(ref ia) => {
+            hir::ExprInlineAsm(ref ia) => {
                 for &(_, ref input) in &ia.inputs {
                     self.consume_expr(&**input);
                 }
@@ -474,29 +474,21 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             }
 
-            ast::ExprBreak(..) |
-            ast::ExprAgain(..) |
-            ast::ExprLit(..) => {}
+            hir::ExprBreak(..) |
+            hir::ExprAgain(..) |
+            hir::ExprLit(..) => {}
 
-            ast::ExprLoop(ref blk, _) => {
+            hir::ExprLoop(ref blk, _) => {
                 self.walk_block(&**blk);
             }
 
-            ast::ExprWhile(ref cond_expr, ref blk, _) => {
+            hir::ExprWhile(ref cond_expr, ref blk, _) => {
                 self.consume_expr(&**cond_expr);
                 self.walk_block(&**blk);
             }
 
-            ast::ExprWhileLet(..) => {
-                self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
-            }
-
-            ast::ExprForLoop(..) => {
-                self.tcx().sess.span_bug(expr.span, "non-desugared ExprForLoop");
-            }
-
-            ast::ExprUnary(op, ref lhs) => {
-                let pass_args = if ast_util::is_by_value_unop(op) {
+            hir::ExprUnary(op, ref lhs) => {
+                let pass_args = if ::rustc_front::util::is_by_value_unop(op) {
                     PassArgs::ByValue
                 } else {
                     PassArgs::ByRef
@@ -507,8 +499,8 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             }
 
-            ast::ExprBinary(op, ref lhs, ref rhs) => {
-                let pass_args = if ast_util::is_by_value_binop(op.node) {
+            hir::ExprBinary(op, ref lhs, ref rhs) => {
+                let pass_args = if ::rustc_front::util::is_by_value_binop(op.node) {
                     PassArgs::ByValue
                 } else {
                     PassArgs::ByRef
@@ -520,42 +512,42 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             }
 
-            ast::ExprBlock(ref blk) => {
+            hir::ExprBlock(ref blk) => {
                 self.walk_block(&**blk);
             }
 
-            ast::ExprRet(ref opt_expr) => {
+            hir::ExprRet(ref opt_expr) => {
                 if let Some(ref expr) = *opt_expr {
                     self.consume_expr(&**expr);
                 }
             }
 
-            ast::ExprAssign(ref lhs, ref rhs) => {
+            hir::ExprAssign(ref lhs, ref rhs) => {
                 self.mutate_expr(expr, &**lhs, JustWrite);
                 self.consume_expr(&**rhs);
             }
 
-            ast::ExprCast(ref base, _) => {
+            hir::ExprCast(ref base, _) => {
                 self.consume_expr(&**base);
             }
 
-            ast::ExprAssignOp(_, ref lhs, ref rhs) => {
+            hir::ExprAssignOp(_, ref lhs, ref rhs) => {
                 // This will have to change if/when we support
                 // overloaded operators for `+=` and so forth.
                 self.mutate_expr(expr, &**lhs, WriteAndRead);
                 self.consume_expr(&**rhs);
             }
 
-            ast::ExprRepeat(ref base, ref count) => {
+            hir::ExprRepeat(ref base, ref count) => {
                 self.consume_expr(&**base);
                 self.consume_expr(&**count);
             }
 
-            ast::ExprClosure(..) => {
+            hir::ExprClosure(..) => {
                 self.walk_captures(expr)
             }
 
-            ast::ExprBox(ref place, ref base) => {
+            hir::ExprBox(ref place, ref base) => {
                 match *place {
                     Some(ref place) => self.consume_expr(&**place),
                     None => {}
@@ -567,16 +559,10 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                         "box with explicit place remains after expansion");
                 }
             }
-
-            ast::ExprMac(..) => {
-                self.tcx().sess.span_bug(
-                    expr.span,
-                    "macro expression remains after expansion");
-            }
         }
     }
 
-    fn walk_callee(&mut self, call: &ast::Expr, callee: &ast::Expr) {
+    fn walk_callee(&mut self, call: &hir::Expr, callee: &hir::Expr) {
         let callee_ty = return_if_err!(self.typer.expr_ty_adjusted(callee));
         debug!("walk_callee: callee={:?} callee_ty={:?}",
                callee, callee_ty);
@@ -617,33 +603,29 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         }
     }
 
-    fn walk_stmt(&mut self, stmt: &ast::Stmt) {
+    fn walk_stmt(&mut self, stmt: &hir::Stmt) {
         match stmt.node {
-            ast::StmtDecl(ref decl, _) => {
+            hir::StmtDecl(ref decl, _) => {
                 match decl.node {
-                    ast::DeclLocal(ref local) => {
+                    hir::DeclLocal(ref local) => {
                         self.walk_local(&**local);
                     }
 
-                    ast::DeclItem(_) => {
+                    hir::DeclItem(_) => {
                         // we don't visit nested items in this visitor,
                         // only the fn body we were given.
                     }
                 }
             }
 
-            ast::StmtExpr(ref expr, _) |
-            ast::StmtSemi(ref expr, _) => {
+            hir::StmtExpr(ref expr, _) |
+            hir::StmtSemi(ref expr, _) => {
                 self.consume_expr(&**expr);
             }
-
-            ast::StmtMac(..) => {
-                self.tcx().sess.span_bug(stmt.span, "unexpanded stmt macro");
-            }
         }
     }
 
-    fn walk_local(&mut self, local: &ast::Local) {
+    fn walk_local(&mut self, local: &hir::Local) {
         match local.init {
             None => {
                 let delegate = &mut self.delegate;
@@ -667,7 +649,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
 
     /// Indicates that the value of `blk` will be consumed, meaning either copied or moved
     /// depending on its type.
-    fn walk_block(&mut self, blk: &ast::Block) {
+    fn walk_block(&mut self, blk: &hir::Block) {
         debug!("walk_block(blk.id={})", blk.id);
 
         for stmt in &blk.stmts {
@@ -680,9 +662,9 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     }
 
     fn walk_struct_expr(&mut self,
-                        _expr: &ast::Expr,
-                        fields: &Vec<ast::Field>,
-                        opt_with: &Option<P<ast::Expr>>) {
+                        _expr: &hir::Expr,
+                        fields: &Vec<hir::Field>,
+                        opt_with: &Option<P<hir::Expr>>) {
         // Consume the expressions supplying values for each field.
         for field in fields {
             self.consume_expr(&*field.expr);
@@ -727,7 +709,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         self.walk_expr(with_expr);
 
         fn contains_field_named(field: ty::FieldDef,
-                                fields: &Vec<ast::Field>)
+                                fields: &Vec<hir::Field>)
                                 -> bool
         {
             fields.iter().any(
@@ -738,7 +720,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     // Invoke the appropriate delegate calls for anything that gets
     // consumed or borrowed as part of the automatic adjustment
     // process.
-    fn walk_adjustment(&mut self, expr: &ast::Expr) {
+    fn walk_adjustment(&mut self, expr: &hir::Expr) {
         let typer = self.typer;
         //NOTE(@jroesch): mixed RefCell borrow causes crash
         let adj = typer.adjustments().get(&expr.id).map(|x| x.clone());
@@ -764,7 +746,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     /// `(*x)` where `x` is of type `Rc<T>`, then this in fact is equivalent to `x.deref()`. Since
     /// `deref()` is declared with `&self`, this is an autoref of `x`.
     fn walk_autoderefs(&mut self,
-                       expr: &ast::Expr,
+                       expr: &hir::Expr,
                        autoderefs: usize) {
         debug!("walk_autoderefs expr={:?} autoderefs={}", expr, autoderefs);
 
@@ -795,7 +777,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     }
 
     fn walk_autoderefref(&mut self,
-                         expr: &ast::Expr,
+                         expr: &hir::Expr,
                          adj: &ty::AutoDerefRef<'tcx>) {
         debug!("walk_autoderefref expr={:?} adj={:?}",
                expr,
@@ -825,7 +807,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     /// `cmt` for the rvalue that will be produced by introduced an
     /// autoref.
     fn walk_autoref(&mut self,
-                    expr: &ast::Expr,
+                    expr: &hir::Expr,
                     cmt_base: mc::cmt<'tcx>,
                     opt_autoref: Option<ty::AutoRef<'tcx>>)
                     -> mc::cmt<'tcx>
@@ -890,9 +872,9 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     // recursively processing the input arguments, and thus the caller
     // should not do so.
     fn walk_overloaded_operator(&mut self,
-                                expr: &ast::Expr,
-                                receiver: &ast::Expr,
-                                rhs: Vec<&ast::Expr>,
+                                expr: &hir::Expr,
+                                receiver: &hir::Expr,
+                                rhs: Vec<&hir::Expr>,
                                 pass_args: PassArgs)
                                 -> bool
     {
@@ -927,7 +909,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         return true;
     }
 
-    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode {
+    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm) -> TrackMatchMode {
         let mut mode = Unknown;
         for pat in &arm.pats {
             self.determine_pat_move_mode(discr_cmt.clone(), &**pat, &mut mode);
@@ -935,7 +917,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         mode
     }
 
-    fn walk_arm(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm, mode: MatchMode) {
+    fn walk_arm(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &hir::Arm, mode: MatchMode) {
         for pat in &arm.pats {
             self.walk_pat(discr_cmt.clone(), &**pat, mode);
         }
@@ -949,7 +931,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
 
     /// Walks an pat that occurs in isolation (i.e. top-level of fn
     /// arg or let binding.  *Not* a match arm or nested pat.)
-    fn walk_irrefutable_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &ast::Pat) {
+    fn walk_irrefutable_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat) {
         let mut mode = Unknown;
         self.determine_pat_move_mode(cmt_discr.clone(), pat, &mut mode);
         let mode = mode.match_mode();
@@ -961,7 +943,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     /// copy, or borrow.
     fn determine_pat_move_mode(&mut self,
                                cmt_discr: mc::cmt<'tcx>,
-                               pat: &ast::Pat,
+                               pat: &hir::Pat,
                                mode: &mut TrackMatchMode) {
         debug!("determine_pat_move_mode cmt_discr={:?} pat={:?}", cmt_discr,
                pat);
@@ -970,9 +952,9 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
             let def_map = &self.tcx().def_map;
             if pat_util::pat_is_binding(def_map, pat) {
                 match pat.node {
-                    ast::PatIdent(ast::BindByRef(_), _, _) =>
+                    hir::PatIdent(hir::BindByRef(_), _, _) =>
                         mode.lub(BorrowingMatch),
-                    ast::PatIdent(ast::BindByValue(_), _, _) => {
+                    hir::PatIdent(hir::BindByValue(_), _, _) => {
                         match copy_or_move(self.typer, &cmt_pat, PatBindingMove) {
                             Copy => mode.lub(CopyingMatch),
                             Move(_) => mode.lub(MovingMatch),
@@ -993,7 +975,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     /// also `walk_irrefutable_pat` for patterns that stand alone).
     fn walk_pat(&mut self,
                 cmt_discr: mc::cmt<'tcx>,
-                pat: &ast::Pat,
+                pat: &hir::Pat,
                 match_mode: MatchMode) {
         debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr,
                pat);
@@ -1026,14 +1008,14 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
 
                 // It is also a borrow or copy/move of the value being matched.
                 match pat.node {
-                    ast::PatIdent(ast::BindByRef(m), _, _) => {
+                    hir::PatIdent(hir::BindByRef(m), _, _) => {
                         if let ty::TyRef(&r, _) = pat_ty.sty {
                             let bk = ty::BorrowKind::from_mutbl(m);
                             delegate.borrow(pat.id, pat.span, cmt_pat,
                                             r, bk, RefBinding);
                         }
                     }
-                    ast::PatIdent(ast::BindByValue(_), _, _) => {
+                    hir::PatIdent(hir::BindByValue(_), _, _) => {
                         let mode = copy_or_move(typer, &cmt_pat, PatBindingMove);
                         debug!("walk_pat binding consuming pat");
                         delegate.consume_pat(pat, cmt_pat, mode);
@@ -1046,7 +1028,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                 }
             } else {
                 match pat.node {
-                    ast::PatVec(_, Some(ref slice_pat), _) => {
+                    hir::PatVec(_, Some(ref slice_pat), _) => {
                         // The `slice_pat` here creates a slice into
                         // the original vector.  This is effectively a
                         // borrow of the elements of the vector being
@@ -1094,8 +1076,8 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
             let tcx = typer.tcx;
 
             match pat.node {
-                ast::PatEnum(_, _) | ast::PatQPath(..) |
-                ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
+                hir::PatEnum(_, _) | hir::PatQPath(..) |
+                hir::PatIdent(_, _, None) | hir::PatStruct(..) => {
                     match def_map.get(&pat.id).map(|d| d.full_def()) {
                         None => {
                             // no definition found: pat is not a
@@ -1169,15 +1151,15 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                     }
                 }
 
-                ast::PatIdent(_, _, Some(_)) => {
+                hir::PatIdent(_, _, Some(_)) => {
                     // Do nothing; this is a binding (not a enum
                     // variant or struct), and the cat_pattern call
                     // will visit the substructure recursively.
                 }
 
-                ast::PatWild(_) | ast::PatTup(..) | ast::PatBox(..) |
-                ast::PatRegion(..) | ast::PatLit(..) | ast::PatRange(..) |
-                ast::PatVec(..) | ast::PatMac(..) => {
+                hir::PatWild(_) | hir::PatTup(..) | hir::PatBox(..) |
+                hir::PatRegion(..) | hir::PatLit(..) | hir::PatRange(..) |
+                hir::PatVec(..) => {
                     // Similarly, each of these cases does not
                     // correspond to a enum variant or struct, so we
                     // do not do any `matched_pat` calls for these
@@ -1187,7 +1169,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         }));
     }
 
-    fn walk_captures(&mut self, closure_expr: &ast::Expr) {
+    fn walk_captures(&mut self, closure_expr: &hir::Expr) {
         debug!("walk_captures({:?})", closure_expr);
 
         self.tcx().with_freevars(closure_expr.id, |freevars| {
diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs
index 77608f40128..2b81be19182 100644
--- a/src/librustc/middle/fast_reject.rs
+++ b/src/librustc/middle/fast_reject.rs
@@ -10,7 +10,7 @@
 
 use middle::def_id::DefId;
 use middle::ty::{self, Ty};
-use syntax::ast;
+use rustc_front::hir;
 
 use self::SimplifiedType::*;
 
@@ -19,9 +19,9 @@ use self::SimplifiedType::*;
 pub enum SimplifiedType {
     BoolSimplifiedType,
     CharSimplifiedType,
-    IntSimplifiedType(ast::IntTy),
-    UintSimplifiedType(ast::UintTy),
-    FloatSimplifiedType(ast::FloatTy),
+    IntSimplifiedType(hir::IntTy),
+    UintSimplifiedType(hir::UintTy),
+    FloatSimplifiedType(hir::FloatTy),
     EnumSimplifiedType(DefId),
     StrSimplifiedType,
     VecSimplifiedType,
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index cfeec1c4f73..00edd054aa5 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -48,8 +48,8 @@ use middle::ty_fold;
 use middle::ty_fold::{TypeFolder, TypeFoldable};
 use middle::ty_relate::{self, Relate, RelateResult, TypeRelation};
 
-use syntax::ast;
 use syntax::codemap::Span;
+use rustc_front::hir;
 
 #[derive(Clone)]
 pub struct CombineFields<'a, 'tcx: 'a> {
@@ -138,7 +138,7 @@ fn unify_integral_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
 fn unify_float_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                                  vid_is_expected: bool,
                                  vid: ty::FloatVid,
-                                 val: ast::FloatTy)
+                                 val: hir::FloatTy)
                                  -> RelateResult<'tcx, Ty<'tcx>>
 {
     try!(infcx
@@ -388,7 +388,7 @@ fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::Int
 }
 
 fn float_unification_error<'tcx>(a_is_expected: bool,
-                                 v: (ast::FloatTy, ast::FloatTy))
+                                 v: (hir::FloatTy, hir::FloatTy))
                                  -> ty::TypeError<'tcx>
 {
     let (a, b) = v;
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 61fa08c4620..8197ccf4be7 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -72,7 +72,11 @@ use super::region_inference::ProcessedErrors;
 use super::region_inference::SameRegions;
 
 use std::collections::HashSet;
-use ast_map;
+
+use front::map as ast_map;
+use rustc_front::hir;
+use rustc_front::print::pprust;
+
 use middle::def;
 use middle::infer;
 use middle::region;
@@ -84,11 +88,9 @@ use std::cell::{Cell, RefCell};
 use std::char::from_u32;
 use std::fmt;
 use syntax::ast;
-use syntax::ast_util::name_to_dummy_lifetime;
 use syntax::owned_slice::OwnedSlice;
-use syntax::codemap::{Pos, Span};
+use syntax::codemap::{self, Pos, Span};
 use syntax::parse::token;
-use syntax::print::pprust;
 use syntax::ptr::P;
 
 impl<'tcx> ty::ctxt<'tcx> {
@@ -96,13 +98,13 @@ impl<'tcx> ty::ctxt<'tcx> {
                                    prefix: &str,
                                    region: ty::Region,
                                    suffix: &str) {
-        fn item_scope_tag(item: &ast::Item) -> &'static str {
+        fn item_scope_tag(item: &hir::Item) -> &'static str {
             match item.node {
-                ast::ItemImpl(..) => "impl",
-                ast::ItemStruct(..) => "struct",
-                ast::ItemEnum(..) => "enum",
-                ast::ItemTrait(..) => "trait",
-                ast::ItemFn(..) => "function body",
+                hir::ItemImpl(..) => "impl",
+                hir::ItemStruct(..) => "struct",
+                hir::ItemEnum(..) => "enum",
+                hir::ItemTrait(..) => "trait",
+                hir::ItemFn(..) => "function body",
                 _ => "item"
             }
         }
@@ -128,12 +130,12 @@ impl<'tcx> ty::ctxt<'tcx> {
                 let tag = match self.map.find(scope.node_id(&self.region_maps)) {
                     Some(ast_map::NodeBlock(_)) => "block",
                     Some(ast_map::NodeExpr(expr)) => match expr.node {
-                        ast::ExprCall(..) => "call",
-                        ast::ExprMethodCall(..) => "method call",
-                        ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
-                        ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) =>  "while let",
-                        ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) =>  "for",
-                        ast::ExprMatch(..) => "match",
+                        hir::ExprCall(..) => "call",
+                        hir::ExprMethodCall(..) => "method call",
+                        hir::ExprMatch(_, _, hir::MatchSource::IfLetDesugar { .. }) => "if let",
+                        hir::ExprMatch(_, _, hir::MatchSource::WhileLetDesugar) =>  "while let",
+                        hir::ExprMatch(_, _, hir::MatchSource::ForLoopDesugar) =>  "for",
+                        hir::ExprMatch(..) => "match",
                         _ => "expression",
                     },
                     Some(ast_map::NodeStmt(_)) => "statement",
@@ -275,12 +277,12 @@ trait ErrorReportingHelpers<'tcx> {
                           origin: &SubregionOrigin<'tcx>);
 
     fn give_expl_lifetime_param(&self,
-                                decl: &ast::FnDecl,
-                                unsafety: ast::Unsafety,
-                                constness: ast::Constness,
+                                decl: &hir::FnDecl,
+                                unsafety: hir::Unsafety,
+                                constness: hir::Constness,
                                 ident: ast::Ident,
-                                opt_explicit_self: Option<&ast::ExplicitSelf_>,
-                                generics: &ast::Generics,
+                                opt_explicit_self: Option<&hir::ExplicitSelf_>,
+                                generics: &hir::Generics,
                                 span: Span);
 }
 
@@ -432,7 +434,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             match parent_node {
                 Some(node) => match node {
                     ast_map::NodeItem(item) => match item.node {
-                        ast::ItemFn(..) => {
+                        hir::ItemFn(..) => {
                             Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id))
                         },
                         _ => None
@@ -944,7 +946,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             Some(ref node) => match *node {
                 ast_map::NodeItem(ref item) => {
                     match item.node {
-                        ast::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
+                        hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
                             Some((fn_decl, gen, unsafety, constness,
                                   item.ident, None, item.span))
                         },
@@ -953,7 +955,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 }
                 ast_map::NodeImplItem(item) => {
                     match item.node {
-                        ast::MethodImplItem(ref sig, _) => {
+                        hir::MethodImplItem(ref sig, _) => {
                             Some((&sig.decl,
                                   &sig.generics,
                                   sig.unsafety,
@@ -962,13 +964,12 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                                   Some(&sig.explicit_self.node),
                                   item.span))
                         }
-                        ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro"),
                         _ => None,
                     }
                 },
                 ast_map::NodeTraitItem(item) => {
                     match item.node {
-                        ast::MethodTraitItem(ref sig, Some(_)) => {
+                        hir::MethodTraitItem(ref sig, Some(_)) => {
                             Some((&sig.decl,
                                   &sig.generics,
                                   sig.unsafety,
@@ -995,7 +996,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
 }
 
 struct RebuildPathInfo<'a> {
-    path: &'a ast::Path,
+    path: &'a hir::Path,
     // indexes to insert lifetime on path.lifetimes
     indexes: Vec<u32>,
     // number of lifetimes we expect to see on the type referred by `path`
@@ -1007,9 +1008,9 @@ struct RebuildPathInfo<'a> {
 
 struct Rebuilder<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
-    fn_decl: &'a ast::FnDecl,
-    expl_self_opt: Option<&'a ast::ExplicitSelf_>,
-    generics: &'a ast::Generics,
+    fn_decl: &'a hir::FnDecl,
+    expl_self_opt: Option<&'a hir::ExplicitSelf_>,
+    generics: &'a hir::Generics,
     same_regions: &'a [SameRegions],
     life_giver: &'a LifeGiver,
     cur_anon: Cell<u32>,
@@ -1023,9 +1024,9 @@ enum FreshOrKept {
 
 impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     fn new(tcx: &'a ty::ctxt<'tcx>,
-           fn_decl: &'a ast::FnDecl,
-           expl_self_opt: Option<&'a ast::ExplicitSelf_>,
-           generics: &'a ast::Generics,
+           fn_decl: &'a hir::FnDecl,
+           expl_self_opt: Option<&'a hir::ExplicitSelf_>,
+           generics: &'a hir::Generics,
            same_regions: &'a [SameRegions],
            life_giver: &'a LifeGiver)
            -> Rebuilder<'a, 'tcx> {
@@ -1042,7 +1043,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     }
 
     fn rebuild(&self)
-               -> (ast::FnDecl, Option<ast::ExplicitSelf_>, ast::Generics) {
+               -> (hir::FnDecl, Option<hir::ExplicitSelf_>, hir::Generics) {
         let mut expl_self_opt = self.expl_self_opt.cloned();
         let mut inputs = self.fn_decl.inputs.clone();
         let mut output = self.fn_decl.output.clone();
@@ -1075,7 +1076,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                                              &all_region_names,
                                              ty_params,
                                              where_clause);
-        let new_fn_decl = ast::FnDecl {
+        let new_fn_decl = hir::FnDecl {
             inputs: inputs,
             output: output,
             variadic: self.fn_decl.variadic
@@ -1085,7 +1086,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
 
     fn pick_lifetime(&self,
                      region_names: &HashSet<ast::Name>)
-                     -> (ast::Lifetime, FreshOrKept) {
+                     -> (hir::Lifetime, FreshOrKept) {
         if !region_names.is_empty() {
             // It's not necessary to convert the set of region names to a
             // vector of string and then sort them. However, it makes the
@@ -1158,15 +1159,15 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     }
 
     fn rebuild_ty_params(&self,
-                         ty_params: OwnedSlice<ast::TyParam>,
-                         lifetime: ast::Lifetime,
+                         ty_params: OwnedSlice<hir::TyParam>,
+                         lifetime: hir::Lifetime,
                          region_names: &HashSet<ast::Name>)
-                         -> OwnedSlice<ast::TyParam> {
+                         -> OwnedSlice<hir::TyParam> {
         ty_params.map(|ty_param| {
             let bounds = self.rebuild_ty_param_bounds(ty_param.bounds.clone(),
                                                       lifetime,
                                                       region_names);
-            ast::TyParam {
+            hir::TyParam {
                 ident: ty_param.ident,
                 id: ty_param.id,
                 bounds: bounds,
@@ -1177,19 +1178,19 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     }
 
     fn rebuild_ty_param_bounds(&self,
-                               ty_param_bounds: OwnedSlice<ast::TyParamBound>,
-                               lifetime: ast::Lifetime,
+                               ty_param_bounds: OwnedSlice<hir::TyParamBound>,
+                               lifetime: hir::Lifetime,
                                region_names: &HashSet<ast::Name>)
-                               -> OwnedSlice<ast::TyParamBound> {
+                               -> OwnedSlice<hir::TyParamBound> {
         ty_param_bounds.map(|tpb| {
             match tpb {
-                &ast::RegionTyParamBound(lt) => {
+                &hir::RegionTyParamBound(lt) => {
                     // FIXME -- it's unclear whether I'm supposed to
                     // substitute lifetime here. I suspect we need to
                     // be passing down a map.
-                    ast::RegionTyParamBound(lt)
+                    hir::RegionTyParamBound(lt)
                 }
-                &ast::TraitTyParamBound(ref poly_tr, modifier) => {
+                &hir::TraitTyParamBound(ref poly_tr, modifier) => {
                     let tr = &poly_tr.trait_ref;
                     let last_seg = tr.path.segments.last().unwrap();
                     let mut insert = Vec::new();
@@ -1207,9 +1208,9 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                         region_names: region_names
                     };
                     let new_path = self.rebuild_path(rebuild_info, lifetime);
-                    ast::TraitTyParamBound(ast::PolyTraitRef {
+                    hir::TraitTyParamBound(hir::PolyTraitRef {
                         bound_lifetimes: poly_tr.bound_lifetimes.clone(),
-                        trait_ref: ast::TraitRef {
+                        trait_ref: hir::TraitRef {
                             path: new_path,
                             ref_id: tr.ref_id,
                         },
@@ -1221,23 +1222,23 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     }
 
     fn rebuild_expl_self(&self,
-                         expl_self_opt: Option<ast::ExplicitSelf_>,
-                         lifetime: ast::Lifetime,
+                         expl_self_opt: Option<hir::ExplicitSelf_>,
+                         lifetime: hir::Lifetime,
                          anon_nums: &HashSet<u32>,
                          region_names: &HashSet<ast::Name>)
-                         -> Option<ast::ExplicitSelf_> {
+                         -> Option<hir::ExplicitSelf_> {
         match expl_self_opt {
             Some(ref expl_self) => match *expl_self {
-                ast::SelfRegion(lt_opt, muta, id) => match lt_opt {
+                hir::SelfRegion(lt_opt, muta, id) => match lt_opt {
                     Some(lt) => if region_names.contains(&lt.name) {
-                        return Some(ast::SelfRegion(Some(lifetime), muta, id));
+                        return Some(hir::SelfRegion(Some(lifetime), muta, id));
                     },
                     None => {
                         let anon = self.cur_anon.get();
                         self.inc_and_offset_cur_anon(1);
                         if anon_nums.contains(&anon) {
                             self.track_anon(anon);
-                            return Some(ast::SelfRegion(Some(lifetime), muta, id));
+                            return Some(hir::SelfRegion(Some(lifetime), muta, id));
                         }
                     }
                 },
@@ -1249,16 +1250,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     }
 
     fn rebuild_generics(&self,
-                        generics: &ast::Generics,
-                        add: &Vec<ast::Lifetime>,
+                        generics: &hir::Generics,
+                        add: &Vec<hir::Lifetime>,
                         keep: &HashSet<ast::Name>,
                         remove: &HashSet<ast::Name>,
-                        ty_params: OwnedSlice<ast::TyParam>,
-                        where_clause: ast::WhereClause)
-                        -> ast::Generics {
+                        ty_params: OwnedSlice<hir::TyParam>,
+                        where_clause: hir::WhereClause)
+                        -> hir::Generics {
         let mut lifetimes = Vec::new();
         for lt in add {
-            lifetimes.push(ast::LifetimeDef { lifetime: *lt,
+            lifetimes.push(hir::LifetimeDef { lifetime: *lt,
                                               bounds: Vec::new() });
         }
         for lt in &generics.lifetimes {
@@ -1267,7 +1268,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                 lifetimes.push((*lt).clone());
             }
         }
-        ast::Generics {
+        hir::Generics {
             lifetimes: lifetimes,
             ty_params: ty_params,
             where_clause: where_clause,
@@ -1275,16 +1276,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     }
 
     fn rebuild_args_ty(&self,
-                       inputs: &[ast::Arg],
-                       lifetime: ast::Lifetime,
+                       inputs: &[hir::Arg],
+                       lifetime: hir::Lifetime,
                        anon_nums: &HashSet<u32>,
                        region_names: &HashSet<ast::Name>)
-                       -> Vec<ast::Arg> {
+                       -> Vec<hir::Arg> {
         let mut new_inputs = Vec::new();
         for arg in inputs {
             let new_ty = self.rebuild_arg_ty_or_output(&*arg.ty, lifetime,
                                                        anon_nums, region_names);
-            let possibly_new_arg = ast::Arg {
+            let possibly_new_arg = hir::Arg {
                 ty: new_ty,
                 pat: arg.pat.clone(),
                 id: arg.id
@@ -1294,31 +1295,31 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
         new_inputs
     }
 
-    fn rebuild_output(&self, ty: &ast::FunctionRetTy,
-                      lifetime: ast::Lifetime,
+    fn rebuild_output(&self, ty: &hir::FunctionRetTy,
+                      lifetime: hir::Lifetime,
                       anon_nums: &HashSet<u32>,
-                      region_names: &HashSet<ast::Name>) -> ast::FunctionRetTy {
+                      region_names: &HashSet<ast::Name>) -> hir::FunctionRetTy {
         match *ty {
-            ast::Return(ref ret_ty) => ast::Return(
+            hir::Return(ref ret_ty) => hir::Return(
                 self.rebuild_arg_ty_or_output(&**ret_ty, lifetime, anon_nums, region_names)
             ),
-            ast::DefaultReturn(span) => ast::DefaultReturn(span),
-            ast::NoReturn(span) => ast::NoReturn(span)
+            hir::DefaultReturn(span) => hir::DefaultReturn(span),
+            hir::NoReturn(span) => hir::NoReturn(span)
         }
     }
 
     fn rebuild_arg_ty_or_output(&self,
-                                ty: &ast::Ty,
-                                lifetime: ast::Lifetime,
+                                ty: &hir::Ty,
+                                lifetime: hir::Lifetime,
                                 anon_nums: &HashSet<u32>,
                                 region_names: &HashSet<ast::Name>)
-                                -> P<ast::Ty> {
+                                -> P<hir::Ty> {
         let mut new_ty = P(ty.clone());
         let mut ty_queue = vec!(ty);
         while !ty_queue.is_empty() {
             let cur_ty = ty_queue.remove(0);
             match cur_ty.node {
-                ast::TyRptr(lt_opt, ref mut_ty) => {
+                hir::TyRptr(lt_opt, ref mut_ty) => {
                     let rebuild = match lt_opt {
                         Some(lt) => region_names.contains(&lt.name),
                         None => {
@@ -1332,16 +1333,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                         }
                     };
                     if rebuild {
-                        let to = ast::Ty {
+                        let to = hir::Ty {
                             id: cur_ty.id,
-                            node: ast::TyRptr(Some(lifetime), mut_ty.clone()),
+                            node: hir::TyRptr(Some(lifetime), mut_ty.clone()),
                             span: cur_ty.span
                         };
                         new_ty = self.rebuild_ty(new_ty, P(to));
                     }
                     ty_queue.push(&*mut_ty.ty);
                 }
-                ast::TyPath(ref maybe_qself, ref path) => {
+                hir::TyPath(ref maybe_qself, ref path) => {
                     let a_def = match self.tcx.def_map.borrow().get(&cur_ty.id) {
                         None => {
                             self.tcx
@@ -1386,15 +1387,15 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                             };
                             let new_path = self.rebuild_path(rebuild_info, lifetime);
                             let qself = maybe_qself.as_ref().map(|qself| {
-                                ast::QSelf {
+                                hir::QSelf {
                                     ty: self.rebuild_arg_ty_or_output(&qself.ty, lifetime,
                                                                       anon_nums, region_names),
                                     position: qself.position
                                 }
                             });
-                            let to = ast::Ty {
+                            let to = hir::Ty {
                                 id: cur_ty.id,
-                                node: ast::TyPath(qself, new_path),
+                                node: hir::TyPath(qself, new_path),
                                 span: cur_ty.span
                             };
                             new_ty = self.rebuild_ty(new_ty, P(to));
@@ -1404,14 +1405,14 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
 
                 }
 
-                ast::TyPtr(ref mut_ty) => {
+                hir::TyPtr(ref mut_ty) => {
                     ty_queue.push(&*mut_ty.ty);
                 }
-                ast::TyVec(ref ty) |
-                ast::TyFixedLengthVec(ref ty, _) => {
+                hir::TyVec(ref ty) |
+                hir::TyFixedLengthVec(ref ty, _) => {
                     ty_queue.push(&**ty);
                 }
-                ast::TyTup(ref tys) => ty_queue.extend(tys.iter().map(|ty| &**ty)),
+                hir::TyTup(ref tys) => ty_queue.extend(tys.iter().map(|ty| &**ty)),
                 _ => {}
             }
         }
@@ -1419,41 +1420,41 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
     }
 
     fn rebuild_ty(&self,
-                  from: P<ast::Ty>,
-                  to: P<ast::Ty>)
-                  -> P<ast::Ty> {
+                  from: P<hir::Ty>,
+                  to: P<hir::Ty>)
+                  -> P<hir::Ty> {
 
-        fn build_to(from: P<ast::Ty>,
-                    to: &mut Option<P<ast::Ty>>)
-                    -> P<ast::Ty> {
+        fn build_to(from: P<hir::Ty>,
+                    to: &mut Option<P<hir::Ty>>)
+                    -> P<hir::Ty> {
             if Some(from.id) == to.as_ref().map(|ty| ty.id) {
                 return to.take().expect("`to` type found more than once during rebuild");
             }
-            from.map(|ast::Ty {id, node, span}| {
+            from.map(|hir::Ty {id, node, span}| {
                 let new_node = match node {
-                    ast::TyRptr(lifetime, mut_ty) => {
-                        ast::TyRptr(lifetime, ast::MutTy {
+                    hir::TyRptr(lifetime, mut_ty) => {
+                        hir::TyRptr(lifetime, hir::MutTy {
                             mutbl: mut_ty.mutbl,
                             ty: build_to(mut_ty.ty, to),
                         })
                     }
-                    ast::TyPtr(mut_ty) => {
-                        ast::TyPtr(ast::MutTy {
+                    hir::TyPtr(mut_ty) => {
+                        hir::TyPtr(hir::MutTy {
                             mutbl: mut_ty.mutbl,
                             ty: build_to(mut_ty.ty, to),
                         })
                     }
-                    ast::TyVec(ty) => ast::TyVec(build_to(ty, to)),
-                    ast::TyFixedLengthVec(ty, e) => {
-                        ast::TyFixedLengthVec(build_to(ty, to), e)
+                    hir::TyVec(ty) => hir::TyVec(build_to(ty, to)),
+                    hir::TyFixedLengthVec(ty, e) => {
+                        hir::TyFixedLengthVec(build_to(ty, to), e)
                     }
-                    ast::TyTup(tys) => {
-                        ast::TyTup(tys.into_iter().map(|ty| build_to(ty, to)).collect())
+                    hir::TyTup(tys) => {
+                        hir::TyTup(tys.into_iter().map(|ty| build_to(ty, to)).collect())
                     }
-                    ast::TyParen(typ) => ast::TyParen(build_to(typ, to)),
+                    hir::TyParen(typ) => hir::TyParen(build_to(typ, to)),
                     other => other
                 };
-                ast::Ty { id: id, node: new_node, span: span }
+                hir::Ty { id: id, node: new_node, span: span }
             })
         }
 
@@ -1462,8 +1463,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
 
     fn rebuild_path(&self,
                     rebuild_info: RebuildPathInfo,
-                    lifetime: ast::Lifetime)
-                    -> ast::Path
+                    lifetime: hir::Lifetime)
+                    -> hir::Path
     {
         let RebuildPathInfo {
             path,
@@ -1475,11 +1476,11 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
 
         let last_seg = path.segments.last().unwrap();
         let new_parameters = match last_seg.parameters {
-            ast::ParenthesizedParameters(..) => {
+            hir::ParenthesizedParameters(..) => {
                 last_seg.parameters.clone()
             }
 
-            ast::AngleBracketedParameters(ref data) => {
+            hir::AngleBracketedParameters(ref data) => {
                 let mut new_lts = Vec::new();
                 if data.lifetimes.is_empty() {
                     // traverse once to see if there's a need to insert lifetime
@@ -1508,7 +1509,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                     self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names)
                 });
                 let new_bindings = data.bindings.map(|b| {
-                    P(ast::TypeBinding {
+                    P(hir::TypeBinding {
                         id: b.id,
                         ident: b.ident,
                         ty: self.rebuild_arg_ty_or_output(&*b.ty,
@@ -1518,21 +1519,21 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                         span: b.span
                     })
                 });
-                ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
+                hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
                     lifetimes: new_lts,
                     types: new_types,
                     bindings: new_bindings,
                })
             }
         };
-        let new_seg = ast::PathSegment {
+        let new_seg = hir::PathSegment {
             identifier: last_seg.identifier,
             parameters: new_parameters
         };
         let mut new_segs = Vec::new();
         new_segs.push_all(path.segments.split_last().unwrap().1);
         new_segs.push(new_seg);
-        ast::Path {
+        hir::Path {
             span: path.span,
             global: path.global,
             segments: new_segs
@@ -1542,12 +1543,12 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
 
 impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
     fn give_expl_lifetime_param(&self,
-                                decl: &ast::FnDecl,
-                                unsafety: ast::Unsafety,
-                                constness: ast::Constness,
+                                decl: &hir::FnDecl,
+                                unsafety: hir::Unsafety,
+                                constness: hir::Constness,
                                 ident: ast::Ident,
-                                opt_explicit_self: Option<&ast::ExplicitSelf_>,
-                                generics: &ast::Generics,
+                                opt_explicit_self: Option<&hir::ExplicitSelf_>,
+                                generics: &hir::Generics,
                                 span: Span) {
         let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, ident,
                                                  opt_explicit_self, generics);
@@ -1832,13 +1833,13 @@ impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> {
 
 fn lifetimes_in_scope(tcx: &ty::ctxt,
                       scope_id: ast::NodeId)
-                      -> Vec<ast::LifetimeDef> {
+                      -> Vec<hir::LifetimeDef> {
     let mut taken = Vec::new();
     let parent = tcx.map.get_parent(scope_id);
     let method_id_opt = match tcx.map.find(parent) {
         Some(node) => match node {
             ast_map::NodeItem(item) => match item.node {
-                ast::ItemFn(_, _, _, _, ref gen, _) => {
+                hir::ItemFn(_, _, _, _, ref gen, _) => {
                     taken.push_all(&gen.lifetimes);
                     None
                 },
@@ -1846,11 +1847,10 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
             },
             ast_map::NodeImplItem(ii) => {
                 match ii.node {
-                    ast::MethodImplItem(ref sig, _) => {
+                    hir::MethodImplItem(ref sig, _) => {
                         taken.push_all(&sig.generics.lifetimes);
                         Some(ii.id)
                     }
-                    ast::MacImplItem(_) => tcx.sess.bug("unexpanded macro"),
                     _ => None,
                 }
             }
@@ -1864,7 +1864,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
         match tcx.map.find(parent) {
             Some(node) => match node {
                 ast_map::NodeItem(item) => match item.node {
-                    ast::ItemImpl(_, _, ref gen, _, _, _) => {
+                    hir::ItemImpl(_, _, ref gen, _, _, _) => {
                         taken.push_all(&gen.lifetimes);
                     }
                     _ => ()
@@ -1881,11 +1881,11 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
 struct LifeGiver {
     taken: HashSet<String>,
     counter: Cell<usize>,
-    generated: RefCell<Vec<ast::Lifetime>>,
+    generated: RefCell<Vec<hir::Lifetime>>,
 }
 
 impl LifeGiver {
-    fn with_taken(taken: &[ast::LifetimeDef]) -> LifeGiver {
+    fn with_taken(taken: &[hir::LifetimeDef]) -> LifeGiver {
         let mut taken_ = HashSet::new();
         for lt in taken {
             let lt_name = lt.lifetime.name.to_string();
@@ -1903,7 +1903,7 @@ impl LifeGiver {
         self.counter.set(c+1);
     }
 
-    fn give_lifetime(&self) -> ast::Lifetime {
+    fn give_lifetime(&self) -> hir::Lifetime {
         let lifetime;
         loop {
             let mut s = String::from("'");
@@ -1931,7 +1931,13 @@ impl LifeGiver {
         }
     }
 
-    fn get_generated_lifetimes(&self) -> Vec<ast::Lifetime> {
+    fn get_generated_lifetimes(&self) -> Vec<hir::Lifetime> {
         self.generated.borrow().clone()
     }
 }
+
+fn name_to_dummy_lifetime(name: ast::Name) -> hir::Lifetime {
+    hir::Lifetime { id: ast::DUMMY_NODE_ID,
+                    span: codemap::DUMMY_SP,
+                    name: name }
+}
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 158ef745de3..4ef96c0f3b4 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -20,6 +20,7 @@ pub use self::freshen::TypeFreshener;
 pub use self::region_inference::{GenericKind, VerifyBound};
 
 use middle::def_id::DefId;
+use rustc_front::hir;
 use middle::free_region::FreeRegionMap;
 use middle::mem_categorization as mc;
 use middle::mem_categorization::McResult;
@@ -1147,7 +1148,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
     /// Apply `adjustment` to the type of `expr`
     pub fn adjust_expr_ty(&self,
-                          expr: &ast::Expr,
+                          expr: &hir::Expr,
                           adjustment: Option<&ty::AutoAdjustment<'tcx>>)
                           -> Ty<'tcx>
     {
@@ -1179,7 +1180,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
+    pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
         match self.tables.borrow().node_types.get(&ex.id) {
             Some(&t) => t,
             None => {
@@ -1446,7 +1447,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         self.resolve_type_vars_or_error(&ty)
     }
 
-    pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
+    pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
         let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
         self.resolve_type_vars_or_error(&ty)
     }
diff --git a/src/librustc/middle/infer/unify_key.rs b/src/librustc/middle/infer/unify_key.rs
index c13cec45dc4..6bb46ac7870 100644
--- a/src/librustc/middle/infer/unify_key.rs
+++ b/src/librustc/middle/infer/unify_key.rs
@@ -10,7 +10,7 @@
 
 use middle::ty::{self, IntVarValue, Ty};
 use rustc_data_structures::unify::UnifyKey;
-use syntax::ast;
+use rustc_front::hir as ast;
 
 pub trait ToType<'tcx> {
     fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index f88e5a69f8a..c042aea829b 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -19,8 +19,8 @@ use std::fmt;
 use syntax::abi::RustIntrinsic;
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::visit::{FnKind, Visitor};
-use syntax::visit;
+use rustc_front::visit::{self, Visitor, FnKind};
+use rustc_front::hir;
 
 pub fn check_crate(tcx: &ctxt) {
     let mut visitor = IntrinsicCheckingVisitor {
@@ -216,8 +216,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
-    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
-                b: &'v ast::Block, s: Span, id: ast::NodeId) {
+    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
+                b: &'v hir::Block, s: Span, id: ast::NodeId) {
         match fk {
             FnKind::ItemFn(..) | FnKind::Method(..) => {
                 let param_env = ty::ParameterEnvironment::for_item(self.tcx, id);
@@ -232,8 +232,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
 
     }
 
-    fn visit_expr(&mut self, expr: &ast::Expr) {
-        if let ast::ExprPath(..) = expr.node {
+    fn visit_expr(&mut self, expr: &hir::Expr) {
+        if let hir::ExprPath(..) = expr.node {
             match self.tcx.resolve_expr(expr) {
                 DefFn(did, _) if self.def_id_is_transmute(did) => {
                     let typ = self.tcx.node_id_to_type(expr.id);
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index d7f40c1f6fd..a34571e4aca 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -28,12 +28,12 @@ use middle::ty;
 use middle::weak_lang_items;
 use util::nodemap::FnvHashMap;
 
-use syntax::ast;
-use syntax::attr::AttrMetaMethods;
+use rustc_front::attr::AttrMetaMethods;
 use syntax::codemap::{DUMMY_SP, Span};
 use syntax::parse::token::InternedString;
-use syntax::visit::Visitor;
-use syntax::visit;
+use rustc_front::visit::Visitor;
+use rustc_front::visit;
+use rustc_front::hir;
 
 use std::iter::Enumerate;
 use std::slice;
@@ -152,7 +152,7 @@ struct LanguageItemCollector<'a> {
 }
 
 impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
-    fn visit_item(&mut self, item: &ast::Item) {
+    fn visit_item(&mut self, item: &hir::Item) {
         if let Some(value) = extract(&item.attrs) {
             let item_index = self.item_refs.get(&value[..]).cloned();
 
@@ -195,7 +195,7 @@ impl<'a> LanguageItemCollector<'a> {
         self.items.items[item_index] = Some(item_def_id);
     }
 
-    pub fn collect_local_language_items(&mut self, krate: &ast::Crate) {
+    pub fn collect_local_language_items(&mut self, krate: &hir::Crate) {
         visit::walk_crate(self, krate);
     }
 
@@ -210,13 +210,13 @@ impl<'a> LanguageItemCollector<'a> {
         })
     }
 
-    pub fn collect(&mut self, krate: &ast::Crate) {
+    pub fn collect(&mut self, krate: &hir::Crate) {
         self.collect_local_language_items(krate);
         self.collect_external_language_items();
     }
 }
 
-pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
+pub fn extract(attrs: &[hir::Attribute]) -> Option<InternedString> {
     for attribute in attrs {
         match attribute.value_str() {
             Some(ref value) if attribute.check_name("lang") => {
@@ -229,7 +229,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
     return None;
 }
 
-pub fn collect_language_items(krate: &ast::Crate,
+pub fn collect_language_items(krate: &hir::Crate,
                               session: &Session) -> LanguageItems {
     let mut collector = LanguageItemCollector::new(session);
     collector.collect(krate);
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index e1866d878bd..476df77e45b 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -119,13 +119,15 @@ use std::{fmt, usize};
 use std::io::prelude::*;
 use std::io;
 use std::rc::Rc;
-use syntax::ast::{self, NodeId, Expr};
+use syntax::ast::{self, NodeId};
 use syntax::codemap::{BytePos, original_sp, Span};
 use syntax::parse::token::special_idents;
-use syntax::print::pprust::{expr_to_string, block_to_string};
 use syntax::ptr::P;
-use syntax::ast_util;
-use syntax::visit::{self, Visitor, FnKind};
+
+use rustc_front::hir::Expr;
+use rustc_front::hir;
+use rustc_front::print::pprust::{expr_to_string, block_to_string};
+use rustc_front::visit::{self, Visitor, FnKind};
 
 /// For use with `propagate_through_loop`.
 enum LoopKind<'a> {
@@ -180,13 +182,13 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
-    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
-                b: &'v ast::Block, s: Span, id: NodeId) {
+    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
+                b: &'v hir::Block, s: Span, id: NodeId) {
         visit_fn(self, fk, fd, b, s, id);
     }
-    fn visit_local(&mut self, l: &ast::Local) { visit_local(self, l); }
+    fn visit_local(&mut self, l: &hir::Local) { visit_local(self, l); }
     fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
-    fn visit_arm(&mut self, a: &ast::Arm) { visit_arm(self, a); }
+    fn visit_arm(&mut self, a: &hir::Arm) { visit_arm(self, a); }
 }
 
 pub fn check_crate(tcx: &ty::ctxt) {
@@ -348,25 +350,25 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> {
-    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
-                b: &'v ast::Block, s: Span, n: NodeId) {
+    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
+                b: &'v hir::Block, s: Span, n: NodeId) {
         check_fn(self, fk, fd, b, s, n);
     }
-    fn visit_local(&mut self, l: &ast::Local) {
+    fn visit_local(&mut self, l: &hir::Local) {
         check_local(self, l);
     }
     fn visit_expr(&mut self, ex: &Expr) {
         check_expr(self, ex);
     }
-    fn visit_arm(&mut self, a: &ast::Arm) {
+    fn visit_arm(&mut self, a: &hir::Arm) {
         check_arm(self, a);
     }
 }
 
 fn visit_fn(ir: &mut IrMaps,
             fk: FnKind,
-            decl: &ast::FnDecl,
-            body: &ast::Block,
+            decl: &hir::FnDecl,
+            body: &hir::Block,
             sp: Span,
             id: ast::NodeId) {
     debug!("visit_fn");
@@ -411,7 +413,7 @@ fn visit_fn(ir: &mut IrMaps,
     lsets.warn_about_unused_args(decl, entry_ln);
 }
 
-fn visit_local(ir: &mut IrMaps, local: &ast::Local) {
+fn visit_local(ir: &mut IrMaps, local: &hir::Local) {
     pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| {
         debug!("adding local variable {}", p_id);
         let name = path1.node.name;
@@ -424,7 +426,7 @@ fn visit_local(ir: &mut IrMaps, local: &ast::Local) {
     visit::walk_local(ir, local);
 }
 
-fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) {
+fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) {
     for pat in &arm.pats {
         pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
             debug!("adding local variable {} from match with bm {:?}",
@@ -443,7 +445,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) {
 fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
-      ast::ExprPath(..) => {
+      hir::ExprPath(..) => {
         let def = ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def();
         debug!("expr {}: path that leads to {:?}", expr.id, def);
         if let DefLocal(..) = def {
@@ -451,7 +453,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         }
         visit::walk_expr(ir, expr);
       }
-      ast::ExprClosure(..) => {
+      hir::ExprClosure(..) => {
         // Interesting control flow (for loops can contain labeled
         // breaks or continues)
         ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
@@ -476,34 +478,25 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
       }
 
       // live nodes required for interesting control flow:
-      ast::ExprIf(..) | ast::ExprMatch(..) | ast::ExprWhile(..) | ast::ExprLoop(..) => {
+      hir::ExprIf(..) | hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) => {
         ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
         visit::walk_expr(ir, expr);
       }
-      ast::ExprIfLet(..) => {
-          ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
-      }
-      ast::ExprWhileLet(..) => {
-          ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
-      }
-      ast::ExprForLoop(..) => {
-          ir.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
-      }
-      ast::ExprBinary(op, _, _) if ast_util::lazy_binop(op.node) => {
+      hir::ExprBinary(op, _, _) if ::rustc_front::util::lazy_binop(op.node) => {
         ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
         visit::walk_expr(ir, expr);
       }
 
       // otherwise, live nodes are not required:
-      ast::ExprIndex(..) | ast::ExprField(..) | ast::ExprTupField(..) |
-      ast::ExprVec(..) | ast::ExprCall(..) | ast::ExprMethodCall(..) |
-      ast::ExprTup(..) | ast::ExprBinary(..) | ast::ExprAddrOf(..) |
-      ast::ExprCast(..) | ast::ExprUnary(..) | ast::ExprBreak(_) |
-      ast::ExprAgain(_) | ast::ExprLit(_) | ast::ExprRet(..) |
-      ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) |
-      ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
-      ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) |
-      ast::ExprRange(..) => {
+      hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
+      hir::ExprVec(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) |
+      hir::ExprTup(..) | hir::ExprBinary(..) | hir::ExprAddrOf(..) |
+      hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprBreak(_) |
+      hir::ExprAgain(_) | hir::ExprLit(_) | hir::ExprRet(..) |
+      hir::ExprBlock(..) | hir::ExprAssign(..) | hir::ExprAssignOp(..) |
+      hir::ExprStruct(..) | hir::ExprRepeat(..) |
+      hir::ExprParen(..) | hir::ExprInlineAsm(..) | hir::ExprBox(..) |
+      hir::ExprRange(..) => {
           visit::walk_expr(ir, expr);
       }
     }
@@ -592,7 +585,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         self.ir.variable(node_id, span)
     }
 
-    fn pat_bindings<F>(&mut self, pat: &ast::Pat, mut f: F) where
+    fn pat_bindings<F>(&mut self, pat: &hir::Pat, mut f: F) where
         F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
     {
         pat_util::pat_bindings(&self.ir.tcx.def_map, pat, |_bm, p_id, sp, _n| {
@@ -602,7 +595,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         })
     }
 
-    fn arm_pats_bindings<F>(&mut self, pat: Option<&ast::Pat>, f: F) where
+    fn arm_pats_bindings<F>(&mut self, pat: Option<&hir::Pat>, f: F) where
         F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId),
     {
         match pat {
@@ -613,12 +606,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn define_bindings_in_pat(&mut self, pat: &ast::Pat, succ: LiveNode)
+    fn define_bindings_in_pat(&mut self, pat: &hir::Pat, succ: LiveNode)
                               -> LiveNode {
         self.define_bindings_in_arm_pats(Some(pat), succ)
     }
 
-    fn define_bindings_in_arm_pats(&mut self, pat: Option<&ast::Pat>, succ: LiveNode)
+    fn define_bindings_in_arm_pats(&mut self, pat: Option<&hir::Pat>, succ: LiveNode)
                                    -> LiveNode {
         let mut succ = succ;
         self.arm_pats_bindings(pat, |this, ln, var, _sp, _id| {
@@ -830,7 +823,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
     // _______________________________________________________________________
 
-    fn compute(&mut self, decl: &ast::FnDecl, body: &ast::Block) -> LiveNode {
+    fn compute(&mut self, decl: &hir::FnDecl, body: &hir::Block) -> LiveNode {
         // if there is a `break` or `again` at the top level, then it's
         // effectively a return---this only occurs in `for` loops,
         // where the body is really a closure.
@@ -855,7 +848,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         entry_ln
     }
 
-    fn propagate_through_fn_block(&mut self, _: &ast::FnDecl, blk: &ast::Block)
+    fn propagate_through_fn_block(&mut self, _: &hir::FnDecl, blk: &hir::Block)
                                   -> LiveNode {
         // the fallthrough exit is only for those cases where we do not
         // explicitly return:
@@ -869,7 +862,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         self.propagate_through_block(blk, s.fallthrough_ln)
     }
 
-    fn propagate_through_block(&mut self, blk: &ast::Block, succ: LiveNode)
+    fn propagate_through_block(&mut self, blk: &hir::Block, succ: LiveNode)
                                -> LiveNode {
         let succ = self.propagate_through_opt_expr(blk.expr.as_ref().map(|e| &**e), succ);
         blk.stmts.iter().rev().fold(succ, |succ, stmt| {
@@ -877,34 +870,30 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         })
     }
 
-    fn propagate_through_stmt(&mut self, stmt: &ast::Stmt, succ: LiveNode)
+    fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode)
                               -> LiveNode {
         match stmt.node {
-            ast::StmtDecl(ref decl, _) => {
+            hir::StmtDecl(ref decl, _) => {
                 self.propagate_through_decl(&**decl, succ)
             }
 
-            ast::StmtExpr(ref expr, _) | ast::StmtSemi(ref expr, _) => {
+            hir::StmtExpr(ref expr, _) | hir::StmtSemi(ref expr, _) => {
                 self.propagate_through_expr(&**expr, succ)
             }
-
-            ast::StmtMac(..) => {
-                self.ir.tcx.sess.span_bug(stmt.span, "unexpanded macro");
-            }
         }
     }
 
-    fn propagate_through_decl(&mut self, decl: &ast::Decl, succ: LiveNode)
+    fn propagate_through_decl(&mut self, decl: &hir::Decl, succ: LiveNode)
                               -> LiveNode {
         match decl.node {
-            ast::DeclLocal(ref local) => {
+            hir::DeclLocal(ref local) => {
                 self.propagate_through_local(&**local, succ)
             }
-            ast::DeclItem(_) => succ,
+            hir::DeclItem(_) => succ,
         }
     }
 
-    fn propagate_through_local(&mut self, local: &ast::Local, succ: LiveNode)
+    fn propagate_through_local(&mut self, local: &hir::Local, succ: LiveNode)
                                -> LiveNode {
         // Note: we mark the variable as defined regardless of whether
         // there is an initializer.  Initially I had thought to only mark
@@ -945,19 +934,19 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         match expr.node {
           // Interesting cases with control flow or which gen/kill
 
-          ast::ExprPath(..) => {
+          hir::ExprPath(..) => {
               self.access_path(expr, succ, ACC_READ | ACC_USE)
           }
 
-          ast::ExprField(ref e, _) => {
+          hir::ExprField(ref e, _) => {
               self.propagate_through_expr(&**e, succ)
           }
 
-          ast::ExprTupField(ref e, _) => {
+          hir::ExprTupField(ref e, _) => {
               self.propagate_through_expr(&**e, succ)
           }
 
-          ast::ExprClosure(_, _, ref blk) => {
+          hir::ExprClosure(_, _, ref blk) => {
               debug!("{} is an ExprClosure",
                      expr_to_string(expr));
 
@@ -985,7 +974,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
               })
           }
 
-          ast::ExprIf(ref cond, ref then, ref els) => {
+          hir::ExprIf(ref cond, ref then, ref els) => {
             //
             //     (cond)
             //       |
@@ -1007,29 +996,17 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.propagate_through_expr(&**cond, ln)
           }
 
-          ast::ExprIfLet(..) => {
-              self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
-          }
-
-          ast::ExprWhile(ref cond, ref blk, _) => {
+          hir::ExprWhile(ref cond, ref blk, _) => {
             self.propagate_through_loop(expr, WhileLoop(&**cond), &**blk, succ)
           }
 
-          ast::ExprWhileLet(..) => {
-              self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
-          }
-
-          ast::ExprForLoop(..) => {
-              self.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
-          }
-
           // Note that labels have been resolved, so we don't need to look
           // at the label ident
-          ast::ExprLoop(ref blk, _) => {
+          hir::ExprLoop(ref blk, _) => {
             self.propagate_through_loop(expr, LoopLoop, &**blk, succ)
           }
 
-          ast::ExprMatch(ref e, ref arms, _) => {
+          hir::ExprMatch(ref e, ref arms, _) => {
             //
             //      (e)
             //       |
@@ -1064,13 +1041,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.propagate_through_expr(&**e, ln)
           }
 
-          ast::ExprRet(ref o_e) => {
+          hir::ExprRet(ref o_e) => {
             // ignore succ and subst exit_ln:
             let exit_ln = self.s.exit_ln;
             self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), exit_ln)
           }
 
-          ast::ExprBreak(opt_label) => {
+          hir::ExprBreak(opt_label) => {
               // Find which label this break jumps to
               let sc = self.find_loop_scope(opt_label, expr.id, expr.span);
 
@@ -1084,7 +1061,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
               }
           }
 
-          ast::ExprAgain(opt_label) => {
+          hir::ExprAgain(opt_label) => {
               // Find which label this expr continues to
               let sc = self.find_loop_scope(opt_label, expr.id, expr.span);
 
@@ -1098,7 +1075,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
               }
           }
 
-          ast::ExprAssign(ref l, ref r) => {
+          hir::ExprAssign(ref l, ref r) => {
             // see comment on lvalues in
             // propagate_through_lvalue_components()
             let succ = self.write_lvalue(&**l, succ, ACC_WRITE);
@@ -1106,7 +1083,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.propagate_through_expr(&**r, succ)
           }
 
-          ast::ExprAssignOp(_, ref l, ref r) => {
+          hir::ExprAssignOp(_, ref l, ref r) => {
             // see comment on lvalues in
             // propagate_through_lvalue_components()
             let succ = self.write_lvalue(&**l, succ, ACC_WRITE|ACC_READ);
@@ -1116,23 +1093,23 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
           // Uninteresting cases: just propagate in rev exec order
 
-          ast::ExprVec(ref exprs) => {
+          hir::ExprVec(ref exprs) => {
             self.propagate_through_exprs(&exprs[..], succ)
           }
 
-          ast::ExprRepeat(ref element, ref count) => {
+          hir::ExprRepeat(ref element, ref count) => {
             let succ = self.propagate_through_expr(&**count, succ);
             self.propagate_through_expr(&**element, succ)
           }
 
-          ast::ExprStruct(_, ref fields, ref with_expr) => {
+          hir::ExprStruct(_, ref fields, ref with_expr) => {
             let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ);
             fields.iter().rev().fold(succ, |succ, field| {
                 self.propagate_through_expr(&*field.expr, succ)
             })
           }
 
-          ast::ExprCall(ref f, ref args) => {
+          hir::ExprCall(ref f, ref args) => {
             let diverges = !self.ir.tcx.is_method_call(expr.id) &&
                 self.ir.tcx.expr_ty_adjusted(&**f).fn_ret().diverges();
             let succ = if diverges {
@@ -1144,7 +1121,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.propagate_through_expr(&**f, succ)
           }
 
-          ast::ExprMethodCall(_, _, ref args) => {
+          hir::ExprMethodCall(_, _, ref args) => {
             let method_call = ty::MethodCall::expr(expr.id);
             let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty;
             let succ = if method_ty.fn_ret().diverges() {
@@ -1155,11 +1132,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.propagate_through_exprs(&args[..], succ)
           }
 
-          ast::ExprTup(ref exprs) => {
+          hir::ExprTup(ref exprs) => {
             self.propagate_through_exprs(&exprs[..], succ)
           }
 
-          ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
+          hir::ExprBinary(op, ref l, ref r) if ::rustc_front::util::lazy_binop(op.node) => {
             let r_succ = self.propagate_through_expr(&**r, succ);
 
             let ln = self.live_node(expr.id, expr.span);
@@ -1169,27 +1146,27 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.propagate_through_expr(&**l, ln)
           }
 
-          ast::ExprIndex(ref l, ref r) |
-          ast::ExprBinary(_, ref l, ref r) |
-          ast::ExprBox(Some(ref l), ref r) => {
+          hir::ExprIndex(ref l, ref r) |
+          hir::ExprBinary(_, ref l, ref r) |
+          hir::ExprBox(Some(ref l), ref r) => {
             let r_succ = self.propagate_through_expr(&**r, succ);
             self.propagate_through_expr(&**l, r_succ)
           }
 
-          ast::ExprRange(ref e1, ref e2) => {
+          hir::ExprRange(ref e1, ref e2) => {
             let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
             e1.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ))
           }
 
-          ast::ExprBox(None, ref e) |
-          ast::ExprAddrOf(_, ref e) |
-          ast::ExprCast(ref e, _) |
-          ast::ExprUnary(_, ref e) |
-          ast::ExprParen(ref e) => {
+          hir::ExprBox(None, ref e) |
+          hir::ExprAddrOf(_, ref e) |
+          hir::ExprCast(ref e, _) |
+          hir::ExprUnary(_, ref e) |
+          hir::ExprParen(ref e) => {
             self.propagate_through_expr(&**e, succ)
           }
 
-          ast::ExprInlineAsm(ref ia) => {
+          hir::ExprInlineAsm(ref ia) => {
 
             let succ = ia.outputs.iter().rev().fold(succ, |succ, &(_, ref expr, _)| {
                 // see comment on lvalues
@@ -1203,17 +1180,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             })
           }
 
-          ast::ExprLit(..) => {
+          hir::ExprLit(..) => {
             succ
           }
 
-          ast::ExprBlock(ref blk) => {
+          hir::ExprBlock(ref blk) => {
             self.propagate_through_block(&**blk, succ)
           }
-
-          ast::ExprMac(..) => {
-            self.ir.tcx.sess.span_bug(expr.span, "unexpanded macro");
-          }
         }
     }
 
@@ -1271,9 +1244,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         // just ignore such cases and treat them as reads.
 
         match expr.node {
-            ast::ExprPath(..) => succ,
-            ast::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ),
-            ast::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ),
+            hir::ExprPath(..) => succ,
+            hir::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ),
+            hir::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ),
             _ => self.propagate_through_expr(expr, succ)
         }
     }
@@ -1282,7 +1255,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                     -> LiveNode {
         match expr.node {
-          ast::ExprPath(..) => {
+          hir::ExprPath(..) => {
               self.access_path(expr, succ, acc)
           }
 
@@ -1313,7 +1286,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn propagate_through_loop(&mut self,
                               expr: &Expr,
                               kind: LoopKind,
-                              body: &ast::Block,
+                              body: &hir::Block,
                               succ: LiveNode)
                               -> LiveNode {
 
@@ -1400,7 +1373,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 // _______________________________________________________________________
 // Checking for error conditions
 
-fn check_local(this: &mut Liveness, local: &ast::Local) {
+fn check_local(this: &mut Liveness, local: &hir::Local) {
     match local.init {
         Some(_) => {
             this.warn_about_unused_or_dead_vars_in_pat(&*local.pat);
@@ -1415,7 +1388,7 @@ fn check_local(this: &mut Liveness, local: &ast::Local) {
     visit::walk_local(this, local);
 }
 
-fn check_arm(this: &mut Liveness, arm: &ast::Arm) {
+fn check_arm(this: &mut Liveness, arm: &hir::Arm) {
     // only consider the first pattern; any later patterns must have
     // the same bindings, and we also consider the first pattern to be
     // the "authoritative" set of ids
@@ -1427,20 +1400,20 @@ fn check_arm(this: &mut Liveness, arm: &ast::Arm) {
 
 fn check_expr(this: &mut Liveness, expr: &Expr) {
     match expr.node {
-      ast::ExprAssign(ref l, ref r) => {
+      hir::ExprAssign(ref l, ref r) => {
         this.check_lvalue(&**l);
         this.visit_expr(&**r);
 
         visit::walk_expr(this, expr);
       }
 
-      ast::ExprAssignOp(_, ref l, _) => {
+      hir::ExprAssignOp(_, ref l, _) => {
         this.check_lvalue(&**l);
 
         visit::walk_expr(this, expr);
       }
 
-      ast::ExprInlineAsm(ref ia) => {
+      hir::ExprInlineAsm(ref ia) => {
         for &(_, ref input) in &ia.inputs {
           this.visit_expr(&**input);
         }
@@ -1455,34 +1428,25 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       }
 
       // no correctness conditions related to liveness
-      ast::ExprCall(..) | ast::ExprMethodCall(..) | ast::ExprIf(..) |
-      ast::ExprMatch(..) | ast::ExprWhile(..) | ast::ExprLoop(..) |
-      ast::ExprIndex(..) | ast::ExprField(..) | ast::ExprTupField(..) |
-      ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprBinary(..) |
-      ast::ExprCast(..) | ast::ExprUnary(..) | ast::ExprRet(..) |
-      ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprLit(_) |
-      ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
-      ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
-      ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
-      ast::ExprRange(..) => {
+      hir::ExprCall(..) | hir::ExprMethodCall(..) | hir::ExprIf(..) |
+      hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) |
+      hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
+      hir::ExprVec(..) | hir::ExprTup(..) | hir::ExprBinary(..) |
+      hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprRet(..) |
+      hir::ExprBreak(..) | hir::ExprAgain(..) | hir::ExprLit(_) |
+      hir::ExprBlock(..) | hir::ExprAddrOf(..) |
+      hir::ExprStruct(..) | hir::ExprRepeat(..) | hir::ExprParen(..) |
+      hir::ExprClosure(..) | hir::ExprPath(..) | hir::ExprBox(..) |
+      hir::ExprRange(..) => {
         visit::walk_expr(this, expr);
       }
-      ast::ExprIfLet(..) => {
-        this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprIfLet");
-      }
-      ast::ExprWhileLet(..) => {
-        this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprWhileLet");
-      }
-      ast::ExprForLoop(..) => {
-        this.ir.tcx.sess.span_bug(expr.span, "non-desugared ExprForLoop");
-      }
     }
 }
 
 fn check_fn(_v: &Liveness,
             _fk: FnKind,
-            _decl: &ast::FnDecl,
-            _body: &ast::Block,
+            _decl: &hir::FnDecl,
+            _body: &hir::Block,
             _sp: Span,
             _id: NodeId) {
     // do not check contents of nested fns
@@ -1503,7 +1467,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                  sp: Span,
                  _fk: FnKind,
                  entry_ln: LiveNode,
-                 body: &ast::Block)
+                 body: &hir::Block)
     {
         // within the fn body, late-bound regions are liberated:
         let fn_ret =
@@ -1521,7 +1485,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     let ends_with_stmt = match body.expr {
                         None if !body.stmts.is_empty() =>
                             match body.stmts.first().unwrap().node {
-                                ast::StmtSemi(ref e, _) => {
+                                hir::StmtSemi(ref e, _) => {
                                     self.ir.tcx.expr_ty(&**e) == t_ret
                                 },
                                 _ => false
@@ -1555,7 +1519,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
     fn check_lvalue(&mut self, expr: &Expr) {
         match expr.node {
-            ast::ExprPath(..) => {
+            hir::ExprPath(..) => {
                 if let DefLocal(nid) = self.ir.tcx.def_map.borrow().get(&expr.id)
                                                                    .unwrap()
                                                                    .full_def() {
@@ -1585,7 +1549,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn warn_about_unused_args(&self, decl: &ast::FnDecl, entry_ln: LiveNode) {
+    fn warn_about_unused_args(&self, decl: &hir::FnDecl, entry_ln: LiveNode) {
         for arg in &decl.inputs {
             pat_util::pat_bindings(&self.ir.tcx.def_map,
                                    &*arg.pat,
@@ -1600,7 +1564,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn warn_about_unused_or_dead_vars_in_pat(&mut self, pat: &ast::Pat) {
+    fn warn_about_unused_or_dead_vars_in_pat(&mut self, pat: &hir::Pat) {
         self.pat_bindings(pat, |this, ln, var, sp, id| {
             if !this.warn_about_unused(sp, id, ln, var) {
                 this.warn_about_dead_assign(sp, id, ln, var);
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index a9914073102..a8c80d52209 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -72,14 +72,15 @@ pub use self::categorization::*;
 
 use self::Aliasability::*;
 
-use ast_map;
 use middle::def_id::DefId;
+use front::map as ast_map;
 use middle::infer;
 use middle::check_const;
 use middle::def;
 use middle::ty::{self, Ty};
 
-use syntax::ast::{MutImmutable, MutMutable};
+use rustc_front::hir::{MutImmutable, MutMutable};
+use rustc_front::hir;
 use syntax::ast;
 use syntax::codemap::Span;
 
@@ -116,7 +117,7 @@ pub enum PointerKind {
     BorrowedPtr(ty::BorrowKind, ty::Region),
 
     /// `*T`
-    UnsafePtr(ast::Mutability),
+    UnsafePtr(hir::Mutability),
 
     /// Implicit deref of the `&T` that results from an overloaded index `[]`.
     Implicit(ty::BorrowKind, ty::Region),
@@ -244,12 +245,12 @@ pub trait ast_node {
     fn span(&self) -> Span;
 }
 
-impl ast_node for ast::Expr {
+impl ast_node for hir::Expr {
     fn id(&self) -> ast::NodeId { self.id }
     fn span(&self) -> Span { self.span }
 }
 
-impl ast_node for ast::Pat {
+impl ast_node for hir::Pat {
     fn id(&self) -> ast::NodeId { self.id }
     fn span(&self) -> Span { self.span }
 }
@@ -262,7 +263,7 @@ pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> {
 pub type McResult<T> = Result<T, ()>;
 
 impl MutabilityCategory {
-    pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory {
+    pub fn from_mutbl(m: hir::Mutability) -> MutabilityCategory {
         let ret = match m {
             MutImmutable => McImmutable,
             MutMutable => McDeclared
@@ -304,8 +305,8 @@ impl MutabilityCategory {
     fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory {
         let ret = match tcx.map.get(id) {
             ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node {
-                ast::PatIdent(bind_mode, _, _) => {
-                    if bind_mode == ast::BindByValue(ast::MutMutable) {
+                hir::PatIdent(bind_mode, _, _) => {
+                    if bind_mode == hir::BindByValue(hir::MutMutable) {
                         McDeclared
                     } else {
                         McImmutable
@@ -366,7 +367,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         self.typer.tcx
     }
 
-    fn expr_ty(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
+    fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
         match self.typer.node_ty(expr.id) {
             Ok(t) => Ok(t),
             Err(()) => {
@@ -376,7 +377,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         }
     }
 
-    fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
+    fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
         let unadjusted_ty = try!(self.expr_ty(expr));
         Ok(unadjusted_ty.adjust(
             self.tcx(), expr.span, expr.id,
@@ -388,14 +389,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         self.typer.node_ty(id)
     }
 
-    fn pat_ty(&self, pat: &ast::Pat) -> McResult<Ty<'tcx>> {
+    fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
         let base_ty = try!(self.typer.node_ty(pat.id));
         // FIXME (Issue #18207): This code detects whether we are
         // looking at a `ref x`, and if so, figures out what the type
         // *being borrowed* is.  But ideally we would put in a more
         // fundamental fix to this conflated use of the node id.
         let ret_ty = match pat.node {
-            ast::PatIdent(ast::BindByRef(_), _, _) => {
+            hir::PatIdent(hir::BindByRef(_), _, _) => {
                 // a bind-by-ref means that the base_ty will be the type of the ident itself,
                 // but what we want here is the type of the underlying value being borrowed.
                 // So peel off one-level, turning the &T into T.
@@ -411,7 +412,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         Ok(ret_ty)
     }
 
-    pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
+    pub fn cat_expr(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> {
         match self.typer.adjustments().get(&expr.id) {
             None => {
                 // No adjustments.
@@ -443,7 +444,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
     }
 
     pub fn cat_expr_autoderefd(&self,
-                               expr: &ast::Expr,
+                               expr: &hir::Expr,
                                autoderefs: usize)
                                -> McResult<cmt<'tcx>> {
         let mut cmt = try!(self.cat_expr_unadjusted(expr));
@@ -456,17 +457,17 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         return Ok(cmt);
     }
 
-    pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
+    pub fn cat_expr_unadjusted(&self, expr: &hir::Expr) -> McResult<cmt<'tcx>> {
         debug!("cat_expr: id={} expr={:?}", expr.id, expr);
 
         let expr_ty = try!(self.expr_ty(expr));
         match expr.node {
-          ast::ExprUnary(ast::UnDeref, ref e_base) => {
+          hir::ExprUnary(hir::UnDeref, ref e_base) => {
             let base_cmt = try!(self.cat_expr(&**e_base));
             self.cat_deref(expr, base_cmt, 0, None)
           }
 
-          ast::ExprField(ref base, f_name) => {
+          hir::ExprField(ref base, f_name) => {
             let base_cmt = try!(self.cat_expr(&**base));
             debug!("cat_expr(cat_field): id={} expr={:?} base={:?}",
                    expr.id,
@@ -475,12 +476,12 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             Ok(self.cat_field(expr, base_cmt, f_name.node.name, expr_ty))
           }
 
-          ast::ExprTupField(ref base, idx) => {
+          hir::ExprTupField(ref base, idx) => {
             let base_cmt = try!(self.cat_expr(&**base));
             Ok(self.cat_tup_field(expr, base_cmt, idx.node, expr_ty))
           }
 
-          ast::ExprIndex(ref base, _) => {
+          hir::ExprIndex(ref base, _) => {
             let method_call = ty::MethodCall::expr(expr.id());
             let context = InteriorOffsetKind::Index;
             match self.typer.node_method_ty(method_call) {
@@ -512,38 +513,28 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             }
           }
 
-          ast::ExprPath(..) => {
+          hir::ExprPath(..) => {
             let def = self.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
-          ast::ExprParen(ref e) => {
+          hir::ExprParen(ref e) => {
             self.cat_expr(&**e)
           }
 
-          ast::ExprAddrOf(..) | ast::ExprCall(..) |
-          ast::ExprAssign(..) | ast::ExprAssignOp(..) |
-          ast::ExprClosure(..) | ast::ExprRet(..) |
-          ast::ExprUnary(..) | ast::ExprRange(..) |
-          ast::ExprMethodCall(..) | ast::ExprCast(..) |
-          ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
-          ast::ExprBinary(..) | ast::ExprWhile(..) |
-          ast::ExprBlock(..) | ast::ExprLoop(..) | ast::ExprMatch(..) |
-          ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
-          ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
-          ast::ExprInlineAsm(..) | ast::ExprBox(..) => {
+          hir::ExprAddrOf(..) | hir::ExprCall(..) |
+          hir::ExprAssign(..) | hir::ExprAssignOp(..) |
+          hir::ExprClosure(..) | hir::ExprRet(..) |
+          hir::ExprUnary(..) | hir::ExprRange(..) |
+          hir::ExprMethodCall(..) | hir::ExprCast(..) |
+          hir::ExprVec(..) | hir::ExprTup(..) | hir::ExprIf(..) |
+          hir::ExprBinary(..) | hir::ExprWhile(..) |
+          hir::ExprBlock(..) | hir::ExprLoop(..) | hir::ExprMatch(..) |
+          hir::ExprLit(..) | hir::ExprBreak(..) |
+          hir::ExprAgain(..) | hir::ExprStruct(..) | hir::ExprRepeat(..) |
+          hir::ExprInlineAsm(..) | hir::ExprBox(..) => {
             Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
           }
-
-          ast::ExprIfLet(..) => {
-            self.tcx().sess.span_bug(expr.span, "non-desugared ExprIfLet");
-          }
-          ast::ExprWhileLet(..) => {
-            self.tcx().sess.span_bug(expr.span, "non-desugared ExprWhileLet");
-          }
-          ast::ExprForLoop(..) => {
-            self.tcx().sess.span_bug(expr.span, "non-desugared ExprForLoop");
-          }
         }
     }
 
@@ -738,7 +729,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             };
 
             match fn_expr.node {
-                ast::ExprClosure(_, _, ref body) => body.id,
+                hir::ExprClosure(_, _, ref body) => body.id,
                 _ => unreachable!()
             }
         };
@@ -1078,8 +1069,8 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
     /// These last two bits of info happen to be things that borrowck needs.
     pub fn cat_slice_pattern(&self,
                              vec_cmt: cmt<'tcx>,
-                             slice_pat: &ast::Pat)
-                             -> McResult<(cmt<'tcx>, ast::Mutability, ty::Region)> {
+                             slice_pat: &hir::Pat)
+                             -> McResult<(cmt<'tcx>, hir::Mutability, ty::Region)> {
         let slice_ty = try!(self.node_ty(slice_pat.id));
         let (slice_mutbl, slice_r) = vec_slice_info(self.tcx(),
                                                     slice_pat,
@@ -1093,9 +1084,9 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         /// ..ref c], then the type of `ref c` will be `&&[]`, so to extract the slice details we
         /// have to recurse through rptrs.
         fn vec_slice_info(tcx: &ty::ctxt,
-                          pat: &ast::Pat,
+                          pat: &hir::Pat,
                           slice_ty: Ty)
-                          -> (ast::Mutability, ty::Region) {
+                          -> (hir::Mutability, ty::Region) {
             match slice_ty.sty {
                 ty::TyRef(r, ref mt) => match mt.ty.sty {
                     ty::TySlice(_) => (mt.mutbl, *r),
@@ -1146,16 +1137,16 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         ret
     }
 
-    pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) -> McResult<()>
-        where F: FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat),
+    pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, mut op: F) -> McResult<()>
+        where F: FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &hir::Pat),
     {
         self.cat_pattern_(cmt, pat, &mut op)
     }
 
     // FIXME(#19596) This is a workaround, but there should be a better way to do this
-    fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
+    fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F)
                        -> McResult<()>
-        where F : FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat),
+        where F : FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &hir::Pat),
     {
         // Here, `cmt` is the categorization for the value being
         // matched and pat is the pattern it is being matched against.
@@ -1223,14 +1214,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         };
 
         match pat.node {
-          ast::PatWild(_) => {
+          hir::PatWild(_) => {
             // _
           }
 
-          ast::PatEnum(_, None) => {
+          hir::PatEnum(_, None) => {
             // variant(..)
           }
-          ast::PatEnum(_, Some(ref subpats)) => {
+          hir::PatEnum(_, Some(ref subpats)) => {
             match opt_def {
                 Some(def::DefVariant(..)) => {
                     // variant(x, y, z)
@@ -1268,19 +1259,19 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             }
           }
 
-          ast::PatQPath(..) => {
+          hir::PatQPath(..) => {
               // Lone constant: ignore
           }
 
-          ast::PatIdent(_, _, Some(ref subpat)) => {
+          hir::PatIdent(_, _, Some(ref subpat)) => {
               try!(self.cat_pattern_(cmt, &**subpat, op));
           }
 
-          ast::PatIdent(_, _, None) => {
+          hir::PatIdent(_, _, None) => {
               // nullary variant or identifier: ignore
           }
 
-          ast::PatStruct(_, ref field_pats, _) => {
+          hir::PatStruct(_, ref field_pats, _) => {
             // {f1: p1, ..., fN: pN}
             for fp in field_pats {
                 let field_ty = try!(self.pat_ty(&*fp.node.pat)); // see (*2)
@@ -1289,7 +1280,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             }
           }
 
-          ast::PatTup(ref subpats) => {
+          hir::PatTup(ref subpats) => {
             // (p1, ..., pN)
             for (i, subpat) in subpats.iter().enumerate() {
                 let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
@@ -1301,7 +1292,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             }
           }
 
-          ast::PatBox(ref subpat) | ast::PatRegion(ref subpat, _) => {
+          hir::PatBox(ref subpat) | hir::PatRegion(ref subpat, _) => {
             // box p1, &p1, &mut p1.  we can ignore the mutability of
             // PatRegion since that information is already contained
             // in the type.
@@ -1309,7 +1300,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
               try!(self.cat_pattern_(subcmt, &**subpat, op));
           }
 
-          ast::PatVec(ref before, ref slice, ref after) => {
+          hir::PatVec(ref before, ref slice, ref after) => {
               let context = InteriorOffsetKind::Pattern;
               let vec_cmt = try!(self.deref_vec(pat, cmt, context));
               let elt_cmt = try!(self.cat_index(pat, vec_cmt, context));
@@ -1326,13 +1317,9 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
               }
           }
 
-          ast::PatLit(_) | ast::PatRange(_, _) => {
+          hir::PatLit(_) | hir::PatRange(_, _) => {
               /*always ok*/
           }
-
-          ast::PatMac(_) => {
-              self.tcx().sess.span_bug(pat.span, "unexpanded macro");
-          }
         }
 
         Ok(())
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 7aac1a376e4..3c483f70a4e 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -14,14 +14,15 @@ use middle::ty;
 use util::nodemap::FnvHashMap;
 
 use syntax::ast;
-use syntax::ast_util::walk_pat;
+use rustc_front::hir;
+use rustc_front::util::walk_pat;
 use syntax::codemap::{Span, DUMMY_SP};
 
 pub type PatIdMap = FnvHashMap<ast::Ident, ast::NodeId>;
 
 // This is used because same-named variables in alternative patterns need to
 // use the NodeId of their namesake in the first pattern.
-pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
+pub fn pat_id_map(dm: &DefMap, pat: &hir::Pat) -> PatIdMap {
     let mut map = FnvHashMap();
     pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
         map.insert(path1.node, p_id);
@@ -29,27 +30,27 @@ pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
     map
 }
 
-pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        ast::PatLit(_) | ast::PatRange(_, _) | ast::PatQPath(..) => true,
-        ast::PatEnum(_, _) |
-        ast::PatIdent(_, _, None) |
-        ast::PatStruct(..) => {
+        hir::PatLit(_) | hir::PatRange(_, _) | hir::PatQPath(..) => true,
+        hir::PatEnum(_, _) |
+        hir::PatIdent(_, _, None) |
+        hir::PatStruct(..) => {
             match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
                 Some(DefVariant(..)) => true,
                 _ => false
             }
         }
-        ast::PatVec(_, _, _) => true,
+        hir::PatVec(_, _, _) => true,
         _ => false
     }
 }
 
-pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        ast::PatEnum(_, _) |
-        ast::PatIdent(_, _, None) |
-        ast::PatStruct(..) => {
+        hir::PatEnum(_, _) |
+        hir::PatIdent(_, _, None) |
+        hir::PatStruct(..) => {
             match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
                 Some(DefVariant(..)) | Some(DefStruct(..)) => true,
                 _ => false
@@ -59,9 +60,9 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        ast::PatIdent(_, _, None) | ast::PatEnum(..) | ast::PatQPath(..) => {
+        hir::PatIdent(_, _, None) | hir::PatEnum(..) | hir::PatQPath(..) => {
             match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
                 Some(DefConst(..)) | Some(DefAssociatedConst(..)) => true,
                 _ => false
@@ -73,9 +74,9 @@ pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
 
 // Same as above, except that partially-resolved defs cause `false` to be
 // returned instead of a panic.
-pub fn pat_is_resolved_const(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        ast::PatIdent(_, _, None) | ast::PatEnum(..) | ast::PatQPath(..) => {
+        hir::PatIdent(_, _, None) | hir::PatEnum(..) | hir::PatQPath(..) => {
             match dm.borrow().get(&pat.id)
                     .and_then(|d| if d.depth == 0 { Some(d.base_def) }
                                   else { None } ) {
@@ -87,9 +88,9 @@ pub fn pat_is_resolved_const(dm: &DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_binding(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        ast::PatIdent(..) => {
+        hir::PatIdent(..) => {
             !pat_is_variant_or_struct(dm, pat) &&
             !pat_is_const(dm, pat)
         }
@@ -97,22 +98,22 @@ pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
     }
 }
 
-pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        ast::PatIdent(..) => pat_is_binding(dm, pat),
-        ast::PatWild(_) => true,
+        hir::PatIdent(..) => pat_is_binding(dm, pat),
+        hir::PatWild(_) => true,
         _ => false
     }
 }
 
 /// Call `it` on every "binding" in a pattern, e.g., on `a` in
 /// `match foo() { Some(a) => (), None => () }`
-pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
-    I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent),
+pub fn pat_bindings<I>(dm: &DefMap, pat: &hir::Pat, mut it: I) where
+    I: FnMut(hir::BindingMode, ast::NodeId, Span, &hir::SpannedIdent),
 {
     walk_pat(pat, |p| {
         match p.node {
-          ast::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
+          hir::PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => {
             it(binding_mode, p.id, p.span, pth);
           }
           _ => {}
@@ -123,7 +124,7 @@ pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
 
 /// Checks if the pattern contains any patterns that bind something to
 /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
-pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_contains_bindings(dm: &DefMap, pat: &hir::Pat) -> bool {
     let mut contains_bindings = false;
     walk_pat(pat, |p| {
         if pat_is_binding(dm, p) {
@@ -138,18 +139,18 @@ pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
 
 /// Checks if the pattern contains any `ref` or `ref mut` bindings,
 /// and if yes wether its containing mutable ones or just immutables ones.
-pub fn pat_contains_ref_binding(dm: &DefMap, pat: &ast::Pat) -> Option<ast::Mutability> {
+pub fn pat_contains_ref_binding(dm: &DefMap, pat: &hir::Pat) -> Option<hir::Mutability> {
     let mut result = None;
     pat_bindings(dm, pat, |mode, _, _, _| {
         match mode {
-            ast::BindingMode::BindByRef(m) => {
+            hir::BindingMode::BindByRef(m) => {
                 // Pick Mutable as maximum
                 match result {
-                    None | Some(ast::MutImmutable) => result = Some(m),
+                    None | Some(hir::MutImmutable) => result = Some(m),
                     _ => (),
                 }
             }
-            ast::BindingMode::BindByValue(_) => { }
+            hir::BindingMode::BindByValue(_) => { }
         }
     });
     result
@@ -157,18 +158,18 @@ pub fn pat_contains_ref_binding(dm: &DefMap, pat: &ast::Pat) -> Option<ast::Muta
 
 /// Checks if the patterns for this arm contain any `ref` or `ref mut`
 /// bindings, and if yes wether its containing mutable ones or just immutables ones.
-pub fn arm_contains_ref_binding(dm: &DefMap, arm: &ast::Arm) -> Option<ast::Mutability> {
+pub fn arm_contains_ref_binding(dm: &DefMap, arm: &hir::Arm) -> Option<hir::Mutability> {
     arm.pats.iter()
             .filter_map(|pat| pat_contains_ref_binding(dm, pat))
             .max_by(|m| match *m {
-                ast::MutMutable => 1,
-                ast::MutImmutable => 0,
+                hir::MutMutable => 1,
+                hir::MutImmutable => 0,
             })
 }
 
 /// Checks if the pattern contains any patterns that bind something to
 /// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`,
-pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
+pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
     let mut contains_bindings = false;
     walk_pat(pat, |p| {
         if pat_is_binding_or_wild(dm, p) {
@@ -181,9 +182,9 @@ pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
     contains_bindings
 }
 
-pub fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Ident> {
+pub fn simple_identifier<'a>(pat: &'a hir::Pat) -> Option<&'a ast::Ident> {
     match pat.node {
-        ast::PatIdent(ast::BindByValue(_), ref path1, None) => {
+        hir::PatIdent(hir::BindByValue(_), ref path1, None) => {
             Some(&path1.node)
         }
         _ => {
@@ -192,25 +193,25 @@ pub fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Ident> {
     }
 }
 
-pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> ast::Path {
-    tcx.with_path(id, |path| ast::Path {
+pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> hir::Path {
+    tcx.with_path(id, |path| hir::Path {
         global: false,
-        segments: path.last().map(|elem| ast::PathSegment {
+        segments: path.last().map(|elem| hir::PathSegment {
             identifier: ast::Ident::new(elem.name()),
-            parameters: ast::PathParameters::none(),
+            parameters: hir::PathParameters::none(),
         }).into_iter().collect(),
         span: DUMMY_SP,
     })
 }
 
 /// Return variants that are necessary to exist for the pattern to match.
-pub fn necessary_variants(dm: &DefMap, pat: &ast::Pat) -> Vec<ast::NodeId> {
+pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<ast::NodeId> {
     let mut variants = vec![];
     walk_pat(pat, |p| {
         match p.node {
-            ast::PatEnum(_, _) |
-            ast::PatIdent(_, _, None) |
-            ast::PatStruct(..) => {
+            hir::PatEnum(_, _) |
+            hir::PatIdent(_, _, None) |
+            hir::PatStruct(..) => {
                 match dm.borrow().get(&p.id) {
                     Some(&PathResolution { base_def: DefVariant(_, id, _), .. }) => {
                         variants.push(id.node);
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 4eef0001696..e53d0073668 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -15,7 +15,7 @@
 // makes all other generics or inline functions that it references
 // reachable as well.
 
-use ast_map;
+use front::map as ast_map;
 use middle::def;
 use middle::def_id::{DefId, LOCAL_CRATE};
 use middle::ty;
@@ -26,35 +26,36 @@ use util::nodemap::NodeSet;
 use std::collections::HashSet;
 use syntax::abi;
 use syntax::ast;
-use syntax::attr;
-use syntax::visit::Visitor;
-use syntax::visit;
+use rustc_front::hir;
+use rustc_front::attr;
+use rustc_front::visit::Visitor;
+use rustc_front::visit;
 
 // Returns true if the given set of generics implies that the item it's
 // associated with must be inlined.
-fn generics_require_inlining(generics: &ast::Generics) -> bool {
+fn generics_require_inlining(generics: &hir::Generics) -> bool {
     !generics.ty_params.is_empty()
 }
 
 // Returns true if the given item must be inlined because it may be
 // monomorphized or it was marked with `#[inline]`. This will only return
 // true for functions.
-fn item_might_be_inlined(item: &ast::Item) -> bool {
+fn item_might_be_inlined(item: &hir::Item) -> bool {
     if attr::requests_inline(&item.attrs) {
         return true
     }
 
     match item.node {
-        ast::ItemImpl(_, _, ref generics, _, _, _) |
-        ast::ItemFn(_, _, _, _, ref generics, _) => {
+        hir::ItemImpl(_, _, ref generics, _, _, _) |
+        hir::ItemFn(_, _, _, _, ref generics, _) => {
             generics_require_inlining(generics)
         }
         _ => false,
     }
 }
 
-fn method_might_be_inlined(tcx: &ty::ctxt, sig: &ast::MethodSig,
-                           impl_item: &ast::ImplItem,
+fn method_might_be_inlined(tcx: &ty::ctxt, sig: &hir::MethodSig,
+                           impl_item: &hir::ImplItem,
                            impl_src: DefId) -> bool {
     if attr::requests_inline(&impl_item.attrs) ||
         generics_require_inlining(&sig.generics) {
@@ -92,10 +93,10 @@ struct ReachableContext<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
 
-    fn visit_expr(&mut self, expr: &ast::Expr) {
+    fn visit_expr(&mut self, expr: &hir::Expr) {
 
         match expr.node {
-            ast::ExprPath(..) => {
+            hir::ExprPath(..) => {
                 let def = match self.tcx.def_map.borrow().get(&expr.id) {
                     Some(d) => d.full_def(),
                     None => {
@@ -126,7 +127,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
                     }
                 }
             }
-            ast::ExprMethodCall(..) => {
+            hir::ExprMethodCall(..) => {
                 let method_call = ty::MethodCall::expr(expr.id);
                 let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
                 match self.tcx.impl_or_trait_item(def_id).container() {
@@ -147,7 +148,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
         visit::walk_expr(self, expr)
     }
 
-    fn visit_item(&mut self, _item: &ast::Item) {
+    fn visit_item(&mut self, _item: &hir::Item) {
         // Do not recurse into items. These items will be added to the worklist
         // and recursed into manually if necessary.
     }
@@ -178,21 +179,21 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
         match self.tcx.map.find(node_id) {
             Some(ast_map::NodeItem(item)) => {
                 match item.node {
-                    ast::ItemFn(..) => item_might_be_inlined(&*item),
+                    hir::ItemFn(..) => item_might_be_inlined(&*item),
                     _ => false,
                 }
             }
             Some(ast_map::NodeTraitItem(trait_method)) => {
                 match trait_method.node {
-                    ast::ConstTraitItem(_, ref default) => default.is_some(),
-                    ast::MethodTraitItem(_, ref body) => body.is_some(),
-                    ast::TypeTraitItem(..) => false,
+                    hir::ConstTraitItem(_, ref default) => default.is_some(),
+                    hir::MethodTraitItem(_, ref body) => body.is_some(),
+                    hir::TypeTraitItem(..) => false,
                 }
             }
             Some(ast_map::NodeImplItem(impl_item)) => {
                 match impl_item.node {
-                    ast::ConstImplItem(..) => true,
-                    ast::MethodImplItem(ref sig, _) => {
+                    hir::ConstImplItem(..) => true,
+                    hir::MethodImplItem(ref sig, _) => {
                         if generics_require_inlining(&sig.generics) ||
                                 attr::requests_inline(&impl_item.attrs) {
                             true
@@ -208,15 +209,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                                       .map
                                       .expect_item(impl_did.node)
                                       .node {
-                                ast::ItemImpl(_, _, ref generics, _, _, _) => {
+                                hir::ItemImpl(_, _, ref generics, _, _, _) => {
                                     generics_require_inlining(generics)
                                 }
                                 _ => false
                             }
                         }
                     }
-                    ast::TypeImplItem(_) => false,
-                    ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
+                    hir::TypeImplItem(_) => false,
                 }
             }
             Some(_) => false,
@@ -257,7 +257,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
             // but all other rust-only interfaces can be private (they will not
             // participate in linkage after this product is produced)
             if let ast_map::NodeItem(item) = *node {
-                if let ast::ItemFn(_, _, _, abi, _, _) = item.node {
+                if let hir::ItemFn(_, _, _, abi, _, _) = item.node {
                     if abi != abi::Rust {
                         self.reachable_symbols.insert(search_item);
                     }
@@ -274,7 +274,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
         match *node {
             ast_map::NodeItem(item) => {
                 match item.node {
-                    ast::ItemFn(_, _, _, _, _, ref search_block) => {
+                    hir::ItemFn(_, _, _, _, _, ref search_block) => {
                         if item_might_be_inlined(&*item) {
                             visit::walk_block(self, &**search_block)
                         }
@@ -283,55 +283,48 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     // Reachable constants will be inlined into other crates
                     // unconditionally, so we need to make sure that their
                     // contents are also reachable.
-                    ast::ItemConst(_, ref init) => {
+                    hir::ItemConst(_, ref init) => {
                         self.visit_expr(&**init);
                     }
 
                     // These are normal, nothing reachable about these
                     // inherently and their children are already in the
                     // worklist, as determined by the privacy pass
-                    ast::ItemExternCrate(_) | ast::ItemUse(_) |
-                    ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
-                    ast::ItemMod(..) | ast::ItemForeignMod(..) |
-                    ast::ItemImpl(..) | ast::ItemTrait(..) |
-                    ast::ItemStruct(..) | ast::ItemEnum(..) |
-                    ast::ItemDefaultImpl(..) => {}
-
-                    _ => {
-                        self.tcx.sess.span_bug(item.span,
-                                               "found non-function item \
-                                                in worklist?!")
-                    }
+                    hir::ItemExternCrate(_) | hir::ItemUse(_) |
+                    hir::ItemTy(..) | hir::ItemStatic(_, _, _) |
+                    hir::ItemMod(..) | hir::ItemForeignMod(..) |
+                    hir::ItemImpl(..) | hir::ItemTrait(..) |
+                    hir::ItemStruct(..) | hir::ItemEnum(..) |
+                    hir::ItemDefaultImpl(..) => {}
                 }
             }
             ast_map::NodeTraitItem(trait_method) => {
                 match trait_method.node {
-                    ast::ConstTraitItem(_, None) |
-                    ast::MethodTraitItem(_, None) => {
+                    hir::ConstTraitItem(_, None) |
+                    hir::MethodTraitItem(_, None) => {
                         // Keep going, nothing to get exported
                     }
-                    ast::ConstTraitItem(_, Some(ref expr)) => {
+                    hir::ConstTraitItem(_, Some(ref expr)) => {
                         self.visit_expr(&*expr);
                     }
-                    ast::MethodTraitItem(_, Some(ref body)) => {
+                    hir::MethodTraitItem(_, Some(ref body)) => {
                         visit::walk_block(self, body);
                     }
-                    ast::TypeTraitItem(..) => {}
+                    hir::TypeTraitItem(..) => {}
                 }
             }
             ast_map::NodeImplItem(impl_item) => {
                 match impl_item.node {
-                    ast::ConstImplItem(_, ref expr) => {
+                    hir::ConstImplItem(_, ref expr) => {
                         self.visit_expr(&*expr);
                     }
-                    ast::MethodImplItem(ref sig, ref body) => {
+                    hir::MethodImplItem(ref sig, ref body) => {
                         let did = self.tcx.map.get_parent_did(search_item);
                         if method_might_be_inlined(self.tcx, sig, impl_item, did) {
                             visit::walk_block(self, body)
                         }
                     }
-                    ast::TypeImplItem(_) => {}
-                    ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
+                    hir::TypeImplItem(_) => {}
                 }
             }
             // Nothing to recurse on for these
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 37b9d8aa645..38167fd058e 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -16,20 +16,22 @@
 //! Most of the documentation on regions can be found in
 //! `middle/typeck/infer/region_inference.rs`
 
-use ast_map;
 use metadata::inline::InlinedItem;
-use middle::ty::{self, Ty};
+use front::map as ast_map;
 use session::Session;
 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
+use middle::ty::{self, Ty};
 
 use std::cell::RefCell;
 use std::collections::hash_map::Entry;
 use std::mem;
 use syntax::codemap::{self, Span};
-use syntax::{ast, visit};
-use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local};
-use syntax::ast_util::stmt_id;
-use syntax::visit::{Visitor, FnKind};
+use syntax::ast::{self, NodeId};
+
+use rustc_front::hir;
+use rustc_front::visit::{self, Visitor, FnKind};
+use rustc_front::hir::{Block, Item, FnDecl, Arm, Pat, Stmt, Expr, Local};
+use rustc_front::util::stmt_id;
 
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
            RustcDecodable, Debug, Copy)]
@@ -632,7 +634,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
     }
 }
 
-fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
+fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) {
     debug!("resolve_block(blk.id={:?})", blk.id);
 
     let prev_cx = visitor.cx;
@@ -676,7 +678,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
         // index information.)
 
         for (i, statement) in blk.stmts.iter().enumerate() {
-            if let ast::StmtDecl(..) = statement.node {
+            if let hir::StmtDecl(..) = statement.node {
                 // Each StmtDecl introduces a subscope for bindings
                 // introduced by the declaration; this subscope covers
                 // a suffix of the block . Each subscope in a block
@@ -703,7 +705,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
     visitor.cx = prev_cx;
 }
 
-fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
+fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
     visitor.terminating_scopes.insert(arm.body.id);
 
     if let Some(ref expr) = arm.guard {
@@ -713,13 +715,13 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
     visit::walk_arm(visitor, arm);
 }
 
-fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &ast::Pat) {
+fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
     visitor.new_node_extent(pat.id);
 
     // If this is a binding (or maybe a binding, I'm too lazy to check
     // the def map) then record the lifetime of that binding.
     match pat.node {
-        ast::PatIdent(..) => {
+        hir::PatIdent(..) => {
             record_var_lifetime(visitor, pat.id, pat.span);
         }
         _ => { }
@@ -728,7 +730,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &ast::Pat) {
     visit::walk_pat(visitor, pat);
 }
 
-fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &ast::Stmt) {
+fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) {
     let stmt_id = stmt_id(stmt);
     debug!("resolve_stmt(stmt.id={:?})", stmt_id);
 
@@ -746,7 +748,7 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &ast::Stmt) {
     visitor.cx.parent = prev_parent;
 }
 
-fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
+fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) {
     debug!("resolve_expr(expr.id={:?})", expr.id);
 
     let expr_extent = visitor.new_node_extent_with_dtor(expr.id);
@@ -763,38 +765,38 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
             // scopes, meaning that temporaries cannot outlive them.
             // This ensures fixed size stacks.
 
-            ast::ExprBinary(codemap::Spanned { node: ast::BiAnd, .. }, _, ref r) |
-            ast::ExprBinary(codemap::Spanned { node: ast::BiOr, .. }, _, ref r) => {
+            hir::ExprBinary(codemap::Spanned { node: hir::BiAnd, .. }, _, ref r) |
+            hir::ExprBinary(codemap::Spanned { node: hir::BiOr, .. }, _, ref r) => {
                 // For shortcircuiting operators, mark the RHS as a terminating
                 // scope since it only executes conditionally.
                 terminating(r.id);
             }
 
-            ast::ExprIf(_, ref then, Some(ref otherwise)) => {
+            hir::ExprIf(_, ref then, Some(ref otherwise)) => {
                 terminating(then.id);
                 terminating(otherwise.id);
             }
 
-            ast::ExprIf(ref expr, ref then, None) => {
+            hir::ExprIf(ref expr, ref then, None) => {
                 terminating(expr.id);
                 terminating(then.id);
             }
 
-            ast::ExprLoop(ref body, _) => {
+            hir::ExprLoop(ref body, _) => {
                 terminating(body.id);
             }
 
-            ast::ExprWhile(ref expr, ref body, _) => {
+            hir::ExprWhile(ref expr, ref body, _) => {
                 terminating(expr.id);
                 terminating(body.id);
             }
 
-            ast::ExprMatch(..) => {
+            hir::ExprMatch(..) => {
                 visitor.cx.var_parent = expr_extent;
             }
 
-            ast::ExprAssignOp(..) | ast::ExprIndex(..) |
-            ast::ExprUnary(..) | ast::ExprCall(..) | ast::ExprMethodCall(..) => {
+            hir::ExprAssignOp(..) | hir::ExprIndex(..) |
+            hir::ExprUnary(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) => {
                 // FIXME(#6268) Nested method calls
                 //
                 // The lifetimes for a call or method call look as follows:
@@ -823,7 +825,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
     visitor.cx = prev_cx;
 }
 
-fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
+fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
     debug!("resolve_local(local.id={:?},local.init={:?})",
            local.id,local.init.is_some());
 
@@ -920,26 +922,26 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
     ///        | [ ..., P&, ... ]
     ///        | ( ..., P&, ... )
     ///        | box P&
-    fn is_binding_pat(pat: &ast::Pat) -> bool {
+    fn is_binding_pat(pat: &hir::Pat) -> bool {
         match pat.node {
-            ast::PatIdent(ast::BindByRef(_), _, _) => true,
+            hir::PatIdent(hir::BindByRef(_), _, _) => true,
 
-            ast::PatStruct(_, ref field_pats, _) => {
+            hir::PatStruct(_, ref field_pats, _) => {
                 field_pats.iter().any(|fp| is_binding_pat(&*fp.node.pat))
             }
 
-            ast::PatVec(ref pats1, ref pats2, ref pats3) => {
+            hir::PatVec(ref pats1, ref pats2, ref pats3) => {
                 pats1.iter().any(|p| is_binding_pat(&**p)) ||
                 pats2.iter().any(|p| is_binding_pat(&**p)) ||
                 pats3.iter().any(|p| is_binding_pat(&**p))
             }
 
-            ast::PatEnum(_, Some(ref subpats)) |
-            ast::PatTup(ref subpats) => {
+            hir::PatEnum(_, Some(ref subpats)) |
+            hir::PatTup(ref subpats) => {
                 subpats.iter().any(|p| is_binding_pat(&**p))
             }
 
-            ast::PatBox(ref subpat) => {
+            hir::PatBox(ref subpat) => {
                 is_binding_pat(&**subpat)
             }
 
@@ -948,9 +950,9 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
     }
 
     /// True if `ty` is a borrowed pointer type like `&int` or `&[...]`.
-    fn is_borrowed_ty(ty: &ast::Ty) -> bool {
+    fn is_borrowed_ty(ty: &hir::Ty) -> bool {
         match ty.node {
-            ast::TyRptr(..) => true,
+            hir::TyRptr(..) => true,
             _ => false
         }
     }
@@ -966,34 +968,34 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
     ///        | E& as ...
     ///        | ( E& )
     fn record_rvalue_scope_if_borrow_expr(visitor: &mut RegionResolutionVisitor,
-                                          expr: &ast::Expr,
+                                          expr: &hir::Expr,
                                           blk_id: CodeExtent) {
         match expr.node {
-            ast::ExprAddrOf(_, ref subexpr) => {
+            hir::ExprAddrOf(_, ref subexpr) => {
                 record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
                 record_rvalue_scope(visitor, &**subexpr, blk_id);
             }
-            ast::ExprStruct(_, ref fields, _) => {
+            hir::ExprStruct(_, ref fields, _) => {
                 for field in fields {
                     record_rvalue_scope_if_borrow_expr(
                         visitor, &*field.expr, blk_id);
                 }
             }
-            ast::ExprVec(ref subexprs) |
-            ast::ExprTup(ref subexprs) => {
+            hir::ExprVec(ref subexprs) |
+            hir::ExprTup(ref subexprs) => {
                 for subexpr in subexprs {
                     record_rvalue_scope_if_borrow_expr(
                         visitor, &**subexpr, blk_id);
                 }
             }
-            ast::ExprUnary(ast::UnUniq, ref subexpr) => {
+            hir::ExprUnary(hir::UnUniq, ref subexpr) => {
                 record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id);
             }
-            ast::ExprCast(ref subexpr, _) |
-            ast::ExprParen(ref subexpr) => {
+            hir::ExprCast(ref subexpr, _) |
+            hir::ExprParen(ref subexpr) => {
                 record_rvalue_scope_if_borrow_expr(visitor, &**subexpr, blk_id)
             }
-            ast::ExprBlock(ref block) => {
+            hir::ExprBlock(ref block) => {
                 match block.expr {
                     Some(ref subexpr) => {
                         record_rvalue_scope_if_borrow_expr(
@@ -1023,7 +1025,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
     ///
     /// Note: ET is intended to match "rvalues or lvalues based on rvalues".
     fn record_rvalue_scope<'a>(visitor: &mut RegionResolutionVisitor,
-                               expr: &'a ast::Expr,
+                               expr: &'a hir::Expr,
                                blk_scope: CodeExtent) {
         let mut expr = expr;
         loop {
@@ -1035,12 +1037,12 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
             visitor.region_maps.record_rvalue_scope(expr.id, blk_scope);
 
             match expr.node {
-                ast::ExprAddrOf(_, ref subexpr) |
-                ast::ExprUnary(ast::UnDeref, ref subexpr) |
-                ast::ExprField(ref subexpr, _) |
-                ast::ExprTupField(ref subexpr, _) |
-                ast::ExprIndex(ref subexpr, _) |
-                ast::ExprParen(ref subexpr) => {
+                hir::ExprAddrOf(_, ref subexpr) |
+                hir::ExprUnary(hir::UnDeref, ref subexpr) |
+                hir::ExprField(ref subexpr, _) |
+                hir::ExprTupField(ref subexpr, _) |
+                hir::ExprIndex(ref subexpr, _) |
+                hir::ExprParen(ref subexpr) => {
                     expr = &**subexpr;
                 }
                 _ => {
@@ -1051,7 +1053,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
     }
 }
 
-fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
+fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) {
     // Items create a new outer block scope as far as we're concerned.
     let prev_cx = visitor.cx;
     let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
@@ -1068,8 +1070,8 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
 
 fn resolve_fn(visitor: &mut RegionResolutionVisitor,
               _: FnKind,
-              decl: &ast::FnDecl,
-              body: &ast::Block,
+              decl: &hir::FnDecl,
+              body: &hir::Block,
               sp: Span,
               id: ast::NodeId) {
     debug!("region::resolve_fn(id={:?}, \
@@ -1159,12 +1161,12 @@ impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
         resolve_item(self, i);
     }
 
-    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+    fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
         visit::walk_impl_item(self, ii);
         self.create_item_scope_if_needed(ii.id);
     }
 
-    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+    fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
         visit::walk_trait_item(self, ti);
         self.create_item_scope_if_needed(ti.id);
     }
@@ -1190,7 +1192,7 @@ impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
     }
 }
 
-pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
+pub fn resolve_crate(sess: &Session, krate: &hir::Crate) -> RegionMaps {
     let maps = RegionMaps {
         code_extents: RefCell::new(vec![]),
         code_extent_interner: RefCell::new(FnvHashMap()),
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index f8d7ed9d1b1..73b3b32f648 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -28,11 +28,12 @@ use std::mem::replace;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
-use syntax::print::pprust::lifetime_to_string;
-use syntax::visit;
-use syntax::visit::{FnKind, Visitor};
 use util::nodemap::NodeMap;
 
+use rustc_front::hir;
+use rustc_front::print::pprust::lifetime_to_string;
+use rustc_front::visit::{self, Visitor, FnKind};
+
 #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
 pub enum DefRegion {
     DefStaticRegion,
@@ -78,10 +79,10 @@ struct LifetimeContext<'a> {
 enum ScopeChain<'a> {
     /// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
     /// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
-    EarlyScope(subst::ParamSpace, &'a Vec<ast::LifetimeDef>, Scope<'a>),
+    EarlyScope(subst::ParamSpace, &'a Vec<hir::LifetimeDef>, Scope<'a>),
     /// LateScope(['a, 'b, ...], s) extends s with late-bound
     /// lifetimes introduced by the declaration binder_id.
-    LateScope(&'a Vec<ast::LifetimeDef>, Scope<'a>),
+    LateScope(&'a Vec<hir::LifetimeDef>, Scope<'a>),
     /// lifetimes introduced by items within a code block are scoped
     /// to that block.
     BlockScope(region::DestructionScopeData, Scope<'a>),
@@ -92,7 +93,7 @@ type Scope<'a> = &'a ScopeChain<'a>;
 
 static ROOT_SCOPE: ScopeChain<'static> = RootScope;
 
-pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegionMap {
+pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap {
     let mut named_region_map = NodeMap();
     visit::walk_crate(&mut LifetimeContext {
         sess: sess,
@@ -107,7 +108,7 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
 }
 
 impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
-    fn visit_item(&mut self, item: &ast::Item) {
+    fn visit_item(&mut self, item: &hir::Item) {
         // Items save/restore the set of labels. This way inner items
         // can freely reuse names, be they loop labels or lifetimes.
         let saved = replace(&mut self.labels_in_fn, vec![]);
@@ -115,26 +116,25 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         // Items always introduce a new root scope
         self.with(RootScope, |_, this| {
             match item.node {
-                ast::ItemFn(..) => {
+                hir::ItemFn(..) => {
                     // Fn lifetimes get added in visit_fn below:
                     visit::walk_item(this, item);
                 }
-                ast::ItemExternCrate(_) |
-                ast::ItemUse(_) |
-                ast::ItemMod(..) |
-                ast::ItemMac(..) |
-                ast::ItemDefaultImpl(..) |
-                ast::ItemForeignMod(..) |
-                ast::ItemStatic(..) |
-                ast::ItemConst(..) => {
+                hir::ItemExternCrate(_) |
+                hir::ItemUse(_) |
+                hir::ItemMod(..) |
+                hir::ItemDefaultImpl(..) |
+                hir::ItemForeignMod(..) |
+                hir::ItemStatic(..) |
+                hir::ItemConst(..) => {
                     // These sorts of items have no lifetime parameters at all.
                     visit::walk_item(this, item);
                 }
-                ast::ItemTy(_, ref generics) |
-                ast::ItemEnum(_, ref generics) |
-                ast::ItemStruct(_, ref generics) |
-                ast::ItemTrait(_, ref generics, _, _) |
-                ast::ItemImpl(_, _, ref generics, _, _, _) => {
+                hir::ItemTy(_, ref generics) |
+                hir::ItemEnum(_, ref generics) |
+                hir::ItemStruct(_, ref generics) |
+                hir::ItemTrait(_, ref generics, _, _) |
+                hir::ItemImpl(_, _, ref generics, _, _, _) => {
                     // These kinds of items have only early bound lifetime parameters.
                     let lifetimes = &generics.lifetimes;
                     let early_scope = EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE);
@@ -150,7 +150,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         replace(&mut self.labels_in_fn, saved);
     }
 
-    fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
+    fn visit_foreign_item(&mut self, item: &hir::ForeignItem) {
         // Items save/restore the set of labels. This way inner items
         // can freely reuse names, be they loop labels or lifetimes.
         let saved = replace(&mut self.labels_in_fn, vec![]);
@@ -158,12 +158,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         // Items always introduce a new root scope
         self.with(RootScope, |_, this| {
             match item.node {
-                ast::ForeignItemFn(_, ref generics) => {
+                hir::ForeignItemFn(_, ref generics) => {
                     this.visit_early_late(subst::FnSpace, generics, |this| {
                         visit::walk_foreign_item(this, item);
                     })
                 }
-                ast::ForeignItemStatic(..) => {
+                hir::ForeignItemStatic(..) => {
                     visit::walk_foreign_item(this, item);
                 }
             }
@@ -173,8 +173,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         replace(&mut self.labels_in_fn, saved);
     }
 
-    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
-                b: &'v ast::Block, s: Span, _: ast::NodeId) {
+    fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
+                b: &'v hir::Block, s: Span, _: ast::NodeId) {
         match fk {
             FnKind::ItemFn(_, generics, _, _, _, _) => {
                 self.visit_early_late(subst::FnSpace, generics, |this| {
@@ -192,9 +192,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         }
     }
 
-    fn visit_ty(&mut self, ty: &ast::Ty) {
+    fn visit_ty(&mut self, ty: &hir::Ty) {
         match ty.node {
-            ast::TyBareFn(ref c) => {
+            hir::TyBareFn(ref c) => {
                 visit::walk_lifetime_decls_helper(self, &c.lifetimes);
                 self.with(LateScope(&c.lifetimes, self.scope), |old_scope, this| {
                     // a bare fn has no bounds, so everything
@@ -203,7 +203,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                     visit::walk_ty(this, ty);
                 });
             }
-            ast::TyPath(None, ref path) => {
+            hir::TyPath(None, ref path) => {
                 // if this path references a trait, then this will resolve to
                 // a trait ref, which introduces a binding scope.
                 match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
@@ -223,12 +223,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         }
     }
 
-    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+    fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
         // We reset the labels on every trait item, so that different
         // methods in an impl can reuse label names.
         let saved = replace(&mut self.labels_in_fn, vec![]);
 
-        if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
+        if let hir::MethodTraitItem(ref sig, None) = trait_item.node {
             self.visit_early_late(
                 subst::FnSpace, &sig.generics,
                 |this| visit::walk_trait_item(this, trait_item))
@@ -239,13 +239,13 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         replace(&mut self.labels_in_fn, saved);
     }
 
-    fn visit_block(&mut self, b: &ast::Block) {
+    fn visit_block(&mut self, b: &hir::Block) {
         self.with(BlockScope(region::DestructionScopeData::new(b.id),
                              self.scope),
                   |_, this| visit::walk_block(this, b));
     }
 
-    fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
+    fn visit_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
         if lifetime_ref.name == special_idents::static_lifetime.name {
             self.insert_lifetime(lifetime_ref, DefStaticRegion);
             return;
@@ -253,7 +253,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         self.resolve_lifetime_ref(lifetime_ref);
     }
 
-    fn visit_generics(&mut self, generics: &ast::Generics) {
+    fn visit_generics(&mut self, generics: &hir::Generics) {
         for ty_param in generics.ty_params.iter() {
             visit::walk_ty_param_bounds_helper(self, &ty_param.bounds);
             match ty_param.default {
@@ -263,7 +263,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         }
         for predicate in &generics.where_clause.predicates {
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ref bounded_ty,
+                &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ ref bounded_ty,
                                                                                ref bounds,
                                                                                ref bound_lifetimes,
                                                                                .. }) => {
@@ -282,7 +282,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                         visit::walk_ty_param_bounds_helper(self, bounds);
                     }
                 }
-                &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
                                                                                 ref bounds,
                                                                                 .. }) => {
 
@@ -291,7 +291,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                         self.visit_lifetime_ref(bound);
                     }
                 }
-                &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ id,
+                &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ id,
                                                                          ref path,
                                                                          ref ty,
                                                                          .. }) => {
@@ -303,8 +303,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
     }
 
     fn visit_poly_trait_ref(&mut self,
-                            trait_ref: &ast::PolyTraitRef,
-                            _modifier: &ast::TraitBoundModifier) {
+                            trait_ref: &hir::PolyTraitRef,
+                            _modifier: &hir::TraitBoundModifier) {
         debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
 
         if !self.trait_ref_hack || !trait_ref.bound_lifetimes.is_empty() {
@@ -337,10 +337,10 @@ fn original_label(span: Span) -> Original {
 fn shadower_label(span: Span) -> Shadower {
     Shadower { kind: ShadowKind::Label, span: span }
 }
-fn original_lifetime(l: &ast::Lifetime) -> Original {
+fn original_lifetime(l: &hir::Lifetime) -> Original {
     Original { kind: ShadowKind::Lifetime, span: l.span }
 }
-fn shadower_lifetime(l: &ast::Lifetime) -> Shadower {
+fn shadower_lifetime(l: &hir::Lifetime) -> Shadower {
     Shadower { kind: ShadowKind::Lifetime, span: l.span }
 }
 
@@ -376,7 +376,7 @@ fn signal_shadowing_problem(
 
 // Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
 // if one of the label shadows a lifetime or another label.
-fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
+fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) {
 
     struct GatherLabels<'a> {
         sess: &'a Session,
@@ -393,11 +393,11 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
     return;
 
     impl<'v, 'a> Visitor<'v> for GatherLabels<'a> {
-        fn visit_expr(&mut self, ex: &'v ast::Expr) {
+        fn visit_expr(&mut self, ex: &'v hir::Expr) {
             // do not recurse into closures defined in the block
             // since they are treated as separate fns from the POV of
             // labels_in_fn
-            if let ast::ExprClosure(..) = ex.node {
+            if let hir::ExprClosure(..) = ex.node {
                 return
             }
             if let Some(label) = expression_label(ex) {
@@ -421,17 +421,15 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
             visit::walk_expr(self, ex)
         }
 
-        fn visit_item(&mut self, _: &ast::Item) {
+        fn visit_item(&mut self, _: &hir::Item) {
             // do not recurse into items defined in the block
         }
     }
 
-    fn expression_label(ex: &ast::Expr) -> Option<ast::Ident> {
+    fn expression_label(ex: &hir::Expr) -> Option<ast::Ident> {
         match ex.node {
-            ast::ExprWhile(_, _, Some(label))       |
-            ast::ExprWhileLet(_, _, _, Some(label)) |
-            ast::ExprForLoop(_, _, _, Some(label))  |
-            ast::ExprLoop(_, Some(label))          => Some(label),
+            hir::ExprWhile(_, _, Some(label)) |
+            hir::ExprLoop(_, Some(label)) => Some(label),
             _ => None,
         }
     }
@@ -471,8 +469,8 @@ impl<'a> LifetimeContext<'a> {
     // the function body itself.
     fn walk_fn<'b>(&mut self,
                    fk: FnKind,
-                   fd: &ast::FnDecl,
-                   fb: &'b ast::Block,
+                   fd: &hir::FnDecl,
+                   fb: &'b hir::Block,
                    _span: Span) {
         match fk {
             FnKind::ItemFn(_, generics, _, _, _, _) => {
@@ -533,7 +531,7 @@ impl<'a> LifetimeContext<'a> {
     /// ordering is not important there.
     fn visit_early_late<F>(&mut self,
                            early_space: subst::ParamSpace,
-                           generics: &ast::Generics,
+                           generics: &hir::Generics,
                            walk: F) where
         F: FnOnce(&mut LifetimeContext),
     {
@@ -553,7 +551,7 @@ impl<'a> LifetimeContext<'a> {
         });
     }
 
-    fn resolve_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
+    fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
         // Walk up the scope chain, tracking the number of fn scopes
         // that we pass through, until we find a lifetime with the
         // given name or we run out of scopes. If we encounter a code
@@ -610,7 +608,7 @@ impl<'a> LifetimeContext<'a> {
 
     fn resolve_free_lifetime_ref(&mut self,
                                  scope_data: region::DestructionScopeData,
-                                 lifetime_ref: &ast::Lifetime,
+                                 lifetime_ref: &hir::Lifetime,
                                  scope: Scope) {
         debug!("resolve_free_lifetime_ref \
                 scope_data: {:?} lifetime_ref: {:?} scope: {:?}",
@@ -660,13 +658,13 @@ impl<'a> LifetimeContext<'a> {
 
     }
 
-    fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) {
+    fn unresolved_lifetime_ref(&self, lifetime_ref: &hir::Lifetime) {
         span_err!(self.sess, lifetime_ref.span, E0261,
             "use of undeclared lifetime name `{}`",
                     lifetime_ref.name);
     }
 
-    fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<ast::LifetimeDef>) {
+    fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<hir::LifetimeDef>) {
         for i in 0..lifetimes.len() {
             let lifetime_i = &lifetimes[i];
 
@@ -701,7 +699,7 @@ impl<'a> LifetimeContext<'a> {
 
     fn check_lifetime_def_for_shadowing(&self,
                                         mut old_scope: Scope,
-                                        lifetime: &ast::Lifetime)
+                                        lifetime: &hir::Lifetime)
     {
         for &(label, label_span) in &self.labels_in_fn {
             // FIXME (#24278): non-hygienic comparison
@@ -742,7 +740,7 @@ impl<'a> LifetimeContext<'a> {
     }
 
     fn insert_lifetime(&mut self,
-                       lifetime_ref: &ast::Lifetime,
+                       lifetime_ref: &hir::Lifetime,
                        def: DefRegion) {
         if lifetime_ref.id == ast::DUMMY_NODE_ID {
             self.sess.span_bug(lifetime_ref.span,
@@ -758,9 +756,9 @@ impl<'a> LifetimeContext<'a> {
     }
 }
 
-fn search_lifetimes<'a>(lifetimes: &'a Vec<ast::LifetimeDef>,
-                    lifetime_ref: &ast::Lifetime)
-                    -> Option<(u32, &'a ast::Lifetime)> {
+fn search_lifetimes<'a>(lifetimes: &'a Vec<hir::LifetimeDef>,
+                    lifetime_ref: &hir::Lifetime)
+                    -> Option<(u32, &'a hir::Lifetime)> {
     for (i, lifetime_decl) in lifetimes.iter().enumerate() {
         if lifetime_decl.lifetime.name == lifetime_ref.name {
             return Some((i as u32, &lifetime_decl.lifetime));
@@ -771,7 +769,7 @@ fn search_lifetimes<'a>(lifetimes: &'a Vec<ast::LifetimeDef>,
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::LifetimeDef> {
+pub fn early_bound_lifetimes<'a>(generics: &'a hir::Generics) -> Vec<hir::LifetimeDef> {
     let referenced_idents = early_bound_lifetime_names(generics);
     if referenced_idents.is_empty() {
         return Vec::new();
@@ -785,7 +783,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::Lifeti
 
 /// Given a set of generic declarations, returns a list of names containing all early bound
 /// lifetime names for those generics. (In fact, this list may also contain other names.)
-fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
+fn early_bound_lifetime_names(generics: &hir::Generics) -> Vec<ast::Name> {
     // Create two lists, dividing the lifetimes into early/late bound.
     // Initially, all of them are considered late, but we will move
     // things from late into early as we go if we find references to
@@ -805,13 +803,13 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
         }
         for predicate in &generics.where_clause.predicates {
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounds,
+                &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bounds,
                                                                               ref bounded_ty,
                                                                               ..}) => {
                     collector.visit_ty(&**bounded_ty);
                     visit::walk_ty_param_bounds_helper(&mut collector, bounds);
                 }
-                &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
                                                                                 ref bounds,
                                                                                 ..}) => {
                     collector.visit_lifetime_ref(lifetime);
@@ -820,7 +818,7 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
                         collector.visit_lifetime_ref(bound);
                     }
                 }
-                &ast::WherePredicate::EqPredicate(_) => unimplemented!()
+                &hir::WherePredicate::EqPredicate(_) => unimplemented!()
             }
         }
     }
@@ -845,7 +843,7 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
     }
 
     impl<'a, 'v> Visitor<'v> for FreeLifetimeCollector<'a> {
-        fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
+        fn visit_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) {
             shuffle(self.early_bound, self.late_bound,
                     lifetime_ref.name);
         }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index d841f9617c8..08f8eb5685e 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -20,15 +20,16 @@ use middle::privacy::PublicItems;
 use metadata::csearch;
 use syntax::parse::token::InternedString;
 use syntax::codemap::{Span, DUMMY_SP};
-use syntax::{attr, visit};
 use syntax::ast;
-use syntax::ast::{Attribute, Block, Crate, FnDecl, NodeId, Variant};
-use syntax::ast::{Item, Generics, StructField};
-use syntax::attr::{Stability, AttrMetaMethods};
-use syntax::visit::{FnKind, Visitor};
+use syntax::ast::NodeId;
 use syntax::feature_gate::emit_feature_err;
 use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap};
 
+use rustc_front::hir;
+use rustc_front::hir::{FnDecl, Attribute, Block, Crate, Item, Generics, StructField, Variant};
+use rustc_front::attr::{self, Stability, AttrMetaMethods};
+use rustc_front::visit::{self, FnKind, Visitor};
+
 use std::mem::replace;
 use std::cmp::Ordering;
 
@@ -166,21 +167,21 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
         // stability of the trait. This is WRONG, but expedient to get
         // libstd stabilized for the 1.0 release.
         let use_parent = match i.node {
-            ast::ItemImpl(_, _, _, Some(_), _, _) => false,
+            hir::ItemImpl(_, _, _, Some(_), _, _) => false,
             _ => true,
         };
 
         // In case of a `pub use <mod>;`, we should not error since the stability
         // is inherited from the module itself
         let required = match i.node {
-            ast::ItemUse(_) => i.vis != ast::Public,
+            hir::ItemUse(_) => i.vis != hir::Public,
             _ => true
         };
 
         self.annotate(i.id, use_parent, &i.attrs, i.span,
                       |v| visit::walk_item(v, i), required);
 
-        if let ast::ItemStruct(ref sd, _) = i.node {
+        if let hir::ItemStruct(ref sd, _) = i.node {
             sd.ctor_id.map(|id| {
                 self.annotate(id, true, &i.attrs, i.span, |_| {}, true)
             });
@@ -193,12 +194,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
         // a stability attribute, so we don't recurse.
     }
 
-    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+    fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
         self.annotate(ti.id, true, &ti.attrs, ti.span,
                       |v| visit::walk_trait_item(v, ti), true);
     }
 
-    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+    fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
         self.annotate(ii.id, true, &ii.attrs, ii.span,
                       |v| visit::walk_impl_item(v, ii), true);
     }
@@ -213,7 +214,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
                       |v| visit::walk_struct_field(v, s), true);
     }
 
-    fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
+    fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
         self.annotate(i.id, true, &i.attrs, i.span, |_| {}, true);
     }
 }
@@ -236,7 +237,7 @@ impl<'tcx> Index<'tcx> {
         for attr in &krate.attrs {
             if &attr.name()[..] == "staged_api" {
                 match attr.node.value.node {
-                    ast::MetaWord(_) => {
+                    hir::MetaWord(_) => {
                         attr::mark_used(attr);
                         is_staged_api = true;
                     }
@@ -335,7 +336,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
 }
 
 impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item) {
+    fn visit_item(&mut self, item: &hir::Item) {
         // When compiling with --test we don't enforce stability on the
         // compiler-generated test module, demarcated with `DUMMY_SP` plus the
         // name `__test`
@@ -346,19 +347,19 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
         visit::walk_item(self, item);
     }
 
-    fn visit_expr(&mut self, ex: &ast::Expr) {
+    fn visit_expr(&mut self, ex: &hir::Expr) {
         check_expr(self.tcx, ex,
                    &mut |id, sp, stab| self.check(id, sp, stab));
         visit::walk_expr(self, ex);
     }
 
-    fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
+    fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
         check_path(self.tcx, path, id,
                    &mut |id, sp, stab| self.check(id, sp, stab));
         visit::walk_path(self, path)
     }
 
-    fn visit_pat(&mut self, pat: &ast::Pat) {
+    fn visit_pat(&mut self, pat: &hir::Pat) {
         check_pat(self.tcx, pat,
                   &mut |id, sp, stab| self.check(id, sp, stab));
         visit::walk_pat(self, pat)
@@ -366,10 +367,10 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
 }
 
 /// Helper for discovering nodes to check for stability
-pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
+pub fn check_item(tcx: &ty::ctxt, item: &hir::Item, warn_about_defns: bool,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
     match item.node {
-        ast::ItemExternCrate(_) => {
+        hir::ItemExternCrate(_) => {
             // compiler-generated `extern crate` items have a dummy span.
             if item.span == DUMMY_SP { return }
 
@@ -384,7 +385,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
         // For implementations of traits, check the stability of each item
         // individually as it's possible to have a stable trait with unstable
         // items.
-        ast::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
+        hir::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
             let trait_did = tcx.def_map.borrow().get(&t.ref_id).unwrap().def_id();
             let trait_items = tcx.trait_items(trait_did);
 
@@ -403,16 +404,16 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
 }
 
 /// Helper for discovering nodes to check for stability
-pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
+pub fn check_expr(tcx: &ty::ctxt, e: &hir::Expr,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
     let span;
     let id = match e.node {
-        ast::ExprMethodCall(i, _, _) => {
+        hir::ExprMethodCall(i, _, _) => {
             span = i.span;
             let method_call = ty::MethodCall::expr(e.id);
             tcx.tables.borrow().method_map[&method_call].def_id
         }
-        ast::ExprField(ref base_e, ref field) => {
+        hir::ExprField(ref base_e, ref field) => {
             span = field.span;
             match tcx.expr_ty_adjusted(base_e).sty {
                 ty::TyStruct(def, _) => def.struct_variant().field_named(field.node.name).did,
@@ -420,7 +421,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
                                        "stability::check_expr: named field access on non-struct")
             }
         }
-        ast::ExprTupField(ref base_e, ref field) => {
+        hir::ExprTupField(ref base_e, ref field) => {
             span = field.span;
             match tcx.expr_ty_adjusted(base_e).sty {
                 ty::TyStruct(def, _) => def.struct_variant().fields[field.node].did,
@@ -430,7 +431,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
                                         something other than a tuple or struct")
             }
         }
-        ast::ExprStruct(_, ref expr_fields, _) => {
+        hir::ExprStruct(_, ref expr_fields, _) => {
             let type_ = tcx.expr_ty(e);
             match type_.sty {
                 ty::TyStruct(def, _) => {
@@ -464,7 +465,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
     maybe_do_stability_check(tcx, id, span, cb);
 }
 
-pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
+pub fn check_path(tcx: &ty::ctxt, path: &hir::Path, id: ast::NodeId,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
     match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
         Some(def::DefPrimTy(..)) => {}
@@ -476,7 +477,7 @@ pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
 
 }
 
-pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
+pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
                  cb: &mut FnMut(DefId, Span, &Option<&Stability>)) {
     debug!("check_pat(pat = {:?})", pat);
     if is_internal(tcx, pat.span) { return; }
@@ -487,18 +488,18 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
     };
     match pat.node {
         // Foo(a, b, c)
-        ast::PatEnum(_, Some(ref pat_fields)) => {
+        hir::PatEnum(_, Some(ref pat_fields)) => {
             for (field, struct_field) in pat_fields.iter().zip(&v.fields) {
                 // a .. pattern is fine, but anything positional is
                 // not.
-                if let ast::PatWild(ast::PatWildMulti) = field.node {
+                if let hir::PatWild(hir::PatWildMulti) = field.node {
                     continue
                 }
                 maybe_do_stability_check(tcx, struct_field.did, field.span, cb)
             }
         }
         // Foo { a, b, c }
-        ast::PatStruct(_, ref pat_fields, _) => {
+        hir::PatStruct(_, ref pat_fields, _) => {
             for field in pat_fields {
                 let did = v.field_named(field.node.ident.name).did;
                 maybe_do_stability_check(tcx, did, field.span, cb);
diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs
index 40f1e9d64f7..a3a903c3393 100644
--- a/src/librustc/middle/traits/error_reporting.rs
+++ b/src/librustc/middle/traits/error_reporting.rs
@@ -31,7 +31,7 @@ use middle::ty_fold::TypeFoldable;
 use std::collections::HashMap;
 use std::fmt;
 use syntax::codemap::Span;
-use syntax::attr::{AttributeMethods, AttrMetaMethods};
+use rustc_front::attr::{AttributeMethods, AttrMetaMethods};
 
 pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                            errors: &Vec<FulfillmentError<'tcx>>) {
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index a4d36c1fda8..544e23c5ffb 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -51,7 +51,8 @@ use middle::wf;
 use std::cell::RefCell;
 use std::fmt;
 use std::rc::Rc;
-use syntax::{abi, ast};
+use syntax::abi;
+use rustc_front::hir;
 use util::common::ErrorReported;
 use util::nodemap::FnvHashMap;
 
@@ -793,7 +794,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         match candidate {
             ImplCandidate(def_id) => {
                 match self.tcx().trait_impl_polarity(def_id) {
-                    Some(ast::ImplPolarity::Negative) => return Err(Unimplemented),
+                    Some(hir::ImplPolarity::Negative) => return Err(Unimplemented),
                     _ => {}
                 }
             }
@@ -1217,7 +1218,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             // provide an impl, but only for suitable `fn` pointers
             ty::TyBareFn(_, &ty::BareFnTy {
-                unsafety: ast::Unsafety::Normal,
+                unsafety: hir::Unsafety::Normal,
                 abi: abi::Rust,
                 sig: ty::Binder(ty::FnSig {
                     inputs: _,
@@ -1676,10 +1677,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     ty::BoundCopy => {
                         match mutbl {
                             // &mut T is affine and hence never `Copy`
-                            ast::MutMutable => Err(Unimplemented),
+                            hir::MutMutable => Err(Unimplemented),
 
                             // &T is always copyable
-                            ast::MutImmutable => ok_if(Vec::new()),
+                            hir::MutImmutable => ok_if(Vec::new()),
                         }
                     }
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 483f2873166..541bc8896aa 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -35,10 +35,11 @@ pub use self::BuiltinBound::Sized as BoundSized;
 pub use self::BuiltinBound::Copy as BoundCopy;
 pub use self::BuiltinBound::Sync as BoundSync;
 
-use ast_map::{self, LinkedPath};
 use back::svh::Svh;
 use session::Session;
 use lint;
+use front::map as ast_map;
+use front::map::LinkedPath;
 use metadata::csearch;
 use middle;
 use middle::cast;
@@ -85,12 +86,14 @@ use core::nonzero::NonZero;
 use std::collections::{HashMap, HashSet};
 use rustc_data_structures::ivar;
 use syntax::abi;
-use syntax::ast::{CrateNum, ItemImpl, ItemTrait};
-use syntax::ast::{MutImmutable, MutMutable, Name, NodeId, Visibility};
-use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
+use syntax::ast::{self, CrateNum, Name, NodeId};
 use syntax::codemap::Span;
 use syntax::parse::token::{InternedString, special_idents};
-use syntax::ast;
+
+use rustc_front::hir;
+use rustc_front::hir::{ItemImpl, ItemTrait};
+use rustc_front::hir::{MutImmutable, MutMutable, Visibility};
+use rustc_front::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
 
 pub type Disr = u64;
 
@@ -109,6 +112,7 @@ pub struct CrateAnalysis {
     pub glob_map: Option<GlobMap>,
 }
 
+
 #[derive(Copy, Clone)]
 pub enum DtorKind {
     NoDtor,
@@ -143,48 +147,48 @@ pub trait IntTypeExt {
 impl IntTypeExt for attr::IntType {
     fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
         match *self {
-            SignedInt(ast::TyI8)      => cx.types.i8,
-            SignedInt(ast::TyI16)     => cx.types.i16,
-            SignedInt(ast::TyI32)     => cx.types.i32,
-            SignedInt(ast::TyI64)     => cx.types.i64,
-            SignedInt(ast::TyIs)   => cx.types.isize,
-            UnsignedInt(ast::TyU8)    => cx.types.u8,
-            UnsignedInt(ast::TyU16)   => cx.types.u16,
-            UnsignedInt(ast::TyU32)   => cx.types.u32,
-            UnsignedInt(ast::TyU64)   => cx.types.u64,
-            UnsignedInt(ast::TyUs) => cx.types.usize,
+            SignedInt(hir::TyI8)      => cx.types.i8,
+            SignedInt(hir::TyI16)     => cx.types.i16,
+            SignedInt(hir::TyI32)     => cx.types.i32,
+            SignedInt(hir::TyI64)     => cx.types.i64,
+            SignedInt(hir::TyIs)   => cx.types.isize,
+            UnsignedInt(hir::TyU8)    => cx.types.u8,
+            UnsignedInt(hir::TyU16)   => cx.types.u16,
+            UnsignedInt(hir::TyU32)   => cx.types.u32,
+            UnsignedInt(hir::TyU64)   => cx.types.u64,
+            UnsignedInt(hir::TyUs) => cx.types.usize,
         }
     }
 
     fn i64_to_disr(&self, val: i64) -> Option<Disr> {
         match *self {
-            SignedInt(ast::TyI8)    => val.to_i8()  .map(|v| v as Disr),
-            SignedInt(ast::TyI16)   => val.to_i16() .map(|v| v as Disr),
-            SignedInt(ast::TyI32)   => val.to_i32() .map(|v| v as Disr),
-            SignedInt(ast::TyI64)   => val.to_i64() .map(|v| v as Disr),
-            UnsignedInt(ast::TyU8)  => val.to_u8()  .map(|v| v as Disr),
-            UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
-            UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
-            UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+            SignedInt(hir::TyI8)    => val.to_i8()  .map(|v| v as Disr),
+            SignedInt(hir::TyI16)   => val.to_i16() .map(|v| v as Disr),
+            SignedInt(hir::TyI32)   => val.to_i32() .map(|v| v as Disr),
+            SignedInt(hir::TyI64)   => val.to_i64() .map(|v| v as Disr),
+            UnsignedInt(hir::TyU8)  => val.to_u8()  .map(|v| v as Disr),
+            UnsignedInt(hir::TyU16) => val.to_u16() .map(|v| v as Disr),
+            UnsignedInt(hir::TyU32) => val.to_u32() .map(|v| v as Disr),
+            UnsignedInt(hir::TyU64) => val.to_u64() .map(|v| v as Disr),
 
-            UnsignedInt(ast::TyUs) |
-            SignedInt(ast::TyIs) => unreachable!(),
+            UnsignedInt(hir::TyUs) |
+            SignedInt(hir::TyIs) => unreachable!(),
         }
     }
 
     fn u64_to_disr(&self, val: u64) -> Option<Disr> {
         match *self {
-            SignedInt(ast::TyI8)    => val.to_i8()  .map(|v| v as Disr),
-            SignedInt(ast::TyI16)   => val.to_i16() .map(|v| v as Disr),
-            SignedInt(ast::TyI32)   => val.to_i32() .map(|v| v as Disr),
-            SignedInt(ast::TyI64)   => val.to_i64() .map(|v| v as Disr),
-            UnsignedInt(ast::TyU8)  => val.to_u8()  .map(|v| v as Disr),
-            UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
-            UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
-            UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+            SignedInt(hir::TyI8)    => val.to_i8()  .map(|v| v as Disr),
+            SignedInt(hir::TyI16)   => val.to_i16() .map(|v| v as Disr),
+            SignedInt(hir::TyI32)   => val.to_i32() .map(|v| v as Disr),
+            SignedInt(hir::TyI64)   => val.to_i64() .map(|v| v as Disr),
+            UnsignedInt(hir::TyU8)  => val.to_u8()  .map(|v| v as Disr),
+            UnsignedInt(hir::TyU16) => val.to_u16() .map(|v| v as Disr),
+            UnsignedInt(hir::TyU32) => val.to_u32() .map(|v| v as Disr),
+            UnsignedInt(hir::TyU64) => val.to_u64() .map(|v| v as Disr),
 
-            UnsignedInt(ast::TyUs) |
-            SignedInt(ast::TyIs) => unreachable!(),
+            UnsignedInt(hir::TyUs) |
+            SignedInt(hir::TyIs) => unreachable!(),
         }
     }
 
@@ -196,18 +200,18 @@ impl IntTypeExt for attr::IntType {
             // SignedInt repr means we *want* to reinterpret the bits
             // treating the highest bit of Disr as a sign-bit, so
             // cast to i64 before range-checking.
-            SignedInt(ast::TyI8)    => add1!((val as i64).to_i8()),
-            SignedInt(ast::TyI16)   => add1!((val as i64).to_i16()),
-            SignedInt(ast::TyI32)   => add1!((val as i64).to_i32()),
-            SignedInt(ast::TyI64)   => add1!(Some(val as i64)),
+            SignedInt(hir::TyI8)    => add1!((val as i64).to_i8()),
+            SignedInt(hir::TyI16)   => add1!((val as i64).to_i16()),
+            SignedInt(hir::TyI32)   => add1!((val as i64).to_i32()),
+            SignedInt(hir::TyI64)   => add1!(Some(val as i64)),
 
-            UnsignedInt(ast::TyU8)  => add1!(val.to_u8()),
-            UnsignedInt(ast::TyU16) => add1!(val.to_u16()),
-            UnsignedInt(ast::TyU32) => add1!(val.to_u32()),
-            UnsignedInt(ast::TyU64) => add1!(Some(val)),
+            UnsignedInt(hir::TyU8)  => add1!(val.to_u8()),
+            UnsignedInt(hir::TyU16) => add1!(val.to_u16()),
+            UnsignedInt(hir::TyU32) => add1!(val.to_u32()),
+            UnsignedInt(hir::TyU64) => add1!(Some(val)),
 
-            UnsignedInt(ast::TyUs) |
-            SignedInt(ast::TyIs) => unreachable!(),
+            UnsignedInt(hir::TyUs) |
+            SignedInt(hir::TyIs) => unreachable!(),
         }
     }
 
@@ -216,17 +220,17 @@ impl IntTypeExt for attr::IntType {
     // full range from `i64::MIN` through `u64::MAX`.
     fn disr_string(&self, val: Disr) -> String {
         match *self {
-            SignedInt(ast::TyI8)    => format!("{}", val as i8 ),
-            SignedInt(ast::TyI16)   => format!("{}", val as i16),
-            SignedInt(ast::TyI32)   => format!("{}", val as i32),
-            SignedInt(ast::TyI64)   => format!("{}", val as i64),
-            UnsignedInt(ast::TyU8)  => format!("{}", val as u8 ),
-            UnsignedInt(ast::TyU16) => format!("{}", val as u16),
-            UnsignedInt(ast::TyU32) => format!("{}", val as u32),
-            UnsignedInt(ast::TyU64) => format!("{}", val as u64),
+            SignedInt(hir::TyI8)    => format!("{}", val as i8 ),
+            SignedInt(hir::TyI16)   => format!("{}", val as i16),
+            SignedInt(hir::TyI32)   => format!("{}", val as i32),
+            SignedInt(hir::TyI64)   => format!("{}", val as i64),
+            UnsignedInt(hir::TyU8)  => format!("{}", val as u8 ),
+            UnsignedInt(hir::TyU16) => format!("{}", val as u16),
+            UnsignedInt(hir::TyU32) => format!("{}", val as u32),
+            UnsignedInt(hir::TyU64) => format!("{}", val as u64),
 
-            UnsignedInt(ast::TyUs) |
-            SignedInt(ast::TyIs) => unreachable!(),
+            UnsignedInt(hir::TyUs) |
+            SignedInt(hir::TyIs) => unreachable!(),
         }
     }
 
@@ -236,17 +240,17 @@ impl IntTypeExt for attr::IntType {
         }
         let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
         match *self {
-            SignedInt(ast::TyI8)    => add1!(val as i8 ),
-            SignedInt(ast::TyI16)   => add1!(val as i16),
-            SignedInt(ast::TyI32)   => add1!(val as i32),
-            SignedInt(ast::TyI64)   => add1!(val as i64),
-            UnsignedInt(ast::TyU8)  => add1!(val as u8 ),
-            UnsignedInt(ast::TyU16) => add1!(val as u16),
-            UnsignedInt(ast::TyU32) => add1!(val as u32),
-            UnsignedInt(ast::TyU64) => add1!(val as u64),
+            SignedInt(hir::TyI8)    => add1!(val as i8 ),
+            SignedInt(hir::TyI16)   => add1!(val as i16),
+            SignedInt(hir::TyI32)   => add1!(val as i32),
+            SignedInt(hir::TyI64)   => add1!(val as i64),
+            UnsignedInt(hir::TyU8)  => add1!(val as u8 ),
+            UnsignedInt(hir::TyU16) => add1!(val as u16),
+            UnsignedInt(hir::TyU32) => add1!(val as u32),
+            UnsignedInt(hir::TyU64) => add1!(val as u64),
 
-            UnsignedInt(ast::TyUs) |
-            SignedInt(ast::TyIs) => unreachable!(),
+            UnsignedInt(hir::TyUs) |
+            SignedInt(hir::TyIs) => unreachable!(),
         }
     }
 }
@@ -294,7 +298,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> {
         }
     }
 
-    pub fn name(&self) -> ast::Name {
+    pub fn name(&self) -> Name {
         match *self {
             ConstTraitItem(ref associated_const) => associated_const.name,
             MethodTraitItem(ref method) => method.name,
@@ -302,7 +306,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> {
         }
     }
 
-    pub fn vis(&self) -> ast::Visibility {
+    pub fn vis(&self) -> hir::Visibility {
         match *self {
             ConstTraitItem(ref associated_const) => associated_const.vis,
             MethodTraitItem(ref method) => method.vis,
@@ -345,12 +349,12 @@ impl ImplOrTraitItemId {
 
 #[derive(Clone, Debug)]
 pub struct Method<'tcx> {
-    pub name: ast::Name,
+    pub name: Name,
     pub generics: Generics<'tcx>,
     pub predicates: GenericPredicates<'tcx>,
     pub fty: BareFnTy<'tcx>,
     pub explicit_self: ExplicitSelfCategory,
-    pub vis: ast::Visibility,
+    pub vis: hir::Visibility,
     pub def_id: DefId,
     pub container: ImplOrTraitItemContainer,
 
@@ -359,12 +363,12 @@ pub struct Method<'tcx> {
 }
 
 impl<'tcx> Method<'tcx> {
-    pub fn new(name: ast::Name,
+    pub fn new(name: Name,
                generics: ty::Generics<'tcx>,
                predicates: GenericPredicates<'tcx>,
                fty: BareFnTy<'tcx>,
                explicit_self: ExplicitSelfCategory,
-               vis: ast::Visibility,
+               vis: hir::Visibility,
                def_id: DefId,
                container: ImplOrTraitItemContainer,
                provided_source: Option<DefId>)
@@ -392,9 +396,9 @@ impl<'tcx> Method<'tcx> {
 
 #[derive(Clone, Copy, Debug)]
 pub struct AssociatedConst<'tcx> {
-    pub name: ast::Name,
+    pub name: Name,
     pub ty: Ty<'tcx>,
-    pub vis: ast::Visibility,
+    pub vis: hir::Visibility,
     pub def_id: DefId,
     pub container: ImplOrTraitItemContainer,
     pub default: Option<DefId>,
@@ -402,9 +406,9 @@ pub struct AssociatedConst<'tcx> {
 
 #[derive(Clone, Copy, Debug)]
 pub struct AssociatedType<'tcx> {
-    pub name: ast::Name,
+    pub name: Name,
     pub ty: Option<Ty<'tcx>>,
-    pub vis: ast::Visibility,
+    pub vis: hir::Visibility,
     pub def_id: DefId,
     pub container: ImplOrTraitItemContainer,
 }
@@ -412,9 +416,10 @@ pub struct AssociatedType<'tcx> {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub struct TypeAndMut<'tcx> {
     pub ty: Ty<'tcx>,
-    pub mutbl: ast::Mutability,
+    pub mutbl: hir::Mutability,
 }
 
+
 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
 pub struct ItemVariances {
     pub types: VecPerParamSpace<Variance>,
@@ -526,11 +531,11 @@ pub struct AutoDerefRef<'tcx> {
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum AutoRef<'tcx> {
     /// Convert from T to &T.
-    AutoPtr(&'tcx Region, ast::Mutability),
+    AutoPtr(&'tcx Region, hir::Mutability),
 
     /// Convert from T to *T.
     /// Value to thin pointer.
-    AutoUnsafe(ast::Mutability),
+    AutoUnsafe(hir::Mutability),
 }
 
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
@@ -561,19 +566,19 @@ pub struct MethodCallee<'tcx> {
 /// our key.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub struct MethodCall {
-    pub expr_id: ast::NodeId,
+    pub expr_id: NodeId,
     pub autoderef: u32
 }
 
 impl MethodCall {
-    pub fn expr(id: ast::NodeId) -> MethodCall {
+    pub fn expr(id: NodeId) -> MethodCall {
         MethodCall {
             expr_id: id,
             autoderef: 0
         }
     }
 
-    pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
+    pub fn autoderef(expr_id: NodeId, autoderef: u32) -> MethodCall {
         MethodCall {
             expr_id: expr_id,
             autoderef: 1 + autoderef
@@ -622,7 +627,7 @@ pub struct TransmuteRestriction<'tcx> {
     pub substituted_to: Ty<'tcx>,
 
     /// NodeId of the transmute intrinsic.
-    pub id: ast::NodeId,
+    pub id: NodeId,
 }
 
 /// Internal storage
@@ -828,11 +833,11 @@ pub struct ctxt<'tcx> {
     pub populated_external_primitive_impls: RefCell<DefIdSet>,
 
     /// These caches are used by const_eval when decoding external constants.
-    pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
-    pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
-    pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
+    pub extern_const_statics: RefCell<DefIdMap<NodeId>>,
+    pub extern_const_variants: RefCell<DefIdMap<NodeId>>,
+    pub extern_const_fns: RefCell<DefIdMap<NodeId>>,
 
-    pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
+    pub node_lint_levels: RefCell<FnvHashMap<(NodeId, lint::LintId),
                                               lint::LevelSource>>,
 
     /// The types that must be asserted to be the same size for `transmute`
@@ -1367,14 +1372,14 @@ impl<'tcx> Borrow<TypeVariants<'tcx>> for InternedTy<'tcx> {
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct BareFnTy<'tcx> {
-    pub unsafety: ast::Unsafety,
+    pub unsafety: hir::Unsafety,
     pub abi: abi::Abi,
     pub sig: PolyFnSig<'tcx>,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash)]
 pub struct ClosureTy<'tcx> {
-    pub unsafety: ast::Unsafety,
+    pub unsafety: hir::Unsafety,
     pub abi: abi::Abi,
     pub sig: PolyFnSig<'tcx>,
 }
@@ -1447,7 +1452,7 @@ impl<'tcx> PolyFnSig<'tcx> {
 pub struct ParamTy {
     pub space: subst::ParamSpace,
     pub idx: u32,
-    pub name: ast::Name,
+    pub name: Name,
 }
 
 /// A [De Bruijn index][dbi] is a standard means of representing
@@ -1595,10 +1600,10 @@ pub enum Region {
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
 pub struct EarlyBoundRegion {
-    pub param_id: ast::NodeId,
+    pub param_id: NodeId,
     pub space: subst::ParamSpace,
     pub index: u32,
-    pub name: ast::Name,
+    pub name: Name,
 }
 
 /// Upvars do not get their own node-id. Instead, we use the pair of
@@ -1606,8 +1611,8 @@ pub struct EarlyBoundRegion {
 /// by the upvar) and the id of the closure expression.
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 pub struct UpvarId {
-    pub var_id: ast::NodeId,
-    pub closure_expr_id: ast::NodeId,
+    pub var_id: NodeId,
+    pub closure_expr_id: NodeId,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
@@ -1742,7 +1747,7 @@ pub enum BoundRegion {
     ///
     /// The def-id is needed to distinguish free regions in
     /// the event of shadowing.
-    BrNamed(DefId, ast::Name),
+    BrNamed(DefId, Name),
 
     /// Fresh bound identifiers created during GLB computations.
     BrFresh(u32),
@@ -1764,13 +1769,13 @@ pub enum TypeVariants<'tcx> {
     TyChar,
 
     /// A primitive signed integer type. For example, `i32`.
-    TyInt(ast::IntTy),
+    TyInt(hir::IntTy),
 
     /// A primitive unsigned integer type. For example, `u32`.
-    TyUint(ast::UintTy),
+    TyUint(hir::UintTy),
 
     /// A primitive floating-point type. For example, `f64`.
-    TyFloat(ast::FloatTy),
+    TyFloat(hir::FloatTy),
 
     /// An enumerated type, defined with `enum`.
     ///
@@ -1778,7 +1783,7 @@ pub enum TypeVariants<'tcx> {
     /// That is, even after substitution it is possible that there are type
     /// variables. This happens when the `TyEnum` corresponds to an enum
     /// definition and not a concrete use of it. To get the correct `TyEnum`
-    /// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
+    /// from the tcx, use the `NodeId` from the `hir::Ty` and look it up in
     /// the `ast_ty_to_ty_cache`. This is probably true for `TyStruct` as
     /// well.
     TyEnum(AdtDef<'tcx>, &'tcx Substs<'tcx>),
@@ -2084,8 +2089,8 @@ impl<T> Binder<T> {
 
 #[derive(Clone, Copy, PartialEq)]
 pub enum IntVarValue {
-    IntType(ast::IntTy),
-    UintType(ast::UintTy),
+    IntType(hir::IntTy),
+    UintType(hir::UintTy),
 }
 
 #[derive(Clone, Copy, Debug)]
@@ -2098,7 +2103,7 @@ pub struct ExpectedFound<T> {
 #[derive(Clone, Debug)]
 pub enum TypeError<'tcx> {
     Mismatch,
-    UnsafetyMismatch(ExpectedFound<ast::Unsafety>),
+    UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
     AbiMismatch(ExpectedFound<abi::Abi>),
     Mutability,
     BoxMutability,
@@ -2117,13 +2122,13 @@ pub enum TypeError<'tcx> {
     Sorts(ExpectedFound<Ty<'tcx>>),
     IntegerAsChar,
     IntMismatch(ExpectedFound<IntVarValue>),
-    FloatMismatch(ExpectedFound<ast::FloatTy>),
+    FloatMismatch(ExpectedFound<hir::FloatTy>),
     Traits(ExpectedFound<DefId>),
     BuiltinBoundsMismatch(ExpectedFound<BuiltinBounds>),
     VariadicMismatch(ExpectedFound<bool>),
     CyclicTy,
     ConvergenceMismatch(ExpectedFound<bool>),
-    ProjectionNameMismatched(ExpectedFound<ast::Name>),
+    ProjectionNameMismatched(ExpectedFound<Name>),
     ProjectionBoundsLength(ExpectedFound<usize>),
     TyParamDefaultMismatch(ExpectedFound<type_variable::Default<'tcx>>)
 }
@@ -2316,7 +2321,7 @@ pub enum ObjectLifetimeDefault {
 
 #[derive(Clone)]
 pub struct TypeParameterDef<'tcx> {
-    pub name: ast::Name,
+    pub name: Name,
     pub def_id: DefId,
     pub space: subst::ParamSpace,
     pub index: u32,
@@ -2327,7 +2332,7 @@ pub struct TypeParameterDef<'tcx> {
 
 #[derive(Clone)]
 pub struct RegionParameterDef {
-    pub name: ast::Name,
+    pub name: Name,
     pub def_id: DefId,
     pub space: subst::ParamSpace,
     pub index: u32,
@@ -2349,7 +2354,7 @@ impl RegionParameterDef {
 }
 
 /// Information about the formal type/lifetime parameters associated
-/// with an item or method. Analogous to ast::Generics.
+/// with an item or method. Analogous to hir::Generics.
 #[derive(Clone, Debug)]
 pub struct Generics<'tcx> {
     pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
@@ -2583,11 +2588,11 @@ pub struct ProjectionPredicate<'tcx> {
 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
 
 impl<'tcx> PolyProjectionPredicate<'tcx> {
-    pub fn item_name(&self) -> ast::Name {
+    pub fn item_name(&self) -> Name {
         self.0.projection_ty.item_name // safe to skip the binder to access a name
     }
 
-    pub fn sort_key(&self) -> (DefId, ast::Name) {
+    pub fn sort_key(&self) -> (DefId, Name) {
         self.0.projection_ty.sort_key()
     }
 }
@@ -2600,11 +2605,11 @@ pub struct ProjectionTy<'tcx> {
     pub trait_ref: ty::TraitRef<'tcx>,
 
     /// The name `N` of the associated type.
-    pub item_name: ast::Name,
+    pub item_name: Name,
 }
 
 impl<'tcx> ProjectionTy<'tcx> {
-    pub fn sort_key(&self) -> (DefId, ast::Name) {
+    pub fn sort_key(&self) -> (DefId, Name) {
         (self.trait_ref.def_id, self.item_name)
     }
 }
@@ -2873,7 +2878,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
         match cx.map.find(id) {
             Some(ast_map::NodeImplItem(ref impl_item)) => {
                 match impl_item.node {
-                    ast::TypeImplItem(_) => {
+                    hir::TypeImplItem(_) => {
                         // associated types don't have their own entry (for some reason),
                         // so for now just grab environment for the impl
                         let impl_id = cx.map.get_parent(id);
@@ -2885,7 +2890,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                                            &predicates,
                                                            id)
                     }
-                    ast::ConstImplItem(_, _) => {
+                    hir::ConstImplItem(_, _) => {
                         let def_id = DefId::local(id);
                         let scheme = cx.lookup_item_type(def_id);
                         let predicates = cx.lookup_predicates(def_id);
@@ -2894,7 +2899,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                                            &predicates,
                                                            id)
                     }
-                    ast::MethodImplItem(_, ref body) => {
+                    hir::MethodImplItem(_, ref body) => {
                         let method_def_id = DefId::local(id);
                         match cx.impl_or_trait_item(method_def_id) {
                             MethodTraitItem(ref method_ty) => {
@@ -2913,12 +2918,11 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                             }
                         }
                     }
-                    ast::MacImplItem(_) => cx.sess.bug("unexpanded macro")
                 }
             }
             Some(ast_map::NodeTraitItem(trait_item)) => {
                 match trait_item.node {
-                    ast::TypeTraitItem(..) => {
+                    hir::TypeTraitItem(..) => {
                         // associated types don't have their own entry (for some reason),
                         // so for now just grab environment for the trait
                         let trait_id = cx.map.get_parent(id);
@@ -2930,7 +2934,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                                            &predicates,
                                                            id)
                     }
-                    ast::ConstTraitItem(..) => {
+                    hir::ConstTraitItem(..) => {
                         let def_id = DefId::local(id);
                         let scheme = cx.lookup_item_type(def_id);
                         let predicates = cx.lookup_predicates(def_id);
@@ -2939,12 +2943,13 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                                            &predicates,
                                                            id)
                     }
-                    ast::MethodTraitItem(_, ref body) => {
+                    hir::MethodTraitItem(_, ref body) => {
                         // for the body-id, use the id of the body
                         // block, unless this is a trait method with
                         // no default, then fallback to the method id.
                         let body_id = body.as_ref().map(|b| b.id).unwrap_or(id);
                         let method_def_id = DefId::local(id);
+
                         match cx.impl_or_trait_item(method_def_id) {
                             MethodTraitItem(ref method_ty) => {
                                 let method_generics = &method_ty.generics;
@@ -2967,7 +2972,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
             }
             Some(ast_map::NodeItem(item)) => {
                 match item.node {
-                    ast::ItemFn(_, _, _, _, _, ref body) => {
+                    hir::ItemFn(_, _, _, _, _, ref body) => {
                         // We assume this is a function.
                         let fn_def_id = DefId::local(id);
                         let fn_scheme = cx.lookup_item_type(fn_def_id);
@@ -2978,11 +2983,11 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                                            &fn_predicates,
                                                            body.id)
                     }
-                    ast::ItemEnum(..) |
-                    ast::ItemStruct(..) |
-                    ast::ItemImpl(..) |
-                    ast::ItemConst(..) |
-                    ast::ItemStatic(..) => {
+                    hir::ItemEnum(..) |
+                    hir::ItemStruct(..) |
+                    hir::ItemImpl(..) |
+                    hir::ItemConst(..) |
+                    hir::ItemStatic(..) => {
                         let def_id = DefId::local(id);
                         let scheme = cx.lookup_item_type(def_id);
                         let predicates = cx.lookup_predicates(def_id);
@@ -2991,7 +2996,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                                            &predicates,
                                                            id)
                     }
-                    ast::ItemTrait(..) => {
+                    hir::ItemTrait(..) => {
                         let def_id = DefId::local(id);
                         let trait_def = cx.lookup_trait_def(def_id);
                         let predicates = cx.lookup_predicates(def_id);
@@ -3061,8 +3066,8 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
 
 #[derive(Copy, Clone)]
 pub enum CopyImplementationError {
-    FieldDoesNotImplementCopy(ast::Name),
-    VariantDoesNotImplementCopy(ast::Name),
+    FieldDoesNotImplementCopy(Name),
+    VariantDoesNotImplementCopy(Name),
     TypeIsStructural,
     TypeHasDestructor,
 }
@@ -3104,7 +3109,7 @@ bitflags! {
 
 /// As `TypeScheme` but for a trait ref.
 pub struct TraitDef<'tcx> {
-    pub unsafety: ast::Unsafety,
+    pub unsafety: hir::Unsafety,
 
     /// If `true`, then this trait had the `#[rustc_paren_sugar]`
     /// attribute, indicating that it should be used with `Foo()`
@@ -3123,7 +3128,7 @@ pub struct TraitDef<'tcx> {
 
     /// A list of the associated types defined in this trait. Useful
     /// for resolving `X::Foo` type markers.
-    pub associated_type_names: Vec<ast::Name>,
+    pub associated_type_names: Vec<Name>,
 
     // Impls of this trait. To allow for quicker lookup, the impls are indexed
     // by a simplified version of their Self type: impls with a simplifiable
@@ -3283,7 +3288,7 @@ pub struct FieldDefData<'tcx, 'container: 'tcx> {
     /// special_idents::unnamed_field.name
     /// if this is a tuple-like field
     pub name: Name,
-    pub vis: ast::Visibility,
+    pub vis: hir::Visibility,
     /// TyIVar is used here to allow for variance (see the doc at
     /// AdtDefData).
     ty: TyIVar<'tcx, 'container>
@@ -3532,7 +3537,7 @@ impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
 impl<'tcx, 'container> FieldDefData<'tcx, 'container> {
     pub fn new(did: DefId,
                name: Name,
-               vis: ast::Visibility) -> Self {
+               vis: hir::Visibility) -> Self {
         FieldDefData {
             did: did,
             name: name,
@@ -3613,18 +3618,18 @@ impl<'tcx> CommonTypes<'tcx> {
             bool: mk(TyBool),
             char: mk(TyChar),
             err: mk(TyError),
-            isize: mk(TyInt(ast::TyIs)),
-            i8: mk(TyInt(ast::TyI8)),
-            i16: mk(TyInt(ast::TyI16)),
-            i32: mk(TyInt(ast::TyI32)),
-            i64: mk(TyInt(ast::TyI64)),
-            usize: mk(TyUint(ast::TyUs)),
-            u8: mk(TyUint(ast::TyU8)),
-            u16: mk(TyUint(ast::TyU16)),
-            u32: mk(TyUint(ast::TyU32)),
-            u64: mk(TyUint(ast::TyU64)),
-            f32: mk(TyFloat(ast::TyF32)),
-            f64: mk(TyFloat(ast::TyF64)),
+            isize: mk(TyInt(hir::TyIs)),
+            i8: mk(TyInt(hir::TyI8)),
+            i16: mk(TyInt(hir::TyI16)),
+            i32: mk(TyInt(hir::TyI32)),
+            i64: mk(TyInt(hir::TyI64)),
+            usize: mk(TyUint(hir::TyUs)),
+            u8: mk(TyUint(hir::TyU8)),
+            u16: mk(TyUint(hir::TyU16)),
+            u32: mk(TyUint(hir::TyU32)),
+            u64: mk(TyUint(hir::TyU64)),
+            f32: mk(TyFloat(hir::TyF32)),
+            f64: mk(TyFloat(hir::TyF64)),
         }
     }
 }
@@ -3913,9 +3918,9 @@ impl<'tcx> ctxt<'tcx> {
 
     /// Create an unsafe fn ty based on a safe fn ty.
     pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
-        assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal);
+        assert_eq!(bare_fn.unsafety, hir::Unsafety::Normal);
         let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
-            unsafety: ast::Unsafety::Unsafe,
+            unsafety: hir::Unsafety::Unsafe,
             abi: bare_fn.abi,
             sig: bare_fn.sig.clone()
         });
@@ -3955,17 +3960,17 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     pub fn type_parameter_def(&self,
-                              node_id: ast::NodeId)
+                              node_id: NodeId)
                               -> TypeParameterDef<'tcx>
     {
         self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
     }
 
-    pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option<ast::Mutability> {
+    pub fn pat_contains_ref_binding(&self, pat: &hir::Pat) -> Option<hir::Mutability> {
         pat_util::pat_contains_ref_binding(&self.def_map, pat)
     }
 
-    pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option<ast::Mutability> {
+    pub fn arm_contains_ref_binding(&self, arm: &hir::Arm) -> Option<hir::Mutability> {
         pat_util::arm_contains_ref_binding(&self.def_map, arm)
     }
 
@@ -4003,30 +4008,30 @@ impl<'tcx> ctxt<'tcx> {
         ctxt::intern_ty(&self.arenas.type_, &self.interner, st)
     }
 
-    pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> {
+    pub fn mk_mach_int(&self, tm: hir::IntTy) -> Ty<'tcx> {
         match tm {
-            ast::TyIs   => self.types.isize,
-            ast::TyI8   => self.types.i8,
-            ast::TyI16  => self.types.i16,
-            ast::TyI32  => self.types.i32,
-            ast::TyI64  => self.types.i64,
+            hir::TyIs   => self.types.isize,
+            hir::TyI8   => self.types.i8,
+            hir::TyI16  => self.types.i16,
+            hir::TyI32  => self.types.i32,
+            hir::TyI64  => self.types.i64,
         }
     }
 
-    pub fn mk_mach_uint(&self, tm: ast::UintTy) -> Ty<'tcx> {
+    pub fn mk_mach_uint(&self, tm: hir::UintTy) -> Ty<'tcx> {
         match tm {
-            ast::TyUs   => self.types.usize,
-            ast::TyU8   => self.types.u8,
-            ast::TyU16  => self.types.u16,
-            ast::TyU32  => self.types.u32,
-            ast::TyU64  => self.types.u64,
+            hir::TyUs   => self.types.usize,
+            hir::TyU8   => self.types.u8,
+            hir::TyU16  => self.types.u16,
+            hir::TyU32  => self.types.u32,
+            hir::TyU64  => self.types.u64,
         }
     }
 
-    pub fn mk_mach_float(&self, tm: ast::FloatTy) -> Ty<'tcx> {
+    pub fn mk_mach_float(&self, tm: hir::FloatTy) -> Ty<'tcx> {
         match tm {
-            ast::TyF32  => self.types.f32,
-            ast::TyF64  => self.types.f64,
+            hir::TyF32  => self.types.f32,
+            hir::TyF64  => self.types.f64,
         }
     }
 
@@ -4056,19 +4061,19 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     pub fn mk_mut_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: ast::MutMutable})
+        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
     }
 
     pub fn mk_imm_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: ast::MutImmutable})
+        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
     }
 
     pub fn mk_mut_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut {ty: ty, mutbl: ast::MutMutable})
+        self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable})
     }
 
     pub fn mk_imm_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut {ty: ty, mutbl: ast::MutImmutable})
+        self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
     }
 
     pub fn mk_nil_ptr(&self) -> Ty<'tcx> {
@@ -4107,7 +4112,7 @@ impl<'tcx> ctxt<'tcx> {
                       output: Ty<'tcx>) -> Ty<'tcx> {
         let input_args = input_tys.iter().cloned().collect();
         self.mk_fn(Some(def_id), self.mk_bare_fn(BareFnTy {
-            unsafety: ast::Unsafety::Normal,
+            unsafety: hir::Unsafety::Normal,
             abi: abi::Rust,
             sig: ty::Binder(FnSig {
                 inputs: input_args,
@@ -4133,7 +4138,7 @@ impl<'tcx> ctxt<'tcx> {
 
     pub fn mk_projection(&self,
                          trait_ref: TraitRef<'tcx>,
-                         item_name: ast::Name)
+                         item_name: Name)
                          -> Ty<'tcx> {
         // take a copy of substs so that we own the vectors inside
         let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name };
@@ -4182,7 +4187,7 @@ impl<'tcx> ctxt<'tcx> {
     pub fn mk_param(&self,
                     space: subst::ParamSpace,
                     index: u32,
-                    name: ast::Name) -> Ty<'tcx> {
+                    name: Name) -> Ty<'tcx> {
         self.mk_ty(TyParam(ParamTy { space: space, idx: index, name: name }))
     }
 
@@ -4304,7 +4309,7 @@ impl<'tcx> TyS<'tcx> {
 impl ParamTy {
     pub fn new(space: subst::ParamSpace,
                index: u32,
-               name: ast::Name)
+               name: Name)
                -> ParamTy {
         ParamTy { space: space, idx: index, name: name }
     }
@@ -4398,7 +4403,7 @@ impl<'tcx> TyS<'tcx> {
     pub fn sequence_element_type(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
         match self.sty {
             TyArray(ty, _) | TySlice(ty) => ty,
-            TyStr => cx.mk_mach_uint(ast::TyU8),
+            TyStr => cx.mk_mach_uint(hir::TyU8),
             _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}",
                                       self)),
         }
@@ -4646,7 +4651,7 @@ impl<'tcx> TyS<'tcx> {
 
             let result = match ty.sty {
                 // usize and isize are ffi-unsafe
-                TyUint(ast::TyUs) | TyInt(ast::TyIs) => {
+                TyUint(hir::TyUs) | TyInt(hir::TyIs) => {
                     TC::None
                 }
 
@@ -4761,11 +4766,11 @@ impl<'tcx> TyS<'tcx> {
         let result = match self.sty {
             TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
             TyRawPtr(..) | TyBareFn(..) | TyRef(_, TypeAndMut {
-                mutbl: ast::MutImmutable, ..
+                mutbl: hir::MutImmutable, ..
             }) => Some(false),
 
             TyStr | TyBox(..) | TyRef(_, TypeAndMut {
-                mutbl: ast::MutMutable, ..
+                mutbl: hir::MutMutable, ..
             }) => Some(true),
 
             TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
@@ -5012,7 +5017,7 @@ impl<'tcx> TyS<'tcx> {
 
     pub fn is_uint(&self) -> bool {
         match self.sty {
-            TyInfer(IntVar(_)) | TyUint(ast::TyUs) => true,
+            TyInfer(IntVar(_)) | TyUint(hir::TyUs) => true,
             _ => false
         }
     }
@@ -5058,7 +5063,7 @@ impl<'tcx> TyS<'tcx> {
 
     pub fn is_machine(&self) -> bool {
         match self.sty {
-            TyInt(ast::TyIs) | TyUint(ast::TyUs) => false,
+            TyInt(hir::TyIs) | TyUint(hir::TyUs) => false,
             TyInt(..) | TyUint(..) | TyFloat(..) => true,
             _ => false
         }
@@ -5073,7 +5078,7 @@ impl<'tcx> TyS<'tcx> {
             TyBox(ty) => {
                 Some(TypeAndMut {
                     ty: ty,
-                    mutbl: ast::MutImmutable,
+                    mutbl: hir::MutImmutable,
                 })
             },
             TyRef(_, mt) => Some(mt),
@@ -5124,7 +5129,7 @@ impl<'tcx> TyS<'tcx> {
     /// See `expr_ty_adjusted`
     pub fn adjust<F>(&'tcx self, cx: &ctxt<'tcx>,
                      span: Span,
-                     expr_id: ast::NodeId,
+                     expr_id: NodeId,
                      adjustment: Option<&AutoAdjustment<'tcx>>,
                      mut method_type: F)
                      -> Ty<'tcx> where
@@ -5423,10 +5428,10 @@ fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
 }
 
 impl BorrowKind {
-    pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
+    pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
         match m {
-            ast::MutMutable => MutBorrow,
-            ast::MutImmutable => ImmBorrow,
+            hir::MutMutable => MutBorrow,
+            hir::MutImmutable => ImmBorrow,
         }
     }
 
@@ -5434,15 +5439,15 @@ impl BorrowKind {
     /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
     /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
     /// question.
-    pub fn to_mutbl_lossy(self) -> ast::Mutability {
+    pub fn to_mutbl_lossy(self) -> hir::Mutability {
         match self {
-            MutBorrow => ast::MutMutable,
-            ImmBorrow => ast::MutImmutable,
+            MutBorrow => hir::MutMutable,
+            ImmBorrow => hir::MutImmutable,
 
             // We have no type corresponding to a unique imm borrow, so
             // use `&mut`. It gives all the capabilities of an `&uniq`
             // and hence is a safe "over approximation".
-            UniqueImmBorrow => ast::MutMutable,
+            UniqueImmBorrow => hir::MutMutable,
         }
     }
 
@@ -5482,7 +5487,7 @@ impl<'tcx> ctxt<'tcx> {
     /// For an enum `t`, `variant` must be some def id.
     pub fn named_element_ty(&self,
                             ty: Ty<'tcx>,
-                            n: ast::Name,
+                            n: Name,
                             variant: Option<DefId>) -> Option<Ty<'tcx>> {
         match (&ty.sty, variant) {
             (&TyStruct(def, substs), None) => {
@@ -5495,7 +5500,7 @@ impl<'tcx> ctxt<'tcx> {
         }
     }
 
-    pub fn node_id_to_type(&self, id: ast::NodeId) -> Ty<'tcx> {
+    pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> {
         match self.node_id_to_type_opt(id) {
            Some(ty) => ty,
            None => self.sess.bug(
@@ -5504,11 +5509,11 @@ impl<'tcx> ctxt<'tcx> {
         }
     }
 
-    pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option<Ty<'tcx>> {
+    pub fn node_id_to_type_opt(&self, id: NodeId) -> Option<Ty<'tcx>> {
         self.tables.borrow().node_types.get(&id).cloned()
     }
 
-    pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> {
+    pub fn node_id_item_substs(&self, id: NodeId) -> ItemSubsts<'tcx> {
         match self.tables.borrow().item_substs.get(&id) {
             None => ItemSubsts::empty(),
             Some(ts) => ts.clone(),
@@ -5517,10 +5522,10 @@ impl<'tcx> ctxt<'tcx> {
 
     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
     // doesn't provide type parameter substitutions.
-    pub fn pat_ty(&self, pat: &ast::Pat) -> Ty<'tcx> {
+    pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
         self.node_id_to_type(pat.id)
     }
-    pub fn pat_ty_opt(&self, pat: &ast::Pat) -> Option<Ty<'tcx>> {
+    pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
         self.node_id_to_type_opt(pat.id)
     }
 
@@ -5534,11 +5539,11 @@ impl<'tcx> ctxt<'tcx> {
     // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
     // instead of "fn(ty) -> T with T = isize".
-    pub fn expr_ty(&self, expr: &ast::Expr) -> Ty<'tcx> {
+    pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
         self.node_id_to_type(expr.id)
     }
 
-    pub fn expr_ty_opt(&self, expr: &ast::Expr) -> Option<Ty<'tcx>> {
+    pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
         self.node_id_to_type_opt(expr.id)
     }
 
@@ -5551,7 +5556,7 @@ impl<'tcx> ctxt<'tcx> {
     /// hard to do, I just hate that code so much I didn't want to touch it
     /// unless it was to fix it properly, which seemed a distraction from the
     /// thread at hand! -nmatsakis
-    pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
+    pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
         self.expr_ty(expr)
             .adjust(self, expr.span, expr.id,
                     self.tables.borrow().adjustments.get(&expr.id),
@@ -5580,7 +5585,7 @@ impl<'tcx> ctxt<'tcx> {
         match self.map.find(id) {
             Some(ast_map::NodeLocal(pat)) => {
                 match pat.node {
-                    ast::PatIdent(_, ref path1, _) => path1.node.name.as_str(),
+                    hir::PatIdent(_, ref path1, _) => path1.node.name.as_str(),
                     _ => {
                         self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, pat));
                     },
@@ -5590,7 +5595,7 @@ impl<'tcx> ctxt<'tcx> {
         }
     }
 
-    pub fn resolve_expr(&self, expr: &ast::Expr) -> def::Def {
+    pub fn resolve_expr(&self, expr: &hir::Expr) -> def::Def {
         match self.def_map.borrow().get(&expr.id) {
             Some(def) => def.full_def(),
             None => {
@@ -5600,9 +5605,9 @@ impl<'tcx> ctxt<'tcx> {
         }
     }
 
-    pub fn expr_is_lval(&self, expr: &ast::Expr) -> bool {
+    pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
          match expr.node {
-            ast::ExprPath(..) => {
+            hir::ExprPath(..) => {
                 // We can't use resolve_expr here, as this needs to run on broken
                 // programs. We don't need to through - associated items are all
                 // rvalues.
@@ -5624,51 +5629,42 @@ impl<'tcx> ctxt<'tcx> {
                 }
             }
 
-            ast::ExprUnary(ast::UnDeref, _) |
-            ast::ExprField(..) |
-            ast::ExprTupField(..) |
-            ast::ExprIndex(..) => {
+            hir::ExprUnary(hir::UnDeref, _) |
+            hir::ExprField(..) |
+            hir::ExprTupField(..) |
+            hir::ExprIndex(..) => {
                 true
             }
 
-            ast::ExprCall(..) |
-            ast::ExprMethodCall(..) |
-            ast::ExprStruct(..) |
-            ast::ExprRange(..) |
-            ast::ExprTup(..) |
-            ast::ExprIf(..) |
-            ast::ExprMatch(..) |
-            ast::ExprClosure(..) |
-            ast::ExprBlock(..) |
-            ast::ExprRepeat(..) |
-            ast::ExprVec(..) |
-            ast::ExprBreak(..) |
-            ast::ExprAgain(..) |
-            ast::ExprRet(..) |
-            ast::ExprWhile(..) |
-            ast::ExprLoop(..) |
-            ast::ExprAssign(..) |
-            ast::ExprInlineAsm(..) |
-            ast::ExprAssignOp(..) |
-            ast::ExprLit(_) |
-            ast::ExprUnary(..) |
-            ast::ExprBox(..) |
-            ast::ExprAddrOf(..) |
-            ast::ExprBinary(..) |
-            ast::ExprCast(..) => {
+            hir::ExprCall(..) |
+            hir::ExprMethodCall(..) |
+            hir::ExprStruct(..) |
+            hir::ExprRange(..) |
+            hir::ExprTup(..) |
+            hir::ExprIf(..) |
+            hir::ExprMatch(..) |
+            hir::ExprClosure(..) |
+            hir::ExprBlock(..) |
+            hir::ExprRepeat(..) |
+            hir::ExprVec(..) |
+            hir::ExprBreak(..) |
+            hir::ExprAgain(..) |
+            hir::ExprRet(..) |
+            hir::ExprWhile(..) |
+            hir::ExprLoop(..) |
+            hir::ExprAssign(..) |
+            hir::ExprInlineAsm(..) |
+            hir::ExprAssignOp(..) |
+            hir::ExprLit(_) |
+            hir::ExprUnary(..) |
+            hir::ExprBox(..) |
+            hir::ExprAddrOf(..) |
+            hir::ExprBinary(..) |
+            hir::ExprCast(..) => {
                 false
             }
 
-            ast::ExprParen(ref e) => self.expr_is_lval(e),
-
-            ast::ExprIfLet(..) |
-            ast::ExprWhileLet(..) |
-            ast::ExprForLoop(..) |
-            ast::ExprMac(..) => {
-                self.sess.span_bug(
-                    expr.span,
-                    "macro expression remains after expansion");
-            }
+            hir::ExprParen(ref e) => self.expr_is_lval(e),
         }
     }
 
@@ -5768,7 +5764,7 @@ impl<'tcx> ctxt<'tcx> {
         if id.is_local() {
             if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
                 ms.iter().filter_map(|ti| {
-                    if let ast::MethodTraitItem(_, Some(_)) = ti.node {
+                    if let hir::MethodTraitItem(_, Some(_)) = ti.node {
                         match self.impl_or_trait_item(DefId::local(ti.id)) {
                             MethodTraitItem(m) => Some(m),
                             _ => {
@@ -5794,7 +5790,7 @@ impl<'tcx> ctxt<'tcx> {
             match self.map.expect_item(id.node).node {
                 ItemTrait(_, _, _, ref tis) => {
                     tis.iter().filter_map(|ti| {
-                        if let ast::ConstTraitItem(_, _) = ti.node {
+                        if let hir::ConstTraitItem(_, _) = ti.node {
                             match self.impl_or_trait_item(DefId::local(ti.id)) {
                                 ConstTraitItem(ac) => Some(ac),
                                 _ => {
@@ -5810,7 +5806,7 @@ impl<'tcx> ctxt<'tcx> {
                 }
                 ItemImpl(_, _, _, _, _, ref iis) => {
                     iis.iter().filter_map(|ii| {
-                        if let ast::ConstImplItem(_, _) = ii.node {
+                        if let hir::ConstImplItem(_, _) = ii.node {
                             match self.impl_or_trait_item(DefId::local(ii.id)) {
                                 ConstTraitItem(ac) => Some(ac),
                                 _ => {
@@ -5850,12 +5846,12 @@ impl<'tcx> ctxt<'tcx> {
         }
     }
 
-    pub fn trait_impl_polarity(&self, id: DefId) -> Option<ast::ImplPolarity> {
+    pub fn trait_impl_polarity(&self, id: DefId) -> Option<hir::ImplPolarity> {
         if id.is_local() {
             match self.map.find(id.node) {
                 Some(ast_map::NodeItem(item)) => {
                     match item.node {
-                        ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
+                        hir::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
                         _ => None
                     }
                 }
@@ -5909,7 +5905,7 @@ impl<'tcx> ctxt<'tcx> {
     pub fn is_impl(&self, id: DefId) -> bool {
         if id.is_local() {
             if let Some(ast_map::NodeItem(
-                &ast::Item { node: ast::ItemImpl(..), .. })) = self.map.find(id.node) {
+                &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id.node) {
                 true
             } else {
                 false
@@ -5919,7 +5915,7 @@ impl<'tcx> ctxt<'tcx> {
         }
     }
 
-    pub fn trait_ref_to_def_id(&self, tr: &ast::TraitRef) -> DefId {
+    pub fn trait_ref_to_def_id(&self, tr: &hir::TraitRef) -> DefId {
         self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
     }
 
@@ -5974,14 +5970,14 @@ impl<'tcx> ctxt<'tcx> {
             //
             // NB. Historically `fn enum_variants` generate i64 here, while
             // rustc_typeck::check would generate isize.
-            _ => SignedInt(ast::TyIs),
+            _ => SignedInt(hir::TyIs),
         };
 
         let repr_type_ty = repr_type.to_ty(self);
         let repr_type = match repr_type {
-            SignedInt(ast::TyIs) =>
+            SignedInt(hir::TyIs) =>
                 SignedInt(self.sess.target.int_type),
-            UnsignedInt(ast::TyUs) =>
+            UnsignedInt(hir::TyUs) =>
                 UnsignedInt(self.sess.target.uint_type),
             other => other
         };
@@ -5989,6 +5985,7 @@ impl<'tcx> ctxt<'tcx> {
         (repr_type, repr_type_ty)
     }
 
+
     // Register a given item type
     pub fn register_item_type(&self, did: DefId, ty: TypeScheme<'tcx>) {
         self.tcache.borrow_mut().insert(did, ty);
@@ -6047,7 +6044,7 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     /// Get the attributes of a definition.
-    pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [ast::Attribute]> {
+    pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [hir::Attribute]> {
         if did.is_local() {
             Cow::Borrowed(self.map.attrs(did.node))
         } else {
@@ -6084,6 +6081,7 @@ impl<'tcx> ctxt<'tcx> {
         })
     }
 
+
     /// Returns the deeply last field of nested structures, or the same type,
     /// if not a structure at all. Corresponds to the only possible unsized
     /// field, and its type can be used to determine unsizing strategy.
@@ -6122,7 +6120,7 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     // Returns the repeat count for a repeating vector expression.
-    pub fn eval_repeat_count(&self, count_expr: &ast::Expr) -> usize {
+    pub fn eval_repeat_count(&self, count_expr: &hir::Expr) -> usize {
         let hint = UncheckedExprHint(self.types.usize);
         match const_eval::eval_const_expr_partial(self, count_expr, hint) {
             Ok(val) => {
@@ -6137,7 +6135,7 @@ impl<'tcx> ctxt<'tcx> {
             }
             Err(err) => {
                 let err_msg = match count_expr.node {
-                    ast::ExprPath(None, ast::Path {
+                    hir::ExprPath(None, hir::Path {
                         global: false,
                         ref segments,
                         ..
@@ -6580,7 +6578,7 @@ impl<'tcx> ctxt<'tcx> {
     /// free parameters. Since we currently represent bound/free type
     /// parameters in the same way, this only has an effect on regions.
     pub fn construct_free_substs(&self, generics: &Generics<'tcx>,
-                                 free_id: ast::NodeId) -> Substs<'tcx> {
+                                 free_id: NodeId) -> Substs<'tcx> {
         // map T => T
         let mut types = VecPerParamSpace::empty();
         for def in generics.types.as_slice() {
@@ -6612,7 +6610,7 @@ impl<'tcx> ctxt<'tcx> {
                                                span: Span,
                                                generics: &ty::Generics<'tcx>,
                                                generic_predicates: &ty::GenericPredicates<'tcx>,
-                                               free_id: ast::NodeId)
+                                               free_id: NodeId)
                                                -> ParameterEnvironment<'a, 'tcx>
     {
         //
@@ -6662,11 +6660,11 @@ impl<'tcx> ctxt<'tcx> {
         traits::normalize_param_env_or_error(unnormalized_env, cause)
     }
 
-    pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
+    pub fn is_method_call(&self, expr_id: NodeId) -> bool {
         self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
     }
 
-    pub fn is_overloaded_autoderef(&self, expr_id: ast::NodeId, autoderefs: u32) -> bool {
+    pub fn is_overloaded_autoderef(&self, expr_id: NodeId, autoderefs: u32) -> bool {
         self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id,
                                                                             autoderefs))
     }
@@ -6762,7 +6760,7 @@ impl<'tcx> ctxt<'tcx> {
 pub enum ExplicitSelfCategory {
     StaticExplicitSelfCategory,
     ByValueExplicitSelfCategory,
-    ByReferenceExplicitSelfCategory(Region, ast::Mutability),
+    ByReferenceExplicitSelfCategory(Region, hir::Mutability),
     ByBoxExplicitSelfCategory,
 }
 
@@ -6778,7 +6776,7 @@ pub struct Freevar {
 
 pub type FreevarMap = NodeMap<Vec<Freevar>>;
 
-pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
+pub type CaptureModeMap = NodeMap<hir::CaptureClause>;
 
 // Trait method resolution
 pub type TraitMap = NodeMap<Vec<DefId>>;
@@ -6804,7 +6802,7 @@ impl<'tcx> AutoDerefRef<'tcx> {
 }
 
 impl<'tcx> ctxt<'tcx> {
-    pub fn with_freevars<T, F>(&self, fid: ast::NodeId, f: F) -> T where
+    pub fn with_freevars<T, F>(&self, fid: NodeId, f: F) -> T where
         F: FnOnce(&[Freevar]) -> T,
     {
         match self.freevars.borrow().get(&fid) {
@@ -7226,7 +7224,7 @@ impl HasTypeFlags for abi::Abi {
     }
 }
 
-impl HasTypeFlags for ast::Unsafety {
+impl HasTypeFlags for hir::Unsafety {
     fn has_type_flags(&self, _flags: TypeFlags) -> bool {
         false
     }
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 09c50804e83..c6d213583af 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -42,7 +42,7 @@ use middle::traits;
 use std::fmt;
 use std::rc::Rc;
 use syntax::abi;
-use syntax::ast;
+use rustc_front::hir;
 use syntax::owned_slice::OwnedSlice;
 use util::nodemap::{FnvHashMap, FnvHashSet};
 
@@ -165,7 +165,7 @@ macro_rules! CopyImpls {
     }
 }
 
-CopyImpls! { (), ast::Unsafety, abi::Abi }
+CopyImpls! { (), hir::Unsafety, abi::Abi }
 
 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
     fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> (T, U) {
diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs
index 5d9535dc3dd..d2d612ece6f 100644
--- a/src/librustc/middle/ty_relate/mod.rs
+++ b/src/librustc/middle/ty_relate/mod.rs
@@ -19,7 +19,7 @@ use middle::ty::{self, HasTypeFlags, Ty, TypeError};
 use middle::ty_fold::TypeFoldable;
 use std::rc::Rc;
 use syntax::abi;
-use syntax::ast;
+use rustc_front::hir as ast;
 
 pub type RelateResult<'tcx, T> = Result<T, ty::TypeError<'tcx>>;
 
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 32b64f4c606..43b7943fd20 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -15,11 +15,11 @@ use session::Session;
 use metadata::csearch;
 use middle::lang_items;
 
-use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token::InternedString;
-use syntax::visit::Visitor;
-use syntax::visit;
+use rustc_front::visit::Visitor;
+use rustc_front::visit;
+use rustc_front::hir;
 
 use std::collections::HashSet;
 
@@ -33,7 +33,7 @@ struct Context<'a> {
 
 /// Checks the crate for usage of weak lang items, returning a vector of all the
 /// language items required by this crate, but not defined yet.
-pub fn check_crate(krate: &ast::Crate,
+pub fn check_crate(krate: &hir::Crate,
                    sess: &Session,
                    items: &mut lang_items::LanguageItems) {
     // These are never called by user code, they're generated by the compiler.
@@ -54,7 +54,7 @@ pub fn check_crate(krate: &ast::Crate,
     verify(sess, items);
 }
 
-pub fn link_name(attrs: &[ast::Attribute]) -> Option<InternedString> {
+pub fn link_name(attrs: &[hir::Attribute]) -> Option<InternedString> {
     lang_items::extract(attrs).and_then(|name| {
         $(if &name[..] == stringify!($name) {
             Some(InternedString::new(stringify!($sym)))
@@ -108,7 +108,7 @@ impl<'a> Context<'a> {
 }
 
 impl<'a, 'v> Visitor<'v> for Context<'a> {
-    fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
+    fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
         match lang_items::extract(&i.attrs) {
             None => {}
             Some(lang_item) => self.register(&lang_item, i.span),
diff --git a/src/librustc/plugin/build.rs b/src/librustc/plugin/build.rs
index 818af33c34d..55fd63b7534 100644
--- a/src/librustc/plugin/build.rs
+++ b/src/librustc/plugin/build.rs
@@ -11,19 +11,20 @@
 //! Used by `rustc` when compiling a plugin crate.
 
 use syntax::ast;
-use syntax::attr;
 use syntax::codemap::Span;
 use syntax::diagnostic;
-use syntax::visit;
-use syntax::visit::Visitor;
+use rustc_front::visit;
+use rustc_front::visit::Visitor;
+use rustc_front::hir;
+use rustc_front::attr;
 
 struct RegistrarFinder {
     registrars: Vec<(ast::NodeId, Span)> ,
 }
 
 impl<'v> Visitor<'v> for RegistrarFinder {
-    fn visit_item(&mut self, item: &ast::Item) {
-        if let ast::ItemFn(..) = item.node {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if let hir::ItemFn(..) = item.node {
             if attr::contains_name(&item.attrs,
                                    "plugin_registrar") {
                 self.registrars.push((item.id, item.span));
@@ -36,7 +37,8 @@ impl<'v> Visitor<'v> for RegistrarFinder {
 
 /// Find the function marked with `#[plugin_registrar]`, if any.
 pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
-                             krate: &ast::Crate) -> Option<ast::NodeId> {
+                             krate: &hir::Crate)
+                             -> Option<ast::NodeId> {
     let mut finder = RegistrarFinder { registrars: Vec::new() };
     visit::walk_crate(&mut finder, krate);
 
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index f0f824a0218..af9f17f3c6f 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -26,9 +26,10 @@ use lint;
 use metadata::cstore;
 
 use syntax::ast;
-use syntax::ast::{IntTy, UintTy};
+use rustc_front::hir::{IntTy, UintTy};
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
+use rustc_front::hir;
 use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
 use syntax::parse;
 use syntax::parse::token::InternedString;
@@ -664,8 +665,8 @@ pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
     };
 
     let (int_type, uint_type) = match &target.target_pointer_width[..] {
-        "32" => (ast::TyI32, ast::TyU32),
-        "64" => (ast::TyI64, ast::TyU64),
+        "32" => (hir::TyI32, hir::TyU32),
+        "64" => (hir::TyI64, hir::TyU64),
         w    => sp.handler().fatal(&format!("target specification was invalid: unrecognized \
                                              target-pointer-width {}", w))
     };
@@ -824,15 +825,16 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
         opt::flagopt_u("", "pretty",
                    "Pretty-print the input instead of compiling;
                    valid types are: `normal` (un-annotated source),
-                   `expanded` (crates expanded),
-                   `typed` (crates expanded, with type annotations), or
+                   `expanded` (crates expanded), or
                    `expanded,identified` (fully parenthesized, AST nodes with IDs).",
                  "TYPE"),
         opt::flagopt_u("", "unpretty",
                      "Present the input source, unstable (and less-pretty) variants;
                       valid types are any of the types for `--pretty`, as well as:
-                      `flowgraph=<nodeid>` (graphviz formatted flowgraph for node), or
-                      `everybody_loops` (all function bodies replaced with `loop {}`).",
+                      `flowgraph=<nodeid>` (graphviz formatted flowgraph for node),
+                      `everybody_loops` (all function bodies replaced with `loop {}`),
+                      `hir` (the HIR), `hir,identified`, or
+                      `hir,typed` (HIR with types for each node).",
                      "TYPE"),
         opt::opt_u("", "show-span", "Show spans for compiler debugging", "expr|pat|ty"),
     ]);
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 1ad5ae9917d..a6ca6a45f95 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -20,9 +20,9 @@ use std::iter::repeat;
 use std::path::Path;
 use std::time::Duration;
 
-use syntax::ast;
-use syntax::visit;
-use syntax::visit::Visitor;
+use rustc_front::hir;
+use rustc_front::visit;
+use rustc_front::visit::Visitor;
 
 // The name of the associated type for `Fn` return types
 pub const FN_OUTPUT_NAME: &'static str = "Output";
@@ -152,18 +152,18 @@ pub fn indenter() -> Indenter {
     Indenter { _cannot_construct_outside_of_this_module: () }
 }
 
-struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
+struct LoopQueryVisitor<P> where P: FnMut(&hir::Expr_) -> bool {
     p: P,
     flag: bool,
 }
 
-impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
-    fn visit_expr(&mut self, e: &ast::Expr) {
+impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&hir::Expr_) -> bool {
+    fn visit_expr(&mut self, e: &hir::Expr) {
         self.flag |= (self.p)(&e.node);
         match e.node {
           // Skip inner loops, since a break in the inner loop isn't a
           // break inside the outer loop
-          ast::ExprLoop(..) | ast::ExprWhile(..) => {}
+          hir::ExprLoop(..) | hir::ExprWhile(..) => {}
           _ => visit::walk_expr(self, e)
         }
     }
@@ -171,7 +171,7 @@ impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> b
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
+pub fn loop_query<P>(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr_) -> bool {
     let mut v = LoopQueryVisitor {
         p: p,
         flag: false,
@@ -180,13 +180,13 @@ pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -
     return v.flag;
 }
 
-struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
+struct BlockQueryVisitor<P> where P: FnMut(&hir::Expr) -> bool {
     p: P,
     flag: bool,
 }
 
-impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
-    fn visit_expr(&mut self, e: &ast::Expr) {
+impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&hir::Expr) -> bool {
+    fn visit_expr(&mut self, e: &hir::Expr) {
         self.flag |= (self.p)(e);
         visit::walk_expr(self, e)
     }
@@ -194,7 +194,7 @@ impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> b
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
+pub fn block_query<P>(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr) -> bool {
     let mut v = BlockQueryVisitor {
         p: p,
         flag: false,
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 62ece6af4f2..a0701d852bc 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -26,7 +26,8 @@ use middle::ty_fold::{self, TypeFoldable};
 use std::fmt;
 use syntax::abi;
 use syntax::parse::token;
-use syntax::{ast, ast_util};
+use syntax::ast::DUMMY_NODE_ID;
+use rustc_front::hir as ast;
 
 pub fn verbose() -> bool {
     ty::tls::with(|tcx| tcx.sess.verbose())
@@ -230,7 +231,7 @@ fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
             ty::BrEnv => {
                 let name = token::intern("'r");
                 let _ = write!(f, "{}", name);
-                ty::BrNamed(DefId::local(ast::DUMMY_NODE_ID), name)
+                ty::BrNamed(DefId::local(DUMMY_NODE_ID), name)
             }
         })
     }).0;
@@ -623,14 +624,55 @@ impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
     }
 }
 
+pub fn int_ty_to_string(t: ast::IntTy, val: Option<i64>) -> String {
+    let s = match t {
+        ast::TyIs => "isize",
+        ast::TyI8 => "i8",
+        ast::TyI16 => "i16",
+        ast::TyI32 => "i32",
+        ast::TyI64 => "i64"
+    };
+
+    match val {
+        // cast to a u64 so we can correctly print INT64_MIN. All integral types
+        // are parsed as u64, so we wouldn't want to print an extra negative
+        // sign.
+        Some(n) => format!("{}{}", n as u64, s),
+        None => s.to_string()
+    }
+}
+
+pub fn uint_ty_to_string(t: ast::UintTy, val: Option<u64>) -> String {
+    let s = match t {
+        ast::TyUs => "usize",
+        ast::TyU8 => "u8",
+        ast::TyU16 => "u16",
+        ast::TyU32 => "u32",
+        ast::TyU64 => "u64"
+    };
+
+    match val {
+        Some(n) => format!("{}{}", n, s),
+        None => s.to_string()
+    }
+}
+
+
+pub fn float_ty_to_string(t: ast::FloatTy) -> String {
+    match t {
+        ast::TyF32 => "f32".to_string(),
+        ast::TyF64 => "f64".to_string(),
+    }
+}
+
 impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             TyBool => write!(f, "bool"),
             TyChar => write!(f, "char"),
-            TyInt(t) => write!(f, "{}", ast_util::int_ty_to_string(t, None)),
-            TyUint(t) => write!(f, "{}", ast_util::uint_ty_to_string(t, None)),
-            TyFloat(t) => write!(f, "{}", ast_util::float_ty_to_string(t)),
+            TyInt(t) => write!(f, "{}", int_ty_to_string(t, None)),
+            TyUint(t) => write!(f, "{}", uint_ty_to_string(t, None)),
+            TyFloat(t) => write!(f, "{}", float_ty_to_string(t)),
             TyBox(typ) => write!(f, "Box<{}>",  typ),
             TyRawPtr(ref tm) => {
                 write!(f, "*{} {}", match tm.mutbl {