about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/session/config.rs6
-rw-r--r--src/librustc_driver/driver.rs5
-rw-r--r--src/librustc_mir/build/block.rs9
-rw-r--r--src/librustc_mir/build/cfg.rs28
-rw-r--r--src/librustc_mir/build/expr/as_constant.rs8
-rw-r--r--src/librustc_mir/build/expr/as_lvalue.rs10
-rw-r--r--src/librustc_mir/build/expr/as_operand.rs10
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs10
-rw-r--r--src/librustc_mir/build/expr/as_temp.rs10
-rw-r--r--src/librustc_mir/build/expr/category.rs2
-rw-r--r--src/librustc_mir/build/expr/into.rs14
-rw-r--r--src/librustc_mir/build/into.rs48
-rw-r--r--src/librustc_mir/build/matches/mod.rs102
-rw-r--r--src/librustc_mir/build/matches/simplify.rs15
-rw-r--r--src/librustc_mir/build/matches/test.rs39
-rw-r--r--src/librustc_mir/build/matches/util.rs33
-rw-r--r--src/librustc_mir/build/misc.rs25
-rw-r--r--src/librustc_mir/build/mod.rs62
-rw-r--r--src/librustc_mir/build/scope.rs60
-rw-r--r--src/librustc_mir/build/stmt.rs6
-rw-r--r--src/librustc_mir/graphviz/mod.rs5
-rw-r--r--src/librustc_mir/hair.rs367
-rw-r--r--src/librustc_mir/lib.rs5
-rw-r--r--src/librustc_mir/mir_map.rs (renamed from src/librustc_mir/dump.rs)69
-rw-r--r--src/librustc_mir/repr.rs179
-rw-r--r--src/librustc_mir/tcx/block.rs24
-rw-r--r--src/librustc_mir/tcx/expr.rs48
-rw-r--r--src/librustc_mir/tcx/mod.rs119
-rw-r--r--src/librustc_mir/tcx/pattern.rs34
-rw-r--r--src/librustc_mir/tcx/to_ref.rs51
30 files changed, 675 insertions, 728 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 0739420ea4d..7e8104d08d6 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -101,7 +101,6 @@ pub struct Options {
     pub parse_only: bool,
     pub no_trans: bool,
     pub treat_err_as_bug: bool,
-    pub always_build_mir: bool,
     pub no_analysis: bool,
     pub debugging_opts: DebuggingOptions,
     pub prints: Vec<PrintRequest>,
@@ -211,7 +210,6 @@ pub fn basic_options() -> Options {
         parse_only: false,
         no_trans: false,
         treat_err_as_bug: false,
-        always_build_mir: false,
         no_analysis: false,
         debugging_opts: basic_debugging_options(),
         prints: Vec::new(),
@@ -578,8 +576,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "Run all passes except translation; no output"),
     treat_err_as_bug: bool = (false, parse_bool,
           "Treat all errors that occur as bugs"),
-    always_build_mir: bool = (false, parse_bool,
-          "Always build MIR for all fns, even without a #[rustc_mir] annotation"),
     no_analysis: bool = (false, parse_bool,
           "Parse and expand the source, but run no analysis"),
     extra_plugins: Vec<String> = (Vec::new(), parse_list,
@@ -895,7 +891,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let parse_only = debugging_opts.parse_only;
     let no_trans = debugging_opts.no_trans;
     let treat_err_as_bug = debugging_opts.treat_err_as_bug;
-    let always_build_mir = debugging_opts.always_build_mir;
     let no_analysis = debugging_opts.no_analysis;
 
     if debugging_opts.debug_llvm {
@@ -1049,7 +1044,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         parse_only: parse_only,
         no_trans: no_trans,
         treat_err_as_bug: treat_err_as_bug,
-        always_build_mir: always_build_mir,
         no_analysis: no_analysis,
         debugging_opts: debugging_opts,
         prints: prints,
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 64d09a23658..91843d23cab 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -738,8 +738,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
         time(time_passes, "match checking", ||
             middle::check_match::check_crate(tcx));
 
-        time(time_passes, "MIR dump", ||
-             mir::dump::dump_crate(tcx));
+        let _mir_map =
+            time(time_passes, "MIR dump", ||
+                 mir::mir_map::build_mir_for_crate(tcx));
 
         time(time_passes, "liveness checking", ||
             middle::liveness::check_crate(tcx));
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index 5604c78e098..21a77bbd232 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -8,15 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use build::{BlockAnd, Builder};
 use hair::*;
 use repr::*;
-use build::{BlockAnd, Builder};
+use rustc_front::hir;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     pub fn ast_block(&mut self,
-                     destination: &Lvalue<H>,
+                     destination: &Lvalue<'tcx>,
                      mut block: BasicBlock,
-                     ast_block: H::Block)
+                     ast_block: &'tcx hir::Block)
                      -> BlockAnd<()> {
         let this = self;
         let Block { extent, span: _, stmts, expr } = this.hir.mirror(ast_block);
diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs
index 955e1b7146a..09166a76f70 100644
--- a/src/librustc_mir/build/cfg.rs
+++ b/src/librustc_mir/build/cfg.rs
@@ -14,15 +14,15 @@
 //! Routines for manipulating the control-flow graph.
 
 use build::CFG;
-use hair::*;
 use repr::*;
+use syntax::codemap::Span;
 
-impl<H:Hair> CFG<H> {
-    pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<H> {
+impl<'tcx> CFG<'tcx> {
+    pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
         &self.basic_blocks[blk.index()]
     }
 
-    pub fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<H> {
+    pub fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> {
         &mut self.basic_blocks[blk.index()]
     }
 
@@ -39,21 +39,21 @@ impl<H:Hair> CFG<H> {
         BasicBlock::new(node_index)
     }
 
-    pub fn push(&mut self, block: BasicBlock, statement: Statement<H>) {
+    pub fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) {
         debug!("push({:?}, {:?})", block, statement);
         self.block_data_mut(block).statements.push(statement);
     }
 
     pub fn push_assign_constant(&mut self,
                                 block: BasicBlock,
-                                span: H::Span,
-                                temp: &Lvalue<H>,
-                                constant: Constant<H>) {
+                                span: Span,
+                                temp: &Lvalue<'tcx>,
+                                constant: Constant<'tcx>) {
         self.push_assign(block, span, temp, Rvalue::Use(Operand::Constant(constant)));
     }
 
-    pub fn push_drop(&mut self, block: BasicBlock, span: H::Span,
-                     kind: DropKind, lvalue: &Lvalue<H>) {
+    pub fn push_drop(&mut self, block: BasicBlock, span: Span,
+                     kind: DropKind, lvalue: &Lvalue<'tcx>) {
         self.push(block, Statement {
             span: span,
             kind: StatementKind::Drop(kind, lvalue.clone())
@@ -62,9 +62,9 @@ impl<H:Hair> CFG<H> {
 
     pub fn push_assign(&mut self,
                        block: BasicBlock,
-                       span: H::Span,
-                       lvalue: &Lvalue<H>,
-                       rvalue: Rvalue<H>) {
+                       span: Span,
+                       lvalue: &Lvalue<'tcx>,
+                       rvalue: Rvalue<'tcx>) {
         self.push(block, Statement {
             span: span,
             kind: StatementKind::Assign(lvalue.clone(), rvalue)
@@ -73,7 +73,7 @@ impl<H:Hair> CFG<H> {
 
     pub fn terminate(&mut self,
                      block: BasicBlock,
-                     terminator: Terminator<H>) {
+                     terminator: Terminator<'tcx>) {
         // Check whether this block has already been terminated. For
         // this, we rely on the fact that the initial state is to have
         // a Diverge terminator and an empty list of targets (which
diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs
index 6cc99a56933..d6de68b18d8 100644
--- a/src/librustc_mir/build/expr/as_constant.rs
+++ b/src/librustc_mir/build/expr/as_constant.rs
@@ -14,17 +14,17 @@ use build::{Builder};
 use hair::*;
 use repr::*;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Compile `expr`, yielding a compile-time constant. Assumes that
     /// `expr` is a valid compile-time constant!
-    pub fn as_constant<M>(&mut self, expr: M) -> Constant<H>
-        where M: Mirror<H, Output=Expr<H>>
+    pub fn as_constant<M>(&mut self, expr: M) -> Constant<'tcx>
+        where M: Mirror<'tcx, Output=Expr<'tcx>>
     {
         let expr = self.hir.mirror(expr);
         self.expr_as_constant(expr)
     }
 
-    fn expr_as_constant(&mut self, expr: Expr<H>) -> Constant<H> {
+    fn expr_as_constant(&mut self, expr: Expr<'tcx>) -> Constant<'tcx> {
         let this = self;
         let Expr { ty, temp_lifetime: _, span, kind } = expr;
         match kind {
diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs
index ffbb9781bdc..c14c8649e30 100644
--- a/src/librustc_mir/build/expr/as_lvalue.rs
+++ b/src/librustc_mir/build/expr/as_lvalue.rs
@@ -15,13 +15,13 @@ use build::expr::category::Category;
 use hair::*;
 use repr::*;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Compile `expr`, yielding an lvalue that we can move from etc.
     pub fn as_lvalue<M>(&mut self,
                         block: BasicBlock,
                         expr: M)
-                        -> BlockAnd<Lvalue<H>>
-        where M: Mirror<H, Output=Expr<H>>
+                        -> BlockAnd<Lvalue<'tcx>>
+        where M: Mirror<'tcx, Output=Expr<'tcx>>
     {
         let expr = self.hir.mirror(expr);
         self.expr_as_lvalue(block, expr)
@@ -29,8 +29,8 @@ impl<H:Hair> Builder<H> {
 
     fn expr_as_lvalue(&mut self,
                       mut block: BasicBlock,
-                      expr: Expr<H>)
-                      -> BlockAnd<Lvalue<H>>
+                      expr: Expr<'tcx>)
+                      -> BlockAnd<Lvalue<'tcx>>
     {
         debug!("expr_as_lvalue(block={:?}, expr={:?})",
                block, expr);
diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs
index 0b236f3a1dc..7fcbf4f5144 100644
--- a/src/librustc_mir/build/expr/as_operand.rs
+++ b/src/librustc_mir/build/expr/as_operand.rs
@@ -15,7 +15,7 @@ use build::expr::category::Category;
 use hair::*;
 use repr::*;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Compile `expr` into a value that can be used as an operand.
     /// If `expr` is an lvalue like `x`, this will introduce a
     /// temporary `tmp = x`, so that we capture the value of `x` at
@@ -23,8 +23,8 @@ impl<H:Hair> Builder<H> {
     pub fn as_operand<M>(&mut self,
                          block: BasicBlock,
                          expr: M)
-                         -> BlockAnd<Operand<H>>
-        where M: Mirror<H, Output=Expr<H>>
+                         -> BlockAnd<Operand<'tcx>>
+        where M: Mirror<'tcx, Output=Expr<'tcx>>
     {
         let expr = self.hir.mirror(expr);
         self.expr_as_operand(block, expr)
@@ -32,8 +32,8 @@ impl<H:Hair> Builder<H> {
 
     fn expr_as_operand(&mut self,
                        mut block: BasicBlock,
-                       expr: Expr<H>)
-                       -> BlockAnd<Operand<H>>
+                       expr: Expr<'tcx>)
+                       -> BlockAnd<Operand<'tcx>>
     {
         debug!("expr_as_operand(block={:?}, expr={:?})",
                block, expr);
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 0f0303525e3..be29964f3b0 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -17,13 +17,13 @@ use build::expr::category::{Category, RvalueFunc};
 use hair::*;
 use repr::*;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Compile `expr`, yielding an rvalue.
     pub fn as_rvalue<M>(&mut self,
                         block: BasicBlock,
                         expr: M)
-                        -> BlockAnd<Rvalue<H>>
-        where M: Mirror<H, Output=Expr<H>>
+                        -> BlockAnd<Rvalue<'tcx>>
+        where M: Mirror<'tcx, Output=Expr<'tcx>>
     {
         let expr = self.hir.mirror(expr);
         self.expr_as_rvalue(block, expr)
@@ -31,8 +31,8 @@ impl<H:Hair> Builder<H> {
 
     fn expr_as_rvalue(&mut self,
                       mut block: BasicBlock,
-                      expr: Expr<H>)
-                      -> BlockAnd<Rvalue<H>>
+                      expr: Expr<'tcx>)
+                      -> BlockAnd<Rvalue<'tcx>>
     {
         debug!("expr_as_rvalue(block={:?}, expr={:?})",
                block, expr);
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index cb652c8a594..6f2814de8d6 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -15,14 +15,14 @@ use build::expr::category::Category;
 use hair::*;
 use repr::*;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Compile `expr` into a fresh temporary. This is used when building
     /// up rvalues so as to freeze the value that will be consumed.
     pub fn as_temp<M>(&mut self,
                       block: BasicBlock,
                       expr: M)
-                      -> BlockAnd<Lvalue<H>>
-        where M: Mirror<H, Output=Expr<H>>
+                      -> BlockAnd<Lvalue<'tcx>>
+        where M: Mirror<'tcx, Output=Expr<'tcx>>
     {
         let expr = self.hir.mirror(expr);
         self.expr_as_temp(block, expr)
@@ -30,8 +30,8 @@ impl<H:Hair> Builder<H> {
 
     fn expr_as_temp(&mut self,
                     mut block: BasicBlock,
-                    expr: Expr<H>)
-                    -> BlockAnd<Lvalue<H>>
+                    expr: Expr<'tcx>)
+                    -> BlockAnd<Lvalue<'tcx>>
     {
         debug!("expr_as_temp(block={:?}, expr={:?})",
                block, expr);
diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs
index 9cab2976b2c..658b7779b44 100644
--- a/src/librustc_mir/build/expr/category.rs
+++ b/src/librustc_mir/build/expr/category.rs
@@ -41,7 +41,7 @@ pub enum RvalueFunc {
 /// Determines the category for a given expression. Note that scope
 /// and paren expressions have no category.
 impl Category {
-    pub fn of<H:Hair>(ek: &ExprKind<H>) -> Option<Category> {
+    pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option<Category> {
         match *ek {
             ExprKind::Scope { .. } => None,
 
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 61eeac30c0f..a2365c8bead 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -15,14 +15,16 @@ use build::expr::category::{Category, RvalueFunc};
 use build::scope::LoopScope;
 use hair::*;
 use repr::*;
+use rustc::middle::region::CodeExtent;
+use syntax::codemap::Span;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Compile `expr`, storing the result into `destination`, which
     /// is assumed to be uninitialized.
     pub fn into_expr(&mut self,
-                     destination: &Lvalue<H>,
+                     destination: &Lvalue<'tcx>,
                      mut block: BasicBlock,
-                     expr: Expr<H>)
+                     expr: Expr<'tcx>)
                      -> BlockAnd<()>
     {
         debug!("into_expr(destination={:?}, block={:?}, expr={:?})",
@@ -266,12 +268,12 @@ impl<H:Hair> Builder<H> {
     }
 
     fn break_or_continue<F>(&mut self,
-                            span: H::Span,
-                            label: Option<H::CodeExtent>,
+                            span: Span,
+                            label: Option<CodeExtent>,
                             block: BasicBlock,
                             exit_selector: F)
                             -> BlockAnd<()>
-        where F: FnOnce(&LoopScope<H>) -> BasicBlock
+        where F: FnOnce(&LoopScope) -> BasicBlock
     {
         let loop_scope = self.find_loop_scope(span, label);
         let exit_block = exit_selector(&loop_scope);
diff --git a/src/librustc_mir/build/into.rs b/src/librustc_mir/build/into.rs
index 426e59f1c40..ac8aae9ed0a 100644
--- a/src/librustc_mir/build/into.rs
+++ b/src/librustc_mir/build/into.rs
@@ -18,50 +18,50 @@ use build::{BlockAnd, Builder};
 use hair::*;
 use repr::*;
 
-pub trait EvalInto<H:Hair> {
-    fn eval_into(self, builder: &mut Builder<H>, destination: &Lvalue<H>,
-                 block: BasicBlock) -> BlockAnd<()>;
+pub trait EvalInto<'tcx> {
+    fn eval_into<'a>(self, builder: &mut Builder<'a,'tcx>, destination: &Lvalue<'tcx>,
+                     block: BasicBlock) -> BlockAnd<()>;
 }
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     pub fn into<E>(&mut self,
-                   destination: &Lvalue<H>,
+                   destination: &Lvalue<'tcx>,
                    block: BasicBlock,
                    expr: E)
                    -> BlockAnd<()>
-        where E: EvalInto<H>
+        where E: EvalInto<'tcx>
     {
         expr.eval_into(self, destination, block)
     }
 }
 
-impl<H:Hair> EvalInto<H> for ExprRef<H> {
-    fn eval_into(self,
-                 builder: &mut Builder<H>,
-                 destination: &Lvalue<H>,
-                 block: BasicBlock)
-                 -> BlockAnd<()> {
+impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
+    fn eval_into<'a>(self,
+                     builder: &mut Builder<'a,'tcx>,
+                     destination: &Lvalue<'tcx>,
+                     block: BasicBlock)
+                     -> BlockAnd<()> {
         let expr = builder.hir.mirror(self);
         builder.into_expr(destination, block, expr)
     }
 }
 
-impl<H:Hair> EvalInto<H> for Expr<H> {
-    fn eval_into(self,
-                 builder: &mut Builder<H>,
-                 destination: &Lvalue<H>,
-                 block: BasicBlock)
-                 -> BlockAnd<()> {
+impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
+    fn eval_into<'a>(self,
+                     builder: &mut Builder<'a,'tcx>,
+                     destination: &Lvalue<'tcx>,
+                     block: BasicBlock)
+                     -> BlockAnd<()> {
         builder.into_expr(destination, block, self)
     }
 }
 
-impl<H:Hair> EvalInto<H> for Option<ExprRef<H>> {
-    fn eval_into(self,
-                 builder: &mut Builder<H>,
-                 destination: &Lvalue<H>,
-                 block: BasicBlock)
-                 -> BlockAnd<()> {
+impl<'tcx> EvalInto<'tcx> for Option<ExprRef<'tcx>> {
+    fn eval_into<'a>(self,
+                     builder: &mut Builder<'a,'tcx>,
+                     destination: &Lvalue<'tcx>,
+                     block: BasicBlock)
+                     -> BlockAnd<()> {
         match self {
             Some(expr) => builder.into(destination, block, expr),
             None => block.unit()
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 4d0acd5fac9..ad6a218b07c 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -15,20 +15,24 @@
 
 use build::{BlockAnd, Builder};
 use repr::*;
+use rustc::middle::region::CodeExtent;
+use rustc::middle::ty::{AdtDef, Ty};
 use hair::*;
+use syntax::ast::{Name, NodeId};
+use syntax::codemap::Span;
 
 // helper functions, broken out by category:
 mod simplify;
 mod test;
 mod util;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     pub fn match_expr(&mut self,
-                      destination: &Lvalue<H>,
-                      span: H::Span,
+                      destination: &Lvalue<'tcx>,
+                      span: Span,
                       mut block: BasicBlock,
-                      discriminant: ExprRef<H>,
-                      arms: Vec<Arm<H>>)
+                      discriminant: ExprRef<'tcx>,
+                      arms: Vec<Arm<'tcx>>)
                       -> BlockAnd<()>
     {
         let discriminant_lvalue =
@@ -49,7 +53,7 @@ impl<H:Hair> Builder<H> {
                         .collect(),
         };
 
-        let arm_bodies: Vec<ExprRef<H>> =
+        let arm_bodies: Vec<ExprRef<'tcx>> =
             arms.iter()
                 .map(|arm| arm.body.clone())
                 .collect();
@@ -60,7 +64,7 @@ impl<H:Hair> Builder<H> {
         // highest priority candidate comes last in the list. This the
         // reverse of the order in which candidates are written in the
         // source.
-        let candidates: Vec<Candidate<H>> =
+        let candidates: Vec<Candidate<'tcx>> =
             arms.iter()
                 .enumerate()
                 .rev() // highest priority comes last
@@ -97,9 +101,9 @@ impl<H:Hair> Builder<H> {
 
     pub fn expr_into_pattern(&mut self,
                              mut block: BasicBlock,
-                             var_extent: H::CodeExtent,          // lifetime of vars
-                             irrefutable_pat: PatternRef<H>,
-                             initializer: ExprRef<H>)
+                             var_extent: CodeExtent,          // lifetime of vars
+                             irrefutable_pat: PatternRef<'tcx>,
+                             initializer: ExprRef<'tcx>)
                              -> BlockAnd<()>
     {
         // optimize the case of `let x = ...`
@@ -125,16 +129,16 @@ impl<H:Hair> Builder<H> {
 
     pub fn lvalue_into_pattern(&mut self,
                                mut block: BasicBlock,
-                               var_extent: H::CodeExtent,
-                               irrefutable_pat: PatternRef<H>,
-                               initializer: &Lvalue<H>)
+                               var_extent: CodeExtent,
+                               irrefutable_pat: PatternRef<'tcx>,
+                               initializer: &Lvalue<'tcx>)
                                -> BlockAnd<()>
     {
         // first, creating the bindings
         self.declare_bindings(var_extent, irrefutable_pat.clone());
 
         // create a dummy candidate
-        let mut candidate = Candidate::<H> {
+        let mut candidate = Candidate::<'tcx> {
             match_pairs: vec![self.match_pair(initializer.clone(), irrefutable_pat.clone())],
             bindings: vec![],
             guard: None,
@@ -159,8 +163,8 @@ impl<H:Hair> Builder<H> {
     }
 
     pub fn declare_bindings(&mut self,
-                            var_extent: H::CodeExtent,
-                            pattern: PatternRef<H>)
+                            var_extent: CodeExtent,
+                            pattern: PatternRef<'tcx>)
     {
         let pattern = self.hir.mirror(pattern);
         match pattern.kind {
@@ -198,69 +202,69 @@ struct ArmBlocks {
 }
 
 #[derive(Clone, Debug)]
-struct Candidate<H:Hair> {
+struct Candidate<'tcx> {
     // all of these must be satisfied...
-    match_pairs: Vec<MatchPair<H>>,
+    match_pairs: Vec<MatchPair<'tcx>>,
 
     // ...these bindings established...
-    bindings: Vec<Binding<H>>,
+    bindings: Vec<Binding<'tcx>>,
 
     // ...and the guard must be evaluated...
-    guard: Option<ExprRef<H>>,
+    guard: Option<ExprRef<'tcx>>,
 
     // ...and then we branch to arm with this index.
     arm_index: usize,
 }
 
 #[derive(Clone, Debug)]
-struct Binding<H:Hair> {
-    span: H::Span,
-    source: Lvalue<H>,
-    name: H::Name,
-    var_id: H::VarId,
-    var_ty: H::Ty,
+struct Binding<'tcx> {
+    span: Span,
+    source: Lvalue<'tcx>,
+    name: Name,
+    var_id: NodeId,
+    var_ty: Ty<'tcx>,
     mutability: Mutability,
-    binding_mode: BindingMode<H>,
+    binding_mode: BindingMode,
 }
 
 #[derive(Clone, Debug)]
-struct MatchPair<H:Hair> {
+struct MatchPair<'tcx> {
     // this lvalue...
-    lvalue: Lvalue<H>,
+    lvalue: Lvalue<'tcx>,
 
     // ... must match this pattern.
-    pattern: Pattern<H>,
+    pattern: Pattern<'tcx>,
 }
 
 #[derive(Clone, Debug, PartialEq)]
-enum TestKind<H:Hair> {
+enum TestKind<'tcx> {
     // test the branches of enum
-    Switch { adt_def: H::AdtDef },
+    Switch { adt_def: AdtDef<'tcx> },
 
     // test for equality
-    Eq { value: Literal<H>, ty: H::Ty },
+    Eq { value: Literal<'tcx>, ty: Ty<'tcx> },
 
     // test whether the value falls within an inclusive range
-    Range { lo: Literal<H>, hi: Literal<H>, ty: H::Ty },
+    Range { lo: Literal<'tcx>, hi: Literal<'tcx>, ty: Ty<'tcx> },
 
     // test length of the slice is equal to len
     Len { len: usize, op: BinOp },
 }
 
 #[derive(Debug)]
-struct Test<H:Hair> {
-    span: H::Span,
-    kind: TestKind<H>,
+struct Test<'tcx> {
+    span: Span,
+    kind: TestKind<'tcx>,
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // Main matching algorithm
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     fn match_candidates(&mut self,
-                        span: H::Span,
+                        span: Span,
                         arm_blocks: &mut ArmBlocks,
-                        mut candidates: Vec<Candidate<H>>,
+                        mut candidates: Vec<Candidate<'tcx>>,
                         mut block: BasicBlock)
     {
         debug!("matched_candidate(span={:?}, block={:?}, candidates={:?})",
@@ -306,7 +310,7 @@ impl<H:Hair> Builder<H> {
         let target_blocks = self.perform_test(block, &match_pair.lvalue, &test);
 
         for (outcome, mut target_block) in target_blocks.into_iter().enumerate() {
-            let applicable_candidates: Vec<Candidate<H>> =
+            let applicable_candidates: Vec<Candidate<'tcx>> =
                 candidates.iter()
                           .filter_map(|candidate| {
                               unpack!(target_block =
@@ -336,7 +340,7 @@ impl<H:Hair> Builder<H> {
     fn bind_and_guard_matched_candidate(&mut self,
                                         mut block: BasicBlock,
                                         arm_blocks: &mut ArmBlocks,
-                                        candidate: Candidate<H>)
+                                        candidate: Candidate<'tcx>)
                                         -> Option<BasicBlock> {
         debug!("bind_and_guard_matched_candidate(block={:?}, candidate={:?})",
                block, candidate);
@@ -363,7 +367,7 @@ impl<H:Hair> Builder<H> {
 
     fn bind_matched_candidate(&mut self,
                               block: BasicBlock,
-                              bindings: Vec<Binding<H>>) {
+                              bindings: Vec<Binding<'tcx>>) {
         debug!("bind_matched_candidate(block={:?}, bindings={:?})",
                block, bindings);
 
@@ -386,19 +390,19 @@ impl<H:Hair> Builder<H> {
     }
 
     fn declare_binding(&mut self,
-                       var_extent: H::CodeExtent,
+                       var_extent: CodeExtent,
                        mutability: Mutability,
-                       name: H::Name,
-                       var_id: H::VarId,
-                       var_ty: H::Ty,
-                       span: H::Span)
+                       name: Name,
+                       var_id: NodeId,
+                       var_ty: Ty<'tcx>,
+                       span: Span)
                        -> u32
     {
         debug!("declare_binding(var_id={:?}, name={:?}, var_ty={:?}, var_extent={:?}, span={:?})",
                var_id, name, var_ty, var_extent, span);
 
         let index = self.var_decls.len();
-        self.var_decls.push(VarDecl::<H> {
+        self.var_decls.push(VarDecl::<'tcx> {
             mutability: mutability,
             name: name,
             ty: var_ty.clone(),
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index f15b2ed5d4e..69c7fd6598a 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -29,10 +29,10 @@ use repr::*;
 
 use std::mem;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     pub fn simplify_candidate(&mut self,
                               mut block: BasicBlock,
-                              candidate: &mut Candidate<H>)
+                              candidate: &mut Candidate<'tcx>)
                               -> BlockAnd<()>
     {
         // repeatedly simplify match pairs until fixed point is reached
@@ -56,13 +56,14 @@ impl<H:Hair> Builder<H> {
 
     /// Tries to simplify `match_pair`, returning true if
     /// successful. If successful, new match pairs and bindings will
-    /// have been pushed into the candidate. On failure (if false is
-    /// returned), no changes are made to candidate.
+    /// have been pushed into the candidate. If no simplification is
+    /// possible, Err is returned and no changes are made to
+    /// candidate.
     fn simplify_match_pair(&mut self,
                            mut block: BasicBlock,
-                           match_pair: MatchPair<H>,
-                           candidate: &mut Candidate<H>)
-                           -> Result<BasicBlock, MatchPair<H>> // returns Err() if cannot simplify
+                           match_pair: MatchPair<'tcx>,
+                           candidate: &mut Candidate<'tcx>)
+                           -> Result<BasicBlock, MatchPair<'tcx>>
     {
         match match_pair.pattern.kind {
             PatternKind::Wild(..) => {
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 2d034baef16..a7ef97e12a0 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -19,12 +19,13 @@ use build::{BlockAnd, Builder};
 use build::matches::{Candidate, MatchPair, Test, TestKind};
 use hair::*;
 use repr::*;
+use syntax::codemap::Span;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Identifies what test is needed to decide if `match_pair` is applicable.
     ///
     /// It is a bug to call this with a simplifyable pattern.
-    pub fn test(&mut self, match_pair: &MatchPair<H>) -> Test<H> {
+    pub fn test(&mut self, match_pair: &MatchPair<'tcx>) -> Test<'tcx> {
         match match_pair.pattern.kind {
             PatternKind::Variant { ref adt_def, variant_index: _, subpatterns: _ } => {
                 Test {
@@ -72,8 +73,8 @@ impl<H:Hair> Builder<H> {
     /// Generates the code to perform a test.
     pub fn perform_test(&mut self,
                         block: BasicBlock,
-                        lvalue: &Lvalue<H>,
-                        test: &Test<H>)
+                        lvalue: &Lvalue<'tcx>,
+                        test: &Test<'tcx>)
                         -> Vec<BasicBlock> {
         match test.kind.clone() {
             TestKind::Switch { adt_def } => {
@@ -149,10 +150,10 @@ impl<H:Hair> Builder<H> {
 
     fn call_comparison_fn(&mut self,
                           block: BasicBlock,
-                          span: H::Span,
-                          item_ref: ItemRef<H>,
-                          lvalue1: Lvalue<H>,
-                          lvalue2: Lvalue<H>)
+                          span: Span,
+                          item_ref: ItemRef<'tcx>,
+                          lvalue1: Lvalue<'tcx>,
+                          lvalue2: Lvalue<'tcx>)
                           -> Vec<BasicBlock> {
         let target_blocks = vec![self.cfg.start_new_block(),
                                  self.cfg.start_new_block()];
@@ -194,11 +195,11 @@ impl<H:Hair> Builder<H> {
     /// @ 22])`.
     pub fn candidate_under_assumption(&mut self,
                                       mut block: BasicBlock,
-                                      test_lvalue: &Lvalue<H>,
-                                      test_kind: &TestKind<H>,
+                                      test_lvalue: &Lvalue<'tcx>,
+                                      test_kind: &TestKind<'tcx>,
                                       test_outcome: usize,
-                                      candidate: &Candidate<H>)
-                                      -> BlockAnd<Option<Candidate<H>>> {
+                                      candidate: &Candidate<'tcx>)
+                                      -> BlockAnd<Option<Candidate<'tcx>>> {
         let candidate = candidate.clone();
         let match_pairs = candidate.match_pairs;
         let result = unpack!(block = self.match_pairs_under_assumption(block,
@@ -216,11 +217,11 @@ impl<H:Hair> Builder<H> {
     /// work of transforming the list of match pairs.
     fn match_pairs_under_assumption(&mut self,
                                     mut block: BasicBlock,
-                                    test_lvalue: &Lvalue<H>,
-                                    test_kind: &TestKind<H>,
+                                    test_lvalue: &Lvalue<'tcx>,
+                                    test_kind: &TestKind<'tcx>,
                                     test_outcome: usize,
-                                    match_pairs: Vec<MatchPair<H>>)
-                                    -> BlockAnd<Option<Vec<MatchPair<H>>>> {
+                                    match_pairs: Vec<MatchPair<'tcx>>)
+                                    -> BlockAnd<Option<Vec<MatchPair<'tcx>>>> {
         let mut result = vec![];
 
         for match_pair in match_pairs {
@@ -279,9 +280,9 @@ impl<H:Hair> Builder<H> {
     /// It is a bug to call this with a simplifyable pattern.
     pub fn consequent_match_pairs_under_assumption(&mut self,
                                                    mut block: BasicBlock,
-                                                   match_pair: MatchPair<H>,
+                                                   match_pair: MatchPair<'tcx>,
                                                    test_outcome: usize)
-                                                   -> BlockAnd<Option<Vec<MatchPair<H>>>> {
+                                                   -> BlockAnd<Option<Vec<MatchPair<'tcx>>>> {
         match match_pair.pattern.kind {
             PatternKind::Variant { adt_def, variant_index, subpatterns } => {
                 if test_outcome != variant_index {
@@ -339,7 +340,7 @@ impl<H:Hair> Builder<H> {
         }
     }
 
-    fn error_simplifyable(&mut self, match_pair: &MatchPair<H>) -> ! {
+    fn error_simplifyable(&mut self, match_pair: &MatchPair<'tcx>) -> ! {
         self.hir.span_bug(
             match_pair.pattern.span,
             &format!("simplifyable pattern found: {:?}", match_pair.pattern))
diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs
index 65a08868666..ae6dc9918f4 100644
--- a/src/librustc_mir/build/matches/util.rs
+++ b/src/librustc_mir/build/matches/util.rs
@@ -14,11 +14,11 @@ use hair::*;
 use repr::*;
 use std::u32;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     pub fn field_match_pairs(&mut self,
-                             lvalue: Lvalue<H>,
-                             subpatterns: Vec<FieldPatternRef<H>>)
-                             -> Vec<MatchPair<H>> {
+                             lvalue: Lvalue<'tcx>,
+                             subpatterns: Vec<FieldPatternRef<'tcx>>)
+                             -> Vec<MatchPair<'tcx>> {
         subpatterns.into_iter()
                    .map(|fieldpat| {
                        let lvalue = lvalue.clone().field(fieldpat.field);
@@ -27,7 +27,8 @@ impl<H:Hair> Builder<H> {
                    .collect()
     }
 
-    pub fn match_pair(&mut self, lvalue: Lvalue<H>, pattern: PatternRef<H>) -> MatchPair<H> {
+    pub fn match_pair(&mut self, lvalue: Lvalue<'tcx>, pattern: PatternRef<'tcx>)
+                      -> MatchPair<'tcx> {
         let pattern = self.hir.mirror(pattern);
         MatchPair::new(lvalue, pattern)
     }
@@ -47,12 +48,12 @@ impl<H:Hair> Builder<H> {
     ///
     /// and creates a match pair `tmp0 @ s`
     pub fn prefix_suffix_slice(&mut self,
-                               match_pairs: &mut Vec<MatchPair<H>>,
+                               match_pairs: &mut Vec<MatchPair<'tcx>>,
                                block: BasicBlock,
-                               lvalue: Lvalue<H>,
-                               prefix: Vec<PatternRef<H>>,
-                               opt_slice: Option<PatternRef<H>>,
-                               suffix: Vec<PatternRef<H>>)
+                               lvalue: Lvalue<'tcx>,
+                               prefix: Vec<PatternRef<'tcx>>,
+                               opt_slice: Option<PatternRef<'tcx>>,
+                               suffix: Vec<PatternRef<'tcx>>)
                                -> BlockAnd<()>
     {
         // If there is a `..P` pattern, create a temporary `t0` for
@@ -76,10 +77,10 @@ impl<H:Hair> Builder<H> {
 
     /// Helper for `prefix_suffix_slice` which just processes the prefix and suffix.
     fn prefix_suffix(&mut self,
-                     match_pairs: &mut Vec<MatchPair<H>>,
-                     lvalue: Lvalue<H>,
-                     prefix: Vec<PatternRef<H>>,
-                     suffix: Vec<PatternRef<H>>)
+                     match_pairs: &mut Vec<MatchPair<'tcx>>,
+                     lvalue: Lvalue<'tcx>,
+                     prefix: Vec<PatternRef<'tcx>>,
+                     suffix: Vec<PatternRef<'tcx>>)
     {
         let min_length = prefix.len() + suffix.len();
         assert!(min_length < u32::MAX as usize);
@@ -118,8 +119,8 @@ impl<H:Hair> Builder<H> {
     }
 }
 
-impl<H:Hair> MatchPair<H> {
-    pub fn new(lvalue: Lvalue<H>, pattern: Pattern<H>) -> MatchPair<H> {
+impl<'tcx> MatchPair<'tcx> {
+    pub fn new(lvalue: Lvalue<'tcx>, pattern: Pattern<'tcx>) -> MatchPair<'tcx> {
         MatchPair { lvalue: lvalue, pattern: pattern }
     }
 }
diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs
index 9fa1d55e82f..8ebe0bc7154 100644
--- a/src/librustc_mir/build/misc.rs
+++ b/src/librustc_mir/build/misc.rs
@@ -14,16 +14,17 @@
 use build::Builder;
 use hair::*;
 use repr::*;
-
+use rustc::middle::ty::Ty;
 use std::u32;
+use syntax::codemap::Span;
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Add a new temporary value of type `ty` storing the result of
     /// evaluating `expr`.
     ///
     /// NB: **No cleanup is scheduled for this temporary.** You should
     /// call `schedule_drop` once the temporary is initialized.
-    pub fn temp(&mut self, ty: H::Ty) -> Lvalue<H> {
+    pub fn temp(&mut self, ty: Ty<'tcx>) -> Lvalue<'tcx> {
         let index = self.temp_decls.len();
         self.temp_decls.push(TempDecl { ty: ty });
         assert!(index < (u32::MAX) as usize);
@@ -35,10 +36,10 @@ impl<H:Hair> Builder<H> {
 
     pub fn push_literal(&mut self,
                         block: BasicBlock,
-                        span: H::Span,
-                        ty: H::Ty,
-                        literal: Literal<H>)
-                        -> Lvalue<H> {
+                        span: Span,
+                        ty: Ty<'tcx>,
+                        literal: Literal<'tcx>)
+                        -> Lvalue<'tcx> {
         let temp = self.temp(ty.clone());
         let constant = Constant { span: span, ty: ty, literal: literal };
         self.cfg.push_assign_constant(block, span, &temp, constant);
@@ -47,9 +48,9 @@ impl<H:Hair> Builder<H> {
 
     pub fn push_usize(&mut self,
                       block: BasicBlock,
-                      span: H::Span,
+                      span: Span,
                       value: usize)
-                      -> Lvalue<H> {
+                      -> Lvalue<'tcx> {
         let usize_ty = self.hir.usize_ty();
         let temp = self.temp(usize_ty);
         self.cfg.push_assign_constant(
@@ -64,9 +65,9 @@ impl<H:Hair> Builder<H> {
 
     pub fn push_item_ref(&mut self,
                          block: BasicBlock,
-                         span: H::Span,
-                         item_ref: ItemRef<H>)
-                         -> Lvalue<H> {
+                         span: Span,
+                         item_ref: ItemRef<'tcx>)
+                         -> Lvalue<'tcx> {
         let literal = Literal::Item { def_id: item_ref.def_id, substs: item_ref.substs };
         self.push_literal(block, span, item_ref.ty, literal)
     }
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 9d00044c660..cf4dc9227c4 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -8,24 +8,30 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use hair::{self, Hair};
+use hair;
+use rustc::middle::region::CodeExtent;
+use rustc::middle::ty::Ty;
 use rustc_data_structures::fnv::FnvHashMap;
+use rustc_front::hir;
 use repr::*;
-
-struct Builder<H:Hair> {
-    hir: H,
-    extents: FnvHashMap<H::CodeExtent, Vec<GraphExtent>>,
-    cfg: CFG<H>,
-    scopes: Vec<scope::Scope<H>>,
-    loop_scopes: Vec<scope::LoopScope<H>>,
-    unit_temp: Lvalue<H>,
-    var_decls: Vec<VarDecl<H>>,
-    var_indices: FnvHashMap<H::VarId, u32>,
-    temp_decls: Vec<TempDecl<H>>,
+use syntax::ast;
+use syntax::codemap::Span;
+use tcx::{Cx, PatNode};
+
+struct Builder<'a,'tcx:'a> {
+    hir: Cx<'a, 'tcx>,
+    extents: FnvHashMap<CodeExtent, Vec<GraphExtent>>,
+    cfg: CFG<'tcx>,
+    scopes: Vec<scope::Scope<'tcx>>,
+    loop_scopes: Vec<scope::LoopScope>,
+    unit_temp: Lvalue<'tcx>,
+    var_decls: Vec<VarDecl<'tcx>>,
+    var_indices: FnvHashMap<ast::NodeId, u32>,
+    temp_decls: Vec<TempDecl<'tcx>>,
 }
 
-struct CFG<H:Hair> {
-    basic_blocks: Vec<BasicBlockData<H>>
+struct CFG<'tcx> {
+    basic_blocks: Vec<BasicBlockData<'tcx>>
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -69,18 +75,18 @@ macro_rules! unpack {
 ///////////////////////////////////////////////////////////////////////////
 // construct() -- the main entry point for building MIR for a function
 
-pub fn construct<H:Hair>(mut hir: H,
-                        _span: H::Span,
-                        implicit_arguments: Vec<H::Ty>,
-                        explicit_arguments: Vec<(H::Ty, H::Pattern)>,
-                        argument_extent: H::CodeExtent,
-                        ast_block: H::Block)
-                        -> Mir<H> {
+pub fn construct<'a,'tcx>(mut hir: Cx<'a,'tcx>,
+                          _span: Span,
+                          implicit_arguments: Vec<Ty<'tcx>>,
+                          explicit_arguments: Vec<(Ty<'tcx>, PatNode<'tcx>)>,
+                          argument_extent: CodeExtent,
+                          ast_block: &'tcx hir::Block)
+                          -> Mir<'tcx> {
     let cfg = CFG { basic_blocks: vec![] };
 
     // it's handy to have a temporary of type `()` sometimes, so make
     // one from the start and keep it available
-    let temp_decls = vec![TempDecl::<H> { ty: hir.unit_ty() }];
+    let temp_decls = vec![TempDecl::<'tcx> { ty: hir.unit_ty() }];
     let unit_temp = Lvalue::Temp(0);
 
     let mut builder = Builder {
@@ -118,14 +124,14 @@ pub fn construct<H:Hair>(mut hir: H,
     }
 }
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     fn args_and_body(&mut self,
                      mut block: BasicBlock,
-                     implicit_arguments: Vec<H::Ty>,
-                     explicit_arguments: Vec<(H::Ty, H::Pattern)>,
-                     argument_extent: H::CodeExtent,
-                     ast_block: H::Block)
-                     -> BlockAnd<Vec<ArgDecl<H>>>
+                     implicit_arguments: Vec<Ty<'tcx>>,
+                     explicit_arguments: Vec<(Ty<'tcx>, PatNode<'tcx>)>,
+                     argument_extent: CodeExtent,
+                     ast_block: &'tcx hir::Block)
+                     -> BlockAnd<Vec<ArgDecl<'tcx>>>
     {
         self.in_scope(argument_extent, block, |this| {
             let arg_decls = {
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 87a4731ac74..4b76bc737fd 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -12,7 +12,7 @@
 Managing the scope stack. The scopes are tied to lexical scopes, so as
 we descend the HAIR, we push a scope on the stack, translate ite
 contents, and then pop it off. Every scope is named by a
-`H::CodeExtent`.
+`CodeExtent`.
 
 ### SEME Regions
 
@@ -23,7 +23,7 @@ via a `break` or `return` or just by fallthrough, that marks an exit
 from the scope. Each lexical scope thus corresponds to a single-entry,
 multiple-exit (SEME) region in the control-flow graph.
 
-For now, we keep a mapping from each `H::CodeExtent` to its
+For now, we keep a mapping from each `CodeExtent` to its
 corresponding SEME region for later reference (see caveat in next
 paragraph). This is because region scopes are tied to
 them. Eventually, when we shift to non-lexical lifetimes, three should
@@ -87,24 +87,26 @@ should go to.
 */
 
 use build::{BlockAnd, Builder, CFG};
-use hair::Hair;
 use repr::*;
+use rustc::middle::region::CodeExtent;
+use rustc::middle::ty::Ty;
+use syntax::codemap::Span;
 
-pub struct Scope<H:Hair> {
-    extent: H::CodeExtent,
+pub struct Scope<'tcx> {
+    extent: CodeExtent,
     exits: Vec<ExecutionPoint>,
-    drops: Vec<(DropKind, H::Span, Lvalue<H>)>,
+    drops: Vec<(DropKind, Span, Lvalue<'tcx>)>,
     cached_block: Option<BasicBlock>,
 }
 
 #[derive(Clone, Debug)]
-pub struct LoopScope<H:Hair> {
-    pub extent: H::CodeExtent,      // extent of the loop
+pub struct LoopScope {
+    pub extent: CodeExtent,      // extent of the loop
     pub continue_block: BasicBlock, // where to go on a `loop`
     pub break_block: BasicBlock,    // where to go on a `break
 }
 
-impl<H:Hair> Builder<H> {
+impl<'a,'tcx> Builder<'a,'tcx> {
     /// Start a loop scope, which tracks where `continue` and `break`
     /// should branch to. See module comment for more details.
     pub fn in_loop_scope<F,R>(&mut self,
@@ -112,12 +114,12 @@ impl<H:Hair> Builder<H> {
                               break_block: BasicBlock,
                               f: F)
                               -> BlockAnd<R>
-        where F: FnOnce(&mut Builder<H>) -> BlockAnd<R>
+        where F: FnOnce(&mut Builder<'a,'tcx>) -> BlockAnd<R>
     {
         let extent = self.extent_of_innermost_scope().unwrap();
-        let loop_scope = LoopScope::<H> { extent: extent.clone(),
-                                          continue_block: loop_block,
-                                          break_block: break_block };
+        let loop_scope = LoopScope { extent: extent.clone(),
+                                     continue_block: loop_block,
+                                     break_block: break_block };
         self.loop_scopes.push(loop_scope);
         let r = f(self);
         assert!(self.loop_scopes.pop().unwrap().extent == extent);
@@ -127,11 +129,11 @@ impl<H:Hair> Builder<H> {
     /// Start a scope. The closure `f` should translate the contents
     /// of the scope. See module comment for more details.
     pub fn in_scope<F,R>(&mut self,
-                         extent: H::CodeExtent,
+                         extent: CodeExtent,
                          block: BasicBlock,
                          f: F)
                          -> BlockAnd<R>
-        where F: FnOnce(&mut Builder<H>) -> BlockAnd<R>
+        where F: FnOnce(&mut Builder<'a,'tcx>) -> BlockAnd<R>
     {
         debug!("in_scope(extent={:?}, block={:?})", extent, block);
 
@@ -180,9 +182,9 @@ impl<H:Hair> Builder<H> {
     /// Finds the loop scope for a given label. This is used for
     /// resolving `break` and `continue`.
     pub fn find_loop_scope(&mut self,
-                           span: H::Span,
-                           label: Option<H::CodeExtent>)
-                           -> LoopScope<H> {
+                           span: Span,
+                           label: Option<CodeExtent>)
+                           -> LoopScope {
         let loop_scope =
             match label {
                 None => {
@@ -211,8 +213,8 @@ impl<H:Hair> Builder<H> {
     /// needed, as well as tracking this exit for the SEME region. See
     /// module comment for details.
     pub fn exit_scope(&mut self,
-                      span: H::Span,
-                      extent: H::CodeExtent,
+                      span: Span,
+                      extent: CodeExtent,
                       block: BasicBlock,
                       target: BasicBlock) {
         let popped_scopes =
@@ -249,11 +251,11 @@ impl<H:Hair> Builder<H> {
     /// Indicates that `lvalue` should be dropped on exit from
     /// `extent`.
     pub fn schedule_drop(&mut self,
-                         span: H::Span,
-                         extent: H::CodeExtent,
+                         span: Span,
+                         extent: CodeExtent,
                          kind: DropKind,
-                         lvalue: &Lvalue<H>,
-                         lvalue_ty: H::Ty)
+                         lvalue: &Lvalue<'tcx>,
+                         lvalue_ty: Ty<'tcx>)
     {
         if self.hir.needs_drop(lvalue_ty, span) {
             match self.scopes.iter_mut().rev().find(|s| s.extent == extent) {
@@ -267,18 +269,18 @@ impl<H:Hair> Builder<H> {
         }
     }
 
-    pub fn extent_of_innermost_scope(&self) -> Option<H::CodeExtent> {
+    pub fn extent_of_innermost_scope(&self) -> Option<CodeExtent> {
         self.scopes.last().map(|scope| scope.extent)
     }
 
-    pub fn extent_of_outermost_scope(&self) -> Option<H::CodeExtent> {
+    pub fn extent_of_outermost_scope(&self) -> Option<CodeExtent> {
         self.scopes.first().map(|scope| scope.extent)
     }
 }
 
-fn diverge_cleanup_helper<H:Hair>(cfg: &mut CFG<H>,
-                                 scopes: &mut [Scope<H>])
-                                 -> BasicBlock {
+fn diverge_cleanup_helper<'tcx>(cfg: &mut CFG<'tcx>,
+                                scopes: &mut [Scope<'tcx>])
+                                -> BasicBlock {
     let len = scopes.len();
 
     if len == 0 {
diff --git a/src/librustc_mir/build/stmt.rs b/src/librustc_mir/build/stmt.rs
index 3dd4f5f253c..01fda2498f7 100644
--- a/src/librustc_mir/build/stmt.rs
+++ b/src/librustc_mir/build/stmt.rs
@@ -12,15 +12,15 @@ use build::{BlockAnd, Builder};
 use hair::*;
 use repr::*;
 
-impl<H:Hair> Builder<H> {
-    pub fn stmts(&mut self, mut block: BasicBlock, stmts: Vec<StmtRef<H>>) -> BlockAnd<()> {
+impl<'a,'tcx> Builder<'a,'tcx> {
+    pub fn stmts(&mut self, mut block: BasicBlock, stmts: Vec<StmtRef<'tcx>>) -> BlockAnd<()> {
         for stmt in stmts {
             unpack!(block = self.stmt(block, stmt));
         }
         block.unit()
     }
 
-    pub fn stmt(&mut self, mut block: BasicBlock, stmt: StmtRef<H>) -> BlockAnd<()> {
+    pub fn stmt(&mut self, mut block: BasicBlock, stmt: StmtRef<'tcx>) -> BlockAnd<()> {
         let this = self;
         let Stmt { span, kind } = this.hir.mirror(stmt);
         match kind {
diff --git a/src/librustc_mir/graphviz/mod.rs b/src/librustc_mir/graphviz/mod.rs
index 01ccf20ae06..0acf59bf357 100644
--- a/src/librustc_mir/graphviz/mod.rs
+++ b/src/librustc_mir/graphviz/mod.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use dot;
-use hair::Hair;
 use repr::*;
 use std::borrow::IntoCow;
 
@@ -20,7 +19,7 @@ pub struct EdgeIndex {
     index: usize,
 }
 
-impl<'a,H:Hair> dot::Labeller<'a, BasicBlock, EdgeIndex> for Mir<H> {
+impl<'a,'tcx> dot::Labeller<'a, BasicBlock, EdgeIndex> for Mir<'tcx> {
     fn graph_id(&'a self) -> dot::Id<'a> {
         dot::Id::new("Mir").unwrap()
     }
@@ -62,7 +61,7 @@ impl<'a,H:Hair> dot::Labeller<'a, BasicBlock, EdgeIndex> for Mir<H> {
     }
 }
 
-impl<'a,H:Hair> dot::GraphWalk<'a, BasicBlock, EdgeIndex> for Mir<H> {
+impl<'a,'tcx> dot::GraphWalk<'a, BasicBlock, EdgeIndex> for Mir<'tcx> {
     fn nodes(&'a self) -> dot::Nodes<'a, BasicBlock> {
         self.all_basic_blocks().into_cow()
     }
diff --git a/src/librustc_mir/hair.rs b/src/librustc_mir/hair.rs
index 18f2dd6dc6e..967ffa5edb1 100644
--- a/src/librustc_mir/hair.rs
+++ b/src/librustc_mir/hair.rs
@@ -15,144 +15,78 @@
 //! structures.
 
 use repr::{BinOp, BorrowKind, Field, Literal, Mutability, UnOp};
-use std::fmt::Debug;
-use std::hash::Hash;
-
-pub trait Hair: Sized+Debug+Clone+Eq+Hash { // (*)
-
-    // (*) the `Sized` and Debug` bounds are the only ones that really
-    // make sense.  The rest are just there so that we can
-    // `#[derive(Clone)]` on things that are parameterized over
-    // `H:HAIR`. It's kind of lame.
-
-    type VarId: Copy+Debug+Eq+Hash;                              // e.g., NodeId for a variable
-    type DefId: Copy+Debug+Eq+Hash;                              // e.g., DefId
-    type AdtDef: Copy+Debug+Eq+Hash;                             // e.g., AdtDef<'tcx>
-    type Name: Copy+Debug+Eq+Hash;                               // e.g., ast::Name
-    type InternedString: Clone+Debug+Eq+Hash;                    // e.g., InternedString
-    type Bytes: Clone+Debug+Eq+Hash;                             // e.g., Rc<Vec<u8>>
-    type Span: Copy+Debug+Eq;                                    // e.g., syntax::codemap::Span
-    type Projection: Clone+Debug+Eq;                             // e.g., ty::ProjectionTy<'tcx>
-    type Substs: Clone+Debug+Eq;                                 // e.g., substs::Substs<'tcx>
-    type ClosureSubsts: Clone+Debug+Eq;                          // e.g., ty::ClosureSubsts<'tcx>
-    type Ty: Clone+Debug+Eq;                                     // e.g., ty::Ty<'tcx>
-    type Region: Copy+Debug;                                     // e.g., ty::Region
-    type CodeExtent: Copy+Debug+Hash+Eq;                         // e.g., region::CodeExtent
-    type ConstVal: Clone+Debug+PartialEq;                        // e.g., ConstVal
-    type Pattern: Clone+Debug+Mirror<Self,Output=Pattern<Self>>; // e.g., &P<ast::Pat>
-    type Expr: Clone+Debug+Mirror<Self,Output=Expr<Self>>;       // e.g., &P<ast::Expr>
-    type Stmt: Clone+Debug+Mirror<Self,Output=Stmt<Self>>;       // e.g., &P<ast::Stmt>
-    type Block: Clone+Debug+Mirror<Self,Output=Block<Self>>;     // e.g., &P<ast::Block>
-    type InlineAsm: Clone+Debug+Eq+Hash;                         // e.g., ast::InlineAsm
-
-    /// Normalizes `ast` into the appropriate `mirror` type.
-    fn mirror<M:Mirror<Self>>(&mut self, ast: M) -> M::Output {
-        ast.make_mirror(self)
-    }
-
-    /// Returns the unit type `()`
-    fn unit_ty(&mut self) -> Self::Ty;
-
-    /// Returns the type `usize`.
-    fn usize_ty(&mut self) -> Self::Ty;
-
-    /// Returns the literal for `value` as a `usize`.
-    fn usize_literal(&mut self, value: usize) -> Literal<Self>;
-
-    /// Returns the type `bool`.
-    fn bool_ty(&mut self) -> Self::Ty;
-
-    /// Returns the literal for `true`
-    fn true_literal(&mut self) -> Literal<Self>;
-
-    /// Returns the literal for `false`
-    fn false_literal(&mut self) -> Literal<Self>;
-
-    /// Returns a reference to `PartialEq::<T,T>::eq`
-    fn partial_eq(&mut self, ty: Self::Ty) -> ItemRef<Self>;
-
-    /// Returns a reference to `PartialOrd::<T,T>::le`
-    fn partial_le(&mut self, ty: Self::Ty) -> ItemRef<Self>;
-
-    /// Returns the number of variants for the given enum
-    fn num_variants(&mut self, adt: Self::AdtDef) -> usize;
-
-    fn fields(&mut self, adt: Self::AdtDef, variant_index: usize) -> Vec<Field<Self>>;
-
-    /// true if a value of type `ty` (may) need to be dropped; this
-    /// may return false even for non-Copy types if there is no
-    /// destructor to execute. If correct result is not known, may be
-    /// approximated by returning `true`; this will result in more
-    /// drops but not incorrect code.
-    fn needs_drop(&mut self, ty: Self::Ty, span: Self::Span) -> bool;
-
-    /// Report an internal inconsistency.
-    fn span_bug(&mut self, span: Self::Span, message: &str) -> !;
-}
+use rustc::middle::def_id::DefId;
+use rustc::middle::region::CodeExtent;
+use rustc::middle::subst::Substs;
+use rustc::middle::ty::{AdtDef, ClosureSubsts, Region, Ty};
+use rustc_front::hir;
+use syntax::ast;
+use syntax::codemap::Span;
+use tcx::{Cx, PatNode};
 
 #[derive(Clone, Debug)]
-pub struct ItemRef<H:Hair> {
-    pub ty: H::Ty,
-    pub def_id: H::DefId,
-    pub substs: H::Substs,
+pub struct ItemRef<'tcx> {
+    pub ty: Ty<'tcx>,
+    pub def_id: DefId,
+    pub substs: &'tcx Substs<'tcx>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Block<H:Hair> {
-    pub extent: H::CodeExtent,
-    pub span: H::Span,
-    pub stmts: Vec<StmtRef<H>>,
-    pub expr: Option<ExprRef<H>>,
+pub struct Block<'tcx> {
+    pub extent: CodeExtent,
+    pub span: Span,
+    pub stmts: Vec<StmtRef<'tcx>>,
+    pub expr: Option<ExprRef<'tcx>>,
 }
 
 #[derive(Clone, Debug)]
-pub enum StmtRef<H:Hair> {
-    Hair(H::Stmt),
-    Mirror(Box<Stmt<H>>),
+pub enum StmtRef<'tcx> {
+    Hair(&'tcx hir::Stmt),
+    Mirror(Box<Stmt<'tcx>>),
 }
 
 #[derive(Clone, Debug)]
-pub struct Stmt<H:Hair> {
-    pub span: H::Span,
-    pub kind: StmtKind<H>,
+pub struct Stmt<'tcx> {
+    pub span: Span,
+    pub kind: StmtKind<'tcx>,
 }
 
 #[derive(Clone, Debug)]
-pub enum StmtKind<H:Hair> {
+pub enum StmtKind<'tcx> {
     Expr {
         /// scope for this statement; may be used as lifetime of temporaries
-        scope: H::CodeExtent,
+        scope: CodeExtent,
 
         /// expression being evaluated in this statement
-        expr: ExprRef<H>
+        expr: ExprRef<'tcx>
     },
 
     Let {
         /// scope for variables bound in this let; covers this and
         /// remaining statements in block
-        remainder_scope: H::CodeExtent,
+        remainder_scope: CodeExtent,
 
         /// scope for the initialization itself; might be used as
         /// lifetime of temporaries
-        init_scope: H::CodeExtent,
+        init_scope: CodeExtent,
 
         /// let <PAT> = ...
-        pattern: PatternRef<H>,
+        pattern: PatternRef<'tcx>,
 
         /// let pat = <INIT> ...
-        initializer: Option<ExprRef<H>>,
+        initializer: Option<ExprRef<'tcx>>,
 
         /// let pat = init; <STMTS>
-        stmts: Vec<StmtRef<H>>
+        stmts: Vec<StmtRef<'tcx>>
     },
 }
 
-// The Hair trait implementor translates their expressions (`H::Expr`)
+// The Hair trait implementor translates their expressions (`&'tcx H::Expr`)
 // into instances of this `Expr` enum. This translation can be done
 // basically as lazilly or as eagerly as desired: every recursive
-// reference to an expression in this enum is an `ExprRef<H>`, which
+// reference to an expression in this enum is an `ExprRef<'tcx>`, which
 // may in turn be another instance of this enum (boxed), or else an
-// untranslated `H::Expr`. Note that instances of `Expr` are very
+// untranslated `&'tcx H::Expr`. Note that instances of `Expr` are very
 // shortlived. They are created by `Hair::to_expr`, analyzed and
 // converted into MIR, and then discarded.
 //
@@ -162,87 +96,88 @@ pub enum StmtKind<H:Hair> {
 // example, method calls and overloaded operators are absent: they are
 // expected to be converted into `Expr::Call` instances.
 #[derive(Clone, Debug)]
-pub struct Expr<H:Hair> {
+pub struct Expr<'tcx> {
     // type of this expression
-    pub ty: H::Ty,
+    pub ty: Ty<'tcx>,
 
     // lifetime of this expression if it should be spilled into a
     // temporary; should be None only if in a constant context
-    pub temp_lifetime: Option<H::CodeExtent>,
+    pub temp_lifetime: Option<CodeExtent>,
 
     // span of the expression in the source
-    pub span: H::Span,
+    pub span: Span,
 
     // kind of expression
-    pub kind: ExprKind<H>,
+    pub kind: ExprKind<'tcx>,
 }
 
 #[derive(Clone, Debug)]
-pub enum ExprKind<H:Hair> {
-    Scope { extent: H::CodeExtent, value: ExprRef<H> },
-    Box { value: ExprRef<H> },
-    Call { fun: ExprRef<H>, args: Vec<ExprRef<H>> },
-    Deref { arg: ExprRef<H> }, // NOT overloaded!
-    Binary { op: BinOp, lhs: ExprRef<H>, rhs: ExprRef<H> }, // NOT overloaded!
-    LogicalOp { op: LogicalOp, lhs: ExprRef<H>, rhs: ExprRef<H> },
-    Unary { op: UnOp, arg: ExprRef<H> }, // NOT overloaded!
-    Cast { source: ExprRef<H> },
-    ReifyFnPointer { source: ExprRef<H> },
-    UnsafeFnPointer { source: ExprRef<H> },
-    Unsize { source: ExprRef<H> },
-    If { condition: ExprRef<H>, then: ExprRef<H>, otherwise: Option<ExprRef<H>> },
-    Loop { condition: Option<ExprRef<H>>, body: ExprRef<H>, },
-    Match { discriminant: ExprRef<H>, arms: Vec<Arm<H>> },
-    Block { body: H::Block },
-    Assign { lhs: ExprRef<H>, rhs: ExprRef<H> },
-    AssignOp { op: BinOp, lhs: ExprRef<H>, rhs: ExprRef<H> },
-    Field { lhs: ExprRef<H>, name: Field<H> },
-    Index { lhs: ExprRef<H>, index: ExprRef<H> },
-    VarRef { id: H::VarId },
+pub enum ExprKind<'tcx> {
+    Scope { extent: CodeExtent, value: ExprRef<'tcx> },
+    Box { value: ExprRef<'tcx> },
+    Call { fun: ExprRef<'tcx>, args: Vec<ExprRef<'tcx>> },
+    Deref { arg: ExprRef<'tcx> }, // NOT overloaded!
+    Binary { op: BinOp, lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> }, // NOT overloaded!
+    LogicalOp { op: LogicalOp, lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> },
+    Unary { op: UnOp, arg: ExprRef<'tcx> }, // NOT overloaded!
+    Cast { source: ExprRef<'tcx> },
+    ReifyFnPointer { source: ExprRef<'tcx> },
+    UnsafeFnPointer { source: ExprRef<'tcx> },
+    Unsize { source: ExprRef<'tcx> },
+    If { condition: ExprRef<'tcx>, then: ExprRef<'tcx>, otherwise: Option<ExprRef<'tcx>> },
+    Loop { condition: Option<ExprRef<'tcx>>, body: ExprRef<'tcx>, },
+    Match { discriminant: ExprRef<'tcx>, arms: Vec<Arm<'tcx>> },
+    Block { body: &'tcx hir::Block },
+    Assign { lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> },
+    AssignOp { op: BinOp, lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> },
+    Field { lhs: ExprRef<'tcx>, name: Field },
+    Index { lhs: ExprRef<'tcx>, index: ExprRef<'tcx> },
+    VarRef { id: ast::NodeId },
     SelfRef, // first argument, used for self in a closure
-    StaticRef { id: H::DefId },
-    Borrow { region: H::Region, borrow_kind: BorrowKind, arg: ExprRef<H> },
-    Break { label: Option<H::CodeExtent> },
-    Continue { label: Option<H::CodeExtent> },
-    Return { value: Option<ExprRef<H>> },
-    Repeat { value: ExprRef<H>, count: ExprRef<H> },
-    Vec { fields: Vec<ExprRef<H>> },
-    Tuple { fields: Vec<ExprRef<H>> },
-    Adt { adt_def: H::AdtDef,
+    StaticRef { id: DefId },
+    Borrow { region: Region, borrow_kind: BorrowKind, arg: ExprRef<'tcx> },
+    Break { label: Option<CodeExtent> },
+    Continue { label: Option<CodeExtent> },
+    Return { value: Option<ExprRef<'tcx>> },
+    Repeat { value: ExprRef<'tcx>, count: ExprRef<'tcx> },
+    Vec { fields: Vec<ExprRef<'tcx>> },
+    Tuple { fields: Vec<ExprRef<'tcx>> },
+    Adt { adt_def: AdtDef<'tcx>,
           variant_index: usize,
-          substs: H::Substs,
-          fields: Vec<FieldExprRef<H>>,
-          base: Option<ExprRef<H>> },
-    Closure { closure_id: H::DefId, substs: H::ClosureSubsts,
-              upvars: Vec<ExprRef<H>> },
-    Literal { literal: Literal<H> },
-    InlineAsm { asm: H::InlineAsm },
+          substs: &'tcx Substs<'tcx>,
+          fields: Vec<FieldExprRef<'tcx>>,
+          base: Option<ExprRef<'tcx>> },
+    Closure { closure_id: DefId,
+              substs: &'tcx ClosureSubsts<'tcx>,
+              upvars: Vec<ExprRef<'tcx>> },
+    Literal { literal: Literal<'tcx> },
+    InlineAsm { asm: &'tcx hir::InlineAsm },
 }
 
 #[derive(Clone, Debug)]
-pub enum ExprRef<H:Hair> {
-    Hair(H::Expr),
-    Mirror(Box<Expr<H>>),
+pub enum ExprRef<'tcx> {
+    Hair(&'tcx hir::Expr),
+    Mirror(Box<Expr<'tcx>>),
 }
 
 #[derive(Clone, Debug)]
-pub struct FieldExprRef<H:Hair> {
-    pub name: Field<H>,
-    pub expr: ExprRef<H>,
+pub struct FieldExprRef<'tcx> {
+    pub name: Field,
+    pub expr: ExprRef<'tcx>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Arm<H:Hair> {
-    pub patterns: Vec<PatternRef<H>>,
-    pub guard: Option<ExprRef<H>>,
-    pub body: ExprRef<H>,
+pub struct Arm<'tcx> {
+    pub patterns: Vec<PatternRef<'tcx>>,
+    pub guard: Option<ExprRef<'tcx>>,
+    pub body: ExprRef<'tcx>,
 }
 
 #[derive(Clone, Debug)]
-pub struct Pattern<H:Hair> {
-    pub ty: H::Ty,
-    pub span: H::Span,
-    pub kind: PatternKind<H>,
+pub struct Pattern<'tcx> {
+    pub ty: Ty<'tcx>,
+    pub span: Span,
+    pub kind: PatternKind<'tcx>,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -252,89 +187,93 @@ pub enum LogicalOp {
 }
 
 #[derive(Clone, Debug)]
-pub enum PatternKind<H:Hair> {
+pub enum PatternKind<'tcx> {
     Wild,
 
     // x, ref x, x @ P, etc
     Binding { mutability: Mutability,
-              name: H::Name,
-              mode: BindingMode<H>,
-              var: H::VarId,
-              ty: H::Ty,
-              subpattern: Option<PatternRef<H>> },
+              name: ast::Name,
+              mode: BindingMode,
+              var: ast::NodeId,
+              ty: Ty<'tcx>,
+              subpattern: Option<PatternRef<'tcx>> },
 
     // Foo(...) or Foo{...} or Foo, where `Foo` is a variant name from an adt with >1 variants
-    Variant { adt_def: H::AdtDef, variant_index: usize, subpatterns: Vec<FieldPatternRef<H>> },
+    Variant { adt_def: AdtDef<'tcx>,
+              variant_index: usize,
+              subpatterns: Vec<FieldPatternRef<'tcx>> },
 
     // (...), Foo(...), Foo{...}, or Foo, where `Foo` is a variant name from an adt with 1 variant
-    Leaf { subpatterns: Vec<FieldPatternRef<H>> },
+    Leaf { subpatterns: Vec<FieldPatternRef<'tcx>> },
 
-    Deref { subpattern: PatternRef<H> }, // box P, &P, &mut P, etc
+    Deref { subpattern: PatternRef<'tcx> }, // box P, &P, &mut P, etc
 
-    Constant { value: Literal<H> },
+    Constant { value: Literal<'tcx> },
 
-    Range { lo: Literal<H>, hi: Literal<H> },
+    Range { lo: Literal<'tcx>, hi: Literal<'tcx> },
 
     // matches against a slice, checking the length and extracting elements
-    Slice { prefix: Vec<PatternRef<H>>,
-            slice: Option<PatternRef<H>>,
-            suffix: Vec<PatternRef<H>> },
+    Slice { prefix: Vec<PatternRef<'tcx>>,
+            slice: Option<PatternRef<'tcx>>,
+            suffix: Vec<PatternRef<'tcx>> },
 
     // fixed match against an array, irrefutable
-    Array { prefix: Vec<PatternRef<H>>,
-            slice: Option<PatternRef<H>>,
-            suffix: Vec<PatternRef<H>> },
+    Array { prefix: Vec<PatternRef<'tcx>>,
+            slice: Option<PatternRef<'tcx>>,
+            suffix: Vec<PatternRef<'tcx>> },
 }
 
 #[derive(Copy, Clone, Debug)]
-pub enum BindingMode<H:Hair> {
+pub enum BindingMode {
     ByValue,
-    ByRef(H::Region, BorrowKind),
+    ByRef(Region, BorrowKind),
 }
 
 #[derive(Clone, Debug)]
-pub enum PatternRef<H:Hair> {
-    Hair(H::Pattern),
-    Mirror(Box<Pattern<H>>),
+pub enum PatternRef<'tcx> {
+    Hair(PatNode<'tcx>),
+    Mirror(Box<Pattern<'tcx>>),
 }
 
 #[derive(Clone, Debug)]
-pub struct FieldPatternRef<H:Hair> {
-    pub field: Field<H>,
-    pub pattern: PatternRef<H>,
+pub struct FieldPatternRef<'tcx> {
+    pub field: Field,
+    pub pattern: PatternRef<'tcx>,
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // The Mirror trait
 
-/// "Mirroring" is the process of converting from a Hair type into one
-/// of the types in this file. For example, the mirror of a `H::Expr`
-/// is an `Expr<H>`. Mirroring is the point at which the actual IR is
-/// converting into the more idealized representation described in
-/// this file. Mirroring is gradual: when you mirror an outer
-/// expression like `e1 + e2`, the references to the inner expressions
-/// `e1` and `e2` are `ExprRef<H>` instances, and they may or may not
-/// be eagerly mirrored.  This allows a single AST node from the
-/// compiler to expand into one or more Hair nodes, which lets the Hair
-/// nodes be simpler.
-pub trait Mirror<H:Hair> {
+/// "Mirroring" is the process of converting from a HIR type into one
+/// of the HAIR types defined in this file. This is basically a "on
+/// the fly" desugaring step that hides a lot of the messiness in the
+/// tcx. For example, the mirror of a `&'tcx hir::Expr` is an
+/// `Expr<'tcx>`.
+///
+/// Mirroring is gradual: when you mirror an outer expression like `e1
+/// + e2`, the references to the inner expressions `e1` and `e2` are
+/// `ExprRef<'tcx>` instances, and they may or may not be eagerly
+/// mirrored.  This allows a single AST node from the compiler to
+/// expand into one or more Hair nodes, which lets the Hair nodes be
+/// simpler.
+pub trait Mirror<'tcx> {
     type Output;
 
-    fn make_mirror(self, hir: &mut H) -> Self::Output;
+    fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Self::Output;
 }
 
-impl<H:Hair> Mirror<H> for Expr<H> {
-    type Output = Expr<H>;
+impl<'tcx> Mirror<'tcx> for Expr<'tcx> {
+    type Output = Expr<'tcx>;
 
-    fn make_mirror(self, _: &mut H) -> Expr<H> {
+    fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Expr<'tcx> {
         self
     }
 }
 
-impl<H:Hair> Mirror<H> for ExprRef<H> {
-    type Output = Expr<H>;
+impl<'tcx> Mirror<'tcx> for ExprRef<'tcx> {
+    type Output = Expr<'tcx>;
 
-    fn make_mirror(self, hir: &mut H) -> Expr<H> {
+    fn make_mirror<'a>(self, hir: &mut Cx<'a,'tcx>) -> Expr<'tcx> {
         match self {
             ExprRef::Hair(h) => h.make_mirror(hir),
             ExprRef::Mirror(m) => *m,
@@ -342,18 +281,18 @@ impl<H:Hair> Mirror<H> for ExprRef<H> {
     }
 }
 
-impl<H:Hair> Mirror<H> for Stmt<H> {
-    type Output = Stmt<H>;
+impl<'tcx> Mirror<'tcx> for Stmt<'tcx> {
+    type Output = Stmt<'tcx>;
 
-    fn make_mirror(self, _: &mut H) -> Stmt<H> {
+    fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Stmt<'tcx> {
         self
     }
 }
 
-impl<H:Hair> Mirror<H> for StmtRef<H> {
-    type Output = Stmt<H>;
+impl<'tcx> Mirror<'tcx> for StmtRef<'tcx> {
+    type Output = Stmt<'tcx>;
 
-    fn make_mirror(self, hir: &mut H) -> Stmt<H> {
+    fn make_mirror<'a>(self, hir: &mut Cx<'a,'tcx>) -> Stmt<'tcx> {
         match self {
             StmtRef::Hair(h) => h.make_mirror(hir),
             StmtRef::Mirror(m) => *m,
@@ -361,18 +300,18 @@ impl<H:Hair> Mirror<H> for StmtRef<H> {
     }
 }
 
-impl<H:Hair> Mirror<H> for Pattern<H> {
-    type Output = Pattern<H>;
+impl<'tcx> Mirror<'tcx> for Pattern<'tcx> {
+    type Output = Pattern<'tcx>;
 
-    fn make_mirror(self, _: &mut H) -> Pattern<H> {
+    fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Pattern<'tcx> {
         self
     }
 }
 
-impl<H:Hair> Mirror<H> for PatternRef<H> {
-    type Output = Pattern<H>;
+impl<'tcx> Mirror<'tcx> for PatternRef<'tcx> {
+    type Output = Pattern<'tcx>;
 
-    fn make_mirror(self, hir: &mut H) -> Pattern<H> {
+    fn make_mirror<'a>(self, hir: &mut Cx<'a,'tcx>) -> Pattern<'tcx> {
         match self {
             PatternRef::Hair(h) => h.make_mirror(hir),
             PatternRef::Mirror(m) => *m,
@@ -380,10 +319,10 @@ impl<H:Hair> Mirror<H> for PatternRef<H> {
     }
 }
 
-impl<H:Hair> Mirror<H> for Block<H> {
-    type Output = Block<H>;
+impl<'tcx> Mirror<'tcx> for Block<'tcx> {
+    type Output = Block<'tcx>;
 
-    fn make_mirror(self, _: &mut H) -> Block<H> {
+    fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Block<'tcx> {
         self
     }
 }
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index ebec1609959..eda9146cefa 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -24,10 +24,13 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 
 #[macro_use] extern crate log;
 extern crate graphviz as dot;
+extern crate rustc;
 extern crate rustc_data_structures;
+extern crate rustc_front;
+extern crate syntax;
 
 pub mod build;
-pub mod dump;
+pub mod mir_map;
 pub mod hair;
 pub mod repr;
 mod graphviz;
diff --git a/src/librustc_mir/dump.rs b/src/librustc_mir/mir_map.rs
index 4251b550cfc..1bf9f00ac3a 100644
--- a/src/librustc_mir/dump.rs
+++ b/src/librustc_mir/mir_map.rs
@@ -30,15 +30,22 @@ use self::rustc::middle::infer;
 use self::rustc::middle::region::CodeExtentData;
 use self::rustc::middle::ty::{self, Ty};
 use self::rustc::util::common::ErrorReported;
+use self::rustc::util::nodemap::NodeMap;
 use self::rustc_front::hir;
 use self::rustc_front::visit;
 use self::syntax::ast;
 use self::syntax::attr::AttrMetaMethods;
 use self::syntax::codemap::Span;
 
-pub fn dump_crate(tcx: &ty::ctxt) {
-    let mut dump = OuterDump { tcx: tcx };
-    visit::walk_crate(&mut dump, tcx.map.krate());
+pub type MirMap<'tcx> = NodeMap<Mir<'tcx>>;
+
+pub fn build_mir_for_crate<'tcx>(tcx: &ty::ctxt<'tcx>) -> MirMap<'tcx>{
+    let mut map = NodeMap();
+    {
+        let mut dump = OuterDump { tcx: tcx, map: &mut map };
+        visit::walk_crate(&mut dump, tcx.map.krate());
+    }
+    map
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -46,27 +53,20 @@ pub fn dump_crate(tcx: &ty::ctxt) {
 
 struct OuterDump<'a,'tcx:'a> {
     tcx: &'a ty::ctxt<'tcx>,
+    map: &'a mut MirMap<'tcx>,
 }
 
 impl<'a, 'tcx> OuterDump<'a, 'tcx> {
-    fn visit_mir<OP>(&self, attributes: &'tcx [ast::Attribute], mut walk_op: OP)
-        where OP: FnMut(&mut InnerDump<'a,'tcx>)
+    fn visit_mir<OP>(&mut self, attributes: &'a [ast::Attribute], mut walk_op: OP)
+        where OP: for<'m> FnMut(&mut InnerDump<'a,'m,'tcx>)
     {
-        let mut built_mir = false;
-
+        let mut closure_dump = InnerDump { tcx: self.tcx, attr: None, map: &mut *self.map };
         for attr in attributes {
             if attr.check_name("rustc_mir") {
-                let mut closure_dump = InnerDump { tcx: self.tcx, attr: Some(attr) };
-                walk_op(&mut closure_dump);
-                built_mir = true;
+                closure_dump.attr = Some(attr);
             }
         }
-
-        let always_build_mir = true;
-        if !built_mir && always_build_mir {
-            let mut closure_dump = InnerDump { tcx: self.tcx, attr: None };
-            walk_op(&mut closure_dump);
-        }
+        walk_op(&mut closure_dump);
     }
 }
 
@@ -82,25 +82,47 @@ impl<'a, 'tcx> visit::Visitor<'tcx> for OuterDump<'a, 'tcx> {
             hir::MethodTraitItem(_, Some(_)) => {
                 self.visit_mir(&trait_item.attrs, |c| visit::walk_trait_item(c, trait_item));
             }
-            _ => { }
+            hir::MethodTraitItem(_, None) |
+            hir::ConstTraitItem(..) |
+            hir::TypeTraitItem(..) => {
+            }
         }
         visit::walk_trait_item(self, trait_item);
     }
+
+    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
+        match impl_item.node {
+            hir::MethodImplItem(..) => {
+                self.visit_mir(&impl_item.attrs, |c| visit::walk_impl_item(c, impl_item));
+            }
+            hir::ConstImplItem(..) | hir::TypeImplItem(..) => { }
+        }
+        visit::walk_impl_item(self, impl_item);
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // InnerDump -- dumps MIR for a single fn and its contained closures
 
-struct InnerDump<'a,'tcx:'a> {
+struct InnerDump<'a,'m,'tcx:'a+'m> {
     tcx: &'a ty::ctxt<'tcx>,
+    map: &'m mut MirMap<'tcx>,
     attr: Option<&'a ast::Attribute>,
 }
 
-impl<'a, 'tcx> visit::Visitor<'tcx> for InnerDump<'a,'tcx> {
+impl<'a, 'm, 'tcx> visit::Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
     fn visit_item(&mut self, _: &'tcx hir::Item) {
         // ignore nested items; they need their own graphviz annotation
     }
 
+    fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {
+        // ignore nested items; they need their own graphviz annotation
+    }
+
+    fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {
+        // ignore nested items; they need their own graphviz annotation
+    }
+
     fn visit_fn(&mut self,
                 fk: visit::FnKind<'tcx>,
                 decl: &'tcx hir::FnDecl,
@@ -155,6 +177,9 @@ impl<'a, 'tcx> visit::Visitor<'tcx> for InnerDump<'a,'tcx> {
                         }
                     }
                 }
+
+                let previous = self.map.insert(id, mir);
+                assert!(previous.is_none());
             }
             Err(ErrorReported) => { }
         }
@@ -169,18 +194,18 @@ fn build_mir<'a,'tcx:'a>(cx: Cx<'a,'tcx>,
                          span: Span,
                          decl: &'tcx hir::FnDecl,
                          body: &'tcx hir::Block)
-                         -> Result<Mir<Cx<'a,'tcx>>, ErrorReported> {
+                         -> Result<Mir<'tcx>, ErrorReported> {
     let arguments =
         decl.inputs
             .iter()
             .map(|arg| {
-                let ty = cx.tcx.node_id_to_type(arg.id);
+                let ty = cx.tcx().node_id_to_type(arg.id);
                 (ty, PatNode::irrefutable(&arg.pat))
             })
             .collect();
 
     let parameter_scope =
-        cx.tcx.region_maps.lookup_code_extent(
+        cx.tcx().region_maps.lookup_code_extent(
             CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.id });
     Ok(build::construct(cx,
                         span,
diff --git a/src/librustc_mir/repr.rs b/src/librustc_mir/repr.rs
index d522518a3d4..bffc44bccbd 100644
--- a/src/librustc_mir/repr.rs
+++ b/src/librustc_mir/repr.rs
@@ -8,22 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use hair::Hair;
+use rustc::middle::const_eval::ConstVal;
+use rustc::middle::def_id::DefId;
+use rustc::middle::region::CodeExtent;
+use rustc::middle::subst::Substs;
+use rustc::middle::ty::{AdtDef, ClosureSubsts, Region, Ty};
 use rustc_data_structures::fnv::FnvHashMap;
+use rustc_front::hir::InlineAsm;
+use syntax::ast::Name;
+use syntax::codemap::Span;
 use std::fmt::{Debug, Formatter, Error};
 use std::slice;
 use std::u32;
 
 /// Lowered representation of a single function.
-pub struct Mir<H:Hair> {
-    pub basic_blocks: Vec<BasicBlockData<H>>,
+pub struct Mir<'tcx> {
+    pub basic_blocks: Vec<BasicBlockData<'tcx>>,
 
     // for every node id
-    pub extents: FnvHashMap<H::CodeExtent, Vec<GraphExtent>>,
+    pub extents: FnvHashMap<CodeExtent, Vec<GraphExtent>>,
 
-    pub var_decls: Vec<VarDecl<H>>,
-    pub arg_decls: Vec<ArgDecl<H>>,
-    pub temp_decls: Vec<TempDecl<H>>,
+    pub var_decls: Vec<VarDecl<'tcx>>,
+    pub arg_decls: Vec<ArgDecl<'tcx>>,
+    pub temp_decls: Vec<TempDecl<'tcx>>,
 }
 
 /// where execution begins
@@ -35,18 +42,18 @@ pub const END_BLOCK: BasicBlock = BasicBlock(1);
 /// where execution ends, on panic
 pub const DIVERGE_BLOCK: BasicBlock = BasicBlock(2);
 
-impl<H:Hair> Mir<H> {
+impl<'tcx> Mir<'tcx> {
     pub fn all_basic_blocks(&self) -> Vec<BasicBlock> {
         (0..self.basic_blocks.len())
             .map(|i| BasicBlock::new(i))
             .collect()
     }
 
-    pub fn basic_block_data(&self, bb: BasicBlock) -> &BasicBlockData<H> {
+    pub fn basic_block_data(&self, bb: BasicBlock) -> &BasicBlockData<'tcx> {
         &self.basic_blocks[bb.index()]
     }
 
-    pub fn basic_block_data_mut(&mut self, bb: BasicBlock) -> &mut BasicBlockData<H> {
+    pub fn basic_block_data_mut(&mut self, bb: BasicBlock) -> &mut BasicBlockData<'tcx> {
         &mut self.basic_blocks[bb.index()]
     }
 }
@@ -111,16 +118,16 @@ pub enum BorrowKind {
 
 // A "variable" is a binding declared by the user as part of the fn
 // decl, a let, etc.
-pub struct VarDecl<H:Hair> {
+pub struct VarDecl<'tcx> {
     pub mutability: Mutability,
-    pub name: H::Name,
-    pub ty: H::Ty,
+    pub name: Name,
+    pub ty: Ty<'tcx>,
 }
 
 // A "temp" is a temporary that we place on the stack. They are
 // anonymous, always mutable, and have only a type.
-pub struct TempDecl<H:Hair> {
-    pub ty: H::Ty,
+pub struct TempDecl<'tcx> {
+    pub ty: Ty<'tcx>,
 }
 
 // A "arg" is one of the function's formal arguments. These are
@@ -134,8 +141,8 @@ pub struct TempDecl<H:Hair> {
 //
 // there is only one argument, of type `(i32, u32)`, but two bindings
 // (`x` and `y`).
-pub struct ArgDecl<H:Hair> {
-    pub ty: H::Ty,
+pub struct ArgDecl<'tcx> {
+    pub ty: Ty<'tcx>,
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -212,12 +219,12 @@ impl Debug for BasicBlock {
 // BasicBlock and Terminator
 
 #[derive(Debug)]
-pub struct BasicBlockData<H:Hair> {
-    pub statements: Vec<Statement<H>>,
-    pub terminator: Terminator<H>,
+pub struct BasicBlockData<'tcx> {
+    pub statements: Vec<Statement<'tcx>>,
+    pub terminator: Terminator<'tcx>,
 }
 
-pub enum Terminator<H:Hair> {
+pub enum Terminator<'tcx> {
     /// block should have one successor in the graph; we jump there
     Goto { target: BasicBlock },
 
@@ -226,10 +233,10 @@ pub enum Terminator<H:Hair> {
     Panic { target: BasicBlock },
 
     /// jump to branch 0 if this lvalue evaluates to true
-    If { cond: Operand<H>, targets: [BasicBlock; 2] },
+    If { cond: Operand<'tcx>, targets: [BasicBlock; 2] },
 
     /// lvalue evaluates to some enum; jump depending on the branch
-    Switch { discr: Lvalue<H>, targets: Vec<BasicBlock> },
+    Switch { discr: Lvalue<'tcx>, targets: Vec<BasicBlock> },
 
     /// Indicates that the last statement in the block panics, aborts,
     /// etc. No successors. This terminator appears on exactly one
@@ -247,10 +254,10 @@ pub enum Terminator<H:Hair> {
     /// block ends with a call; it should have two successors. The
     /// first successor indicates normal return. The second indicates
     /// unwinding.
-    Call { data: CallData<H>, targets: [BasicBlock; 2] },
+    Call { data: CallData<'tcx>, targets: [BasicBlock; 2] },
 }
 
-impl<H:Hair> Terminator<H> {
+impl<'tcx> Terminator<'tcx> {
     pub fn successors(&self) -> &[BasicBlock] {
         use self::Terminator::*;
         match *self {
@@ -266,19 +273,19 @@ impl<H:Hair> Terminator<H> {
 }
 
 #[derive(Debug)]
-pub struct CallData<H:Hair> {
+pub struct CallData<'tcx> {
     /// where the return value is written to
-    pub destination: Lvalue<H>,
+    pub destination: Lvalue<'tcx>,
 
     /// the fn being called
-    pub func: Lvalue<H>,
+    pub func: Lvalue<'tcx>,
 
     /// the arguments
-    pub args: Vec<Lvalue<H>>,
+    pub args: Vec<Lvalue<'tcx>>,
 }
 
-impl<H:Hair> BasicBlockData<H> {
-    pub fn new(terminator: Terminator<H>) -> BasicBlockData<H> {
+impl<'tcx> BasicBlockData<'tcx> {
+    pub fn new(terminator: Terminator<'tcx>) -> BasicBlockData<'tcx> {
         BasicBlockData {
             statements: vec![],
             terminator: terminator,
@@ -286,7 +293,7 @@ impl<H:Hair> BasicBlockData<H> {
     }
 }
 
-impl<H:Hair> Debug for Terminator<H> {
+impl<'tcx> Debug for Terminator<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
         use self::Terminator::*;
         match *self {
@@ -318,15 +325,15 @@ impl<H:Hair> Debug for Terminator<H> {
 ///////////////////////////////////////////////////////////////////////////
 // Statements
 
-pub struct Statement<H:Hair> {
-    pub span: H::Span,
-    pub kind: StatementKind<H>,
+pub struct Statement<'tcx> {
+    pub span: Span,
+    pub kind: StatementKind<'tcx>,
 }
 
 #[derive(Debug)]
-pub enum StatementKind<H:Hair> {
-    Assign(Lvalue<H>, Rvalue<H>),
-    Drop(DropKind, Lvalue<H>),
+pub enum StatementKind<'tcx> {
+    Assign(Lvalue<'tcx>, Rvalue<'tcx>),
+    Drop(DropKind, Lvalue<'tcx>),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -335,7 +342,7 @@ pub enum DropKind {
     Deep
 }
 
-impl<H:Hair> Debug for Statement<H> {
+impl<'tcx> Debug for Statement<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
         use self::StatementKind::*;
         match self.kind {
@@ -351,7 +358,7 @@ impl<H:Hair> Debug for Statement<H> {
 /// A path to a value; something that can be evaluated without
 /// changing or disturbing program state.
 #[derive(Clone, PartialEq)]
-pub enum Lvalue<H:Hair> {
+pub enum Lvalue<'tcx> {
     /// local variable declared by the user
     Var(u32),
 
@@ -363,13 +370,13 @@ pub enum Lvalue<H:Hair> {
     Arg(u32),
 
     /// static or static mut variable
-    Static(H::DefId),
+    Static(DefId),
 
     /// the return pointer of the fn
     ReturnPointer,
 
     /// projection out of an lvalue (access a field, deref a pointer, etc)
-    Projection(Box<LvalueProjection<H>>)
+    Projection(Box<LvalueProjection<'tcx>>)
 }
 
 /// The `Projection` data structure defines things of the form `B.x`
@@ -377,15 +384,15 @@ pub enum Lvalue<H:Hair> {
 /// shared between `Constant` and `Lvalue`. See the aliases
 /// `LvalueProjection` etc below.
 #[derive(Clone, Debug, PartialEq)]
-pub struct Projection<H:Hair,B,V> {
+pub struct Projection<'tcx,B,V> {
     pub base: B,
-    pub elem: ProjectionElem<H,V>,
+    pub elem: ProjectionElem<'tcx,V>,
 }
 
 #[derive(Clone, Debug, PartialEq)]
-pub enum ProjectionElem<H:Hair,V> {
+pub enum ProjectionElem<'tcx,V> {
     Deref,
-    Field(Field<H>),
+    Field(Field),
     Index(V),
 
     // These indices are generated by slice patterns. Easiest to explain
@@ -406,44 +413,44 @@ pub enum ProjectionElem<H:Hair,V> {
     // "Downcast" to a variant of an ADT. Currently, we only introduce
     // this for ADTs with more than one variant. It may be better to
     // just introduce it always, or always for enums.
-    Downcast(H::AdtDef, usize),
+    Downcast(AdtDef<'tcx>, usize),
 }
 
 /// Alias for projections as they appear in lvalues, where the base is an lvalue
 /// and the index is an operand.
-pub type LvalueProjection<H> =
-    Projection<H,Lvalue<H>,Operand<H>>;
+pub type LvalueProjection<'tcx> =
+    Projection<'tcx,Lvalue<'tcx>,Operand<'tcx>>;
 
 /// Alias for projections as they appear in lvalues, where the base is an lvalue
 /// and the index is an operand.
-pub type LvalueElem<H> =
-    ProjectionElem<H,Operand<H>>;
+pub type LvalueElem<'tcx> =
+    ProjectionElem<'tcx,Operand<'tcx>>;
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum Field<H:Hair> {
-    Named(H::Name),
+pub enum Field {
+    Named(Name),
     Indexed(usize),
 }
 
-impl<H:Hair> Lvalue<H> {
-    pub fn field(self, f: Field<H>) -> Lvalue<H> {
+impl<'tcx> Lvalue<'tcx> {
+    pub fn field(self, f: Field) -> Lvalue<'tcx> {
         self.elem(ProjectionElem::Field(f))
     }
 
-    pub fn deref(self) -> Lvalue<H> {
+    pub fn deref(self) -> Lvalue<'tcx> {
         self.elem(ProjectionElem::Deref)
     }
 
-    pub fn index(self, index: Operand<H>) -> Lvalue<H> {
+    pub fn index(self, index: Operand<'tcx>) -> Lvalue<'tcx> {
         self.elem(ProjectionElem::Index(index))
     }
 
-    pub fn elem(self, elem: LvalueElem<H>) -> Lvalue<H> {
+    pub fn elem(self, elem: LvalueElem<'tcx>) -> Lvalue<'tcx> {
         Lvalue::Projection(Box::new(LvalueProjection { base: self, elem: elem }))
     }
 }
 
-impl<H:Hair> Debug for Lvalue<H> {
+impl<'tcx> Debug for Lvalue<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
         use self::Lvalue::*;
 
@@ -487,12 +494,12 @@ impl<H:Hair> Debug for Lvalue<H> {
 // being nested in one another.
 
 #[derive(Clone, PartialEq)]
-pub enum Operand<H:Hair> {
-    Consume(Lvalue<H>),
-    Constant(Constant<H>),
+pub enum Operand<'tcx> {
+    Consume(Lvalue<'tcx>),
+    Constant(Constant<'tcx>),
 }
 
-impl<H:Hair> Debug for Operand<H> {
+impl<'tcx> Debug for Operand<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
         use self::Operand::*;
         match *self {
@@ -506,34 +513,34 @@ impl<H:Hair> Debug for Operand<H> {
 // Rvalues
 
 #[derive(Clone)]
-pub enum Rvalue<H:Hair> {
+pub enum Rvalue<'tcx> {
     // x (either a move or copy, depending on type of x)
-    Use(Operand<H>),
+    Use(Operand<'tcx>),
 
     // [x; 32]
-    Repeat(Operand<H>, Operand<H>),
+    Repeat(Operand<'tcx>, Operand<'tcx>),
 
     // &x or &mut x
-    Ref(H::Region, BorrowKind, Lvalue<H>),
+    Ref(Region, BorrowKind, Lvalue<'tcx>),
 
     // length of a [X] or [X;n] value
-    Len(Lvalue<H>),
+    Len(Lvalue<'tcx>),
 
-    Cast(CastKind, Operand<H>, H::Ty),
+    Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
 
-    BinaryOp(BinOp, Operand<H>, Operand<H>),
+    BinaryOp(BinOp, Operand<'tcx>, Operand<'tcx>),
 
-    UnaryOp(UnOp, Operand<H>),
+    UnaryOp(UnOp, Operand<'tcx>),
 
     // Creates an *uninitialized* Box
-    Box(H::Ty),
+    Box(Ty<'tcx>),
 
     // Create an aggregate value, like a tuple or struct.  This is
     // only needed because we want to distinguish `dest = Foo { x:
     // ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
     // that `Foo` has a destructor. These rvalues can be optimized
     // away after type-checking and before lowering.
-    Aggregate(AggregateKind<H>, Vec<Operand<H>>),
+    Aggregate(AggregateKind<'tcx>, Vec<Operand<'tcx>>),
 
     // Generates a slice of the form `&input[from_start..L-from_end]`
     // where `L` is the length of the slice. This is only created by
@@ -541,12 +548,12 @@ pub enum Rvalue<H:Hair> {
     // .., z]` might create a slice with `from_start=2` and
     // `from_end=1`.
     Slice {
-        input: Lvalue<H>,
+        input: Lvalue<'tcx>,
         from_start: usize,
         from_end: usize,
     },
 
-    InlineAsm(H::InlineAsm),
+    InlineAsm(&'tcx InlineAsm),
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -568,11 +575,11 @@ pub enum CastKind {
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub enum AggregateKind<H:Hair> {
+pub enum AggregateKind<'tcx> {
     Vec,
     Tuple,
-    Adt(H::AdtDef, usize, H::Substs),
-    Closure(H::DefId, H::ClosureSubsts),
+    Adt(AdtDef<'tcx>, usize, &'tcx Substs<'tcx>),
+    Closure(DefId, &'tcx ClosureSubsts<'tcx>),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -619,7 +626,7 @@ pub enum UnOp {
     Neg
 }
 
-impl<H:Hair> Debug for Rvalue<H> {
+impl<'tcx> Debug for Rvalue<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
         use self::Rvalue::*;
 
@@ -648,15 +655,15 @@ impl<H:Hair> Debug for Rvalue<H> {
 // particular one must be wary of `NaN`!
 
 #[derive(Clone, Debug, PartialEq)]
-pub struct Constant<H:Hair> {
-    pub span: H::Span,
-    pub ty: H::Ty,
-    pub literal: Literal<H>
+pub struct Constant<'tcx> {
+    pub span: Span,
+    pub ty: Ty<'tcx>,
+    pub literal: Literal<'tcx>
 }
 
 #[derive(Clone, Debug, PartialEq)]
-pub enum Literal<H:Hair> {
-    Item { def_id: H::DefId, substs: H::Substs },
-    Value { value: H::ConstVal },
+pub enum Literal<'tcx> {
+    Item { def_id: DefId, substs: &'tcx Substs<'tcx> },
+    Value { value: ConstVal },
 }
 
diff --git a/src/librustc_mir/tcx/block.rs b/src/librustc_mir/tcx/block.rs
index 033e6ed2968..69cbe4b67e5 100644
--- a/src/librustc_mir/tcx/block.rs
+++ b/src/librustc_mir/tcx/block.rs
@@ -12,16 +12,16 @@ use hair::*;
 
 use tcx::Cx;
 use tcx::pattern::PatNode;
-use tcx::rustc::middle::region::{BlockRemainder, CodeExtentData};
-use tcx::rustc_front::hir;
-use tcx::syntax::ast;
-use tcx::syntax::ptr::P;
 use tcx::to_ref::ToRef;
+use rustc::middle::region::{BlockRemainder, CodeExtentData};
+use rustc_front::hir;
+use syntax::ast;
+use syntax::ptr::P;
 
-impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Block {
-    type Output = Block<Cx<'a,'tcx>>;
+impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
+    type Output = Block<'tcx>;
 
-    fn make_mirror(self, cx: &mut Cx<'a,'tcx>) -> Block<Cx<'a,'tcx>> {
+    fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Block<'tcx> {
         // We have to eagerly translate the "spine" of the statements
         // in order to get the lexical scoping correctly.
         let stmts = mirror_stmts(cx, self.id, self.stmts.iter().enumerate());
@@ -34,10 +34,10 @@ impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Block {
     }
 }
 
-impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Stmt {
-    type Output = Stmt<Cx<'a,'tcx>>;
+impl<'tcx> Mirror<'tcx> for &'tcx hir::Stmt {
+    type Output = Stmt<'tcx>;
 
-    fn make_mirror(self, _cx: &mut Cx<'a,'tcx>) -> Stmt<Cx<'a,'tcx>> {
+    fn make_mirror<'a>(self, _cx: &mut Cx<'a,'tcx>) -> Stmt<'tcx> {
         // In order to get the scoping correct, we eagerly mirror
         // statements when we translate the enclosing block, so we
         // should in fact never get to this point.
@@ -48,7 +48,7 @@ impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Stmt {
 fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>,
                                   block_id: ast::NodeId,
                                   mut stmts: STMTS)
-                                  -> Vec<StmtRef<Cx<'a,'tcx>>>
+                                  -> Vec<StmtRef<'tcx>>
     where STMTS: Iterator<Item=(usize, &'tcx P<hir::Stmt>)>
 {
     let mut result = vec![];
@@ -101,7 +101,7 @@ fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>,
 
 pub fn to_expr_ref<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                                block: &'tcx hir::Block)
-                               -> ExprRef<Cx<'a, 'tcx>> {
+                               -> ExprRef<'tcx> {
     let block_ty = cx.tcx.node_id_to_type(block.id);
     let temp_lifetime = cx.tcx.region_maps.temporary_scope(block.id);
     let expr = Expr {
diff --git a/src/librustc_mir/tcx/expr.rs b/src/librustc_mir/tcx/expr.rs
index 098a85514eb..c14b83c9370 100644
--- a/src/librustc_mir/tcx/expr.rs
+++ b/src/librustc_mir/tcx/expr.rs
@@ -15,22 +15,22 @@ use std::rc::Rc;
 use tcx::Cx;
 use tcx::block;
 use tcx::pattern::PatNode;
-use tcx::rustc::front::map;
-use tcx::rustc::middle::const_eval;
-use tcx::rustc::middle::def;
-use tcx::rustc::middle::region::CodeExtent;
-use tcx::rustc::middle::pat_util;
-use tcx::rustc::middle::ty::{self, Ty};
-use tcx::rustc_front::hir;
-use tcx::rustc_front::util as hir_util;
-use tcx::syntax::parse::token;
-use tcx::syntax::ptr::P;
 use tcx::to_ref::ToRef;
-
-impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Expr {
-    type Output = Expr<Cx<'a,'tcx>>;
-
-    fn make_mirror(self, cx: &mut Cx<'a,'tcx>) -> Expr<Cx<'a,'tcx>> {
+use rustc::front::map;
+use rustc::middle::const_eval;
+use rustc::middle::def;
+use rustc::middle::region::CodeExtent;
+use rustc::middle::pat_util;
+use rustc::middle::ty::{self, Ty};
+use rustc_front::hir;
+use rustc_front::util as hir_util;
+use syntax::parse::token;
+use syntax::ptr::P;
+
+impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
+    type Output = Expr<'tcx>;
+
+    fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Expr<'tcx> {
         debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span);
 
         let expr_ty = cx.tcx.expr_ty(self); // note: no adjustments (yet)!
@@ -427,7 +427,7 @@ impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for &'tcx hir::Expr {
 fn method_callee<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                              expr: &hir::Expr,
                              method_call: ty::MethodCall)
-                             -> Expr<Cx<'a,'tcx>> {
+                             -> Expr<'tcx> {
     let tables = cx.tcx.tables.borrow();
     let callee = &tables.method_map[&method_call];
     let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
@@ -451,7 +451,7 @@ fn to_borrow_kind(m: hir::Mutability) -> BorrowKind {
     }
 }
 
-fn convert_arm<'a,'tcx:'a>(cx: &Cx<'a,'tcx>, arm: &'tcx hir::Arm) -> Arm<Cx<'a,'tcx>> {
+fn convert_arm<'a,'tcx:'a>(cx: &Cx<'a,'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
     let map = if arm.pats.len() == 1 {
         None
     } else {
@@ -469,7 +469,7 @@ fn convert_arm<'a,'tcx:'a>(cx: &Cx<'a,'tcx>, arm: &'tcx hir::Arm) -> Arm<Cx<'a,'
 
 fn convert_path_expr<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                                  expr: &'tcx hir::Expr)
-                                 -> ExprKind<Cx<'a,'tcx>>
+                                 -> ExprKind<'tcx>
 {
     let substs = cx.tcx.mk_substs(cx.tcx.node_id_item_substs(expr.id).substs);
     match cx.tcx.def_map.borrow()[&expr.id].full_def() {
@@ -502,7 +502,7 @@ fn convert_path_expr<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
 fn convert_var<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                            expr: &'tcx hir::Expr,
                            def: def::Def)
-                           -> ExprKind<Cx<'a,'tcx>>
+                           -> ExprKind<'tcx>
 {
     let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
 
@@ -665,9 +665,9 @@ fn overloaded_operator<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                                    expr: &'tcx hir::Expr,
                                    method_call: ty::MethodCall,
                                    pass_args: PassArgs,
-                                   receiver: ExprRef<Cx<'a,'tcx>>,
+                                   receiver: ExprRef<'tcx>,
                                    args: Vec<&'tcx P<hir::Expr>>)
-                                   -> ExprKind<Cx<'a,'tcx>>
+                                   -> ExprKind<'tcx>
 {
     // the receiver has all the adjustments that are needed, so we can
     // just push a reference to it
@@ -718,9 +718,9 @@ fn overloaded_lvalue<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                                  expr: &'tcx hir::Expr,
                                  method_call: ty::MethodCall,
                                  pass_args: PassArgs,
-                                 receiver: ExprRef<Cx<'a,'tcx>>,
+                                 receiver: ExprRef<'tcx>,
                                  args: Vec<&'tcx P<hir::Expr>>)
-                                 -> ExprKind<Cx<'a,'tcx>>
+                                 -> ExprKind<'tcx>
 {
     // For an overloaded *x or x[y] expression of type T, the method
     // call returns an &T and we must add the deref so that the types
@@ -754,7 +754,7 @@ fn capture_freevar<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                                closure_expr: &'tcx hir::Expr,
                                freevar: &ty::Freevar,
                                freevar_ty: Ty<'tcx>)
-                               -> ExprRef<Cx<'a,'tcx>> {
+                               -> ExprRef<'tcx> {
     let id_var = freevar.def.var_id();
     let upvar_id = ty::UpvarId { var_id: id_var, closure_expr_id: closure_expr.id };
     let upvar_capture = cx.tcx.upvar_capture(upvar_id).unwrap();
diff --git a/src/librustc_mir/tcx/mod.rs b/src/librustc_mir/tcx/mod.rs
index 04f52a52464..be731317482 100644
--- a/src/librustc_mir/tcx/mod.rs
+++ b/src/librustc_mir/tcx/mod.rs
@@ -8,31 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+/*!
+ * This module contains the code to convert from the wacky tcx data
+ * structures into the hair. The `builder` is generally ignorant of
+ * the tcx etc, and instead goes through the `Cx` for most of its
+ * work.
+ */
+
 use hair::*;
 use repr::*;
-use std::fmt::{Debug, Formatter, Error};
-use std::hash::{Hash, Hasher};
-use std::rc::Rc;
-
-use self::rustc::middle::const_eval::ConstVal;
-use self::rustc::middle::def_id::DefId;
-use self::rustc::middle::infer::InferCtxt;
-use self::rustc::middle::region::CodeExtent;
-use self::rustc::middle::subst::{self, Subst, Substs};
-use self::rustc::middle::ty::{self, Ty};
-use self::rustc_front::hir;
-use self::syntax::ast;
-use self::syntax::codemap::Span;
-use self::syntax::parse::token::{self, special_idents, InternedString};
-
-extern crate rustc;
-extern crate rustc_front;
-extern crate syntax;
+
+use rustc::middle::const_eval::ConstVal;
+use rustc::middle::def_id::DefId;
+use rustc::middle::infer::InferCtxt;
+use rustc::middle::subst::{Subst, Substs};
+use rustc::middle::ty::{self, Ty};
+use syntax::codemap::Span;
+use syntax::parse::token::{self, special_idents};
 
 #[derive(Copy, Clone)]
 pub struct Cx<'a,'tcx:'a> {
-    pub tcx: &'a ty::ctxt<'tcx>,
-    pub infcx: &'a InferCtxt<'a,'tcx>,
+    tcx: &'a ty::ctxt<'tcx>,
+    infcx: &'a InferCtxt<'a,'tcx>,
 }
 
 impl<'a,'tcx> Cx<'a,'tcx> {
@@ -43,66 +40,51 @@ impl<'a,'tcx> Cx<'a,'tcx> {
 
 pub use self::pattern::PatNode;
 
-impl<'a,'tcx:'a> Hair for Cx<'a, 'tcx> {
-    type VarId = ast::NodeId;
-    type DefId = DefId;
-    type AdtDef = ty::AdtDef<'tcx>;
-    type Name = ast::Name;
-    type InternedString = InternedString;
-    type Bytes = Rc<Vec<u8>>;
-    type Span = Span;
-    type Projection = ty::ProjectionTy<'tcx>;
-    type Substs = &'tcx subst::Substs<'tcx>;
-    type ClosureSubsts = &'tcx ty::ClosureSubsts<'tcx>;
-    type Ty = Ty<'tcx>;
-    type Region = ty::Region;
-    type CodeExtent = CodeExtent;
-    type ConstVal = ConstVal;
-    type Pattern = PatNode<'tcx>;
-    type Expr = &'tcx hir::Expr;
-    type Stmt = &'tcx hir::Stmt;
-    type Block = &'tcx hir::Block;
-    type InlineAsm = &'tcx hir::InlineAsm;
-
-    fn unit_ty(&mut self) -> Ty<'tcx> {
+impl<'a,'tcx:'a> Cx<'a, 'tcx> {
+    /// Normalizes `ast` into the appropriate `mirror` type.
+    pub fn mirror<M:Mirror<'tcx>>(&mut self, ast: M) -> M::Output {
+        ast.make_mirror(self)
+    }
+
+    pub fn unit_ty(&mut self) -> Ty<'tcx> {
         self.tcx.mk_nil()
     }
 
-    fn usize_ty(&mut self) -> Ty<'tcx> {
+    pub fn usize_ty(&mut self) -> Ty<'tcx> {
         self.tcx.types.usize
     }
 
-    fn usize_literal(&mut self, value: usize) -> Literal<Self> {
+    pub fn usize_literal(&mut self, value: usize) -> Literal<'tcx> {
         Literal::Value { value: ConstVal::Uint(value as u64) }
     }
 
-    fn bool_ty(&mut self) -> Ty<'tcx> {
+    pub fn bool_ty(&mut self) -> Ty<'tcx> {
         self.tcx.types.bool
     }
 
-    fn true_literal(&mut self) -> Literal<Self> {
+    pub fn true_literal(&mut self) -> Literal<'tcx> {
         Literal::Value { value: ConstVal::Bool(true) }
     }
 
-    fn false_literal(&mut self) -> Literal<Self> {
+    pub fn false_literal(&mut self) -> Literal<'tcx> {
         Literal::Value { value: ConstVal::Bool(false) }
     }
 
-    fn partial_eq(&mut self, ty: Ty<'tcx>) -> ItemRef<Self> {
+    pub fn partial_eq(&mut self, ty: Ty<'tcx>) -> ItemRef<'tcx> {
         let eq_def_id = self.tcx.lang_items.eq_trait().unwrap();
         self.cmp_method_ref(eq_def_id, "eq", ty)
     }
 
-    fn partial_le(&mut self, ty: Ty<'tcx>) -> ItemRef<Self> {
+    pub fn partial_le(&mut self, ty: Ty<'tcx>) -> ItemRef<'tcx> {
         let ord_def_id = self.tcx.lang_items.ord_trait().unwrap();
         self.cmp_method_ref(ord_def_id, "le", ty)
     }
 
-    fn num_variants(&mut self, adt_def: ty::AdtDef<'tcx>) -> usize {
+    pub fn num_variants(&mut self, adt_def: ty::AdtDef<'tcx>) -> usize {
         adt_def.variants.len()
     }
 
-    fn fields(&mut self, adt_def: ty::AdtDef<'tcx>, variant_index: usize) -> Vec<Field<Self>> {
+    pub fn fields(&mut self, adt_def: ty::AdtDef<'tcx>, variant_index: usize) -> Vec<Field> {
         adt_def.variants[variant_index]
             .fields
             .iter()
@@ -117,7 +99,7 @@ impl<'a,'tcx:'a> Hair for Cx<'a, 'tcx> {
             .collect()
     }
 
-    fn needs_drop(&mut self, ty: Ty<'tcx>, span: Self::Span) -> bool {
+    pub fn needs_drop(&mut self, ty: Ty<'tcx>, span: Span) -> bool {
         if self.infcx.type_moves_by_default(ty, span) {
             // FIXME(#21859) we should do an add'l check here to determine if
             // any dtor will execute, but the relevant fn
@@ -130,17 +112,19 @@ impl<'a,'tcx:'a> Hair for Cx<'a, 'tcx> {
         }
     }
 
-    fn span_bug(&mut self, span: Self::Span, message: &str) -> ! {
+    pub fn span_bug(&mut self, span: Span, message: &str) -> ! {
         self.tcx.sess.span_bug(span, message)
     }
-}
 
-impl<'a,'tcx:'a> Cx<'a,'tcx> {
+    pub fn tcx(&self) -> &'a ty::ctxt<'tcx> {
+        self.tcx
+    }
+
     fn cmp_method_ref(&mut self,
                       trait_def_id: DefId,
                       method_name: &str,
                       arg_ty: Ty<'tcx>)
-                      -> ItemRef<Cx<'a,'tcx>> {
+                      -> ItemRef<'tcx> {
         let method_name = token::intern(method_name);
         let substs = Substs::new_trait(vec![arg_ty], vec![], arg_ty);
         for trait_item in self.tcx.trait_items(trait_def_id).iter() {
@@ -167,29 +151,6 @@ impl<'a,'tcx:'a> Cx<'a,'tcx> {
     }
 }
 
-// We only need this impl so that we do deriving for things that are
-// defined relative to the `Hair` trait. See `Hair` trait for more
-// details.
-impl<'a,'tcx> PartialEq for Cx<'a,'tcx> {
-    fn eq(&self, _: &Cx<'a,'tcx>) -> bool {
-        panic!("Cx should never ACTUALLY be compared for equality")
-    }
-}
-
-impl<'a,'tcx> Eq for Cx<'a,'tcx> { }
-
-impl<'a,'tcx> Hash for Cx<'a,'tcx> {
-    fn hash<H: Hasher>(&self, _: &mut H) {
-        panic!("Cx should never ACTUALLY be hashed")
-    }
-}
-
-impl<'a,'tcx> Debug for Cx<'a,'tcx> {
-    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
-        write!(fmt, "Tcx")
-    }
-}
-
 mod block;
 mod expr;
 mod pattern;
diff --git a/src/librustc_mir/tcx/pattern.rs b/src/librustc_mir/tcx/pattern.rs
index fe0c2c6c76a..9407f9e7600 100644
--- a/src/librustc_mir/tcx/pattern.rs
+++ b/src/librustc_mir/tcx/pattern.rs
@@ -14,15 +14,15 @@ use repr::*;
 use rustc_data_structures::fnv::FnvHashMap;
 use std::rc::Rc;
 use tcx::Cx;
-use tcx::rustc::middle::const_eval;
-use tcx::rustc::middle::def;
-use tcx::rustc::middle::pat_util::{pat_is_resolved_const, pat_is_binding};
-use tcx::rustc::middle::subst::Substs;
-use tcx::rustc::middle::ty::{self, Ty};
-use tcx::rustc_front::hir;
-use tcx::syntax::ast;
-use tcx::syntax::ptr::P;
 use tcx::to_ref::ToRef;
+use rustc::middle::const_eval;
+use rustc::middle::def;
+use rustc::middle::pat_util::{pat_is_resolved_const, pat_is_binding};
+use rustc::middle::subst::Substs;
+use rustc::middle::ty::{self, Ty};
+use rustc_front::hir;
+use syntax::ast;
+use syntax::ptr::P;
 
 /// When there are multiple patterns in a single arm, each one has its
 /// own node-ids for the bindings.  References to the variables always
@@ -58,15 +58,15 @@ impl<'tcx> PatNode<'tcx> {
         PatNode::new(pat, None)
     }
 
-    fn pat_ref<'a>(&self, pat: &'tcx hir::Pat) -> PatternRef<Cx<'a,'tcx>> {
+    fn pat_ref<'a>(&self, pat: &'tcx hir::Pat) -> PatternRef<'tcx> {
         PatNode::new(pat, self.binding_map.clone()).to_ref()
     }
 
-    fn pat_refs<'a>(&self, pats: &'tcx Vec<P<hir::Pat>>) -> Vec<PatternRef<Cx<'a,'tcx>>> {
+    fn pat_refs<'a>(&self, pats: &'tcx Vec<P<hir::Pat>>) -> Vec<PatternRef<'tcx>> {
         pats.iter().map(|p| self.pat_ref(p)).collect()
     }
 
-    fn opt_pat_ref<'a>(&self, pat: &'tcx Option<P<hir::Pat>>) -> Option<PatternRef<Cx<'a,'tcx>>> {
+    fn opt_pat_ref<'a>(&self, pat: &'tcx Option<P<hir::Pat>>) -> Option<PatternRef<'tcx>> {
         pat.as_ref().map(|p| self.pat_ref(p))
     }
 
@@ -76,7 +76,7 @@ impl<'tcx> PatNode<'tcx> {
                                   prefix: &'tcx Vec<P<hir::Pat>>,
                                   slice: &'tcx Option<P<hir::Pat>>,
                                   suffix: &'tcx Vec<P<hir::Pat>>)
-                                  -> PatternKind<Cx<'a,'tcx>>
+                                  -> PatternKind<'tcx>
     {
         match ty.sty {
             ty::TySlice(..) =>
@@ -107,8 +107,8 @@ impl<'tcx> PatNode<'tcx> {
 
     fn variant_or_leaf<'a>(&self,
                            cx: &mut Cx<'a, 'tcx>,
-                           subpatterns: Vec<FieldPatternRef<Cx<'a,'tcx>>>)
-                           -> PatternKind<Cx<'a,'tcx>>
+                           subpatterns: Vec<FieldPatternRef<'tcx>>)
+                           -> PatternKind<'tcx>
     {
         let def = cx.tcx.def_map.borrow().get(&self.pat.id).unwrap().full_def();
         match def {
@@ -138,10 +138,10 @@ impl<'tcx> PatNode<'tcx> {
     }
 }
 
-impl<'a,'tcx:'a> Mirror<Cx<'a,'tcx>> for PatNode<'tcx> {
-    type Output = Pattern<Cx<'a,'tcx>>;
+impl<'tcx> Mirror<'tcx> for PatNode<'tcx> {
+    type Output = Pattern<'tcx>;
 
-    fn make_mirror(self, cx: &mut Cx<'a,'tcx>) -> Pattern<Cx<'a,'tcx>> {
+    fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Pattern<'tcx> {
         let kind = match self.pat.node {
             hir::PatWild(..) =>
                 PatternKind::Wild,
diff --git a/src/librustc_mir/tcx/to_ref.rs b/src/librustc_mir/tcx/to_ref.rs
index 3c8a5534e1a..7da8d7deefd 100644
--- a/src/librustc_mir/tcx/to_ref.rs
+++ b/src/librustc_mir/tcx/to_ref.rs
@@ -11,58 +11,57 @@
 use hair::*;
 use repr::*;
 
-use tcx::Cx;
 use tcx::pattern::PatNode;
-use tcx::rustc_front::hir;
-use tcx::syntax::ptr::P;
+use rustc_front::hir;
+use syntax::ptr::P;
 
-pub trait ToRef<H> {
+pub trait ToRef {
     type Output;
     fn to_ref(self) -> Self::Output;
 }
 
-impl<'a,'tcx:'a> ToRef<Cx<'a,'tcx>> for &'tcx hir::Expr {
-    type Output = ExprRef<Cx<'a,'tcx>>;
+impl<'a,'tcx:'a> ToRef for &'tcx hir::Expr {
+    type Output = ExprRef<'tcx>;
 
-    fn to_ref(self) -> ExprRef<Cx<'a,'tcx>> {
+    fn to_ref(self) -> ExprRef<'tcx> {
         ExprRef::Hair(self)
     }
 }
 
-impl<'a,'tcx:'a> ToRef<Cx<'a,'tcx>> for &'tcx P<hir::Expr> {
-    type Output = ExprRef<Cx<'a,'tcx>>;
+impl<'a,'tcx:'a> ToRef for &'tcx P<hir::Expr> {
+    type Output = ExprRef<'tcx>;
 
-    fn to_ref(self) -> ExprRef<Cx<'a,'tcx>> {
+    fn to_ref(self) -> ExprRef<'tcx> {
         ExprRef::Hair(&**self)
     }
 }
 
-impl<'a,'tcx:'a> ToRef<Cx<'a,'tcx>> for Expr<Cx<'a,'tcx>> {
-    type Output = ExprRef<Cx<'a,'tcx>>;
+impl<'a,'tcx:'a> ToRef for Expr<'tcx> {
+    type Output = ExprRef<'tcx>;
 
-    fn to_ref(self) -> ExprRef<Cx<'a,'tcx>> {
+    fn to_ref(self) -> ExprRef<'tcx> {
         ExprRef::Mirror(Box::new(self))
     }
 }
 
-impl<'a,'tcx:'a> ToRef<Cx<'a,'tcx>> for PatNode<'tcx> {
-    type Output = PatternRef<Cx<'a,'tcx>>;
+impl<'a,'tcx:'a> ToRef for PatNode<'tcx> {
+    type Output = PatternRef<'tcx>;
 
-    fn to_ref(self) -> PatternRef<Cx<'a,'tcx>> {
+    fn to_ref(self) -> PatternRef<'tcx> {
         PatternRef::Hair(self)
     }
 }
 
-impl<'a,'tcx:'a> ToRef<Cx<'a,'tcx>> for Pattern<Cx<'a,'tcx>> {
-    type Output = PatternRef<Cx<'a,'tcx>>;
+impl<'a,'tcx:'a> ToRef for Pattern<'tcx> {
+    type Output = PatternRef<'tcx>;
 
-    fn to_ref(self) -> PatternRef<Cx<'a,'tcx>> {
+    fn to_ref(self) -> PatternRef<'tcx> {
         PatternRef::Mirror(Box::new(self))
     }
 }
 
-impl<'a,'tcx:'a,T,U> ToRef<Cx<'a,'tcx>> for &'tcx Option<T>
-    where &'tcx T: ToRef<Cx<'a,'tcx>, Output=U>
+impl<'a,'tcx:'a,T,U> ToRef for &'tcx Option<T>
+    where &'tcx T: ToRef<Output=U>
 {
     type Output = Option<U>;
 
@@ -71,8 +70,8 @@ impl<'a,'tcx:'a,T,U> ToRef<Cx<'a,'tcx>> for &'tcx Option<T>
     }
 }
 
-impl<'a,'tcx:'a,T,U> ToRef<Cx<'a,'tcx>> for &'tcx Vec<T>
-    where &'tcx T: ToRef<Cx<'a,'tcx>, Output=U>
+impl<'a,'tcx:'a,T,U> ToRef for &'tcx Vec<T>
+    where &'tcx T: ToRef<Output=U>
 {
     type Output = Vec<U>;
 
@@ -81,10 +80,10 @@ impl<'a,'tcx:'a,T,U> ToRef<Cx<'a,'tcx>> for &'tcx Vec<T>
     }
 }
 
-impl<'a,'tcx:'a> ToRef<Cx<'a,'tcx>> for &'tcx hir::Field {
-    type Output = FieldExprRef<Cx<'a,'tcx>>;
+impl<'a,'tcx:'a> ToRef for &'tcx hir::Field {
+    type Output = FieldExprRef<'tcx>;
 
-    fn to_ref(self) -> FieldExprRef<Cx<'a,'tcx>> {
+    fn to_ref(self) -> FieldExprRef<'tcx> {
         FieldExprRef {
             name: Field::Named(self.name.node),
             expr: self.expr.to_ref()