about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-05-03 04:56:42 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-05-11 04:14:58 +0300
commit513d392f7e66b416e5ba6f4f778ae2cfadb10832 (patch)
tree0999a16d87052034ad6b9a6624dcd71972ffd525 /src
parent8fc2c4652cea0cb228cb27fc7c37d3272c9e4f9a (diff)
downloadrust-513d392f7e66b416e5ba6f4f778ae2cfadb10832.tar.gz
rust-513d392f7e66b416e5ba6f4f778ae2cfadb10832.zip
rustc: Replace &'a TyCtxt<'tcx> with a TyCtxt<'a, 'tcx> wrapper.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/cfg/construct.rs4
-rw-r--r--src/librustc/cfg/mod.rs2
-rw-r--r--src/librustc/dep_graph/visit.rs8
-rw-r--r--src/librustc/hir/pat_util.rs2
-rw-r--r--src/librustc/infer/bivariate.rs2
-rw-r--r--src/librustc/infer/combine.rs4
-rw-r--r--src/librustc/infer/equate.rs2
-rw-r--r--src/librustc/infer/error_reporting.rs14
-rw-r--r--src/librustc/infer/freshen.rs2
-rw-r--r--src/librustc/infer/glb.rs2
-rw-r--r--src/librustc/infer/higher_ranked/mod.rs8
-rw-r--r--src/librustc/infer/lub.rs2
-rw-r--r--src/librustc/infer/mod.rs14
-rw-r--r--src/librustc/infer/region_inference/graphviz.rs6
-rw-r--r--src/librustc/infer/region_inference/mod.rs19
-rw-r--r--src/librustc/infer/resolve.rs6
-rw-r--r--src/librustc/infer/sub.rs2
-rw-r--r--src/librustc/infer/unify_key.rs6
-rw-r--r--src/librustc/lint/context.rs9
-rw-r--r--src/librustc/middle/astconv_util.rs10
-rw-r--r--src/librustc/middle/cstore.rs161
-rw-r--r--src/librustc/middle/dataflow.rs4
-rw-r--r--src/librustc/middle/dead.rs17
-rw-r--r--src/librustc/middle/effect.rs4
-rw-r--r--src/librustc/middle/expr_use_visitor.rs6
-rw-r--r--src/librustc/middle/free_region.rs2
-rw-r--r--src/librustc/middle/intrinsicck.rs4
-rw-r--r--src/librustc/middle/liveness.rs14
-rw-r--r--src/librustc/middle/mem_categorization.rs8
-rw-r--r--src/librustc/middle/reachable.rs8
-rw-r--r--src/librustc/middle/stability.rs42
-rw-r--r--src/librustc/mir/tcx.rs21
-rw-r--r--src/librustc/mir/transform.rs24
-rw-r--r--src/librustc/traits/coherence.rs37
-rw-r--r--src/librustc/traits/error_reporting.rs8
-rw-r--r--src/librustc/traits/fulfill.rs76
-rw-r--r--src/librustc/traits/object_safety.rs24
-rw-r--r--src/librustc/traits/project.rs2
-rw-r--r--src/librustc/traits/select.rs2
-rw-r--r--src/librustc/traits/specialize/mod.rs2
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs44
-rw-r--r--src/librustc/traits/util.rs40
-rw-r--r--src/librustc/ty/_match.rs6
-rw-r--r--src/librustc/ty/adjustment.rs9
-rw-r--r--src/librustc/ty/contents.rs14
-rw-r--r--src/librustc/ty/context.rs192
-rw-r--r--src/librustc/ty/error.rs6
-rw-r--r--src/librustc/ty/fast_reject.rs2
-rw-r--r--src/librustc/ty/fold.rs50
-rw-r--r--src/librustc/ty/item_path.rs20
-rw-r--r--src/librustc/ty/layout.rs2
-rw-r--r--src/librustc/ty/mod.rs185
-rw-r--r--src/librustc/ty/relate.rs2
-rw-r--r--src/librustc/ty/structural_impls.rs18
-rw-r--r--src/librustc/ty/sty.rs34
-rw-r--r--src/librustc/ty/subst.rs27
-rw-r--r--src/librustc/ty/trait_def.rs30
-rw-r--r--src/librustc/ty/util.rs89
-rw-r--r--src/librustc/ty/wf.rs4
-rw-r--r--src/librustc/util/ppaux.rs22
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs2
-rw-r--r--src/librustc_borrowck/borrowck/fragments.rs57
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/mod.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/dataflow.rs4
-rw-r--r--src/librustc_borrowck/borrowck/mir/gather_moves.rs8
-rw-r--r--src/librustc_borrowck/borrowck/mir/mod.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs14
-rw-r--r--src/librustc_borrowck/borrowck/move_data.rs21
-rw-r--r--src/librustc_const_eval/check_match.rs8
-rw-r--r--src/librustc_const_eval/eval.rs63
-rw-r--r--src/librustc_driver/driver.rs16
-rw-r--r--src/librustc_driver/pretty.rs16
-rw-r--r--src/librustc_driver/test.rs2
-rw-r--r--src/librustc_incremental/assert_dep_graph.rs8
-rw-r--r--src/librustc_incremental/calculate_svh.rs18
-rw-r--r--src/librustc_incremental/persist/directory.rs8
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs6
-rw-r--r--src/librustc_incremental/persist/load.rs17
-rw-r--r--src/librustc_incremental/persist/save.rs9
-rw-r--r--src/librustc_incremental/persist/util.rs4
-rw-r--r--src/librustc_lint/builtin.rs14
-rw-r--r--src/librustc_lint/types.rs12
-rw-r--r--src/librustc_metadata/astencode.rs50
-rw-r--r--src/librustc_metadata/csearch.rs73
-rw-r--r--src/librustc_metadata/decoder.rs137
-rw-r--r--src/librustc_metadata/encoder.rs16
-rw-r--r--src/librustc_metadata/tls_context.rs10
-rw-r--r--src/librustc_metadata/tydecode.rs6
-rw-r--r--src/librustc_metadata/tyencode.rs4
-rw-r--r--src/librustc_mir/build/scope.rs22
-rw-r--r--src/librustc_mir/graphviz.rs8
-rw-r--r--src/librustc_mir/hair/cx/mod.rs4
-rw-r--r--src/librustc_mir/mir_map.rs14
-rw-r--r--src/librustc_mir/pretty.rs33
-rw-r--r--src/librustc_mir/transform/break_critical_edges.rs2
-rw-r--r--src/librustc_mir/transform/erase_regions.rs6
-rw-r--r--src/librustc_mir/transform/no_landing_pads.rs2
-rw-r--r--src/librustc_mir/transform/promote_consts.rs8
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs16
-rw-r--r--src/librustc_mir/transform/remove_dead_blocks.rs2
-rw-r--r--src/librustc_mir/transform/simplify_cfg.rs2
-rw-r--r--src/librustc_mir/transform/type_check.rs6
-rw-r--r--src/librustc_passes/consts.rs4
-rw-r--r--src/librustc_passes/rvalues.rs6
-rw-r--r--src/librustc_privacy/lib.rs37
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs4
-rw-r--r--src/librustc_save_analysis/external_data.rs50
-rw-r--r--src/librustc_save_analysis/lib.rs8
-rw-r--r--src/librustc_trans/_match.rs8
-rw-r--r--src/librustc_trans/adt.rs23
-rw-r--r--src/librustc_trans/back/link.rs4
-rw-r--r--src/librustc_trans/back/symbol_names.rs6
-rw-r--r--src/librustc_trans/base.rs14
-rw-r--r--src/librustc_trans/callee.rs10
-rw-r--r--src/librustc_trans/cleanup.rs4
-rw-r--r--src/librustc_trans/closure.rs8
-rw-r--r--src/librustc_trans/collector.rs91
-rw-r--r--src/librustc_trans/common.rs20
-rw-r--r--src/librustc_trans/consts.rs2
-rw-r--r--src/librustc_trans/context.rs8
-rw-r--r--src/librustc_trans/expr.rs16
-rw-r--r--src/librustc_trans/glue.rs10
-rw-r--r--src/librustc_trans/meth.rs18
-rw-r--r--src/librustc_trans/monomorphize.rs20
-rw-r--r--src/librustc_trans/partitioning.rs30
-rw-r--r--src/librustc_typeck/astconv.rs20
-rw-r--r--src/librustc_typeck/check/coercion.rs2
-rw-r--r--src/librustc_typeck/check/method/confirm.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs18
-rw-r--r--src/librustc_typeck/check/regionck.rs2
-rw-r--r--src/librustc_typeck/check/upvar.rs2
-rw-r--r--src/librustc_typeck/check/wfcheck.rs6
-rw-r--r--src/librustc_typeck/check/writeback.rs8
-rw-r--r--src/librustc_typeck/check_unused.rs4
-rw-r--r--src/librustc_typeck/coherence/mod.rs2
-rw-r--r--src/librustc_typeck/coherence/orphan.rs4
-rw-r--r--src/librustc_typeck/coherence/overlap.rs10
-rw-r--r--src/librustc_typeck/coherence/unsafety.rs4
-rw-r--r--src/librustc_typeck/collect.rs10
-rw-r--r--src/librustc_typeck/lib.rs8
-rw-r--r--src/librustc_typeck/variance/constraints.rs2
-rw-r--r--src/librustc_typeck/variance/mod.rs2
-rw-r--r--src/librustc_typeck/variance/terms.rs6
-rw-r--r--src/librustdoc/clean/inline.rs26
-rw-r--r--src/librustdoc/core.rs6
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs4
147 files changed, 1331 insertions, 1338 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index 70497491355..a1f1fdb6b0e 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -19,7 +19,7 @@ use syntax::ptr::P;
 use hir::{self, PatKind};
 
 struct CFGBuilder<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     graph: CFGGraph,
     fn_exit: CFGIndex,
     loop_scopes: Vec<LoopScope>,
@@ -32,7 +32,7 @@ struct LoopScope {
     break_index: CFGIndex,    // where to go on a `break
 }
 
-pub fn construct(tcx: &TyCtxt,
+pub fn construct(tcx: TyCtxt,
                  blk: &hir::Block) -> CFG {
     let mut graph = graph::Graph::new();
     let entry = graph.add_node(CFGNodeData::Entry);
diff --git a/src/librustc/cfg/mod.rs b/src/librustc/cfg/mod.rs
index e86bf6ebc58..e9c4dd1d87d 100644
--- a/src/librustc/cfg/mod.rs
+++ b/src/librustc/cfg/mod.rs
@@ -58,7 +58,7 @@ pub type CFGNode = graph::Node<CFGNodeData>;
 pub type CFGEdge = graph::Edge<CFGEdgeData>;
 
 impl CFG {
-    pub fn new(tcx: &TyCtxt,
+    pub fn new(tcx: TyCtxt,
                blk: &hir::Block) -> CFG {
         construct::construct(tcx, blk)
     }
diff --git a/src/librustc/dep_graph/visit.rs b/src/librustc/dep_graph/visit.rs
index cdc16216798..4cc3f138ddd 100644
--- a/src/librustc/dep_graph/visit.rs
+++ b/src/librustc/dep_graph/visit.rs
@@ -22,13 +22,13 @@ use super::dep_node::DepNode;
 /// read edge from the corresponding AST node. This is used in
 /// compiler passes to automatically record the item that they are
 /// working on.
-pub fn visit_all_items_in_krate<'tcx,V,F>(tcx: &TyCtxt<'tcx>,
-                                          mut dep_node_fn: F,
-                                          visitor: &mut V)
+pub fn visit_all_items_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx>,
+                                                mut dep_node_fn: F,
+                                                visitor: &mut V)
     where F: FnMut(DefId) -> DepNode<DefId>, V: Visitor<'tcx>
 {
     struct TrackingVisitor<'visit, 'tcx: 'visit, F: 'visit, V: 'visit> {
-        tcx: &'visit TyCtxt<'tcx>,
+        tcx: TyCtxt<'visit, 'tcx>,
         dep_node_fn: &'visit mut F,
         visitor: &'visit mut V
     }
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 6cc5a29062f..17ad2189f68 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -209,7 +209,7 @@ pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
     }
 }
 
-pub fn def_to_path(tcx: &TyCtxt, id: DefId) -> hir::Path {
+pub fn def_to_path(tcx: TyCtxt, id: DefId) -> hir::Path {
     let name = tcx.item_name(id);
     hir::Path::from_ident(DUMMY_SP, hir::Ident::from_name(name))
 }
diff --git a/src/librustc/infer/bivariate.rs b/src/librustc/infer/bivariate.rs
index 156d8e8c95f..71058647c36 100644
--- a/src/librustc/infer/bivariate.rs
+++ b/src/librustc/infer/bivariate.rs
@@ -45,7 +45,7 @@ impl<'a, 'tcx> Bivariate<'a, 'tcx> {
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
     fn tag(&self) -> &'static str { "Bivariate" }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> { self.fields.tcx() }
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs
index 0812d8d0de4..96b0dba9d39 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -151,7 +151,7 @@ fn unify_float_variable(&self,
 }
 
 impl<'a, 'tcx> CombineFields<'a, 'tcx> {
-    pub fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.infcx.tcx
     }
 
@@ -300,7 +300,7 @@ struct Generalizer<'cx, 'tcx:'cx> {
 }
 
 impl<'cx, 'tcx> ty::fold::TypeFolder<'tcx> for Generalizer<'cx, 'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> {
+    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs
index d6a66f74c2d..eff66469c4e 100644
--- a/src/librustc/infer/equate.rs
+++ b/src/librustc/infer/equate.rs
@@ -36,7 +36,7 @@ impl<'a, 'tcx> Equate<'a, 'tcx> {
 impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
     fn tag(&self) -> &'static str { "Equate" }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> { self.fields.tcx() }
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs
index 940d7e911ff..66e5f52544d 100644
--- a/src/librustc/infer/error_reporting.rs
+++ b/src/librustc/infer/error_reporting.rs
@@ -95,8 +95,8 @@ use syntax::codemap::{self, Pos, Span};
 use syntax::parse::token;
 use syntax::ptr::P;
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn note_and_explain_region(&self,
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn note_and_explain_region(self,
                                    err: &mut DiagnosticBuilder,
                                    prefix: &str,
                                    region: ty::Region,
@@ -112,7 +112,7 @@ impl<'tcx> TyCtxt<'tcx> {
             }
         }
 
-        fn explain_span(tcx: &TyCtxt, heading: &str, span: Span)
+        fn explain_span(tcx: TyCtxt, heading: &str, span: Span)
                         -> (String, Option<Span>) {
             let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo);
             (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
@@ -474,7 +474,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             }
         }
 
-        fn free_regions_from_same_fn(tcx: &TyCtxt,
+        fn free_regions_from_same_fn(tcx: TyCtxt,
                                      sub: Region,
                                      sup: Region)
                                      -> Option<FreeRegionsFromSameFn> {
@@ -1109,7 +1109,7 @@ struct RebuildPathInfo<'a> {
 }
 
 struct Rebuilder<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     fn_decl: &'a hir::FnDecl,
     expl_self_opt: Option<&'a hir::ExplicitSelf_>,
     generics: &'a hir::Generics,
@@ -1125,7 +1125,7 @@ enum FreshOrKept {
 }
 
 impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>,
+    fn new(tcx: TyCtxt<'a, 'tcx>,
            fn_decl: &'a hir::FnDecl,
            expl_self_opt: Option<&'a hir::ExplicitSelf_>,
            generics: &'a hir::Generics,
@@ -1929,7 +1929,7 @@ impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> {
     }
 }
 
-fn lifetimes_in_scope(tcx: &TyCtxt,
+fn lifetimes_in_scope(tcx: TyCtxt,
                       scope_id: ast::NodeId)
                       -> Vec<hir::LifetimeDef> {
     let mut taken = Vec::new();
diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs
index b0f1e9d890c..7c87c0a8791 100644
--- a/src/librustc/infer/freshen.rs
+++ b/src/librustc/infer/freshen.rs
@@ -78,7 +78,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
-    fn tcx<'b>(&'b self) -> &'b TyCtxt<'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs
index 37717c2b6bc..da7d5894da9 100644
--- a/src/librustc/infer/glb.rs
+++ b/src/librustc/infer/glb.rs
@@ -36,7 +36,7 @@ impl<'a, 'tcx> Glb<'a, 'tcx> {
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {
     fn tag(&self) -> &'static str { "Glb" }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> { self.fields.tcx() }
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index 8572eee5ccc..546bfe65fe9 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -329,10 +329,10 @@ fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
     }
 }
 
-fn fold_regions_in<'tcx, T, F>(tcx: &TyCtxt<'tcx>,
-                               unbound_value: &T,
-                               mut fldr: F)
-                               -> T
+fn fold_regions_in<'a, 'tcx, T, F>(tcx: TyCtxt<'a, 'tcx>,
+                                   unbound_value: &T,
+                                   mut fldr: F)
+                                   -> T
     where T: TypeFoldable<'tcx>,
           F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
 {
diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs
index 32b2fe911e8..6bb4a22b4c7 100644
--- a/src/librustc/infer/lub.rs
+++ b/src/librustc/infer/lub.rs
@@ -36,7 +36,7 @@ impl<'a, 'tcx> Lub<'a, 'tcx> {
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {
     fn tag(&self) -> &'static str { "Lub" }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> { self.fields.tcx() }
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index c876f6adae5..1036b918b9a 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -74,7 +74,7 @@ pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
 pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
 
 pub struct InferCtxt<'a, 'tcx: 'a> {
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
 
     pub tables: &'a RefCell<ty::Tables<'tcx>>,
 
@@ -385,7 +385,7 @@ impl fmt::Display for FixupError {
 }
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-    pub fn new(tcx: &'a TyCtxt<'tcx>,
+    pub fn new(tcx: TyCtxt<'a, 'tcx>,
                tables: &'a RefCell<ty::Tables<'tcx>>,
                param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>,
                projection_mode: ProjectionMode)
@@ -406,7 +406,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn normalizing(tcx: &'a TyCtxt<'tcx>,
+    pub fn normalizing(tcx: TyCtxt<'a, 'tcx>,
                        tables: &'a RefCell<ty::Tables<'tcx>>,
                        projection_mode: ProjectionMode)
                        -> Self {
@@ -441,8 +441,8 @@ pub struct CombinedSnapshot {
 }
 
 // NOTE: Callable from trans only!
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn normalize_associated_type<T>(&self, value: &T) -> T
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn normalize_associated_type<T>(self, value: &T) -> T
         where T : TypeFoldable<'tcx>
     {
         debug!("normalize_associated_type(t={:?})", value);
@@ -1523,7 +1523,7 @@ pub fn drain_fulfillment_cx<T>(&self,
     }
 }
 
-impl<'tcx> TypeTrace<'tcx> {
+impl<'a, 'tcx> TypeTrace<'tcx> {
     pub fn span(&self) -> Span {
         self.origin.span()
     }
@@ -1539,7 +1539,7 @@ impl<'tcx> TypeTrace<'tcx> {
         }
     }
 
-    pub fn dummy(tcx: &TyCtxt<'tcx>) -> TypeTrace<'tcx> {
+    pub fn dummy(tcx: TyCtxt<'a, 'tcx>) -> TypeTrace<'tcx> {
         TypeTrace {
             origin: TypeOrigin::Misc(codemap::DUMMY_SP),
             values: Types(ExpectedFound {
diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs
index e611c005691..05303ae1376 100644
--- a/src/librustc/infer/region_inference/graphviz.rs
+++ b/src/librustc/infer/region_inference/graphviz.rs
@@ -119,7 +119,7 @@ pub fn maybe_print_constraints_for<'a, 'tcx>(region_vars: &RegionVarBindings<'a,
 }
 
 struct ConstraintGraph<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     graph_name: String,
     map: &'a FnvHashMap<Constraint, SubregionOrigin<'tcx>>,
     node_ids: FnvHashMap<Node, usize>,
@@ -139,7 +139,7 @@ enum Edge {
 }
 
 impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>,
+    fn new(tcx: TyCtxt<'a, 'tcx>,
            name: String,
            map: &'a ConstraintMap<'tcx>)
            -> ConstraintGraph<'a, 'tcx> {
@@ -258,7 +258,7 @@ impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> {
 
 pub type ConstraintMap<'tcx> = FnvHashMap<Constraint, SubregionOrigin<'tcx>>;
 
-fn dump_region_constraints_to<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
+fn dump_region_constraints_to<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx>,
                                             map: &ConstraintMap<'tcx>,
                                             path: &str)
                                             -> io::Result<()> {
diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs
index 2f610bf2380..9dcc19d76b5 100644
--- a/src/librustc/infer/region_inference/mod.rs
+++ b/src/librustc/infer/region_inference/mod.rs
@@ -191,7 +191,7 @@ impl SameRegions {
 pub type CombineMap = FnvHashMap<TwoRegions, RegionVid>;
 
 pub struct RegionVarBindings<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     var_origins: RefCell<Vec<RegionVariableOrigin>>,
 
     // Constraints of the form `A <= B` introduced by the region
@@ -254,7 +254,7 @@ pub struct RegionSnapshot {
 }
 
 impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
-    pub fn new(tcx: &'a TyCtxt<'tcx>) -> RegionVarBindings<'a, 'tcx> {
+    pub fn new(tcx: TyCtxt<'a, 'tcx>) -> RegionVarBindings<'a, 'tcx> {
         RegionVarBindings {
             tcx: tcx,
             var_origins: RefCell::new(Vec::new()),
@@ -1362,8 +1362,8 @@ impl<'tcx> fmt::Display for GenericKind<'tcx> {
     }
 }
 
-impl<'tcx> GenericKind<'tcx> {
-    pub fn to_ty(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+impl<'a, 'tcx> GenericKind<'tcx> {
+    pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         match *self {
             GenericKind::Param(ref p) => p.to_ty(tcx),
             GenericKind::Projection(ref p) => tcx.mk_projection(p.trait_ref.clone(), p.item_name),
@@ -1424,12 +1424,11 @@ impl VerifyBound {
         }
     }
 
-    fn is_met<'tcx>(&self,
-                    tcx: &TyCtxt<'tcx>,
-                    free_regions: &FreeRegionMap,
-                    var_values: &Vec<VarValue>,
-                    min: ty::Region)
-                    -> bool {
+    fn is_met(&self, tcx: TyCtxt,
+              free_regions: &FreeRegionMap,
+              var_values: &Vec<VarValue>,
+              min: ty::Region)
+              -> bool {
         match self {
             &VerifyBound::AnyRegion(ref rs) =>
                 rs.iter()
diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs
index 8651b52e3fe..c2f38332f54 100644
--- a/src/librustc/infer/resolve.rs
+++ b/src/librustc/infer/resolve.rs
@@ -30,7 +30,7 @@ impl<'a, 'tcx> OpportunisticTypeResolver<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for OpportunisticTypeResolver<'a, 'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> {
         self.infcx.tcx
     }
 
@@ -58,7 +58,7 @@ impl<'a, 'tcx> OpportunisticTypeAndRegionResolver<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for OpportunisticTypeAndRegionResolver<'a, 'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> {
         self.infcx.tcx
     }
 
@@ -104,7 +104,7 @@ struct FullTypeResolver<'a, 'tcx:'a> {
 }
 
 impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs
index a85ae46e662..d6a16727363 100644
--- a/src/librustc/infer/sub.rs
+++ b/src/librustc/infer/sub.rs
@@ -36,7 +36,7 @@ impl<'a, 'tcx> Sub<'a, 'tcx> {
 
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {
     fn tag(&self) -> &'static str { "Sub" }
-    fn tcx(&self) -> &'a TyCtxt<'tcx> { self.fields.infcx.tcx }
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.fields.infcx.tcx }
     fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
     fn with_cause<F,R>(&mut self, cause: Cause, f: F) -> R
diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs
index a9eb20b8299..bf54e7c1b39 100644
--- a/src/librustc/infer/unify_key.rs
+++ b/src/librustc/infer/unify_key.rs
@@ -13,7 +13,7 @@ use ty::{self, IntVarValue, Ty, TyCtxt};
 use rustc_data_structures::unify::{Combine, UnifyKey};
 
 pub trait ToType<'tcx> {
-    fn to_type(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx>;
+    fn to_type<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx>;
 }
 
 impl UnifyKey for ty::IntVid {
@@ -51,7 +51,7 @@ impl UnifyKey for ty::RegionVid {
 }
 
 impl<'tcx> ToType<'tcx> for IntVarValue {
-    fn to_type(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+    fn to_type<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         match *self {
             ty::IntType(i) => tcx.mk_mach_int(i),
             ty::UintType(i) => tcx.mk_mach_uint(i),
@@ -69,7 +69,7 @@ impl UnifyKey for ty::FloatVid {
 }
 
 impl<'tcx> ToType<'tcx> for ast::FloatTy {
-    fn to_type(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+    fn to_type<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         tcx.mk_mach_float(*self)
     }
 }
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 43c0e197e16..a6d6895154c 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -297,7 +297,7 @@ impl LintStore {
 /// Context for lint checking after type checking.
 pub struct LateContext<'a, 'tcx: 'a> {
     /// Type context we're checking in.
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
 
     /// The crate being checked.
     pub krate: &'a hir::Crate,
@@ -652,7 +652,7 @@ impl<'a> EarlyContext<'a> {
 }
 
 impl<'a, 'tcx> LateContext<'a, 'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>,
+    fn new(tcx: TyCtxt<'a, 'tcx>,
            krate: &'a hir::Crate,
            access_levels: &'a AccessLevels) -> LateContext<'a, 'tcx> {
         // We want to own the lint store, so move it out of the session.
@@ -740,7 +740,8 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
     /// items in the context of the outer item, so enable
     /// deep-walking.
     fn visit_nested_item(&mut self, item: hir::ItemId) {
-        self.visit_item(self.tcx.map.expect_item(item.id))
+        let tcx = self.tcx;
+        self.visit_item(tcx.map.expect_item(item.id))
     }
 
     fn visit_item(&mut self, it: &hir::Item) {
@@ -1219,7 +1220,7 @@ fn check_lint_name_cmdline(sess: &Session, lint_cx: &LintStore,
 /// Perform lint checking on a crate.
 ///
 /// Consumes the `lint_store` field of the `Session`.
-pub fn check_crate(tcx: &TyCtxt, access_levels: &AccessLevels) {
+pub fn check_crate(tcx: TyCtxt, access_levels: &AccessLevels) {
     let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck);
 
     let krate = tcx.map.krate();
diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs
index f9a9a451d45..de0d41ea64b 100644
--- a/src/librustc/middle/astconv_util.rs
+++ b/src/librustc/middle/astconv_util.rs
@@ -20,8 +20,8 @@ use ty::{Ty, TyCtxt};
 use syntax::codemap::Span;
 use hir as ast;
 
-impl<'tcx> TyCtxt<'tcx> {
-pub fn prohibit_type_params(&self, segments: &[ast::PathSegment]) {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) {
     for segment in segments {
         for typ in segment.parameters.types() {
             span_err!(self.sess, typ.span, E0109,
@@ -40,13 +40,13 @@ pub fn prohibit_type_params(&self, segments: &[ast::PathSegment]) {
     }
 }
 
-pub fn prohibit_projection(&self, span: Span)
+pub fn prohibit_projection(self, span: Span)
 {
     span_err!(self.sess, span, E0229,
               "associated type bindings are not allowed here");
 }
 
-pub fn prim_ty_to_ty(&self,
+pub fn prim_ty_to_ty(self,
                      segments: &[ast::PathSegment],
                      nty: ast::PrimTy)
                      -> Ty<'tcx> {
@@ -63,7 +63,7 @@ pub fn prim_ty_to_ty(&self,
 
 /// If a type in the AST is a primitive type, return the ty::Ty corresponding
 /// to it.
-pub fn ast_ty_to_prim_ty(&self, ast_ty: &ast::Ty) -> Option<Ty<'tcx>> {
+pub fn ast_ty_to_prim_ty(self, ast_ty: &ast::Ty) -> Option<Ty<'tcx>> {
     if let ast::TyPath(None, ref path) = ast_ty.node {
         let def = match self.def_map.borrow().get(&ast_ty.id) {
             None => {
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 03550565596..e3d94c7a5d3 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -160,57 +160,56 @@ pub trait CrateStore<'tcx> : Any {
     fn stability(&self, def: DefId) -> Option<attr::Stability>;
     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation>;
     fn visibility(&self, def: DefId) -> ty::Visibility;
-    fn closure_kind(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
-                    -> ty::ClosureKind;
-    fn closure_ty(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
-                  -> ty::ClosureTy<'tcx>;
+    fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind;
+    fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def_id: DefId)
+                      -> ty::ClosureTy<'tcx>;
     fn item_variances(&self, def: DefId) -> ty::ItemVariances;
     fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
-    fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                 -> ty::TypeScheme<'tcx>;
+    fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                     -> ty::TypeScheme<'tcx>;
     fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
     fn item_name(&self, def: DefId) -> ast::Name;
-    fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                       -> ty::GenericPredicates<'tcx>;
-    fn item_super_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                             -> ty::GenericPredicates<'tcx>;
+    fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                           -> ty::GenericPredicates<'tcx>;
+    fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                                 -> ty::GenericPredicates<'tcx>;
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
     fn item_symbol(&self, def: DefId) -> String;
-    fn trait_def(&self, tcx: &TyCtxt<'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
-    fn adt_def(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
+    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
+    fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
     fn method_arg_names(&self, did: DefId) -> Vec<String>;
     fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
 
     // trait info
     fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId>;
-    fn provided_trait_methods(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                              -> Vec<Rc<ty::Method<'tcx>>>;
+    fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                                  -> Vec<Rc<ty::Method<'tcx>>>;
     fn trait_item_def_ids(&self, def: DefId)
                           -> Vec<ty::ImplOrTraitItemId>;
 
     // impl info
     fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
-    fn impl_trait_ref(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                      -> Option<ty::TraitRef<'tcx>>;
+    fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                          -> Option<ty::TraitRef<'tcx>>;
     fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity>;
     fn custom_coerce_unsized_kind(&self, def: DefId)
                                   -> Option<ty::adjustment::CustomCoerceUnsized>;
-    fn associated_consts(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                         -> Vec<Rc<ty::AssociatedConst<'tcx>>>;
+    fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                             -> Vec<Rc<ty::AssociatedConst<'tcx>>>;
     fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
 
     // trait/impl-item info
-    fn trait_of_item(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
-                     -> Option<DefId>;
-    fn impl_or_trait_item(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> Option<ty::ImplOrTraitItem<'tcx>>;
+    fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def_id: DefId)
+                         -> Option<DefId>;
+    fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> Option<ty::ImplOrTraitItem<'tcx>>;
 
     // flags
     fn is_const_fn(&self, did: DefId) -> bool;
     fn is_defaulted_trait(&self, did: DefId) -> bool;
     fn is_impl(&self, did: DefId) -> bool;
     fn is_default_impl(&self, impl_did: DefId) -> bool;
-    fn is_extern_item(&self, tcx: &TyCtxt<'tcx>, did: DefId) -> bool;
+    fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, did: DefId) -> bool;
     fn is_static_method(&self, did: DefId) -> bool;
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
     fn is_typedef(&self, did: DefId) -> bool;
@@ -251,10 +250,10 @@ pub trait CrateStore<'tcx> : Any {
     fn crate_top_level_items(&self, cnum: ast::CrateNum) -> Vec<ChildItem>;
 
     // misc. metadata
-    fn maybe_get_item_ast(&'tcx self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> FoundAst<'tcx>;
-    fn maybe_get_item_mir(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> Option<Mir<'tcx>>;
+    fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> FoundAst<'tcx>;
+    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> Option<Mir<'tcx>>;
     fn is_item_mir_available(&self, def: DefId) -> bool;
 
     // This is basically a 1-based range of ints, which is a little
@@ -266,22 +265,21 @@ pub trait CrateStore<'tcx> : Any {
     // utility functions
     fn metadata_filename(&self) -> &str;
     fn metadata_section_name(&self, target: &Target) -> &str;
-    fn encode_type(&self,
-                   tcx: &TyCtxt<'tcx>,
-                   ty: Ty<'tcx>,
-                   def_id_to_string: fn(&TyCtxt<'tcx>, DefId) -> String)
-                   -> Vec<u8>;
+    fn encode_type<'a>(&self,
+                       tcx: TyCtxt<'a, 'tcx>,
+                       ty: Ty<'tcx>,
+                       def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx>, DefId) -> String)
+                       -> Vec<u8>;
     fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>;
     fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource;
     fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum>;
-    fn encode_metadata(&self,
-                       tcx: &TyCtxt<'tcx>,
-                       reexports: &def::ExportMap,
-                       item_symbols: &RefCell<NodeMap<String>>,
-                       link_meta: &LinkMeta,
-                       reachable: &NodeSet,
-                       mir_map: &MirMap<'tcx>,
-                       krate: &hir::Crate) -> Vec<u8>;
+    fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx>,
+                           reexports: &def::ExportMap,
+                           item_symbols: &RefCell<NodeMap<String>>,
+                           link_meta: &LinkMeta,
+                           reachable: &NodeSet,
+                           mir_map: &MirMap<'tcx>,
+                           krate: &hir::Crate) -> Vec<u8>;
     fn metadata_encoding_version(&self) -> &[u8];
 }
 
@@ -339,63 +337,63 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     fn stability(&self, def: DefId) -> Option<attr::Stability> { bug!("stability") }
     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { bug!("deprecation") }
     fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
-    fn closure_kind(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
-                    -> ty::ClosureKind  { bug!("closure_kind") }
-    fn closure_ty(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
-                  -> ty::ClosureTy<'tcx>  { bug!("closure_ty") }
+    fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind  { bug!("closure_kind") }
+    fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def_id: DefId)
+                      -> ty::ClosureTy<'tcx>  { bug!("closure_ty") }
     fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") }
     fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
-    fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                 -> ty::TypeScheme<'tcx> { bug!("item_type") }
+    fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                     -> ty::TypeScheme<'tcx> { bug!("item_type") }
     fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
         bug!("visible_parent_map")
     }
     fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") }
-    fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                       -> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
-    fn item_super_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                             -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
+    fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                           -> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
+    fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                                 -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
     fn item_symbol(&self, def: DefId) -> String { bug!("item_symbol") }
-    fn trait_def(&self, tcx: &TyCtxt<'tcx>, def: DefId)-> ty::TraitDef<'tcx>
+    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
         { bug!("trait_def") }
-    fn adt_def(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
+    fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
         { bug!("adt_def") }
     fn method_arg_names(&self, did: DefId) -> Vec<String> { bug!("method_arg_names") }
     fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
 
     // trait info
     fn implementations_of_trait(&self, def_id: DefId) -> Vec<DefId> { vec![] }
-    fn provided_trait_methods(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                              -> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
+    fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                                  -> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
     fn trait_item_def_ids(&self, def: DefId)
                           -> Vec<ty::ImplOrTraitItemId> { bug!("trait_item_def_ids") }
 
     // impl info
     fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
         { bug!("impl_items") }
-    fn impl_trait_ref(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                      -> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
+    fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                          -> Option<ty::TraitRef<'tcx>> { bug!("impl_trait_ref") }
     fn impl_polarity(&self, def: DefId) -> Option<hir::ImplPolarity> { bug!("impl_polarity") }
     fn custom_coerce_unsized_kind(&self, def: DefId)
                                   -> Option<ty::adjustment::CustomCoerceUnsized>
         { bug!("custom_coerce_unsized_kind") }
-    fn associated_consts(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                         -> Vec<Rc<ty::AssociatedConst<'tcx>>> { bug!("associated_consts") }
+    fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                             -> Vec<Rc<ty::AssociatedConst<'tcx>>> { bug!("associated_consts") }
     fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
 
     // trait/impl-item info
-    fn trait_of_item(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
-                     -> Option<DefId> { bug!("trait_of_item") }
-    fn impl_or_trait_item(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
+    fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def_id: DefId)
+                         -> Option<DefId> { bug!("trait_of_item") }
+    fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
 
     // flags
     fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
     fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") }
     fn is_impl(&self, did: DefId) -> bool { bug!("is_impl") }
     fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
-    fn is_extern_item(&self, tcx: &TyCtxt<'tcx>, did: DefId) -> bool { bug!("is_extern_item") }
+    fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, did: DefId) -> bool
+        { bug!("is_extern_item") }
     fn is_static_method(&self, did: DefId) -> bool { bug!("is_static_method") }
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
     fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") }
@@ -448,10 +446,10 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
         { bug!("crate_top_level_items") }
 
     // misc. metadata
-    fn maybe_get_item_ast(&'tcx self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> FoundAst<'tcx> { bug!("maybe_get_item_ast") }
-    fn maybe_get_item_mir(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
+    fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> FoundAst<'tcx> { bug!("maybe_get_item_ast") }
+    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
     fn is_item_mir_available(&self, def: DefId) -> bool {
         bug!("is_item_mir_available")
     }
@@ -465,25 +463,24 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     // utility functions
     fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
     fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
-    fn encode_type(&self,
-                   tcx: &TyCtxt<'tcx>,
-                   ty: Ty<'tcx>,
-                   def_id_to_string: fn(&TyCtxt<'tcx>, DefId) -> String)
-                   -> Vec<u8> {
+    fn encode_type<'a>(&self,
+                       tcx: TyCtxt<'a, 'tcx>,
+                       ty: Ty<'tcx>,
+                       def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx>, DefId) -> String)
+                       -> Vec<u8> {
         bug!("encode_type")
     }
     fn used_crates(&self, prefer: LinkagePreference) -> Vec<(ast::CrateNum, Option<PathBuf>)>
         { vec![] }
     fn used_crate_source(&self, cnum: ast::CrateNum) -> CrateSource { bug!("used_crate_source") }
     fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<ast::CrateNum> { None }
-    fn encode_metadata(&self,
-                       tcx: &TyCtxt<'tcx>,
-                       reexports: &def::ExportMap,
-                       item_symbols: &RefCell<NodeMap<String>>,
-                       link_meta: &LinkMeta,
-                       reachable: &NodeSet,
-                       mir_map: &MirMap<'tcx>,
-                       krate: &hir::Crate) -> Vec<u8> { vec![] }
+    fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx>,
+                           reexports: &def::ExportMap,
+                           item_symbols: &RefCell<NodeMap<String>>,
+                           link_meta: &LinkMeta,
+                           reachable: &NodeSet,
+                           mir_map: &MirMap<'tcx>,
+                           krate: &hir::Crate) -> Vec<u8> { vec![] }
     fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
 }
 
@@ -510,7 +507,7 @@ pub mod tls {
     use hir::def_id::DefId;
 
     pub trait EncodingContext<'tcx> {
-        fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
+        fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx>;
         fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: Ty<'tcx>);
         fn encode_substs(&self, encoder: &mut OpaqueEncoder, substs: &Substs<'tcx>);
     }
@@ -577,7 +574,7 @@ pub mod tls {
     }
 
     pub trait DecodingContext<'tcx> {
-        fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
+        fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx>;
         fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx>;
         fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx>;
         fn translate_def_id(&self, def_id: DefId) -> DefId;
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index 1aaaa4bcd77..dc58a663195 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -37,7 +37,7 @@ pub enum EntryOrExit {
 
 #[derive(Clone)]
 pub struct DataFlowContext<'a, 'tcx: 'a, O> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 
     /// a name for the analysis using this dataflow instance
     analysis_name: &'static str,
@@ -222,7 +222,7 @@ pub enum KillFrom {
 }
 
 impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
-    pub fn new(tcx: &'a TyCtxt<'tcx>,
+    pub fn new(tcx: TyCtxt<'a, 'tcx>,
                analysis_name: &'static str,
                decl: Option<&hir::FnDecl>,
                cfg: &cfg::CFG,
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 576a9bb33e8..a1fe1b521f5 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -31,7 +31,7 @@ use syntax::attr;
 // explored. For example, if it's a live NodeItem that is a
 // function, then we should explore its block to check for codes that
 // may need to be marked as live.
-fn should_explore(tcx: &TyCtxt, node_id: ast::NodeId) -> bool {
+fn should_explore(tcx: TyCtxt, node_id: ast::NodeId) -> bool {
     match tcx.map.find(node_id) {
         Some(ast_map::NodeItem(..)) |
         Some(ast_map::NodeImplItem(..)) |
@@ -45,7 +45,7 @@ fn should_explore(tcx: &TyCtxt, node_id: ast::NodeId) -> bool {
 
 struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     worklist: Vec<ast::NodeId>,
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     live_symbols: Box<HashSet<ast::NodeId>>,
     struct_has_extern_repr: bool,
     ignore_non_const_paths: bool,
@@ -54,7 +54,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>,
+    fn new(tcx: TyCtxt<'a, 'tcx>,
            worklist: Vec<ast::NodeId>) -> MarkSymbolVisitor<'a, 'tcx> {
         MarkSymbolVisitor {
             worklist: worklist,
@@ -362,7 +362,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
     }
 }
 
-fn create_and_seed_worklist(tcx: &TyCtxt,
+fn create_and_seed_worklist(tcx: TyCtxt,
                             access_levels: &privacy::AccessLevels,
                             krate: &hir::Crate) -> Vec<ast::NodeId> {
     let mut worklist = Vec::new();
@@ -385,7 +385,7 @@ fn create_and_seed_worklist(tcx: &TyCtxt,
     return life_seeder.worklist;
 }
 
-fn find_live(tcx: &TyCtxt,
+fn find_live(tcx: TyCtxt,
              access_levels: &privacy::AccessLevels,
              krate: &hir::Crate)
              -> Box<HashSet<ast::NodeId>> {
@@ -405,7 +405,7 @@ fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
 }
 
 struct DeadVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     live_symbols: Box<HashSet<ast::NodeId>>,
 }
 
@@ -504,7 +504,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
     /// an error. We could do this also by checking the parents, but
     /// this is how the code is setup and it seems harmless enough.
     fn visit_nested_item(&mut self, item: hir::ItemId) {
-        self.visit_item(self.tcx.map.expect_item(item.id))
+        let tcx = self.tcx;
+        self.visit_item(tcx.map.expect_item(item.id))
     }
 
     fn visit_item(&mut self, item: &hir::Item) {
@@ -582,7 +583,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt, access_levels: &privacy::AccessLevels) {
+pub fn check_crate(tcx: TyCtxt, access_levels: &privacy::AccessLevels) {
     let _task = tcx.dep_graph.in_task(DepNode::DeadCheck);
     let krate = tcx.map.krate();
     let live_symbols = find_live(tcx, access_levels, krate);
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index ac7a1b8aa0d..55a130697fe 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -51,7 +51,7 @@ fn type_is_unsafe_function(ty: Ty) -> bool {
 }
 
 struct EffectCheckVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 
     /// Whether we're in an unsafe context.
     unsafe_context: UnsafeContext,
@@ -183,7 +183,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt) {
+pub fn check_crate(tcx: TyCtxt) {
     let _task = tcx.dep_graph.in_task(DepNode::EffectCheck);
 
     let mut visitor = EffectCheckVisitor {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 002f202796c..b662dc81d94 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -209,7 +209,7 @@ enum OverloadedCallType {
 }
 
 impl OverloadedCallType {
-    fn from_trait_id(tcx: &TyCtxt, trait_id: DefId)
+    fn from_trait_id(tcx: TyCtxt, trait_id: DefId)
                      -> OverloadedCallType {
         for &(maybe_function_trait, overloaded_call_type) in &[
             (tcx.lang_items.fn_once_trait(), FnOnceOverloadedCall),
@@ -227,7 +227,7 @@ impl OverloadedCallType {
         bug!("overloaded call didn't map to known function trait")
     }
 
-    fn from_method_id(tcx: &TyCtxt, method_id: DefId)
+    fn from_method_id(tcx: TyCtxt, method_id: DefId)
                       -> OverloadedCallType {
         let method = tcx.impl_or_trait_item(method_id);
         OverloadedCallType::from_trait_id(tcx, method.container().id())
@@ -306,7 +306,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
         }
     }
 
-    fn tcx(&self) -> &'t TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'t, 'tcx> {
         self.typer.tcx
     }
 
diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs
index ccd927a3289..e4ce8976713 100644
--- a/src/librustc/middle/free_region.rs
+++ b/src/librustc/middle/free_region.rs
@@ -121,7 +121,7 @@ impl FreeRegionMap {
     /// Determines whether one region is a subregion of another.  This is intended to run *after
     /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
     pub fn is_subregion_of(&self,
-                           tcx: &TyCtxt,
+                           tcx: TyCtxt,
                            sub_region: ty::Region,
                            super_region: ty::Region)
                            -> bool {
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 2c205f48248..ee201335b11 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -22,7 +22,7 @@ use syntax::codemap::Span;
 use hir::intravisit::{self, Visitor, FnKind};
 use hir;
 
-pub fn check_crate(tcx: &TyCtxt) {
+pub fn check_crate(tcx: TyCtxt) {
     let mut visitor = ItemVisitor {
         tcx: tcx
     };
@@ -30,7 +30,7 @@ pub fn check_crate(tcx: &TyCtxt) {
 }
 
 struct ItemVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>
+    tcx: TyCtxt<'a, 'tcx>
 }
 
 impl<'a, 'tcx> ItemVisitor<'a, 'tcx> {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index cd84e5ee7bf..2d269133932 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -169,7 +169,7 @@ enum LiveNodeKind {
     ExitNode
 }
 
-fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: &TyCtxt) -> String {
+fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt) -> String {
     let cm = tcx.sess.codemap();
     match lnk {
         FreeVarNode(s) => {
@@ -195,7 +195,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
     fn visit_arm(&mut self, a: &hir::Arm) { visit_arm(self, a); }
 }
 
-pub fn check_crate(tcx: &TyCtxt) {
+pub fn check_crate(tcx: TyCtxt) {
     let _task = tcx.dep_graph.in_task(DepNode::Liveness);
     tcx.map.krate().visit_all_items(&mut IrMaps::new(tcx));
     tcx.sess.abort_if_errors();
@@ -263,7 +263,7 @@ enum VarKind {
 }
 
 struct IrMaps<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 
     num_live_nodes: usize,
     num_vars: usize,
@@ -275,7 +275,7 @@ struct IrMaps<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> IrMaps<'a, 'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>) -> IrMaps<'a, 'tcx> {
+    fn new(tcx: TyCtxt<'a, 'tcx>) -> IrMaps<'a, 'tcx> {
         IrMaps {
             tcx: tcx,
             num_live_nodes: 0,
@@ -1486,9 +1486,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             ty::FnConverging(t_ret)
                     if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() => {
 
-                let param_env = ParameterEnvironment::for_item(&self.ir.tcx, id);
-                let t_ret_subst = t_ret.subst(&self.ir.tcx, &param_env.free_substs);
-                let infcx = InferCtxt::new(&self.ir.tcx,
+                let param_env = ParameterEnvironment::for_item(self.ir.tcx, id);
+                let t_ret_subst = t_ret.subst(self.ir.tcx, &param_env.free_substs);
+                let infcx = InferCtxt::new(self.ir.tcx,
                                            &self.ir.tcx.tables,
                                            Some(param_env),
                                            ProjectionMode::Any);
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 4c440b15988..9faae0c098d 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -302,7 +302,7 @@ impl MutabilityCategory {
         ret
     }
 
-    fn from_local(tcx: &TyCtxt, id: ast::NodeId) -> MutabilityCategory {
+    fn from_local(tcx: TyCtxt, id: ast::NodeId) -> MutabilityCategory {
         let ret = match tcx.map.get(id) {
             ast_map::NodeLocal(p) => match p.node {
                 PatKind::Ident(bind_mode, _, _) => {
@@ -363,7 +363,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         MemCategorizationContext { typer: typer }
     }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.typer.tcx
     }
 
@@ -1082,7 +1082,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         /// In a pattern like [a, b, ..c], normally `c` has slice type, but if you have [a, b,
         /// ..ref c], then the type of `ref c` will be `&&[]`, so to extract the slice details we
         /// have to recurse through rptrs.
-        fn vec_slice_info(tcx: &TyCtxt,
+        fn vec_slice_info(tcx: TyCtxt,
                           pat: &hir::Pat,
                           slice_ty: Ty)
                           -> (hir::Mutability, ty::Region) {
@@ -1463,7 +1463,7 @@ impl<'tcx> cmt_<'tcx> {
     }
 
 
-    pub fn descriptive_string(&self, tcx: &TyCtxt) -> String {
+    pub fn descriptive_string(&self, tcx: TyCtxt) -> String {
         match self.cat {
             Categorization::StaticItem => {
                 "static item".to_string()
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 63bccc2d02e..b2036d7a4c0 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -55,7 +55,7 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
     }
 }
 
-fn method_might_be_inlined(tcx: &TyCtxt, sig: &hir::MethodSig,
+fn method_might_be_inlined(tcx: TyCtxt, sig: &hir::MethodSig,
                            impl_item: &hir::ImplItem,
                            impl_src: DefId) -> bool {
     if attr::requests_inline(&impl_item.attrs) ||
@@ -77,7 +77,7 @@ fn method_might_be_inlined(tcx: &TyCtxt, sig: &hir::MethodSig,
 // Information needed while computing reachability.
 struct ReachableContext<'a, 'tcx: 'a> {
     // The type context.
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     // The set of items which must be exported in the linkage sense.
     reachable_symbols: NodeSet,
     // A worklist of item IDs. Each item ID in this worklist will be inlined
@@ -142,7 +142,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
 
 impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
     // Creates a new reachability computation context.
-    fn new(tcx: &'a TyCtxt<'tcx>) -> ReachableContext<'a, 'tcx> {
+    fn new(tcx: TyCtxt<'a, 'tcx>) -> ReachableContext<'a, 'tcx> {
         let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
             *ty != config::CrateTypeExecutable
         });
@@ -344,7 +344,7 @@ impl<'a, 'v> Visitor<'v> for CollectPrivateImplItemsVisitor<'a> {
     }
 }
 
-pub fn find_reachable(tcx: &TyCtxt,
+pub fn find_reachable(tcx: TyCtxt,
                       access_levels: &privacy::AccessLevels)
                       -> NodeSet {
     let _task = tcx.dep_graph.in_task(DepNode::Reachability);
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index f596f3b4a50..6edbb6c584f 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -72,7 +72,7 @@ pub struct Index<'tcx> {
 
 // A private tree-walker for producing an Index.
 struct Annotator<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     index: &'a mut Index<'tcx>,
     parent_stab: Option<&'tcx Stability>,
     parent_depr: Option<Deprecation>,
@@ -203,7 +203,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
     /// nested items in the context of the outer item, so enable
     /// deep-walking.
     fn visit_nested_item(&mut self, item: hir::ItemId) {
-        self.visit_item(self.tcx.map.expect_item(item.id))
+        let tcx = self.tcx;
+        self.visit_item(tcx.map.expect_item(item.id))
     }
 
     fn visit_item(&mut self, i: &Item) {
@@ -277,9 +278,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
     }
 }
 
-impl<'tcx> Index<'tcx> {
+impl<'a, 'tcx> Index<'tcx> {
     /// Construct the stability index for a crate being compiled.
-    pub fn build(&mut self, tcx: &TyCtxt<'tcx>, access_levels: &AccessLevels) {
+    pub fn build(&mut self, tcx: TyCtxt<'a, 'tcx>, access_levels: &AccessLevels) {
         let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
         let krate = tcx.map.krate();
         let mut annotator = Annotator {
@@ -319,7 +320,7 @@ impl<'tcx> Index<'tcx> {
 /// Cross-references the feature names of unstable APIs with enabled
 /// features and possibly prints errors. Returns a list of all
 /// features used.
-pub fn check_unstable_api_usage(tcx: &TyCtxt)
+pub fn check_unstable_api_usage(tcx: TyCtxt)
                                 -> FnvHashMap<InternedString, StabilityLevel> {
     let _task = tcx.dep_graph.in_task(DepNode::StabilityCheck);
     let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
@@ -339,7 +340,7 @@ pub fn check_unstable_api_usage(tcx: &TyCtxt)
 }
 
 struct Checker<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     active_features: FnvHashSet<InternedString>,
     used_features: FnvHashMap<InternedString, StabilityLevel>,
     // Within a block where feature gate checking can be skipped.
@@ -411,7 +412,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
     /// nested items in the context of the outer item, so enable
     /// deep-walking.
     fn visit_nested_item(&mut self, item: hir::ItemId) {
-        self.visit_item(self.tcx.map.expect_item(item.id))
+        let tcx = self.tcx;
+        self.visit_item(tcx.map.expect_item(item.id))
     }
 
     fn visit_item(&mut self, item: &hir::Item) {
@@ -466,7 +468,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
 }
 
 /// Helper for discovering nodes to check for stability
-pub fn check_item(tcx: &TyCtxt, item: &hir::Item, warn_about_defns: bool,
+pub fn check_item(tcx: TyCtxt, item: &hir::Item, warn_about_defns: bool,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>)) {
     match item.node {
         hir::ItemExternCrate(_) => {
@@ -503,7 +505,7 @@ pub fn check_item(tcx: &TyCtxt, item: &hir::Item, warn_about_defns: bool,
 }
 
 /// Helper for discovering nodes to check for stability
-pub fn check_expr(tcx: &TyCtxt, e: &hir::Expr,
+pub fn check_expr(tcx: TyCtxt, e: &hir::Expr,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>)) {
     let span;
     let id = match e.node {
@@ -564,7 +566,7 @@ pub fn check_expr(tcx: &TyCtxt, e: &hir::Expr,
     maybe_do_stability_check(tcx, id, span, cb);
 }
 
-pub fn check_path(tcx: &TyCtxt, path: &hir::Path, id: ast::NodeId,
+pub fn check_path(tcx: TyCtxt, path: &hir::Path, id: ast::NodeId,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>)) {
     match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
         Some(Def::PrimTy(..)) => {}
@@ -576,7 +578,7 @@ pub fn check_path(tcx: &TyCtxt, path: &hir::Path, id: ast::NodeId,
     }
 }
 
-pub fn check_path_list_item(tcx: &TyCtxt, item: &hir::PathListItem,
+pub fn check_path_list_item(tcx: TyCtxt, item: &hir::PathListItem,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>)) {
     match tcx.def_map.borrow().get(&item.node.id()).map(|d| d.full_def()) {
         Some(Def::PrimTy(..)) => {}
@@ -587,7 +589,7 @@ pub fn check_path_list_item(tcx: &TyCtxt, item: &hir::PathListItem,
     }
 }
 
-pub fn check_pat(tcx: &TyCtxt, pat: &hir::Pat,
+pub fn check_pat(tcx: TyCtxt, pat: &hir::Pat,
                  cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>)) {
     debug!("check_pat(pat = {:?})", pat);
     if is_internal(tcx, pat.span) { return; }
@@ -616,7 +618,7 @@ pub fn check_pat(tcx: &TyCtxt, pat: &hir::Pat,
     }
 }
 
-fn maybe_do_stability_check(tcx: &TyCtxt, id: DefId, span: Span,
+fn maybe_do_stability_check(tcx: TyCtxt, id: DefId, span: Span,
                             cb: &mut FnMut(DefId, Span,
                                            &Option<&Stability>, &Option<Deprecation>)) {
     if is_internal(tcx, span) {
@@ -634,11 +636,11 @@ fn maybe_do_stability_check(tcx: &TyCtxt, id: DefId, span: Span,
     cb(id, span, &stability, &deprecation);
 }
 
-fn is_internal(tcx: &TyCtxt, span: Span) -> bool {
+fn is_internal(tcx: TyCtxt, span: Span) -> bool {
     tcx.sess.codemap().span_allows_unstable(span)
 }
 
-fn is_staged_api(tcx: &TyCtxt, id: DefId) -> bool {
+fn is_staged_api(tcx: TyCtxt, id: DefId) -> bool {
     match tcx.trait_item_of_item(id) {
         Some(ty::MethodTraitItemId(trait_method_id))
             if trait_method_id != id => {
@@ -651,10 +653,10 @@ fn is_staged_api(tcx: &TyCtxt, id: DefId) -> bool {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
 /// Lookup the stability for a node, loading external crate
 /// metadata as necessary.
-pub fn lookup_stability(&self, id: DefId) -> Option<&'tcx Stability> {
+pub fn lookup_stability(self, id: DefId) -> Option<&'tcx Stability> {
     if let Some(st) = self.stability.borrow().stab_map.get(&id) {
         return *st;
     }
@@ -664,7 +666,7 @@ pub fn lookup_stability(&self, id: DefId) -> Option<&'tcx Stability> {
     st
 }
 
-pub fn lookup_deprecation(&self, id: DefId) -> Option<Deprecation> {
+pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
     if let Some(depr) = self.stability.borrow().depr_map.get(&id) {
         return depr.clone();
     }
@@ -674,7 +676,7 @@ pub fn lookup_deprecation(&self, id: DefId) -> Option<Deprecation> {
     depr
 }
 
-fn lookup_stability_uncached(&self, id: DefId) -> Option<&'tcx Stability> {
+fn lookup_stability_uncached(self, id: DefId) -> Option<&'tcx Stability> {
     debug!("lookup(id={:?})", id);
     if id.is_local() {
         None // The stability cache is filled partially lazily
@@ -683,7 +685,7 @@ fn lookup_stability_uncached(&self, id: DefId) -> Option<&'tcx Stability> {
     }
 }
 
-fn lookup_deprecation_uncached(&self, id: DefId) -> Option<Deprecation> {
+fn lookup_deprecation_uncached(self, id: DefId) -> Option<Deprecation> {
     debug!("lookup(id={:?})", id);
     if id.is_local() {
         None // The stability cache is filled partially lazily
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index d710417bf20..3d59f8965ed 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -30,12 +30,12 @@ pub enum LvalueTy<'tcx> {
                variant_index: usize },
 }
 
-impl<'tcx> LvalueTy<'tcx> {
+impl<'a, 'tcx> LvalueTy<'tcx> {
     pub fn from_ty(ty: Ty<'tcx>) -> LvalueTy<'tcx> {
         LvalueTy::Ty { ty: ty }
     }
 
-    pub fn to_ty(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+    pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         match *self {
             LvalueTy::Ty { ty } =>
                 ty,
@@ -44,8 +44,7 @@ impl<'tcx> LvalueTy<'tcx> {
         }
     }
 
-    pub fn projection_ty(self,
-                         tcx: &TyCtxt<'tcx>,
+    pub fn projection_ty(self, tcx: TyCtxt<'a, 'tcx>,
                          elem: &LvalueElem<'tcx>)
                          -> LvalueTy<'tcx>
     {
@@ -101,9 +100,8 @@ impl<'tcx> TypeFoldable<'tcx> for LvalueTy<'tcx> {
     }
 }
 
-impl<'tcx> Mir<'tcx> {
-    pub fn operand_ty(&self,
-                      tcx: &TyCtxt<'tcx>,
+impl<'a, 'tcx> Mir<'tcx> {
+    pub fn operand_ty(&self, tcx: TyCtxt<'a, 'tcx>,
                       operand: &Operand<'tcx>)
                       -> Ty<'tcx>
     {
@@ -113,8 +111,7 @@ impl<'tcx> Mir<'tcx> {
         }
     }
 
-    pub fn binop_ty(&self,
-                    tcx: &TyCtxt<'tcx>,
+    pub fn binop_ty(&self, tcx: TyCtxt<'a, 'tcx>,
                     op: BinOp,
                     lhs_ty: Ty<'tcx>,
                     rhs_ty: Ty<'tcx>)
@@ -138,8 +135,7 @@ impl<'tcx> Mir<'tcx> {
         }
     }
 
-    pub fn lvalue_ty(&self,
-                     tcx: &TyCtxt<'tcx>,
+    pub fn lvalue_ty(&self, tcx: TyCtxt<'a, 'tcx>,
                      lvalue: &Lvalue<'tcx>)
                      -> LvalueTy<'tcx>
     {
@@ -159,8 +155,7 @@ impl<'tcx> Mir<'tcx> {
         }
     }
 
-    pub fn rvalue_ty(&self,
-                     tcx: &TyCtxt<'tcx>,
+    pub fn rvalue_ty(&self, tcx: TyCtxt<'a, 'tcx>,
                      rvalue: &Rvalue<'tcx>)
                      -> Option<Ty<'tcx>>
     {
diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs
index 520bfbddf9f..1d8ca5f84d1 100644
--- a/src/librustc/mir/transform.rs
+++ b/src/librustc/mir/transform.rs
@@ -34,7 +34,7 @@ pub enum MirSource {
 }
 
 impl MirSource {
-    pub fn from_node(tcx: &TyCtxt, id: NodeId) -> MirSource {
+    pub fn from_node(tcx: TyCtxt, id: NodeId) -> MirSource {
         use hir::*;
 
         // Handle constants in enum discriminants, types, and repeat expressions.
@@ -79,21 +79,21 @@ pub trait Pass {
 
 /// A pass which inspects the whole MirMap.
 pub trait MirMapPass<'tcx>: Pass {
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, map: &mut MirMap<'tcx>);
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, map: &mut MirMap<'tcx>);
 }
 
 /// A pass which inspects Mir of functions in isolation.
 pub trait MirPass<'tcx>: Pass {
-    fn run_pass_on_promoted(&mut self, tcx: &TyCtxt<'tcx>,
-                            item_id: NodeId, index: usize,
-                            mir: &mut Mir<'tcx>) {
+    fn run_pass_on_promoted<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>,
+                                item_id: NodeId, index: usize,
+                                mir: &mut Mir<'tcx>) {
         self.run_pass(tcx, MirSource::Promoted(item_id, index), mir);
     }
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, src: MirSource, mir: &mut Mir<'tcx>);
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>);
 }
 
 impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, map: &mut MirMap<'tcx>) {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, map: &mut MirMap<'tcx>) {
         for (&id, mir) in &mut map.map {
             let def_id = tcx.map.local_def_id(id);
             let _task = tcx.dep_graph.in_task(self.dep_node(def_id));
@@ -114,7 +114,7 @@ pub struct Passes {
     plugin_passes: Vec<Box<for<'tcx> MirMapPass<'tcx>>>
 }
 
-impl Passes {
+impl<'a, 'tcx> Passes {
     pub fn new() -> Passes {
         let passes = Passes {
             passes: Vec::new(),
@@ -123,17 +123,17 @@ impl Passes {
         passes
     }
 
-    pub fn run_passes<'tcx>(&mut self, pcx: &TyCtxt<'tcx>, map: &mut MirMap<'tcx>) {
+    pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx>, map: &mut MirMap<'tcx>) {
         for pass in &mut self.plugin_passes {
-            pass.run_pass(pcx, map);
+            pass.run_pass(tcx, map);
         }
         for pass in &mut self.passes {
-            pass.run_pass(pcx, map);
+            pass.run_pass(tcx, map);
         }
     }
 
     /// Pushes a built-in pass.
-    pub fn push_pass(&mut self, pass: Box<for<'a> MirMapPass<'a>>) {
+    pub fn push_pass(&mut self, pass: Box<for<'b> MirMapPass<'b>>) {
         self.passes.push(pass);
     }
 }
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index ca2224d7884..03478eaf61a 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -86,7 +86,8 @@ fn overlap<'cx, 'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
     Some(selcx.infcx().resolve_type_vars_if_possible(&a_impl_header))
 }
 
-pub fn trait_ref_is_knowable<'tcx>(tcx: &TyCtxt<'tcx>, trait_ref: &ty::TraitRef<'tcx>) -> bool
+pub fn trait_ref_is_knowable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                       trait_ref: &ty::TraitRef<'tcx>) -> bool
 {
     debug!("trait_ref_is_knowable(trait_ref={:?})", trait_ref);
 
@@ -128,9 +129,9 @@ pub enum OrphanCheckErr<'tcx> {
 ///
 /// 1. All type parameters in `Self` must be "covered" by some local type constructor.
 /// 2. Some local type must appear in `Self`.
-pub fn orphan_check<'tcx>(tcx: &TyCtxt<'tcx>,
-                          impl_def_id: DefId)
-                          -> Result<(), OrphanCheckErr<'tcx>>
+pub fn orphan_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                              impl_def_id: DefId)
+                              -> Result<(), OrphanCheckErr<'tcx>>
 {
     debug!("orphan_check({:?})", impl_def_id);
 
@@ -149,10 +150,10 @@ pub fn orphan_check<'tcx>(tcx: &TyCtxt<'tcx>,
     orphan_check_trait_ref(tcx, &trait_ref, InferIsLocal(false))
 }
 
-fn orphan_check_trait_ref<'tcx>(tcx: &TyCtxt<'tcx>,
-                                trait_ref: &ty::TraitRef<'tcx>,
-                                infer_is_local: InferIsLocal)
-                                -> Result<(), OrphanCheckErr<'tcx>>
+fn orphan_check_trait_ref<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                    trait_ref: &ty::TraitRef<'tcx>,
+                                    infer_is_local: InferIsLocal)
+                                    -> Result<(), OrphanCheckErr<'tcx>>
 {
     debug!("orphan_check_trait_ref(trait_ref={:?}, infer_is_local={})",
            trait_ref, infer_is_local.0);
@@ -197,10 +198,10 @@ fn orphan_check_trait_ref<'tcx>(tcx: &TyCtxt<'tcx>,
     return Err(OrphanCheckErr::NoLocalInputType);
 }
 
-fn uncovered_tys<'tcx>(tcx: &TyCtxt<'tcx>,
-                       ty: Ty<'tcx>,
-                       infer_is_local: InferIsLocal)
-                       -> Vec<Ty<'tcx>>
+fn uncovered_tys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                           ty: Ty<'tcx>,
+                           infer_is_local: InferIsLocal)
+                           -> Vec<Ty<'tcx>>
 {
     if ty_is_local_constructor(tcx, ty, infer_is_local) {
         vec![]
@@ -221,13 +222,13 @@ fn is_type_parameter<'tcx>(ty: Ty<'tcx>) -> bool {
     }
 }
 
-fn ty_is_local<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>, infer_is_local: InferIsLocal) -> bool
+fn ty_is_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, ty: Ty<'tcx>, infer_is_local: InferIsLocal) -> bool
 {
     ty_is_local_constructor(tcx, ty, infer_is_local) ||
         fundamental_ty(tcx, ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, infer_is_local))
 }
 
-fn fundamental_ty<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool
+fn fundamental_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> bool
 {
     match ty.sty {
         ty::TyBox(..) | ty::TyRef(..) =>
@@ -241,10 +242,10 @@ fn fundamental_ty<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool
     }
 }
 
-fn ty_is_local_constructor<'tcx>(tcx: &TyCtxt<'tcx>,
-                                 ty: Ty<'tcx>,
-                                 infer_is_local: InferIsLocal)
-                                 -> bool
+fn ty_is_local_constructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                     ty: Ty<'tcx>,
+                                     infer_is_local: InferIsLocal)
+                                     -> bool
 {
     debug!("ty_is_local_constructor({:?})", ty);
 
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index fb030288a72..f1fe990863a 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -558,8 +558,8 @@ pub fn report_selection_error(&self,
 }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-pub fn recursive_type_with_infinite_size_error(&self,
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+pub fn recursive_type_with_infinite_size_error(self,
                                                type_def_id: DefId)
                                                -> DiagnosticBuilder<'tcx>
 {
@@ -573,7 +573,7 @@ pub fn recursive_type_with_infinite_size_error(&self,
     err
 }
 
-pub fn report_object_safety_error(&self,
+pub fn report_object_safety_error(self,
                                   span: Span,
                                   trait_def_id: DefId,
                                   warning_node_id: Option<ast::NodeId>,
@@ -744,7 +744,7 @@ fn predicate_can_apply(&self, pred: ty::PolyTraitRef<'tcx>) -> bool {
 
     impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx>
     {
-        fn tcx(&self) -> &TyCtxt<'tcx> { self.infcx.tcx }
+        fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.infcx.tcx }
 
         fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
             if let ty::TyParam(..) = ty.sty {
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index efee80c6566..c7061fc8c2f 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -111,7 +111,7 @@ pub struct PendingPredicateObligation<'tcx> {
     pub stalled_on: Vec<Ty<'tcx>>,
 }
 
-impl<'tcx> FulfillmentContext<'tcx> {
+impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
     pub fn new() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
@@ -129,11 +129,11 @@ impl<'tcx> FulfillmentContext<'tcx> {
     /// `SomeTrait` or a where clause that lets us unify `$0` with
     /// something concrete. If this fails, we'll unify `$0` with
     /// `projection_ty` again.
-    pub fn normalize_projection_type<'a>(&mut self,
-                                         infcx: &InferCtxt<'a,'tcx>,
-                                         projection_ty: ty::ProjectionTy<'tcx>,
-                                         cause: ObligationCause<'tcx>)
-                                         -> Ty<'tcx>
+    pub fn normalize_projection_type(&mut self,
+                                     infcx: &InferCtxt<'a,'tcx>,
+                                     projection_ty: ty::ProjectionTy<'tcx>,
+                                     cause: ObligationCause<'tcx>)
+                                     -> Ty<'tcx>
     {
         debug!("normalize_projection_type(projection_ty={:?})",
                projection_ty);
@@ -154,11 +154,11 @@ impl<'tcx> FulfillmentContext<'tcx> {
         normalized.value
     }
 
-    pub fn register_builtin_bound<'a>(&mut self,
-                                      infcx: &InferCtxt<'a,'tcx>,
-                                      ty: Ty<'tcx>,
-                                      builtin_bound: ty::BuiltinBound,
-                                      cause: ObligationCause<'tcx>)
+    pub fn register_builtin_bound(&mut self,
+                                  infcx: &InferCtxt<'a, 'tcx>,
+                                  ty: Ty<'tcx>,
+                                  builtin_bound: ty::BuiltinBound,
+                                  cause: ObligationCause<'tcx>)
     {
         match infcx.tcx.predicate_for_builtin_bound(cause, builtin_bound, 0, ty) {
             Ok(predicate) => {
@@ -168,17 +168,17 @@ impl<'tcx> FulfillmentContext<'tcx> {
         }
     }
 
-    pub fn register_region_obligation<'a>(&mut self,
-                                          t_a: Ty<'tcx>,
-                                          r_b: ty::Region,
-                                          cause: ObligationCause<'tcx>)
+    pub fn register_region_obligation(&mut self,
+                                      t_a: Ty<'tcx>,
+                                      r_b: ty::Region,
+                                      cause: ObligationCause<'tcx>)
     {
         register_region_obligation(t_a, r_b, cause, &mut self.region_obligations);
     }
 
-    pub fn register_predicate_obligation<'a>(&mut self,
-                                             infcx: &InferCtxt<'a,'tcx>,
-                                             obligation: PredicateObligation<'tcx>)
+    pub fn register_predicate_obligation(&mut self,
+                                         infcx: &InferCtxt<'a, 'tcx>,
+                                         obligation: PredicateObligation<'tcx>)
     {
         // this helps to reduce duplicate errors, as well as making
         // debug output much nicer to read and so on.
@@ -199,9 +199,9 @@ impl<'tcx> FulfillmentContext<'tcx> {
         self.predicates.push_tree(obligation, LocalFulfilledPredicates::new());
     }
 
-    pub fn register_rfc1592_obligation<'a>(&mut self,
-                                           _infcx: &InferCtxt<'a,'tcx>,
-                                           obligation: PredicateObligation<'tcx>)
+    pub fn register_rfc1592_obligation(&mut self,
+                                       _infcx: &InferCtxt<'a,'tcx>,
+                                       obligation: PredicateObligation<'tcx>)
     {
         self.rfc1592_obligations.push(obligation);
     }
@@ -216,7 +216,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
         }
     }
 
-    pub fn select_rfc1592_obligations<'a>(&mut self,
+    pub fn select_rfc1592_obligations(&mut self,
                                       infcx: &InferCtxt<'a,'tcx>)
                                       -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
@@ -230,9 +230,10 @@ impl<'tcx> FulfillmentContext<'tcx> {
 
         Ok(())
     }
-    pub fn select_all_or_error<'a>(&mut self,
-                                   infcx: &InferCtxt<'a,'tcx>)
-                                   -> Result<(),Vec<FulfillmentError<'tcx>>>
+
+    pub fn select_all_or_error(&mut self,
+                               infcx: &InferCtxt<'a,'tcx>)
+                               -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         self.select_where_possible(infcx)?;
 
@@ -248,9 +249,9 @@ impl<'tcx> FulfillmentContext<'tcx> {
         }
     }
 
-    pub fn select_where_possible<'a>(&mut self,
-                                     infcx: &InferCtxt<'a,'tcx>)
-                                     -> Result<(),Vec<FulfillmentError<'tcx>>>
+    pub fn select_where_possible(&mut self,
+                                 infcx: &InferCtxt<'a, 'tcx>)
+                                 -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         let mut selcx = SelectionContext::new(infcx);
         self.select(&mut selcx)
@@ -260,8 +261,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
         self.predicates.pending_obligations()
     }
 
-    fn is_duplicate_or_add(&mut self,
-                           tcx: &TyCtxt<'tcx>,
+    fn is_duplicate_or_add(&mut self, tcx: TyCtxt<'a, 'tcx>,
                            predicate: &ty::Predicate<'tcx>)
                            -> bool {
         // For "global" predicates -- that is, predicates that don't
@@ -289,10 +289,8 @@ impl<'tcx> FulfillmentContext<'tcx> {
 
     /// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
     /// only attempts to select obligations that haven't been seen before.
-    fn select<'a>(&mut self,
-                  selcx: &mut SelectionContext<'a, 'tcx>)
-                  -> Result<(),Vec<FulfillmentError<'tcx>>>
-    {
+    fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>)
+              -> Result<(),Vec<FulfillmentError<'tcx>>> {
         debug!("select(obligation-forest-size={})", self.predicates.len());
 
         let mut errors = Vec::new();
@@ -466,7 +464,7 @@ struct AncestorSet<'b, 'tcx: 'b> {
     backtrace: Backtrace<'b, PendingPredicateObligation<'tcx>>,
 }
 
-impl<'b, 'tcx> AncestorSet<'b, 'tcx> {
+impl<'a, 'b, 'tcx> AncestorSet<'b, 'tcx> {
     fn new(backtrace: &Backtrace<'b, PendingPredicateObligation<'tcx>>) -> Self {
         AncestorSet {
             populated: false,
@@ -479,10 +477,10 @@ impl<'b, 'tcx> AncestorSet<'b, 'tcx> {
     /// to `predicate` (`predicate` is assumed to be fully
     /// type-resolved).  Returns `None` if not; otherwise, returns
     /// `Some` with the index within the backtrace.
-    fn has<'a>(&mut self,
-               infcx: &InferCtxt<'a, 'tcx>,
-               predicate: &ty::Predicate<'tcx>)
-               -> Option<usize> {
+    fn has(&mut self,
+           infcx: &InferCtxt<'a, 'tcx>,
+           predicate: &ty::Predicate<'tcx>)
+           -> Option<usize> {
         // the first time, we have to populate the cache
         if !self.populated {
             let backtrace = self.backtrace.clone();
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index ea129d437fb..5419994cdd1 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -53,8 +53,8 @@ pub enum MethodViolationCode {
     Generic,
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-pub fn is_object_safe(&self, trait_def_id: DefId) -> bool {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+pub fn is_object_safe(self, trait_def_id: DefId) -> bool {
     // Because we query yes/no results frequently, we keep a cache:
     let def = self.lookup_trait_def(trait_def_id);
 
@@ -78,7 +78,7 @@ pub fn is_object_safe(&self, trait_def_id: DefId) -> bool {
 /// astconv - currently, Self in supertraits. This is needed
 /// because `object_safety_violations` can't be used during
 /// type collection.
-pub fn astconv_object_safety_violations(&self, trait_def_id: DefId)
+pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
                                         -> Vec<ObjectSafetyViolation<'tcx>>
 {
     let mut violations = vec![];
@@ -94,7 +94,7 @@ pub fn astconv_object_safety_violations(&self, trait_def_id: DefId)
     violations
 }
 
-pub fn object_safety_violations(&self, trait_def_id: DefId)
+pub fn object_safety_violations(self, trait_def_id: DefId)
                                 -> Vec<ObjectSafetyViolation<'tcx>>
 {
     traits::supertrait_def_ids(self, trait_def_id)
@@ -102,7 +102,7 @@ pub fn object_safety_violations(&self, trait_def_id: DefId)
         .collect()
 }
 
-fn object_safety_violations_for_trait(&self, trait_def_id: DefId)
+fn object_safety_violations_for_trait(self, trait_def_id: DefId)
                                       -> Vec<ObjectSafetyViolation<'tcx>>
 {
     // Check methods for violations.
@@ -134,7 +134,7 @@ fn object_safety_violations_for_trait(&self, trait_def_id: DefId)
     violations
 }
 
-fn supertraits_reference_self(&self, trait_def_id: DefId) -> bool {
+fn supertraits_reference_self(self, trait_def_id: DefId) -> bool {
     let trait_def = self.lookup_trait_def(trait_def_id);
     let trait_ref = trait_def.trait_ref.clone();
     let trait_ref = trait_ref.to_poly_trait_ref();
@@ -166,13 +166,13 @@ fn supertraits_reference_self(&self, trait_def_id: DefId) -> bool {
         })
 }
 
-fn trait_has_sized_self(&self, trait_def_id: DefId) -> bool {
+fn trait_has_sized_self(self, trait_def_id: DefId) -> bool {
     let trait_def = self.lookup_trait_def(trait_def_id);
     let trait_predicates = self.lookup_predicates(trait_def_id);
     self.generics_require_sized_self(&trait_def.generics, &trait_predicates)
 }
 
-fn generics_require_sized_self(&self,
+fn generics_require_sized_self(self,
                                generics: &ty::Generics<'tcx>,
                                predicates: &ty::GenericPredicates<'tcx>)
                                -> bool
@@ -208,7 +208,7 @@ fn generics_require_sized_self(&self,
 }
 
 /// Returns `Some(_)` if this method makes the containing trait not object safe.
-fn object_safety_violation_for_method(&self,
+fn object_safety_violation_for_method(self,
                                       trait_def_id: DefId,
                                       method: &ty::Method<'tcx>)
                                       -> Option<MethodViolationCode>
@@ -226,7 +226,7 @@ fn object_safety_violation_for_method(&self,
 /// object.  Note that object-safe traits can have some
 /// non-vtable-safe methods, so long as they require `Self:Sized` or
 /// otherwise ensure that they cannot be used when `Self=Trait`.
-pub fn is_vtable_safe_method(&self,
+pub fn is_vtable_safe_method(self,
                              trait_def_id: DefId,
                              method: &ty::Method<'tcx>)
                              -> bool
@@ -238,7 +238,7 @@ pub fn is_vtable_safe_method(&self,
 /// object; this does not necessarily imply that the enclosing trait
 /// is not object safe, because the method might have a where clause
 /// `Self:Sized`.
-fn virtual_call_violation_for_method(&self,
+fn virtual_call_violation_for_method(self,
                                      trait_def_id: DefId,
                                      method: &ty::Method<'tcx>)
                                      -> Option<MethodViolationCode>
@@ -279,7 +279,7 @@ fn virtual_call_violation_for_method(&self,
     None
 }
 
-fn contains_illegal_self_type_reference(&self,
+fn contains_illegal_self_type_reference(self,
                                         trait_def_id: DefId,
                                         ty: Ty<'tcx>)
                                         -> bool
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index bc26ee615f7..49f40e1533d 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -354,7 +354,7 @@ impl<'a,'b,'tcx> AssociatedTypeNormalizer<'a,'b,'tcx> {
 }
 
 impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> {
+    fn tcx<'c>(&'c self) -> TyCtxt<'c, 'tcx> {
         self.selcx.tcx()
     }
 
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index c47f728eec5..861810de22c 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -283,7 +283,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         self.infcx
     }
 
-    pub fn tcx(&self) -> &'cx TyCtxt<'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'cx, 'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 3d80e149f4f..0e96f96823f 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -108,7 +108,7 @@ pub fn translate_substs<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 /// Specialization is determined by the sets of types to which the impls apply;
 /// impl1 specializes impl2 if it applies to a subset of the types impl2 applies
 /// to.
-pub fn specializes(tcx: &TyCtxt, impl1_def_id: DefId, impl2_def_id: DefId) -> bool {
+pub fn specializes(tcx: TyCtxt, impl1_def_id: DefId, impl2_def_id: DefId) -> bool {
     // The feature gate should prevent introducing new specializations, but not
     // taking advantage of upstream ones.
     if !tcx.sess.features.borrow().specialization &&
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index f79054fcf02..b88028a4aae 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -81,7 +81,7 @@ enum InsertResult<'a, 'tcx: 'a> {
     Overlapped(Overlap<'a, 'tcx>),
 }
 
-impl Children {
+impl<'a, 'tcx> Children {
     fn new() -> Children {
         Children {
             nonblanket_impls: FnvHashMap(),
@@ -90,7 +90,7 @@ impl Children {
     }
 
     /// Insert an impl into this set of children without comparing to any existing impls
-    fn insert_blindly(&mut self, tcx: &TyCtxt, impl_def_id: DefId) {
+    fn insert_blindly(&mut self, tcx: TyCtxt, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
         if let Some(sty) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
             self.nonblanket_impls.entry(sty).or_insert(vec![]).push(impl_def_id)
@@ -101,11 +101,11 @@ impl Children {
 
     /// Attempt to insert an impl into this set of children, while comparing for
     /// specialiation relationships.
-    fn insert<'a, 'tcx>(&mut self,
-                        tcx: &'a TyCtxt<'tcx>,
-                        impl_def_id: DefId,
-                        simplified_self: Option<SimplifiedType>)
-                        -> InsertResult<'a, 'tcx>
+    fn insert(&mut self,
+              tcx: TyCtxt<'a, 'tcx>,
+              impl_def_id: DefId,
+              simplified_self: Option<SimplifiedType>)
+              -> InsertResult<'a, 'tcx>
     {
         for slot in match simplified_self {
             Some(sty) => self.filtered_mut(sty),
@@ -150,19 +150,19 @@ impl Children {
         InsertResult::BecameNewSibling
     }
 
-    fn iter_mut<'a>(&'a mut self) -> Box<Iterator<Item = &'a mut DefId> + 'a> {
+    fn iter_mut(&'a mut self) -> Box<Iterator<Item = &'a mut DefId> + 'a> {
         let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter_mut());
         Box::new(self.blanket_impls.iter_mut().chain(nonblanket))
     }
 
-    fn filtered_mut<'a>(&'a mut self, sty: SimplifiedType)
-                        -> Box<Iterator<Item = &'a mut DefId> + 'a> {
+    fn filtered_mut(&'a mut self, sty: SimplifiedType)
+                    -> Box<Iterator<Item = &'a mut DefId> + 'a> {
         let nonblanket = self.nonblanket_impls.entry(sty).or_insert(vec![]).iter_mut();
         Box::new(self.blanket_impls.iter_mut().chain(nonblanket))
     }
 }
 
-impl Graph {
+impl<'a, 'tcx> Graph {
     pub fn new() -> Graph {
         Graph {
             parent: Default::default(),
@@ -173,10 +173,10 @@ impl Graph {
     /// Insert a local impl into the specialization graph. If an existing impl
     /// conflicts with it (has overlap, but neither specializes the other),
     /// information about the area of overlap is returned in the `Err`.
-    pub fn insert<'a, 'tcx>(&mut self,
-                            tcx: &'a TyCtxt<'tcx>,
-                            impl_def_id: DefId)
-                            -> Result<(), Overlap<'a, 'tcx>> {
+    pub fn insert(&mut self,
+                  tcx: TyCtxt<'a, 'tcx>,
+                  impl_def_id: DefId)
+                  -> Result<(), Overlap<'a, 'tcx>> {
         assert!(impl_def_id.is_local());
 
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
@@ -235,7 +235,7 @@ impl Graph {
     }
 
     /// Insert cached metadata mapping from a child impl back to its parent.
-    pub fn record_impl_from_cstore(&mut self, tcx: &TyCtxt, parent: DefId, child: DefId) {
+    pub fn record_impl_from_cstore(&mut self, tcx: TyCtxt, parent: DefId, child: DefId) {
         if self.parent.insert(child, parent).is_some() {
             bug!("When recording an impl from the crate store, information about its parent \
                   was already present.");
@@ -260,7 +260,7 @@ pub enum Node {
     Trait(DefId),
 }
 
-impl Node {
+impl<'a, 'tcx> Node {
     pub fn is_from_trait(&self) -> bool {
         match *self {
             Node::Trait(..) => true,
@@ -269,7 +269,7 @@ impl Node {
     }
 
     /// Iterate over the items defined directly by the given (impl or trait) node.
-    pub fn items<'a, 'tcx>(&self, tcx: &'a TyCtxt<'tcx>) -> NodeItems<'a, 'tcx> {
+    pub fn items(&self, tcx: TyCtxt<'a, 'tcx>) -> NodeItems<'a, 'tcx> {
         match *self {
             Node::Impl(impl_def_id) => {
                 NodeItems::Impl {
@@ -299,7 +299,7 @@ impl Node {
 /// An iterator over the items defined within a trait or impl.
 pub enum NodeItems<'a, 'tcx: 'a> {
     Impl {
-        tcx: &'a TyCtxt<'tcx>,
+        tcx: TyCtxt<'a, 'tcx>,
         items: cell::Ref<'a, Vec<ty::ImplOrTraitItemId>>,
         idx: usize,
     },
@@ -411,7 +411,7 @@ impl<'a, 'tcx> Iterator for ConstDefs<'a, 'tcx> {
 impl<'a, 'tcx> Ancestors<'a, 'tcx> {
     /// Search the items from the given ancestors, returning each type definition
     /// with the given name.
-    pub fn type_defs(self, tcx: &'a TyCtxt<'tcx>, name: Name) -> TypeDefs<'a, 'tcx> {
+    pub fn type_defs(self, tcx: TyCtxt<'a, 'tcx>, name: Name) -> TypeDefs<'a, 'tcx> {
         let iter = self.flat_map(move |node| {
             node.items(tcx)
                 .filter_map(move |item| {
@@ -432,7 +432,7 @@ impl<'a, 'tcx> Ancestors<'a, 'tcx> {
 
     /// Search the items from the given ancestors, returning each fn definition
     /// with the given name.
-    pub fn fn_defs(self, tcx: &'a TyCtxt<'tcx>, name: Name) -> FnDefs<'a, 'tcx> {
+    pub fn fn_defs(self, tcx: TyCtxt<'a, 'tcx>, name: Name) -> FnDefs<'a, 'tcx> {
         let iter = self.flat_map(move |node| {
             node.items(tcx)
                 .filter_map(move |item| {
@@ -453,7 +453,7 @@ impl<'a, 'tcx> Ancestors<'a, 'tcx> {
 
     /// Search the items from the given ancestors, returning each const
     /// definition with the given name.
-    pub fn const_defs(self, tcx: &'a TyCtxt<'tcx>, name: Name) -> ConstDefs<'a, 'tcx> {
+    pub fn const_defs(self, tcx: TyCtxt<'a, 'tcx>, name: Name) -> ConstDefs<'a, 'tcx> {
         let iter = self.flat_map(move |node| {
             node.items(tcx)
                 .filter_map(move |item| {
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 629b1152b60..15819992222 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -18,8 +18,8 @@ use util::nodemap::FnvHashSet;
 
 use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
 
-fn anonymize_predicate<'tcx>(tcx: &TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>)
-                             -> ty::Predicate<'tcx> {
+fn anonymize_predicate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, pred: &ty::Predicate<'tcx>)
+                                 -> ty::Predicate<'tcx> {
     match *pred {
         ty::Predicate::Trait(ref data) =>
             ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)),
@@ -52,12 +52,12 @@ fn anonymize_predicate<'tcx>(tcx: &TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>)
 
 
 struct PredicateSet<'a,'tcx:'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     set: FnvHashSet<ty::Predicate<'tcx>>,
 }
 
 impl<'a,'tcx> PredicateSet<'a,'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>) -> PredicateSet<'a,'tcx> {
+    fn new(tcx: TyCtxt<'a, 'tcx>) -> PredicateSet<'a,'tcx> {
         PredicateSet { tcx: tcx, set: FnvHashSet() }
     }
 
@@ -88,13 +88,13 @@ impl<'a,'tcx> PredicateSet<'a,'tcx> {
 /// Foo : 'static`, and we know that `T : Foo`, then we know that `T :
 /// 'static`.
 pub struct Elaborator<'cx, 'tcx:'cx> {
-    tcx: &'cx TyCtxt<'tcx>,
+    tcx: TyCtxt<'cx, 'tcx>,
     stack: Vec<ty::Predicate<'tcx>>,
     visited: PredicateSet<'cx,'tcx>,
 }
 
 pub fn elaborate_trait_ref<'cx, 'tcx>(
-    tcx: &'cx TyCtxt<'tcx>,
+    tcx: TyCtxt<'cx, 'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>)
     -> Elaborator<'cx, 'tcx>
 {
@@ -102,7 +102,7 @@ pub fn elaborate_trait_ref<'cx, 'tcx>(
 }
 
 pub fn elaborate_trait_refs<'cx, 'tcx>(
-    tcx: &'cx TyCtxt<'tcx>,
+    tcx: TyCtxt<'cx, 'tcx>,
     trait_refs: &[ty::PolyTraitRef<'tcx>])
     -> Elaborator<'cx, 'tcx>
 {
@@ -113,7 +113,7 @@ pub fn elaborate_trait_refs<'cx, 'tcx>(
 }
 
 pub fn elaborate_predicates<'cx, 'tcx>(
-    tcx: &'cx TyCtxt<'tcx>,
+    tcx: TyCtxt<'cx, 'tcx>,
     mut predicates: Vec<ty::Predicate<'tcx>>)
     -> Elaborator<'cx, 'tcx>
 {
@@ -222,14 +222,14 @@ impl<'cx, 'tcx> Iterator for Elaborator<'cx, 'tcx> {
 
 pub type Supertraits<'cx, 'tcx> = FilterToTraits<Elaborator<'cx, 'tcx>>;
 
-pub fn supertraits<'cx, 'tcx>(tcx: &'cx TyCtxt<'tcx>,
+pub fn supertraits<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx>,
                               trait_ref: ty::PolyTraitRef<'tcx>)
                               -> Supertraits<'cx, 'tcx>
 {
     elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
 }
 
-pub fn transitive_bounds<'cx, 'tcx>(tcx: &'cx TyCtxt<'tcx>,
+pub fn transitive_bounds<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx>,
                                     bounds: &[ty::PolyTraitRef<'tcx>])
                                     -> Supertraits<'cx, 'tcx>
 {
@@ -240,12 +240,12 @@ pub fn transitive_bounds<'cx, 'tcx>(tcx: &'cx TyCtxt<'tcx>,
 // Iterator over def-ids of supertraits
 
 pub struct SupertraitDefIds<'cx, 'tcx:'cx> {
-    tcx: &'cx TyCtxt<'tcx>,
+    tcx: TyCtxt<'cx, 'tcx>,
     stack: Vec<DefId>,
     visited: FnvHashSet<DefId>,
 }
 
-pub fn supertrait_def_ids<'cx, 'tcx>(tcx: &'cx TyCtxt<'tcx>,
+pub fn supertrait_def_ids<'cx, 'tcx>(tcx: TyCtxt<'cx, 'tcx>,
                                      trait_def_id: DefId)
                                      -> SupertraitDefIds<'cx, 'tcx>
 {
@@ -391,8 +391,8 @@ pub fn predicate_for_trait_ref<'tcx>(
     }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-pub fn trait_ref_for_builtin_bound(&self,
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+pub fn trait_ref_for_builtin_bound(self,
     builtin_bound: ty::BuiltinBound,
     param_ty: Ty<'tcx>)
     -> Result<ty::TraitRef<'tcx>, ErrorReported>
@@ -411,7 +411,7 @@ pub fn trait_ref_for_builtin_bound(&self,
     }
 }
 
-pub fn predicate_for_trait_def(&self,
+pub fn predicate_for_trait_def(self,
     cause: ObligationCause<'tcx>,
     trait_def_id: DefId,
     recursion_depth: usize,
@@ -426,7 +426,7 @@ pub fn predicate_for_trait_def(&self,
     predicate_for_trait_ref(cause, trait_ref, recursion_depth)
 }
 
-pub fn predicate_for_builtin_bound(&self,
+pub fn predicate_for_builtin_bound(self,
     cause: ObligationCause<'tcx>,
     builtin_bound: ty::BuiltinBound,
     recursion_depth: usize,
@@ -440,7 +440,7 @@ pub fn predicate_for_builtin_bound(&self,
 /// Cast a trait reference into a reference to one of its super
 /// traits; returns `None` if `target_trait_def_id` is not a
 /// supertrait.
-pub fn upcast_choices(&self,
+pub fn upcast_choices(self,
                       source_trait_ref: ty::PolyTraitRef<'tcx>,
                       target_trait_def_id: DefId)
                       -> Vec<ty::PolyTraitRef<'tcx>>
@@ -457,7 +457,7 @@ pub fn upcast_choices(&self,
 /// Given a trait `trait_ref`, returns the number of vtable entries
 /// that come from `trait_ref`, excluding its supertraits. Used in
 /// computing the vtable base for an upcast trait of a trait object.
-pub fn count_own_vtable_entries(&self, trait_ref: ty::PolyTraitRef<'tcx>) -> usize {
+pub fn count_own_vtable_entries(self, trait_ref: ty::PolyTraitRef<'tcx>) -> usize {
     let mut entries = 0;
     // Count number of methods and add them to the total offset.
     // Skip over associated types and constants.
@@ -472,7 +472,7 @@ pub fn count_own_vtable_entries(&self, trait_ref: ty::PolyTraitRef<'tcx>) -> usi
 /// Given an upcast trait object described by `object`, returns the
 /// index of the method `method_def_id` (which should be part of
 /// `object.upcast_trait_ref`) within the vtable for `object`.
-pub fn get_vtable_index_of_object_method(&self,
+pub fn get_vtable_index_of_object_method(self,
                                          object: &super::VtableObjectData<'tcx>,
                                          method_def_id: DefId) -> usize {
     // Count number of methods preceding the one we are selecting and
@@ -498,7 +498,7 @@ pub fn get_vtable_index_of_object_method(&self,
          method_def_id);
 }
 
-pub fn closure_trait_ref_and_return_type(&self,
+pub fn closure_trait_ref_and_return_type(self,
     fn_trait_def_id: DefId,
     self_ty: Ty<'tcx>,
     sig: &ty::PolyFnSig<'tcx>,
diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs
index d0ccc3e0fdd..c024611d769 100644
--- a/src/librustc/ty/_match.rs
+++ b/src/librustc/ty/_match.rs
@@ -29,18 +29,18 @@ use ty::relate::{self, Relate, TypeRelation, RelateResult};
 /// important thing about the result is Ok/Err. Also, matching never
 /// affects any type variables or unification state.
 pub struct Match<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>
+    tcx: TyCtxt<'a, 'tcx>
 }
 
 impl<'a, 'tcx> Match<'a, 'tcx> {
-    pub fn new(tcx: &'a TyCtxt<'tcx>) -> Match<'a, 'tcx> {
+    pub fn new(tcx: TyCtxt<'a, 'tcx>) -> Match<'a, 'tcx> {
         Match { tcx: tcx }
     }
 }
 
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Match<'a, 'tcx> {
     fn tag(&self) -> &'static str { "Match" }
-    fn tcx(&self) -> &'a TyCtxt<'tcx> { self.tcx }
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.tcx }
     fn a_is_expected(&self) -> bool { true } // irrelevant
 
     fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index 7510bd07251..8cbe110baec 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -136,9 +136,10 @@ pub enum CustomCoerceUnsized {
     Struct(usize)
 }
 
-impl<'tcx> ty::TyS<'tcx> {
+impl<'a, 'tcx> ty::TyS<'tcx> {
     /// See `expr_ty_adjusted`
-    pub fn adjust<F>(&'tcx self, tcx: &TyCtxt<'tcx>,
+    pub fn adjust<F>(&'tcx self,
+                     tcx: TyCtxt<'a, 'tcx>,
                      span: Span,
                      expr_id: ast::NodeId,
                      adjustment: Option<&AutoAdjustment<'tcx>>,
@@ -215,7 +216,7 @@ impl<'tcx> ty::TyS<'tcx> {
     }
 
     pub fn adjust_for_autoderef<F>(&'tcx self,
-                                   tcx: &TyCtxt<'tcx>,
+                                   tcx: TyCtxt<'a, 'tcx>,
                                    expr_id: ast::NodeId,
                                    expr_span: Span,
                                    autoderef: u32, // how many autoderefs so far?
@@ -243,7 +244,7 @@ impl<'tcx> ty::TyS<'tcx> {
         }
     }
 
-    pub fn adjust_for_autoref(&'tcx self, tcx: &TyCtxt<'tcx>,
+    pub fn adjust_for_autoref(&'tcx self, tcx: TyCtxt<'a, 'tcx>,
                               autoref: Option<AutoRef<'tcx>>)
                               -> Ty<'tcx> {
         match autoref {
diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs
index cae7f4d6444..381b07dc7c8 100644
--- a/src/librustc/ty/contents.rs
+++ b/src/librustc/ty/contents.rs
@@ -89,7 +89,7 @@ impl TypeContents {
         self.intersects(TC::InteriorUnsafe)
     }
 
-    pub fn needs_drop(&self, _: &TyCtxt) -> bool {
+    pub fn needs_drop(&self, _: TyCtxt) -> bool {
         self.intersects(TC::NeedsDrop)
     }
 
@@ -139,13 +139,13 @@ impl fmt::Debug for TypeContents {
     }
 }
 
-impl<'tcx> ty::TyS<'tcx> {
-    pub fn type_contents(&'tcx self, tcx: &TyCtxt<'tcx>) -> TypeContents {
+impl<'a, 'tcx> ty::TyS<'tcx> {
+    pub fn type_contents(&'tcx self, tcx: TyCtxt<'a, 'tcx>) -> TypeContents {
         return tcx.tc_cache.memoize(self, || tc_ty(tcx, self, &mut FnvHashMap()));
 
-        fn tc_ty<'tcx>(tcx: &TyCtxt<'tcx>,
-                       ty: Ty<'tcx>,
-                       cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
+        fn tc_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                           ty: Ty<'tcx>,
+                           cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
         {
             // Subtle: Note that we are *not* using tcx.tc_cache here but rather a
             // private cache for this walk.  This is needed in the case of cyclic
@@ -255,7 +255,7 @@ impl<'tcx> ty::TyS<'tcx> {
             result
         }
 
-        fn apply_lang_items(tcx: &TyCtxt, did: DefId, tc: TypeContents)
+        fn apply_lang_items(tcx: TyCtxt, did: DefId, tc: TypeContents)
                             -> TypeContents {
             if Some(did) == tcx.lang_items.unsafe_cell_type() {
                 tc | TC::InteriorUnsafe
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index c7ae038eb7a..95e3a5c104c 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -41,6 +41,7 @@ use arena::TypedArena;
 use std::borrow::Borrow;
 use std::cell::{Cell, RefCell, Ref};
 use std::hash::{Hash, Hasher};
+use std::ops::Deref;
 use std::rc::Rc;
 use syntax::ast::{self, Name, NodeId};
 use syntax::attr;
@@ -138,7 +139,7 @@ pub struct Tables<'tcx> {
     pub fru_field_types: NodeMap<Vec<Ty<'tcx>>>
 }
 
-impl<'tcx> Tables<'tcx> {
+impl<'a, 'tcx> Tables<'tcx> {
     pub fn empty() -> Tables<'tcx> {
         Tables {
             node_types: FnvHashMap(),
@@ -154,7 +155,7 @@ impl<'tcx> Tables<'tcx> {
     }
 
     pub fn closure_kind(this: &RefCell<Self>,
-                        tcx: &TyCtxt<'tcx>,
+                        tcx: TyCtxt<'a, 'tcx>,
                         def_id: DefId)
                         -> ty::ClosureKind {
         // If this is a local def-id, it should be inserted into the
@@ -164,13 +165,13 @@ impl<'tcx> Tables<'tcx> {
             return kind;
         }
 
-        let kind = tcx.sess.cstore.closure_kind(tcx, def_id);
+        let kind = tcx.sess.cstore.closure_kind(def_id);
         this.borrow_mut().closure_kinds.insert(def_id, kind);
         kind
     }
 
     pub fn closure_type(this: &RefCell<Self>,
-                        tcx: &TyCtxt<'tcx>,
+                        tcx: TyCtxt<'a, 'tcx>,
                         def_id: DefId,
                         substs: &ClosureSubsts<'tcx>)
                         -> ty::ClosureTy<'tcx>
@@ -217,7 +218,19 @@ impl<'tcx> CommonTypes<'tcx> {
 /// The data structure to keep track of all the information that typechecker
 /// generates so that so that it can be reused and doesn't have to be redone
 /// later on.
-pub struct TyCtxt<'tcx> {
+#[derive(Copy, Clone)]
+pub struct TyCtxt<'a, 'tcx: 'a> {
+    gcx: &'a GlobalCtxt<'tcx>
+}
+
+impl<'a, 'tcx> Deref for TyCtxt<'a, 'tcx> {
+    type Target = &'a GlobalCtxt<'tcx>;
+    fn deref(&self) -> &&'a GlobalCtxt<'tcx> {
+        &self.gcx
+    }
+}
+
+pub struct GlobalCtxt<'tcx> {
     /// The arenas that types etc are allocated from.
     arenas: &'tcx CtxtArenas<'tcx>,
 
@@ -432,8 +445,8 @@ pub struct TyCtxt<'tcx> {
     pub layout_cache: RefCell<FnvHashMap<Ty<'tcx>, &'tcx Layout>>,
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn crate_name(&self, cnum: ast::CrateNum) -> token::InternedString {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn crate_name(self, cnum: ast::CrateNum) -> token::InternedString {
         if cnum == LOCAL_CRATE {
             self.crate_name.clone()
         } else {
@@ -441,7 +454,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn crate_disambiguator(&self, cnum: ast::CrateNum) -> token::InternedString {
+    pub fn crate_disambiguator(self, cnum: ast::CrateNum) -> token::InternedString {
         if cnum == LOCAL_CRATE {
             self.sess.crate_disambiguator.get().as_str()
         } else {
@@ -449,14 +462,14 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn type_parameter_def(&self,
+    pub fn type_parameter_def(self,
                               node_id: NodeId)
                               -> ty::TypeParameterDef<'tcx>
     {
         self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
     }
 
-    pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> {
+    pub fn node_types(self) -> Ref<'a, NodeMap<Ty<'tcx>>> {
         fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<Ty<'tcx>> {
             &tables.node_types
         }
@@ -464,11 +477,11 @@ impl<'tcx> TyCtxt<'tcx> {
         Ref::map(self.tables.borrow(), projection)
     }
 
-    pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
+    pub fn node_type_insert(self, id: NodeId, ty: Ty<'tcx>) {
         self.tables.borrow_mut().node_types.insert(id, ty);
     }
 
-    pub fn intern_trait_def(&self, def: ty::TraitDef<'tcx>)
+    pub fn intern_trait_def(self, def: ty::TraitDef<'tcx>)
                             -> &'tcx ty::TraitDef<'tcx> {
         let did = def.trait_ref.def_id;
         let interned = self.arenas.trait_defs.alloc(def);
@@ -478,12 +491,12 @@ impl<'tcx> TyCtxt<'tcx> {
         interned
     }
 
-    pub fn alloc_trait_def(&self, def: ty::TraitDef<'tcx>)
+    pub fn alloc_trait_def(self, def: ty::TraitDef<'tcx>)
                            -> &'tcx ty::TraitDef<'tcx> {
         self.arenas.trait_defs.alloc(def)
     }
 
-    pub fn intern_adt_def(&self,
+    pub fn intern_adt_def(self,
                           did: DefId,
                           kind: ty::AdtKind,
                           variants: Vec<ty::VariantDefData<'tcx, 'tcx>>)
@@ -497,7 +510,7 @@ impl<'tcx> TyCtxt<'tcx> {
         interned
     }
 
-    pub fn intern_stability(&self, stab: attr::Stability) -> &'tcx attr::Stability {
+    pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability {
         if let Some(st) = self.stability_interner.borrow().get(&stab) {
             return st;
         }
@@ -511,7 +524,7 @@ impl<'tcx> TyCtxt<'tcx> {
         interned
     }
 
-    pub fn intern_layout(&self, layout: Layout) -> &'tcx Layout {
+    pub fn intern_layout(self, layout: Layout) -> &'tcx Layout {
         if let Some(layout) = self.layout_interner.borrow().get(&layout) {
             return layout;
         }
@@ -525,44 +538,44 @@ impl<'tcx> TyCtxt<'tcx> {
         interned
     }
 
-    pub fn store_free_region_map(&self, id: NodeId, map: FreeRegionMap) {
+    pub fn store_free_region_map(self, id: NodeId, map: FreeRegionMap) {
         if self.free_region_maps.borrow_mut().insert(id, map).is_some() {
             bug!("Tried to overwrite interned FreeRegionMap for NodeId {:?}", id)
         }
     }
 
-    pub fn free_region_map(&self, id: NodeId) -> FreeRegionMap {
+    pub fn free_region_map(self, id: NodeId) -> FreeRegionMap {
         self.free_region_maps.borrow()[&id].clone()
     }
 
-    pub fn lift<T: ?Sized + Lift<'tcx>>(&self, value: &T) -> Option<T::Lifted> {
+    pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
         value.lift_to_tcx(self)
     }
 
-    /// Create a type context and call the closure with a `&TyCtxt` reference
+    /// Create a type context and call the closure with a `TyCtxt` reference
     /// to the context. The closure enforces that the type context and any interned
     /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
     /// reference to the context, to allow formatting values that need it.
     pub fn create_and_enter<F, R>(s: &'tcx Session,
-                                 arenas: &'tcx CtxtArenas<'tcx>,
-                                 def_map: RefCell<DefMap>,
-                                 named_region_map: resolve_lifetime::NamedRegionMap,
-                                 map: ast_map::Map<'tcx>,
-                                 freevars: FreevarMap,
+                                  arenas: &'tcx CtxtArenas<'tcx>,
+                                  def_map: RefCell<DefMap>,
+                                  named_region_map: resolve_lifetime::NamedRegionMap,
+                                  map: ast_map::Map<'tcx>,
+                                  freevars: FreevarMap,
                                  maybe_unused_trait_imports: NodeSet,
-                                 region_maps: RegionMaps,
-                                 lang_items: middle::lang_items::LanguageItems,
-                                 stability: stability::Index<'tcx>,
+                                  region_maps: RegionMaps,
+                                  lang_items: middle::lang_items::LanguageItems,
+                                  stability: stability::Index<'tcx>,
                                  crate_name: &str,
-                                 f: F) -> R
-                                 where F: FnOnce(&TyCtxt<'tcx>) -> R
+                                  f: F) -> R
+                                  where F: for<'b> FnOnce(TyCtxt<'b, 'tcx>) -> R
     {
         let data_layout = TargetDataLayout::parse(s);
         let interner = RefCell::new(FnvHashMap());
         let common_types = CommonTypes::new(&arenas.type_, &interner);
         let dep_graph = map.dep_graph.clone();
         let fulfilled_predicates = traits::GlobalFulfilledPredicates::new(dep_graph.clone());
-        tls::enter(TyCtxt {
+        tls::enter(GlobalCtxt {
             arenas: arenas,
             interner: interner,
             substs_interner: RefCell::new(FnvHashMap()),
@@ -637,12 +650,12 @@ impl<'tcx> TyCtxt<'tcx> {
 /// e.g. `()` or `u8`, was interned in a different context.
 pub trait Lift<'tcx> {
     type Lifted;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<Self::Lifted>;
+    fn lift_to_tcx<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Option<Self::Lifted>;
 }
 
 impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
     type Lifted = Ty<'tcx>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<Ty<'tcx>> {
+    fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<Ty<'tcx>> {
         if let Some(&ty) = tcx.interner.borrow().get(&self.sty) {
             if *self as *const _ == ty as *const _ {
                 return Some(ty);
@@ -654,7 +667,7 @@ impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
     type Lifted = &'tcx Substs<'tcx>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<&'tcx Substs<'tcx>> {
+    fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<&'tcx Substs<'tcx>> {
         if let Some(&substs) = tcx.substs_interner.borrow().get(*self) {
             if *self as *const _ == substs as *const _ {
                 return Some(substs);
@@ -666,7 +679,7 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
 
 
 pub mod tls {
-    use ty::TyCtxt;
+    use super::{GlobalCtxt, TyCtxt};
 
     use std::cell::Cell;
     use std::fmt;
@@ -675,10 +688,10 @@ pub mod tls {
     /// Marker type used for the scoped TLS slot.
     /// The type context cannot be used directly because the scoped TLS
     /// in libstd doesn't allow types generic over lifetimes.
-    struct ThreadLocalTyCx;
+    enum ThreadLocalGlobalCtxt {}
 
     thread_local! {
-        static TLS_TCX: Cell<Option<*const ThreadLocalTyCx>> = Cell::new(None)
+        static TLS_TCX: Cell<Option<*const ThreadLocalGlobalCtxt>> = Cell::new(None)
     }
 
     fn span_debug(span: codemap::Span, f: &mut fmt::Formatter) -> fmt::Result {
@@ -687,15 +700,18 @@ pub mod tls {
         })
     }
 
-    pub fn enter<'tcx, F: FnOnce(&TyCtxt<'tcx>) -> R, R>(tcx: TyCtxt<'tcx>, f: F) -> R {
+    pub fn enter<'tcx, F: for<'a> FnOnce(TyCtxt<'a, 'tcx>) -> R, R>(gcx: GlobalCtxt<'tcx>,
+                                                                    f: F) -> R {
         codemap::SPAN_DEBUG.with(|span_dbg| {
             let original_span_debug = span_dbg.get();
             span_dbg.set(span_debug);
-            let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
+            let tls_ptr = &gcx as *const _ as *const ThreadLocalGlobalCtxt;
             let result = TLS_TCX.with(|tls| {
                 let prev = tls.get();
                 tls.set(Some(tls_ptr));
-                let ret = f(&tcx);
+                let ret = f(TyCtxt {
+                    gcx: &gcx
+                });
                 tls.set(prev);
                 ret
             });
@@ -704,14 +720,16 @@ pub mod tls {
         })
     }
 
-    pub fn with<F: FnOnce(&TyCtxt) -> R, R>(f: F) -> R {
+    pub fn with<F: FnOnce(TyCtxt) -> R, R>(f: F) -> R {
         TLS_TCX.with(|tcx| {
             let tcx = tcx.get().unwrap();
-            f(unsafe { &*(tcx as *const TyCtxt) })
+            f(TyCtxt {
+                gcx: unsafe { &*(tcx as *const GlobalCtxt) }
+            })
         })
     }
 
-    pub fn with_opt<F: FnOnce(Option<&TyCtxt>) -> R, R>(f: F) -> R {
+    pub fn with_opt<F: FnOnce(Option<TyCtxt>) -> R, R>(f: F) -> R {
         if TLS_TCX.with(|tcx| tcx.get().is_some()) {
             with(|v| f(Some(v)))
         } else {
@@ -735,7 +753,7 @@ macro_rules! sty_debug_print {
                 both_infer: usize,
             }
 
-            pub fn go(tcx: &TyCtxt) {
+            pub fn go(tcx: TyCtxt) {
                 let mut total = DebugStat {
                     total: 0,
                     region_infer: 0, ty_infer: 0, both_infer: 0,
@@ -782,8 +800,8 @@ macro_rules! sty_debug_print {
     }}
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn print_debug_stats(&self) {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn print_debug_stats(self) {
         sty_debug_print!(
             self,
             TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr,
@@ -830,9 +848,9 @@ fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool {
             |(index, bound)| bounds[index].sort_key() <= bound.sort_key())
 }
 
-impl<'tcx> TyCtxt<'tcx> {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
     // Type constructors
-    pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
+    pub fn mk_substs(self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
         if let Some(substs) = self.substs_interner.borrow().get(&substs) {
             return *substs;
         }
@@ -843,7 +861,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Create an unsafe fn ty based on a safe fn ty.
-    pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
+    pub fn safe_to_unsafe_fn_ty(self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
         assert_eq!(bare_fn.unsafety, hir::Unsafety::Normal);
         self.mk_fn_ptr(ty::BareFnTy {
             unsafety: hir::Unsafety::Unsafe,
@@ -852,7 +870,7 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
+    pub fn mk_bare_fn(self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
         if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
             return *bare_fn;
         }
@@ -862,7 +880,7 @@ impl<'tcx> TyCtxt<'tcx> {
         bare_fn
     }
 
-    pub fn mk_region(&self, region: Region) -> &'tcx Region {
+    pub fn mk_region(self, region: Region) -> &'tcx Region {
         if let Some(region) = self.region_interner.borrow().get(&region) {
             return *region;
         }
@@ -902,11 +920,11 @@ impl<'tcx> TyCtxt<'tcx> {
 
     // Interns a type/name combination, stores the resulting box in cx.interner,
     // and returns the box as cast to an unsafe ptr (see comments for Ty above).
-    pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
+    pub fn mk_ty(self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
         TyCtxt::intern_ty(&self.arenas.type_, &self.interner, st)
     }
 
-    pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> {
+    pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {
         match tm {
             ast::IntTy::Is   => self.types.isize,
             ast::IntTy::I8   => self.types.i8,
@@ -916,7 +934,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn mk_mach_uint(&self, tm: ast::UintTy) -> Ty<'tcx> {
+    pub fn mk_mach_uint(self, tm: ast::UintTy) -> Ty<'tcx> {
         match tm {
             ast::UintTy::Us   => self.types.usize,
             ast::UintTy::U8   => self.types.u8,
@@ -926,89 +944,89 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn mk_mach_float(&self, tm: ast::FloatTy) -> Ty<'tcx> {
+    pub fn mk_mach_float(self, tm: ast::FloatTy) -> Ty<'tcx> {
         match tm {
             ast::FloatTy::F32  => self.types.f32,
             ast::FloatTy::F64  => self.types.f64,
         }
     }
 
-    pub fn mk_str(&self) -> Ty<'tcx> {
+    pub fn mk_str(self) -> Ty<'tcx> {
         self.mk_ty(TyStr)
     }
 
-    pub fn mk_static_str(&self) -> Ty<'tcx> {
+    pub fn mk_static_str(self) -> Ty<'tcx> {
         self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str())
     }
 
-    pub fn mk_enum(&self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
+    pub fn mk_enum(self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
         // take a copy of substs so that we own the vectors inside
         self.mk_ty(TyEnum(def, substs))
     }
 
-    pub fn mk_box(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ty(TyBox(ty))
     }
 
-    pub fn mk_ptr(&self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
+    pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
         self.mk_ty(TyRawPtr(tm))
     }
 
-    pub fn mk_ref(&self, r: &'tcx Region, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
+    pub fn mk_ref(self, r: &'tcx Region, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
         self.mk_ty(TyRef(r, tm))
     }
 
-    pub fn mk_mut_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn mk_mut_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
     }
 
-    pub fn mk_imm_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn mk_imm_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
     }
 
-    pub fn mk_mut_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable})
     }
 
-    pub fn mk_imm_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
     }
 
-    pub fn mk_nil_ptr(&self) -> Ty<'tcx> {
+    pub fn mk_nil_ptr(self) -> Ty<'tcx> {
         self.mk_imm_ptr(self.mk_nil())
     }
 
-    pub fn mk_array(&self, ty: Ty<'tcx>, n: usize) -> Ty<'tcx> {
+    pub fn mk_array(self, ty: Ty<'tcx>, n: usize) -> Ty<'tcx> {
         self.mk_ty(TyArray(ty, n))
     }
 
-    pub fn mk_slice(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         self.mk_ty(TySlice(ty))
     }
 
-    pub fn mk_tup(&self, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
+    pub fn mk_tup(self, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
         self.mk_ty(TyTuple(ts))
     }
 
-    pub fn mk_nil(&self) -> Ty<'tcx> {
+    pub fn mk_nil(self) -> Ty<'tcx> {
         self.mk_tup(Vec::new())
     }
 
-    pub fn mk_bool(&self) -> Ty<'tcx> {
+    pub fn mk_bool(self) -> Ty<'tcx> {
         self.mk_ty(TyBool)
     }
 
-    pub fn mk_fn_def(&self, def_id: DefId,
+    pub fn mk_fn_def(self, def_id: DefId,
                      substs: &'tcx Substs<'tcx>,
                      fty: BareFnTy<'tcx>) -> Ty<'tcx> {
         self.mk_ty(TyFnDef(def_id, substs, self.mk_bare_fn(fty)))
     }
 
-    pub fn mk_fn_ptr(&self, fty: BareFnTy<'tcx>) -> Ty<'tcx> {
+    pub fn mk_fn_ptr(self, fty: BareFnTy<'tcx>) -> Ty<'tcx> {
         self.mk_ty(TyFnPtr(self.mk_bare_fn(fty)))
     }
 
-    pub fn mk_trait(&self,
+    pub fn mk_trait(self,
                     principal: ty::PolyTraitRef<'tcx>,
                     bounds: ExistentialBounds<'tcx>)
                     -> Ty<'tcx>
@@ -1022,7 +1040,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_ty(TyTrait(inner))
     }
 
-    pub fn mk_projection(&self,
+    pub fn mk_projection(self,
                          trait_ref: TraitRef<'tcx>,
                          item_name: Name)
                          -> Ty<'tcx> {
@@ -1031,12 +1049,12 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_ty(TyProjection(inner))
     }
 
-    pub fn mk_struct(&self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
+    pub fn mk_struct(self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
         // take a copy of substs so that we own the vectors inside
         self.mk_ty(TyStruct(def, substs))
     }
 
-    pub fn mk_closure(&self,
+    pub fn mk_closure(self,
                       closure_id: DefId,
                       substs: &'tcx Substs<'tcx>,
                       tys: Vec<Ty<'tcx>>)
@@ -1047,45 +1065,45 @@ impl<'tcx> TyCtxt<'tcx> {
         }))
     }
 
-    pub fn mk_closure_from_closure_substs(&self,
+    pub fn mk_closure_from_closure_substs(self,
                                           closure_id: DefId,
                                           closure_substs: Box<ClosureSubsts<'tcx>>)
                                           -> Ty<'tcx> {
         self.mk_ty(TyClosure(closure_id, closure_substs))
     }
 
-    pub fn mk_var(&self, v: TyVid) -> Ty<'tcx> {
+    pub fn mk_var(self, v: TyVid) -> Ty<'tcx> {
         self.mk_infer(TyVar(v))
     }
 
-    pub fn mk_int_var(&self, v: IntVid) -> Ty<'tcx> {
+    pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
         self.mk_infer(IntVar(v))
     }
 
-    pub fn mk_float_var(&self, v: FloatVid) -> Ty<'tcx> {
+    pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
         self.mk_infer(FloatVar(v))
     }
 
-    pub fn mk_infer(&self, it: InferTy) -> Ty<'tcx> {
+    pub fn mk_infer(self, it: InferTy) -> Ty<'tcx> {
         self.mk_ty(TyInfer(it))
     }
 
-    pub fn mk_param(&self,
+    pub fn mk_param(self,
                     space: subst::ParamSpace,
                     index: u32,
                     name: Name) -> Ty<'tcx> {
         self.mk_ty(TyParam(ParamTy { space: space, idx: index, name: name }))
     }
 
-    pub fn mk_self_type(&self) -> Ty<'tcx> {
+    pub fn mk_self_type(self) -> Ty<'tcx> {
         self.mk_param(subst::SelfSpace, 0, keywords::SelfType.name())
     }
 
-    pub fn mk_param_from_def(&self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
+    pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
         self.mk_param(def.space, def.index, def.name)
     }
 
-    pub fn trait_items(&self, trait_did: DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> {
+    pub fn trait_items(self, trait_did: DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> {
         self.trait_items_cache.memoize(trait_did, || {
             let def_ids = self.trait_item_def_ids(trait_did);
             Rc::new(def_ids.iter()
@@ -1095,7 +1113,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Obtain the representation annotation for a struct definition.
-    pub fn lookup_repr_hints(&self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
+    pub fn lookup_repr_hints(self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
         self.repr_hint_cache.memoize(did, || {
             Rc::new(if did.is_local() {
                 self.get_attrs(did).iter().flat_map(|meta| {
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 9dc61e513b5..48f3e0e0bf7 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -211,7 +211,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
 }
 
 impl<'tcx> ty::TyS<'tcx> {
-    fn sort_string(&self, tcx: &TyCtxt) -> String {
+    fn sort_string(&self, tcx: TyCtxt) -> String {
         match self.sty {
             ty::TyBool | ty::TyChar | ty::TyInt(_) |
             ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr => self.to_string(),
@@ -252,8 +252,8 @@ impl<'tcx> ty::TyS<'tcx> {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn note_and_explain_type_err(&self,
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn note_and_explain_type_err(self,
                                      db: &mut DiagnosticBuilder,
                                      err: &TypeError<'tcx>,
                                      sp: Span) {
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs
index 29647253ad2..ff257e0c3b5 100644
--- a/src/librustc/ty/fast_reject.rs
+++ b/src/librustc/ty/fast_reject.rs
@@ -43,7 +43,7 @@ pub enum SimplifiedType {
 /// then we can't say much about whether two types would unify. Put another way,
 /// `can_simplify_params` should be true if type parameters appear free in `ty` and `false` if they
 /// are to be considered bound.
-pub fn simplify_type(tcx: &TyCtxt,
+pub fn simplify_type(tcx: TyCtxt,
                      ty: Ty,
                      can_simplify_params: bool)
                      -> Option<SimplifiedType>
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 8fcbc062952..c01842d8af4 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -114,7 +114,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
 /// identity fold, it should invoke `foo.fold_with(self)` to fold each
 /// sub-item.
 pub trait TypeFolder<'tcx> : Sized {
-    fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
+    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx>;
 
     fn fold_binder<T>(&mut self, t: &Binder<T>) -> Binder<T>
         where T : TypeFoldable<'tcx>
@@ -202,14 +202,14 @@ pub trait TypeVisitor<'tcx> : Sized {
 // Some sample folders
 
 pub struct BottomUpFolder<'a, 'tcx: 'a, F> where F: FnMut(Ty<'tcx>) -> Ty<'tcx> {
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
     pub fldop: F,
 }
 
 impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where
     F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
 {
-    fn tcx(&self) -> &TyCtxt<'tcx> { self.tcx }
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.tcx }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
         let t1 = ty.super_fold_with(self);
@@ -220,10 +220,10 @@ impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where
 ///////////////////////////////////////////////////////////////////////////
 // Region folder
 
-impl<'tcx> TyCtxt<'tcx> {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
     /// Collects the free and escaping regions in `value` into `region_set`. Returns
     /// whether any late-bound regions were skipped
-    pub fn collect_regions<T>(&self,
+    pub fn collect_regions<T>(self,
         value: &T,
         region_set: &mut FnvHashSet<ty::Region>)
         -> bool
@@ -238,7 +238,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Folds the escaping and free regions in `value` using `f`, and
     /// sets `skipped_regions` to true if any late-bound region was found
     /// and skipped.
-    pub fn fold_regions<T,F>(&self,
+    pub fn fold_regions<T,F>(self,
         value: &T,
         skipped_regions: &mut bool,
         mut f: F)
@@ -260,14 +260,14 @@ impl<'tcx> TyCtxt<'tcx> {
 /// visited by `fld_r`.
 
 pub struct RegionFolder<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     skipped_regions: &'a mut bool,
     current_depth: u32,
     fld_r: &'a mut (FnMut(ty::Region, u32) -> ty::Region + 'a),
 }
 
 impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
-    pub fn new<F>(tcx: &'a TyCtxt<'tcx>,
+    pub fn new<F>(tcx: TyCtxt<'a, 'tcx>,
                   skipped_regions: &'a mut bool,
                   fld_r: &'a mut F) -> RegionFolder<'a, 'tcx>
         where F : FnMut(ty::Region, u32) -> ty::Region
@@ -283,7 +283,7 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
 
 impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx>
 {
-    fn tcx(&self) -> &TyCtxt<'tcx> { self.tcx }
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.tcx }
 
     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
         self.current_depth += 1;
@@ -315,14 +315,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx>
 // Replaces the escaping regions in a type.
 
 struct RegionReplacer<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     current_depth: u32,
     fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region + 'a),
     map: FnvHashMap<ty::BoundRegion, ty::Region>
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn replace_late_bound_regions<T,F>(&self,
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn replace_late_bound_regions<T,F>(self,
         value: &Binder<T>,
         mut f: F)
         -> (T, FnvHashMap<ty::BoundRegion, ty::Region>)
@@ -337,7 +337,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Replace any late-bound regions bound in `value` with free variants attached to scope-id
     /// `scope_id`.
-    pub fn liberate_late_bound_regions<T>(&self,
+    pub fn liberate_late_bound_regions<T>(self,
         all_outlive_scope: region::CodeExtent,
         value: &Binder<T>)
         -> T
@@ -350,7 +350,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
     /// becomes `for<'a,'b> Foo`.
-    pub fn flatten_late_bound_regions<T>(&self, bound2_value: &Binder<Binder<T>>)
+    pub fn flatten_late_bound_regions<T>(self, bound2_value: &Binder<Binder<T>>)
                                          -> Binder<T>
         where T: TypeFoldable<'tcx>
     {
@@ -371,7 +371,7 @@ impl<'tcx> TyCtxt<'tcx> {
         Binder(value)
     }
 
-    pub fn no_late_bound_regions<T>(&self, value: &Binder<T>) -> Option<T>
+    pub fn no_late_bound_regions<T>(self, value: &Binder<T>) -> Option<T>
         where T : TypeFoldable<'tcx>
     {
         if value.0.has_escaping_regions() {
@@ -383,7 +383,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
     /// method lookup and a few other places where precise region relationships are not required.
-    pub fn erase_late_bound_regions<T>(&self, value: &Binder<T>) -> T
+    pub fn erase_late_bound_regions<T>(self, value: &Binder<T>) -> T
         where T : TypeFoldable<'tcx>
     {
         self.replace_late_bound_regions(value, |_| ty::ReStatic).0
@@ -397,7 +397,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
     /// structurally identical.  For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
     /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
-    pub fn anonymize_late_bound_regions<T>(&self, sig: &Binder<T>) -> Binder<T>
+    pub fn anonymize_late_bound_regions<T>(self, sig: &Binder<T>) -> Binder<T>
         where T : TypeFoldable<'tcx>,
     {
         let mut counter = 0;
@@ -409,7 +409,7 @@ impl<'tcx> TyCtxt<'tcx> {
 }
 
 impl<'a, 'tcx> RegionReplacer<'a, 'tcx> {
-    fn new<F>(tcx: &'a TyCtxt<'tcx>, fld_r: &'a mut F) -> RegionReplacer<'a, 'tcx>
+    fn new<F>(tcx: TyCtxt<'a, 'tcx>, fld_r: &'a mut F) -> RegionReplacer<'a, 'tcx>
         where F : FnMut(ty::BoundRegion) -> ty::Region
     {
         RegionReplacer {
@@ -423,7 +423,7 @@ impl<'a, 'tcx> RegionReplacer<'a, 'tcx> {
 
 impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx>
 {
-    fn tcx(&self) -> &TyCtxt<'tcx> { self.tcx }
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.tcx }
 
     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
         self.current_depth += 1;
@@ -463,11 +463,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx>
 ///////////////////////////////////////////////////////////////////////////
 // Region eraser
 
-impl<'tcx> TyCtxt<'tcx> {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
     /// Returns an equivalent value with all free regions removed (note
     /// that late-bound regions remain, because they are important for
     /// subtyping, but they are anonymized and normalized as well)..
-    pub fn erase_regions<T>(&self, value: &T) -> T
+    pub fn erase_regions<T>(self, value: &T) -> T
         where T : TypeFoldable<'tcx>
     {
         let value1 = value.fold_with(&mut RegionEraser(self));
@@ -475,10 +475,10 @@ impl<'tcx> TyCtxt<'tcx> {
                value, value1);
         return value1;
 
-        struct RegionEraser<'a, 'tcx: 'a>(&'a TyCtxt<'tcx>);
+        struct RegionEraser<'a, 'tcx: 'a>(TyCtxt<'a, 'tcx>);
 
         impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
-            fn tcx(&self) -> &TyCtxt<'tcx> { self.0 }
+            fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.0 }
 
             fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 match self.tcx().normalized_cache.borrow().get(&ty).cloned() {
@@ -543,8 +543,8 @@ pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
     }
 }
 
-pub fn shift_regions<'tcx, T:TypeFoldable<'tcx>>(tcx: &TyCtxt<'tcx>,
-                                                 amount: u32, value: &T) -> T {
+pub fn shift_regions<'a, 'tcx, T:TypeFoldable<'tcx>>(tcx: TyCtxt<'a, 'tcx>,
+                                                     amount: u32, value: &T) -> T {
     debug!("shift_regions(value={:?}, amount={})",
            value, amount);
 
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index e390456a87c..aef54b75db5 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -14,24 +14,24 @@ use hir::def_id::{DefId, CRATE_DEF_INDEX};
 use ty::{self, Ty, TyCtxt};
 use syntax::ast;
 
-impl<'tcx> TyCtxt<'tcx> {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
     /// Returns a string identifying this def-id. This string is
     /// suitable for user output. It is relative to the current crate
     /// root.
-    pub fn item_path_str(&self, def_id: DefId) -> String {
+    pub fn item_path_str(self, def_id: DefId) -> String {
         let mut buffer = LocalPathBuffer::new(RootMode::Local);
         self.push_item_path(&mut buffer, def_id);
         buffer.into_string()
     }
 
     /// Returns a string identifying this local node-id.
-    pub fn node_path_str(&self, id: ast::NodeId) -> String {
+    pub fn node_path_str(self, id: ast::NodeId) -> String {
         self.item_path_str(self.map.local_def_id(id))
     }
 
     /// Returns a string identifying this def-id. This string is
     /// suitable for user output. It always begins with a crate identifier.
-    pub fn absolute_item_path_str(&self, def_id: DefId) -> String {
+    pub fn absolute_item_path_str(self, def_id: DefId) -> String {
         let mut buffer = LocalPathBuffer::new(RootMode::Absolute);
         self.push_item_path(&mut buffer, def_id);
         buffer.into_string()
@@ -40,7 +40,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns the "path" to a particular crate. This can proceed in
     /// various ways, depending on the `root_mode` of the `buffer`.
     /// (See `RootMode` enum for more details.)
-    pub fn push_krate_path<T>(&self, buffer: &mut T, cnum: ast::CrateNum)
+    pub fn push_krate_path<T>(self, buffer: &mut T, cnum: ast::CrateNum)
         where T: ItemPathBuffer
     {
         match *buffer.root_mode() {
@@ -83,7 +83,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// If possible, this pushes a global path resolving to `external_def_id` that is visible
     /// from at least one local module and returns true. If the crate defining `external_def_id` is
     /// declared with an `extern crate`, the path is guarenteed to use the `extern crate`.
-    pub fn try_push_visible_item_path<T>(&self, buffer: &mut T, external_def_id: DefId) -> bool
+    pub fn try_push_visible_item_path<T>(self, buffer: &mut T, external_def_id: DefId) -> bool
         where T: ItemPathBuffer
     {
         let visible_parent_map = self.sess.cstore.visible_parent_map();
@@ -116,7 +116,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn push_item_path<T>(&self, buffer: &mut T, def_id: DefId)
+    pub fn push_item_path<T>(self, buffer: &mut T, def_id: DefId)
         where T: ItemPathBuffer
     {
         match *buffer.root_mode() {
@@ -164,7 +164,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    fn push_impl_path<T>(&self,
+    fn push_impl_path<T>(self,
                          buffer: &mut T,
                          impl_def_id: DefId)
         where T: ItemPathBuffer
@@ -253,7 +253,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    fn push_impl_path_fallback<T>(&self,
+    fn push_impl_path_fallback<T>(self,
                                   buffer: &mut T,
                                   impl_def_id: DefId)
         where T: ItemPathBuffer
@@ -284,7 +284,7 @@ impl<'tcx> TyCtxt<'tcx> {
 /// function tries to find a "characteristic def-id" for a
 /// type. It's just a heuristic so it makes some questionable
 /// decisions and we may want to adjust it later.
-pub fn characteristic_def_id_of_type<'tcx>(ty: Ty<'tcx>) -> Option<DefId> {
+pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
     match ty.sty {
         ty::TyStruct(adt_def, _) |
         ty::TyEnum(adt_def, _) => Some(adt_def.did),
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index bcdc9feab5b..aef67552df5 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -364,7 +364,7 @@ impl Integer {
     /// signed discriminant range and #[repr] attribute.
     /// N.B.: u64 values above i64::MAX will be treated as signed, but
     /// that shouldn't affect anything, other than maybe debuginfo.
-    pub fn repr_discr(tcx: &TyCtxt, hint: attr::ReprAttr, min: i64, max: i64)
+    pub fn repr_discr(tcx: TyCtxt, hint: attr::ReprAttr, min: i64, max: i64)
                       -> (Integer, bool) {
         // Theoretically, negative values could be larger in unsigned representation
         // than the unsigned representation of the signed minimum. However, if there
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 59fd6263c85..91cac6999aa 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -165,10 +165,10 @@ pub struct ImplHeader<'tcx> {
     pub predicates: Vec<Predicate<'tcx>>,
 }
 
-impl<'tcx> ImplHeader<'tcx> {
-    pub fn with_fresh_ty_vars<'a>(selcx: &mut traits::SelectionContext<'a, 'tcx>,
-                                  impl_def_id: DefId)
-                                  -> ImplHeader<'tcx>
+impl<'a, 'tcx> ImplHeader<'tcx> {
+    pub fn with_fresh_ty_vars(selcx: &mut traits::SelectionContext<'a, 'tcx>,
+                              impl_def_id: DefId)
+                              -> ImplHeader<'tcx>
     {
         let tcx = selcx.tcx();
         let impl_generics = tcx.lookup_item_type(impl_def_id).generics;
@@ -303,7 +303,7 @@ impl<'a> NodeIdTree for ast_map::Map<'a> {
 }
 
 impl Visibility {
-    pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: &TyCtxt) -> Self {
+    pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
         match *visibility {
             hir::Public => Visibility::Public,
             hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID),
@@ -773,22 +773,21 @@ pub struct GenericPredicates<'tcx> {
     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
 }
 
-impl<'tcx> GenericPredicates<'tcx> {
+impl<'a, 'tcx> GenericPredicates<'tcx> {
     pub fn empty() -> GenericPredicates<'tcx> {
         GenericPredicates {
             predicates: VecPerParamSpace::empty(),
         }
     }
 
-    pub fn instantiate(&self, tcx: &TyCtxt<'tcx>, substs: &Substs<'tcx>)
+    pub fn instantiate(&self, tcx: TyCtxt<'a, 'tcx>, substs: &Substs<'tcx>)
                        -> InstantiatedPredicates<'tcx> {
         InstantiatedPredicates {
             predicates: self.predicates.subst(tcx, substs),
         }
     }
 
-    pub fn instantiate_supertrait(&self,
-                                  tcx: &TyCtxt<'tcx>,
+    pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'tcx>,
                                   poly_trait_ref: &ty::PolyTraitRef<'tcx>)
                                   -> InstantiatedPredicates<'tcx>
     {
@@ -833,14 +832,13 @@ pub enum Predicate<'tcx> {
     ClosureKind(DefId, ClosureKind),
 }
 
-impl<'tcx> Predicate<'tcx> {
+impl<'a, 'tcx> Predicate<'tcx> {
     /// Performs a substitution suitable for going from a
     /// poly-trait-ref to supertraits that must hold if that
     /// poly-trait-ref holds. This is slightly different from a normal
     /// substitution in terms of what happens with bound regions.  See
     /// lengthy comment below for details.
-    pub fn subst_supertrait(&self,
-                            tcx: &TyCtxt<'tcx>,
+    pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'tcx>,
                             trait_ref: &ty::PolyTraitRef<'tcx>)
                             -> ty::Predicate<'tcx>
     {
@@ -1212,7 +1210,7 @@ impl<'tcx> TraitRef<'tcx> {
 /// more distinctions clearer.
 #[derive(Clone)]
 pub struct ParameterEnvironment<'a, 'tcx:'a> {
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
 
     /// See `construct_free_substs` for details.
     pub free_substs: Substs<'tcx>,
@@ -1262,7 +1260,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
     }
 
     /// Construct a parameter environment given an item, impl item, or trait item
-    pub fn for_item(tcx: &'a TyCtxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
+    pub fn for_item(tcx: TyCtxt<'a, 'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
         match tcx.map.find(id) {
             Some(ast_map::NodeImplItem(ref impl_item)) => {
                 match impl_item.node {
@@ -1570,8 +1568,8 @@ impl VariantKind {
     }
 }
 
-impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
-    fn new(tcx: &TyCtxt<'tcx>,
+impl<'a, 'tcx, 'container> AdtDefData<'tcx, 'container> {
+    fn new(tcx: TyCtxt<'a, 'tcx>,
            did: DefId,
            kind: AdtKind,
            variants: Vec<VariantDefData<'tcx, 'container>>) -> Self {
@@ -1601,7 +1599,7 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
         }
     }
 
-    fn calculate_dtorck(&'tcx self, tcx: &TyCtxt<'tcx>) {
+    fn calculate_dtorck(&'tcx self, tcx: TyCtxt<'a, 'tcx>) {
         if tcx.is_adt_dtorck(self) {
             self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK);
         }
@@ -1622,7 +1620,7 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     /// true, this type being safe for destruction requires it to be
     /// alive; Otherwise, only the contents are required to be.
     #[inline]
-    pub fn is_dtorck(&'tcx self, tcx: &TyCtxt<'tcx>) -> bool {
+    pub fn is_dtorck(&'tcx self, tcx: TyCtxt<'a, 'tcx>) -> bool {
         if !self.flags.get().intersects(AdtFlags::IS_DTORCK_VALID) {
             self.calculate_dtorck(tcx)
         }
@@ -1663,12 +1661,12 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     }
 
     #[inline]
-    pub fn type_scheme(&self, tcx: &TyCtxt<'tcx>) -> TypeScheme<'tcx> {
+    pub fn type_scheme(&self, tcx: TyCtxt<'a, 'tcx>) -> TypeScheme<'tcx> {
         tcx.lookup_item_type(self.did)
     }
 
     #[inline]
-    pub fn predicates(&self, tcx: &TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
+    pub fn predicates(&self, tcx: TyCtxt<'a, 'tcx>) -> GenericPredicates<'tcx> {
         tcx.lookup_predicates(self.did)
     }
 
@@ -1756,7 +1754,7 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     ///
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer, e.g. issue #31299.
-    pub fn sized_constraint(&self, tcx: &ty::TyCtxt<'tcx>) -> Ty<'tcx> {
+    pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         let dep_node = DepNode::SizedConstraint(self.did);
         match self.sized_constraint.get(dep_node) {
             None => {
@@ -1769,7 +1767,7 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     }
 }
 
-impl<'tcx> AdtDefData<'tcx, 'tcx> {
+impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
     /// Calculates the Sized-constraint.
     ///
     /// As the Sized-constraint of enums can be a *set* of types,
@@ -1785,7 +1783,7 @@ impl<'tcx> AdtDefData<'tcx, 'tcx> {
     ///       such.
     ///     - a TyError, if a type contained itself. The representability
     ///       check should catch this case.
-    fn calculate_sized_constraint_inner(&'tcx self, tcx: &ty::TyCtxt<'tcx>,
+    fn calculate_sized_constraint_inner(&'tcx self, tcx: TyCtxt<'a, 'tcx>,
                                         stack: &mut Vec<AdtDefMaster<'tcx>>)
     {
 
@@ -1838,7 +1836,7 @@ impl<'tcx> AdtDefData<'tcx, 'tcx> {
 
     fn sized_constraint_for_ty(
         &'tcx self,
-        tcx: &ty::TyCtxt<'tcx>,
+        tcx: TyCtxt<'a, 'tcx>,
         stack: &mut Vec<AdtDefMaster<'tcx>>,
         ty: Ty<'tcx>
     ) -> Vec<Ty<'tcx>> {
@@ -1953,7 +1951,7 @@ impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
     }
 }
 
-impl<'tcx, 'container> FieldDefData<'tcx, 'container> {
+impl<'a, 'tcx, 'container> FieldDefData<'tcx, 'container> {
     pub fn new(did: DefId,
                name: Name,
                vis: Visibility) -> Self {
@@ -1965,7 +1963,7 @@ impl<'tcx, 'container> FieldDefData<'tcx, 'container> {
         }
     }
 
-    pub fn ty(&self, tcx: &TyCtxt<'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
+    pub fn ty(&self, tcx: TyCtxt<'a, 'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
         self.unsubst_ty().subst(tcx, subst)
     }
 
@@ -1996,7 +1994,7 @@ pub enum ClosureKind {
 }
 
 impl ClosureKind {
-    pub fn trait_did(&self, tcx: &TyCtxt) -> DefId {
+    pub fn trait_did(&self, tcx: TyCtxt) -> DefId {
         let result = match *self {
             ClosureKind::Fn => tcx.lang_items.require(FnTraitLangItem),
             ClosureKind::FnMut => {
@@ -2146,8 +2144,8 @@ impl BorrowKind {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn node_id_to_type(self, id: NodeId) -> Ty<'tcx> {
         match self.node_id_to_type_opt(id) {
            Some(ty) => ty,
            None => bug!("node_id_to_type: no type for node `{}`",
@@ -2155,11 +2153,11 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn node_id_to_type_opt(&self, id: NodeId) -> Option<Ty<'tcx>> {
+    pub fn node_id_to_type_opt(self, id: NodeId) -> Option<Ty<'tcx>> {
         self.tables.borrow().node_types.get(&id).cloned()
     }
 
-    pub fn node_id_item_substs(&self, id: NodeId) -> ItemSubsts<'tcx> {
+    pub fn node_id_item_substs(self, id: NodeId) -> ItemSubsts<'tcx> {
         match self.tables.borrow().item_substs.get(&id) {
             None => ItemSubsts::empty(),
             Some(ts) => ts.clone(),
@@ -2168,10 +2166,10 @@ impl<'tcx> TyCtxt<'tcx> {
 
     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
     // doesn't provide type parameter substitutions.
-    pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
+    pub fn pat_ty(self, pat: &hir::Pat) -> Ty<'tcx> {
         self.node_id_to_type(pat.id)
     }
-    pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
+    pub fn pat_ty_opt(self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
         self.node_id_to_type_opt(pat.id)
     }
 
@@ -2185,11 +2183,11 @@ impl<'tcx> TyCtxt<'tcx> {
     // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
     // instead of "fn(ty) -> T with T = isize".
-    pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
+    pub fn expr_ty(self, expr: &hir::Expr) -> Ty<'tcx> {
         self.node_id_to_type(expr.id)
     }
 
-    pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
+    pub fn expr_ty_opt(self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
         self.node_id_to_type_opt(expr.id)
     }
 
@@ -2202,7 +2200,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// hard to do, I just hate that code so much I didn't want to touch it
     /// unless it was to fix it properly, which seemed a distraction from the
     /// thread at hand! -nmatsakis
-    pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> Ty<'tcx> {
+    pub fn expr_ty_adjusted(self, expr: &hir::Expr) -> Ty<'tcx> {
         self.expr_ty(expr)
             .adjust(self, expr.span, expr.id,
                     self.tables.borrow().adjustments.get(&expr.id),
@@ -2211,7 +2209,7 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
+    pub fn expr_ty_adjusted_opt(self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
         self.expr_ty_opt(expr).map(|t| t.adjust(self,
                                                 expr.span,
                                                 expr.id,
@@ -2221,7 +2219,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }))
     }
 
-    pub fn expr_span(&self, id: NodeId) -> Span {
+    pub fn expr_span(self, id: NodeId) -> Span {
         match self.map.find(id) {
             Some(ast_map::NodeExpr(e)) => {
                 e.span
@@ -2235,7 +2233,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn local_var_name_str(&self, id: NodeId) -> InternedString {
+    pub fn local_var_name_str(self, id: NodeId) -> InternedString {
         match self.map.find(id) {
             Some(ast_map::NodeLocal(pat)) => {
                 match pat.node {
@@ -2249,7 +2247,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn resolve_expr(&self, expr: &hir::Expr) -> Def {
+    pub fn resolve_expr(self, expr: &hir::Expr) -> Def {
         match self.def_map.borrow().get(&expr.id) {
             Some(def) => def.full_def(),
             None => {
@@ -2258,7 +2256,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn expr_is_lval(&self, expr: &hir::Expr) -> bool {
+    pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
          match expr.node {
             hir::ExprPath(..) => {
                 // We can't use resolve_expr here, as this needs to run on broken
@@ -2320,7 +2318,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
+    pub fn provided_trait_methods(self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
         if let Some(id) = self.map.as_local_node_id(id) {
             if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id).node {
                 ms.iter().filter_map(|ti| {
@@ -2345,7 +2343,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn associated_consts(&self, id: DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
+    pub fn associated_consts(self, id: DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
         if let Some(id) = self.map.as_local_node_id(id) {
             match self.map.expect_item(id).node {
                 ItemTrait(_, _, _, ref tis) => {
@@ -2389,7 +2387,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn trait_impl_polarity(&self, id: DefId) -> Option<hir::ImplPolarity> {
+    pub fn trait_impl_polarity(self, id: DefId) -> Option<hir::ImplPolarity> {
         if let Some(id) = self.map.as_local_node_id(id) {
             match self.map.find(id) {
                 Some(ast_map::NodeItem(item)) => {
@@ -2405,7 +2403,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn custom_coerce_unsized_kind(&self, did: DefId) -> adjustment::CustomCoerceUnsized {
+    pub fn custom_coerce_unsized_kind(self, did: DefId) -> adjustment::CustomCoerceUnsized {
         self.custom_coerce_unsized_kinds.memoize(did, || {
             let (kind, src) = if did.krate != LOCAL_CRATE {
                 (self.sess.cstore.custom_coerce_unsized_kind(did), "external")
@@ -2424,14 +2422,14 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    pub fn impl_or_trait_item(&self, id: DefId) -> ImplOrTraitItem<'tcx> {
+    pub fn impl_or_trait_item(self, id: DefId) -> ImplOrTraitItem<'tcx> {
         lookup_locally_or_in_crate_store(
             "impl_or_trait_items", id, &self.impl_or_trait_items,
             || self.sess.cstore.impl_or_trait_item(self, id)
                    .expect("missing ImplOrTraitItem in metadata"))
     }
 
-    pub fn trait_item_def_ids(&self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
+    pub fn trait_item_def_ids(self, id: DefId) -> Rc<Vec<ImplOrTraitItemId>> {
         lookup_locally_or_in_crate_store(
             "trait_item_def_ids", id, &self.trait_item_def_ids,
             || Rc::new(self.sess.cstore.trait_item_def_ids(id)))
@@ -2439,14 +2437,14 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Returns the trait-ref corresponding to a given impl, or None if it is
     /// an inherent impl.
-    pub fn impl_trait_ref(&self, id: DefId) -> Option<TraitRef<'tcx>> {
+    pub fn impl_trait_ref(self, id: DefId) -> Option<TraitRef<'tcx>> {
         lookup_locally_or_in_crate_store(
             "impl_trait_refs", id, &self.impl_trait_refs,
             || self.sess.cstore.impl_trait_ref(self, id))
     }
 
     /// Returns whether this DefId refers to an impl
-    pub fn is_impl(&self, id: DefId) -> bool {
+    pub fn is_impl(self, id: DefId) -> bool {
         if let Some(id) = self.map.as_local_node_id(id) {
             if let Some(ast_map::NodeItem(
                 &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id) {
@@ -2459,11 +2457,11 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn trait_ref_to_def_id(&self, tr: &hir::TraitRef) -> DefId {
+    pub fn trait_ref_to_def_id(self, tr: &hir::TraitRef) -> DefId {
         self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
     }
 
-    pub fn def_key(&self, id: DefId) -> ast_map::DefKey {
+    pub fn def_key(self, id: DefId) -> ast_map::DefKey {
         if id.is_local() {
             self.map.def_key(id)
         } else {
@@ -2474,7 +2472,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns the `DefPath` of an item. Note that if `id` is not
     /// local to this crate -- or is inlined into this crate -- the
     /// result will be a non-local `DefPath`.
-    pub fn def_path(&self, id: DefId) -> ast_map::DefPath {
+    pub fn def_path(self, id: DefId) -> ast_map::DefPath {
         if id.is_local() {
             self.map.def_path(id)
         } else {
@@ -2482,7 +2480,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn item_name(&self, id: DefId) -> ast::Name {
+    pub fn item_name(self, id: DefId) -> ast::Name {
         if let Some(id) = self.map.as_local_node_id(id) {
             self.map.name(id)
         } else {
@@ -2491,20 +2489,20 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     // Register a given item type
-    pub fn register_item_type(&self, did: DefId, ty: TypeScheme<'tcx>) {
+    pub fn register_item_type(self, did: DefId, ty: TypeScheme<'tcx>) {
         self.tcache.borrow_mut().insert(did, ty);
     }
 
     // If the given item is in an external crate, looks up its type and adds it to
     // the type cache. Returns the type parameters and type.
-    pub fn lookup_item_type(&self, did: DefId) -> TypeScheme<'tcx> {
+    pub fn lookup_item_type(self, did: DefId) -> TypeScheme<'tcx> {
         lookup_locally_or_in_crate_store(
             "tcache", did, &self.tcache,
             || self.sess.cstore.item_type(self, did))
     }
 
     /// Given the did of a trait, returns its canonical trait ref.
-    pub fn lookup_trait_def(&self, did: DefId) -> &'tcx TraitDef<'tcx> {
+    pub fn lookup_trait_def(self, did: DefId) -> &'tcx TraitDef<'tcx> {
         lookup_locally_or_in_crate_store(
             "trait_defs", did, &self.trait_defs,
             || self.alloc_trait_def(self.sess.cstore.trait_def(self, did))
@@ -2514,7 +2512,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Given the did of an ADT, return a master reference to its
     /// definition. Unless you are planning on fulfilling the ADT's fields,
     /// use lookup_adt_def instead.
-    pub fn lookup_adt_def_master(&self, did: DefId) -> AdtDefMaster<'tcx> {
+    pub fn lookup_adt_def_master(self, did: DefId) -> AdtDefMaster<'tcx> {
         lookup_locally_or_in_crate_store(
             "adt_defs", did, &self.adt_defs,
             || self.sess.cstore.adt_def(self, did)
@@ -2522,21 +2520,21 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Given the did of an ADT, return a reference to its definition.
-    pub fn lookup_adt_def(&self, did: DefId) -> AdtDef<'tcx> {
+    pub fn lookup_adt_def(self, did: DefId) -> AdtDef<'tcx> {
         // when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
         // would be needed here.
         self.lookup_adt_def_master(did)
     }
 
     /// Given the did of an item, returns its full set of predicates.
-    pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
+    pub fn lookup_predicates(self, did: DefId) -> GenericPredicates<'tcx> {
         lookup_locally_or_in_crate_store(
             "predicates", did, &self.predicates,
             || self.sess.cstore.item_predicates(self, did))
     }
 
     /// Given the did of a trait, returns its superpredicates.
-    pub fn lookup_super_predicates(&self, did: DefId) -> GenericPredicates<'tcx> {
+    pub fn lookup_super_predicates(self, did: DefId) -> GenericPredicates<'tcx> {
         lookup_locally_or_in_crate_store(
             "super_predicates", did, &self.super_predicates,
             || self.sess.cstore.item_super_predicates(self, did))
@@ -2548,9 +2546,9 @@ impl<'tcx> TyCtxt<'tcx> {
     ///
     /// (Note that this implies that if `ty` has a destructor attached,
     /// then `type_needs_drop` will definitely return `true` for `ty`.)
-    pub fn type_needs_drop_given_env<'a>(&self,
+    pub fn type_needs_drop_given_env<'b>(self,
                                          ty: Ty<'tcx>,
-                                         param_env: &ty::ParameterEnvironment<'a,'tcx>) -> bool {
+                                         param_env: &ty::ParameterEnvironment<'b,'tcx>) -> bool {
         // Issue #22536: We first query type_moves_by_default.  It sees a
         // normalized version of the type, and therefore will definitely
         // know whether the type implements Copy (and thus needs no
@@ -2576,7 +2574,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Get the attributes of a definition.
-    pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [ast::Attribute]> {
+    pub fn get_attrs(self, did: DefId) -> Cow<'tcx, [ast::Attribute]> {
         if let Some(id) = self.map.as_local_node_id(did) {
             Cow::Borrowed(self.map.attrs(id))
         } else {
@@ -2585,28 +2583,28 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Determine whether an item is annotated with an attribute
-    pub fn has_attr(&self, did: DefId, attr: &str) -> bool {
+    pub fn has_attr(self, did: DefId, attr: &str) -> bool {
         self.get_attrs(did).iter().any(|item| item.check_name(attr))
     }
 
     /// Determine whether an item is annotated with `#[repr(packed)]`
-    pub fn lookup_packed(&self, did: DefId) -> bool {
+    pub fn lookup_packed(self, did: DefId) -> bool {
         self.lookup_repr_hints(did).contains(&attr::ReprPacked)
     }
 
     /// Determine whether an item is annotated with `#[simd]`
-    pub fn lookup_simd(&self, did: DefId) -> bool {
+    pub fn lookup_simd(self, did: DefId) -> bool {
         self.has_attr(did, "simd")
             || self.lookup_repr_hints(did).contains(&attr::ReprSimd)
     }
 
-    pub fn item_variances(&self, item_id: DefId) -> Rc<ItemVariances> {
+    pub fn item_variances(self, item_id: DefId) -> Rc<ItemVariances> {
         lookup_locally_or_in_crate_store(
             "item_variance_map", item_id, &self.item_variance_map,
             || Rc::new(self.sess.cstore.item_variances(item_id)))
     }
 
-    pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool {
+    pub fn trait_has_default_impl(self, trait_def_id: DefId) -> bool {
         self.populate_implementations_for_trait_if_necessary(trait_def_id);
 
         let def = self.lookup_trait_def(trait_def_id);
@@ -2614,13 +2612,13 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Records a trait-to-implementation mapping.
-    pub fn record_trait_has_default_impl(&self, trait_def_id: DefId) {
+    pub fn record_trait_has_default_impl(self, trait_def_id: DefId) {
         let def = self.lookup_trait_def(trait_def_id);
         def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
     }
 
     /// Load primitive inherent implementations if necessary
-    pub fn populate_implementations_for_primitive_if_necessary(&self,
+    pub fn populate_implementations_for_primitive_if_necessary(self,
                                                                primitive_def_id: DefId) {
         if primitive_def_id.is_local() {
             return
@@ -2646,7 +2644,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Populates the type context with all the inherent implementations for
     /// the given type if necessary.
-    pub fn populate_inherent_implementations_for_type_if_necessary(&self,
+    pub fn populate_inherent_implementations_for_type_if_necessary(self,
                                                                    type_id: DefId) {
         if type_id.is_local() {
             return
@@ -2676,7 +2674,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Populates the type context with all the implementations for the given
     /// trait if necessary.
-    pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: DefId) {
+    pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) {
         if trait_id.is_local() {
             return
         }
@@ -2723,11 +2721,11 @@ impl<'tcx> TyCtxt<'tcx> {
         def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
     }
 
-    pub fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind {
+    pub fn closure_kind(self, def_id: DefId) -> ty::ClosureKind {
         Tables::closure_kind(&self.tables, self, def_id)
     }
 
-    pub fn closure_type(&self,
+    pub fn closure_type(self,
                         def_id: DefId,
                         substs: &ClosureSubsts<'tcx>)
                         -> ty::ClosureTy<'tcx>
@@ -2737,13 +2735,13 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Given the def_id of an impl, return the def_id of the trait it implements.
     /// If it implements no trait, return `None`.
-    pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
+    pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
         self.impl_trait_ref(def_id).map(|tr| tr.def_id)
     }
 
     /// If the given def ID describes a method belonging to an impl, return the
     /// ID of the impl that the method belongs to. Otherwise, return `None`.
-    pub fn impl_of_method(&self, def_id: DefId) -> Option<DefId> {
+    pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
         if def_id.krate != LOCAL_CRATE {
             return self.sess.cstore.impl_or_trait_item(self, def_id).and_then(|item| {
                 match item.container() {
@@ -2766,7 +2764,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// If the given def ID describes an item belonging to a trait (either a
     /// default method or an implementation of a trait method), return the ID of
     /// the trait that the method belongs to. Otherwise, return `None`.
-    pub fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
+    pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
         if def_id.krate != LOCAL_CRATE {
             return self.sess.cstore.trait_of_item(self, def_id);
         }
@@ -2787,7 +2785,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// is already that of the original trait method, then the return value is
     /// the same).
     /// Otherwise, return `None`.
-    pub fn trait_item_of_item(&self, def_id: DefId) -> Option<ImplOrTraitItemId> {
+    pub fn trait_item_of_item(self, def_id: DefId) -> Option<ImplOrTraitItemId> {
         let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) {
             Some(m) => m.clone(),
             None => return None,
@@ -2805,8 +2803,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Construct a parameter environment suitable for static contexts or other contexts where there
     /// are no free type/lifetime parameters in scope.
-    pub fn empty_parameter_environment<'a>(&'a self)
-                                           -> ParameterEnvironment<'a,'tcx> {
+    pub fn empty_parameter_environment(self) -> ParameterEnvironment<'a,'tcx> {
 
         // for an empty parameter environment, there ARE no free
         // regions, so it shouldn't matter what we use for the free id
@@ -2825,7 +2822,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// In general, this means converting from bound parameters to
     /// free parameters. Since we currently represent bound/free type
     /// parameters in the same way, this only has an effect on regions.
-    pub fn construct_free_substs(&self, generics: &Generics<'tcx>,
+    pub fn construct_free_substs(self, generics: &Generics<'tcx>,
                                  free_id_outlive: CodeExtent) -> Substs<'tcx> {
         // map T => T
         let mut types = VecPerParamSpace::empty();
@@ -2854,12 +2851,12 @@ impl<'tcx> TyCtxt<'tcx> {
     /// See `ParameterEnvironment` struct def'n for details.
     /// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)`
     /// for the `free_id_outlive` parameter. (But note that that is not always quite right.)
-    pub fn construct_parameter_environment<'a>(&'a self,
-                                               span: Span,
-                                               generics: &ty::Generics<'tcx>,
-                                               generic_predicates: &ty::GenericPredicates<'tcx>,
-                                               free_id_outlive: CodeExtent)
-                                               -> ParameterEnvironment<'a, 'tcx>
+    pub fn construct_parameter_environment(self,
+                                           span: Span,
+                                           generics: &ty::Generics<'tcx>,
+                                           generic_predicates: &ty::GenericPredicates<'tcx>,
+                                           free_id_outlive: CodeExtent)
+                                           -> ParameterEnvironment<'a, 'tcx>
     {
         //
         // Construct the free substs.
@@ -2902,20 +2899,20 @@ impl<'tcx> TyCtxt<'tcx> {
         traits::normalize_param_env_or_error(unnormalized_env, cause)
     }
 
-    pub fn is_method_call(&self, expr_id: NodeId) -> bool {
+    pub fn is_method_call(self, expr_id: NodeId) -> bool {
         self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
     }
 
-    pub fn is_overloaded_autoderef(&self, expr_id: NodeId, autoderefs: u32) -> bool {
+    pub fn is_overloaded_autoderef(self, expr_id: NodeId, autoderefs: u32) -> bool {
         self.tables.borrow().method_map.contains_key(&MethodCall::autoderef(expr_id,
                                                                             autoderefs))
     }
 
-    pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
+    pub fn upvar_capture(self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
         Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
     }
 
-    pub fn visit_all_items_in_krate<V,F>(&self,
+    pub fn visit_all_items_in_krate<V,F>(self,
                                          dep_node_fn: F,
                                          visitor: &mut V)
         where F: FnMut(DefId) -> DepNode<DefId>, V: Visitor<'tcx>
@@ -2925,7 +2922,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
     /// with the name of the crate containing the impl.
-    pub fn span_of_impl(&self, impl_did: DefId) -> Result<Span, InternedString> {
+    pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, InternedString> {
         if impl_did.is_local() {
             let node_id = self.map.as_local_node_id(impl_did).unwrap();
             Ok(self.map.span(node_id))
@@ -2944,8 +2941,8 @@ pub enum ExplicitSelfCategory {
     ByBox,
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn with_freevars<T, F>(&self, fid: NodeId, f: F) -> T where
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
         F: FnOnce(&[hir::Freevar]) -> T,
     {
         match self.freevars.borrow().get(&fid) {
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index f14e680e9e0..9bddd8383cd 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -29,7 +29,7 @@ pub enum Cause {
 }
 
 pub trait TypeRelation<'a,'tcx> : Sized {
-    fn tcx(&self) -> &'a TyCtxt<'tcx>;
+    fn tcx(&self) -> TyCtxt<'a, 'tcx>;
 
     /// Returns a static string we can use for printouts.
     fn tag(&self) -> &'static str;
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index ac3dfa82bd6..d20417714e5 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -24,14 +24,14 @@ use hir;
 
 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
     type Lifted = (A::Lifted, B::Lifted);
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
     }
 }
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
     type Lifted = Vec<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Option<Self::Lifted> {
         // type annotation needed to inform `projection_must_outlive`
         let mut result : Vec<<T as Lift<'tcx>>::Lifted>
             = Vec::with_capacity(self.len());
@@ -48,14 +48,14 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
 
 impl<'tcx> Lift<'tcx> for ty::Region {
     type Lifted = Self;
-    fn lift_to_tcx(&self, _: &TyCtxt<'tcx>) -> Option<ty::Region> {
+    fn lift_to_tcx(&self, _: TyCtxt) -> Option<ty::Region> {
         Some(*self)
     }
 }
 
 impl<'a, 'tcx> Lift<'tcx> for TraitRef<'a> {
     type Lifted = TraitRef<'tcx>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<TraitRef<'tcx>> {
+    fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<TraitRef<'tcx>> {
         tcx.lift(&self.substs).map(|substs| TraitRef {
             def_id: self.def_id,
             substs: substs
@@ -65,7 +65,7 @@ impl<'a, 'tcx> Lift<'tcx> for TraitRef<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
     type Lifted = ty::TraitPredicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
+    fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
         tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
             trait_ref: trait_ref
         })
@@ -74,21 +74,21 @@ impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::EquatePredicate<'a> {
     type Lifted = ty::EquatePredicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<ty::EquatePredicate<'tcx>> {
+    fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<ty::EquatePredicate<'tcx>> {
         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::EquatePredicate(a, b))
     }
 }
 
 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
     }
 }
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
     type Lifted = ty::ProjectionPredicate<'tcx>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
+    fn lift_to_tcx<'b>(&self, tcx: TyCtxt<'b, 'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
         tcx.lift(&(self.projection_ty.trait_ref, self.ty)).map(|(trait_ref, ty)| {
             ty::ProjectionPredicate {
                 projection_ty: ty::ProjectionTy {
@@ -103,7 +103,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
     type Lifted = ty::Binder<T::Lifted>;
-    fn lift_to_tcx(&self, tcx: &TyCtxt<'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx<'a>(&self, tcx: TyCtxt<'a, 'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.0).map(|x| ty::Binder(x))
     }
 }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 05d1dc75530..6dd406c3f8c 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -270,7 +270,7 @@ pub struct TraitTy<'tcx> {
     pub bounds: ExistentialBounds<'tcx>,
 }
 
-impl<'tcx> TraitTy<'tcx> {
+impl<'a, 'tcx> TraitTy<'tcx> {
     pub fn principal_def_id(&self) -> DefId {
         self.principal.0.def_id
     }
@@ -279,8 +279,7 @@ impl<'tcx> TraitTy<'tcx> {
     /// we convert the principal trait-ref into a normal trait-ref,
     /// you must give *some* self-type. A common choice is `mk_err()`
     /// or some skolemized type.
-    pub fn principal_trait_ref_with_self_ty(&self,
-                                            tcx: &TyCtxt<'tcx>,
+    pub fn principal_trait_ref_with_self_ty(&self, tcx: TyCtxt<'a, 'tcx>,
                                             self_ty: Ty<'tcx>)
                                             -> ty::PolyTraitRef<'tcx>
     {
@@ -293,8 +292,7 @@ impl<'tcx> TraitTy<'tcx> {
         })
     }
 
-    pub fn projection_bounds_with_self_ty(&self,
-                                          tcx: &TyCtxt<'tcx>,
+    pub fn projection_bounds_with_self_ty(&self, tcx: TyCtxt<'a, 'tcx>,
                                           self_ty: Ty<'tcx>)
                                           -> Vec<ty::PolyProjectionPredicate<'tcx>>
     {
@@ -523,7 +521,7 @@ pub struct ParamTy {
     pub name: Name,
 }
 
-impl ParamTy {
+impl<'a, 'tcx> ParamTy {
     pub fn new(space: subst::ParamSpace,
                index: u32,
                name: Name)
@@ -539,7 +537,7 @@ impl ParamTy {
         ParamTy::new(def.space, def.index, def.name)
     }
 
-    pub fn to_ty<'tcx>(self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+    pub fn to_ty(self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         tcx.mk_param(self.space, self.idx, self.name)
     }
 
@@ -764,7 +762,7 @@ impl<'tcx> ExistentialBounds<'tcx> {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub struct BuiltinBounds(EnumSet<BuiltinBound>);
 
-impl BuiltinBounds {
+impl<'a, 'tcx> BuiltinBounds {
     pub fn empty() -> BuiltinBounds {
         BuiltinBounds(EnumSet::new())
     }
@@ -773,9 +771,9 @@ impl BuiltinBounds {
         self.into_iter()
     }
 
-    pub fn to_predicates<'tcx>(&self,
-                               tcx: &TyCtxt<'tcx>,
-                               self_ty: Ty<'tcx>) -> Vec<ty::Predicate<'tcx>> {
+    pub fn to_predicates(&self, tcx: TyCtxt<'a, 'tcx>,
+                         self_ty: Ty<'tcx>)
+                         -> Vec<ty::Predicate<'tcx>> {
         self.iter().filter_map(|builtin_bound|
             match tcx.trait_ref_for_builtin_bound(builtin_bound, self_ty) {
                 Ok(trait_ref) => Some(trait_ref.to_predicate()),
@@ -821,8 +819,8 @@ impl CLike for BuiltinBound {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn try_add_builtin_trait(&self,
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn try_add_builtin_trait(self,
                                  trait_def_id: DefId,
                                  builtin_bounds: &mut EnumSet<BuiltinBound>)
                                  -> bool
@@ -886,7 +884,7 @@ impl Region {
 }
 
 // Type utilities
-impl<'tcx> TyS<'tcx> {
+impl<'a, 'tcx> TyS<'tcx> {
     pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
         match self.sty {
             ty::TyParam(ref d) => Some(d.clone()),
@@ -901,7 +899,7 @@ impl<'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn is_empty(&self, _cx: &TyCtxt) -> bool {
+    pub fn is_empty(&self, _cx: TyCtxt) -> bool {
         // FIXME(#24885): be smarter here
         match self.sty {
             TyEnum(def, _) | TyStruct(def, _) => def.is_empty(),
@@ -973,7 +971,7 @@ impl<'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn sequence_element_type(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+    pub fn sequence_element_type(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         match self.sty {
             TyArray(ty, _) | TySlice(ty) => ty,
             TyStr => tcx.mk_mach_uint(ast::UintTy::U8),
@@ -981,7 +979,7 @@ impl<'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn simd_type(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+    pub fn simd_type(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         match self.sty {
             TyStruct(def, substs) => {
                 def.struct_variant().fields[0].ty(tcx, substs)
@@ -990,7 +988,7 @@ impl<'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn simd_size(&self, _cx: &TyCtxt) -> usize {
+    pub fn simd_size(&self, _cx: TyCtxt) -> usize {
         match self.sty {
             TyStruct(def, _) => def.struct_variant().fields.len(),
             _ => bug!("simd_size called on invalid type")
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index dd547da59e9..bb6d06d49e4 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -36,7 +36,7 @@ pub struct Substs<'tcx> {
     pub regions: VecPerParamSpace<ty::Region>,
 }
 
-impl<'tcx> Substs<'tcx> {
+impl<'a, 'tcx> Substs<'tcx> {
     pub fn new(t: VecPerParamSpace<Ty<'tcx>>,
                r: VecPerParamSpace<ty::Region>)
                -> Substs<'tcx>
@@ -122,7 +122,7 @@ impl<'tcx> Substs<'tcx> {
     }
 
     /// Creates a trait-ref out of this substs, ignoring the FnSpace substs
-    pub fn to_trait_ref(&self, tcx: &TyCtxt<'tcx>, trait_id: DefId)
+    pub fn to_trait_ref(&self, tcx: TyCtxt<'a, 'tcx>, trait_id: DefId)
                         -> ty::TraitRef<'tcx> {
         let Substs { mut types, mut regions } = self.clone();
         types.truncate(FnSpace, 0);
@@ -532,22 +532,21 @@ impl<'a,T> IntoIterator for &'a VecPerParamSpace<T> {
 // there is more information available (for better errors).
 
 pub trait Subst<'tcx> : Sized {
-    fn subst(&self, tcx: &TyCtxt<'tcx>, substs: &Substs<'tcx>) -> Self {
+    fn subst<'a>(&self, tcx: TyCtxt<'a, 'tcx>, substs: &Substs<'tcx>) -> Self {
         self.subst_spanned(tcx, substs, None)
     }
 
-    fn subst_spanned(&self, tcx: &TyCtxt<'tcx>,
-                     substs: &Substs<'tcx>,
-                     span: Option<Span>)
-                     -> Self;
+    fn subst_spanned<'a>(&self, tcx: TyCtxt<'a, 'tcx>,
+                         substs: &Substs<'tcx>,
+                         span: Option<Span>)
+                         -> Self;
 }
 
 impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
-    fn subst_spanned(&self,
-                     tcx: &TyCtxt<'tcx>,
-                     substs: &Substs<'tcx>,
-                     span: Option<Span>)
-                     -> T
+    fn subst_spanned<'a>(&self, tcx: TyCtxt<'a, 'tcx>,
+                         substs: &Substs<'tcx>,
+                         span: Option<Span>)
+                         -> T
     {
         let mut folder = SubstFolder { tcx: tcx,
                                        substs: substs,
@@ -563,7 +562,7 @@ impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
 // The actual substitution engine itself is a type folder.
 
 struct SubstFolder<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     substs: &'a Substs<'tcx>,
 
     // The location for which the substitution is performed, if available.
@@ -580,7 +579,7 @@ struct SubstFolder<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> { self.tcx }
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.tcx }
 
     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
         self.region_binders_passed += 1;
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs
index f194afaa817..1b9f4909e2b 100644
--- a/src/librustc/ty/trait_def.rs
+++ b/src/librustc/ty/trait_def.rs
@@ -73,7 +73,7 @@ pub struct TraitDef<'tcx> {
     pub flags: Cell<TraitFlags>
 }
 
-impl<'tcx> TraitDef<'tcx> {
+impl<'a, 'tcx> TraitDef<'tcx> {
     pub fn new(unsafety: hir::Unsafety,
                paren_sugar: bool,
                generics: ty::Generics<'tcx>,
@@ -117,19 +117,18 @@ impl<'tcx> TraitDef<'tcx> {
         );
     }
 
-    fn write_trait_impls(&self, tcx: &TyCtxt<'tcx>) {
+    fn write_trait_impls(&self, tcx: TyCtxt<'a, 'tcx>) {
         tcx.dep_graph.write(DepNode::TraitImpls(self.trait_ref.def_id));
     }
 
-    fn read_trait_impls(&self, tcx: &TyCtxt<'tcx>) {
+    fn read_trait_impls(&self, tcx: TyCtxt<'a, 'tcx>) {
         tcx.dep_graph.read(DepNode::TraitImpls(self.trait_ref.def_id));
     }
 
     /// Records a basic trait-to-implementation mapping.
     ///
     /// Returns `true` iff the impl has not previously been recorded.
-    fn record_impl(&self,
-                   tcx: &TyCtxt<'tcx>,
+    fn record_impl(&self, tcx: TyCtxt<'a, 'tcx>,
                    impl_def_id: DefId,
                    impl_trait_ref: TraitRef<'tcx>)
                    -> bool {
@@ -164,8 +163,7 @@ impl<'tcx> TraitDef<'tcx> {
     }
 
     /// Records a trait-to-implementation mapping for a crate-local impl.
-    pub fn record_local_impl(&self,
-                             tcx: &TyCtxt<'tcx>,
+    pub fn record_local_impl(&self, tcx: TyCtxt<'a, 'tcx>,
                              impl_def_id: DefId,
                              impl_trait_ref: TraitRef<'tcx>) {
         assert!(impl_def_id.is_local());
@@ -178,8 +176,7 @@ impl<'tcx> TraitDef<'tcx> {
     /// The `parent_impl` is the immediately-less-specialized impl, or the
     /// trait's def ID if the impl is not a specialization -- information that
     /// should be pulled from the metadata.
-    pub fn record_remote_impl(&self,
-                              tcx: &TyCtxt<'tcx>,
+    pub fn record_remote_impl(&self, tcx: TyCtxt<'a, 'tcx>,
                               impl_def_id: DefId,
                               impl_trait_ref: TraitRef<'tcx>,
                               parent_impl: DefId) {
@@ -197,22 +194,21 @@ impl<'tcx> TraitDef<'tcx> {
     /// Adds a local impl into the specialization graph, returning an error with
     /// overlap information if the impl overlaps but does not specialize an
     /// existing impl.
-    pub fn add_impl_for_specialization<'a>(&self,
-                                           tcx: &'a TyCtxt<'tcx>,
-                                           impl_def_id: DefId)
-                                           -> Result<(), traits::Overlap<'a, 'tcx>> {
+    pub fn add_impl_for_specialization(&self, tcx: TyCtxt<'a, 'tcx>,
+                                       impl_def_id: DefId)
+                                       -> Result<(), traits::Overlap<'a, 'tcx>> {
         assert!(impl_def_id.is_local());
 
         self.specialization_graph.borrow_mut()
             .insert(tcx, impl_def_id)
     }
 
-    pub fn ancestors<'a>(&'a self, of_impl: DefId) -> specialization_graph::Ancestors<'a, 'tcx> {
+    pub fn ancestors(&'a self, of_impl: DefId) -> specialization_graph::Ancestors<'a, 'tcx> {
         specialization_graph::ancestors(self, of_impl)
     }
 
-        pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &TyCtxt<'tcx>, mut f: F)  {
-            self.read_trait_impls(tcx);
+    pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: TyCtxt<'a, 'tcx>, mut f: F) {
+        self.read_trait_impls(tcx);
         tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
 
         for &impl_def_id in self.blanket_impls.borrow().iter() {
@@ -229,7 +225,7 @@ impl<'tcx> TraitDef<'tcx> {
     /// Iterate over every impl that could possibly match the
     /// self-type `self_ty`.
     pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
-                                                   tcx: &TyCtxt<'tcx>,
+                                                   tcx: TyCtxt<'a, 'tcx>,
                                                    self_ty: Ty<'tcx>,
                                                    mut f: F)
     {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index a18fdebbaa9..70f03d3c8e8 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -32,14 +32,14 @@ use syntax::codemap::Span;
 use hir;
 
 pub trait IntTypeExt {
-    fn to_ty<'tcx>(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx>;
-    fn disr_incr(&self, tcx: &TyCtxt, val: Option<Disr>) -> Option<Disr>;
+    fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx>;
+    fn disr_incr(&self, tcx: TyCtxt, val: Option<Disr>) -> Option<Disr>;
     fn assert_ty_matches(&self, val: Disr);
-    fn initial_discriminant(&self, tcx: &TyCtxt) -> Disr;
+    fn initial_discriminant(&self, tcx: TyCtxt) -> Disr;
 }
 
 impl IntTypeExt for attr::IntType {
-    fn to_ty<'tcx>(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx> {
+    fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx>) -> Ty<'tcx> {
         match *self {
             SignedInt(ast::IntTy::I8)      => tcx.types.i8,
             SignedInt(ast::IntTy::I16)     => tcx.types.i16,
@@ -54,7 +54,7 @@ impl IntTypeExt for attr::IntType {
         }
     }
 
-    fn initial_discriminant(&self, tcx: &TyCtxt) -> Disr {
+    fn initial_discriminant(&self, tcx: TyCtxt) -> Disr {
         match *self {
             SignedInt(ast::IntTy::I8)    => ConstInt::I8(0),
             SignedInt(ast::IntTy::I16)   => ConstInt::I16(0),
@@ -93,7 +93,7 @@ impl IntTypeExt for attr::IntType {
         }
     }
 
-    fn disr_incr(&self, tcx: &TyCtxt, val: Option<Disr>) -> Option<Disr> {
+    fn disr_incr(&self, tcx: TyCtxt, val: Option<Disr>) -> Option<Disr> {
         if let Some(val) = val {
             self.assert_ty_matches(val);
             (val + ConstInt::Infer(1)).ok()
@@ -170,18 +170,18 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn pat_contains_ref_binding(&self, pat: &hir::Pat) -> Option<hir::Mutability> {
+impl<'a, 'tcx> TyCtxt<'a, 'tcx> {
+    pub fn pat_contains_ref_binding(self, pat: &hir::Pat) -> Option<hir::Mutability> {
         pat_util::pat_contains_ref_binding(&self.def_map, pat)
     }
 
-    pub fn arm_contains_ref_binding(&self, arm: &hir::Arm) -> Option<hir::Mutability> {
+    pub fn arm_contains_ref_binding(self, arm: &hir::Arm) -> Option<hir::Mutability> {
         pat_util::arm_contains_ref_binding(&self.def_map, arm)
     }
 
     /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
     /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
-    pub fn positional_element_ty(&self,
+    pub fn positional_element_ty(self,
                                  ty: Ty<'tcx>,
                                  i: usize,
                                  variant: Option<DefId>) -> Option<Ty<'tcx>> {
@@ -203,7 +203,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Returns the type of element at field `n` in struct or struct-like type `t`.
     /// For an enum `t`, `variant` must be some def id.
-    pub fn named_element_ty(&self,
+    pub fn named_element_ty(self,
                             ty: Ty<'tcx>,
                             n: Name,
                             variant: Option<DefId>) -> Option<Ty<'tcx>> {
@@ -221,7 +221,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns the IntType representation.
     /// This used to ensure `int_ty` doesn't contain `usize` and `isize`
     /// by converting them to their actual types. That doesn't happen anymore.
-    pub fn enum_repr_type(&self, opt_hint: Option<&attr::ReprAttr>) -> attr::IntType {
+    pub fn enum_repr_type(self, opt_hint: Option<&attr::ReprAttr>) -> attr::IntType {
         match opt_hint {
             // Feed in the given type
             Some(&attr::ReprInt(_, int_t)) => int_t,
@@ -236,7 +236,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns the deeply last field of nested structures, or the same type,
     /// if not a structure at all. Corresponds to the only possible unsized
     /// field, and its type can be used to determine unsizing strategy.
-    pub fn struct_tail(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn struct_tail(self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
         while let TyStruct(def, substs) = ty.sty {
             match def.struct_variant().fields.last() {
                 Some(f) => ty = f.ty(self, substs),
@@ -251,7 +251,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// structure definitions.
     /// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
     /// whereas struct_tail produces `T`, and `Trait`, respectively.
-    pub fn struct_lockstep_tails(&self,
+    pub fn struct_lockstep_tails(self,
                                  source: Ty<'tcx>,
                                  target: Ty<'tcx>)
                                  -> (Ty<'tcx>, Ty<'tcx>) {
@@ -286,7 +286,7 @@ impl<'tcx> TyCtxt<'tcx> {
     ///
     /// Requires that trait definitions have been processed so that we can
     /// elaborate predicates and walk supertraits.
-    pub fn required_region_bounds(&self,
+    pub fn required_region_bounds(self,
                                   erased_self_ty: Ty<'tcx>,
                                   predicates: Vec<ty::Predicate<'tcx>>)
                                   -> Vec<ty::Region>    {
@@ -332,12 +332,12 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Creates a hash of the type `Ty` which will be the same no matter what crate
     /// context it's calculated within. This is used by the `type_id` intrinsic.
-    pub fn hash_crate_independent(&self, ty: Ty<'tcx>, svh: &Svh) -> u64 {
+    pub fn hash_crate_independent(self, ty: Ty<'tcx>, svh: &Svh) -> u64 {
         let mut state = SipHasher::new();
         helper(self, ty, svh, &mut state);
         return state.finish();
 
-        fn helper<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>, svh: &Svh,
+        fn helper<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, ty: Ty<'tcx>, svh: &Svh,
                         state: &mut SipHasher) {
             macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
             macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
@@ -487,7 +487,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// `adt` that do not strictly outlive the adt value itself.
     /// (This allows programs to make cyclic structures without
     /// resorting to unasfe means; see RFCs 769 and 1238).
-    pub fn is_adt_dtorck(&self, adt: ty::AdtDef<'tcx>) -> bool {
+    pub fn is_adt_dtorck(self, adt: ty::AdtDef<'tcx>) -> bool {
         let dtor_method = match adt.destructor() {
             Some(dtor) => dtor,
             None => return false
@@ -506,11 +506,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 }
 
-impl<'tcx> ty::TyS<'tcx> {
-    fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
-                       bound: ty::BuiltinBound,
-                       span: Span)
-                       -> bool
+impl<'a, 'tcx> ty::TyS<'tcx> {
+    fn impls_bound(&'tcx self, param_env: &ParameterEnvironment<'a, 'tcx>,
+                   bound: ty::BuiltinBound,
+                   span: Span)
+                   -> bool
     {
         let tcx = param_env.tcx;
         let infcx = InferCtxt::new(tcx, &tcx.tables, Some(param_env.clone()),
@@ -526,8 +526,8 @@ impl<'tcx> ty::TyS<'tcx> {
     }
 
     // FIXME (@jroesch): I made this public to use it, not sure if should be private
-    pub fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
-                           span: Span) -> bool {
+    pub fn moves_by_default(&'tcx self, param_env: &ParameterEnvironment<'a, 'tcx>,
+                            span: Span) -> bool {
         if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
             return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
         }
@@ -562,8 +562,8 @@ impl<'tcx> ty::TyS<'tcx> {
     }
 
     #[inline]
-    pub fn is_sized<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
-                        span: Span) -> bool
+    pub fn is_sized(&'tcx self, param_env: &ParameterEnvironment<'a, 'tcx>,
+                    span: Span) -> bool
     {
         if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
             return self.flags.get().intersects(TypeFlags::IS_SIZED);
@@ -572,8 +572,8 @@ impl<'tcx> ty::TyS<'tcx> {
         self.is_sized_uncached(param_env, span)
     }
 
-    fn is_sized_uncached<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
-                             span: Span) -> bool {
+    fn is_sized_uncached(&'tcx self, param_env: &ParameterEnvironment<'a, 'tcx>,
+                         span: Span) -> bool {
         assert!(!self.needs_infer());
 
         // Fast-path for primitive types
@@ -600,8 +600,8 @@ impl<'tcx> ty::TyS<'tcx> {
     }
 
     #[inline]
-    pub fn layout<'a>(&'tcx self, infcx: &InferCtxt<'a, 'tcx>)
-                      -> Result<&'tcx Layout, LayoutError<'tcx>> {
+    pub fn layout(&'tcx self, infcx: &InferCtxt<'a, 'tcx>)
+                  -> Result<&'tcx Layout, LayoutError<'tcx>> {
         let can_cache = !self.has_param_types() && !self.has_self_ty();
         if can_cache {
             if let Some(&cached) = infcx.tcx.layout_cache.borrow().get(&self) {
@@ -620,21 +620,22 @@ impl<'tcx> ty::TyS<'tcx> {
 
     /// Check whether a type is representable. This means it cannot contain unboxed
     /// structural recursion. This check is needed for structs and enums.
-    pub fn is_representable(&'tcx self, tcx: &TyCtxt<'tcx>, sp: Span) -> Representability {
+    pub fn is_representable(&'tcx self, tcx: TyCtxt<'a, 'tcx>, sp: Span) -> Representability {
 
         // Iterate until something non-representable is found
-        fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(tcx: &TyCtxt<'tcx>,
-                                                                    sp: Span,
-                                                                    seen: &mut Vec<Ty<'tcx>>,
-                                                                    iter: It)
-                                                                    -> Representability {
+        fn find_nonrepresentable<'a, 'tcx, It>(tcx: TyCtxt<'a, 'tcx>,
+                                               sp: Span,
+                                               seen: &mut Vec<Ty<'tcx>>,
+                                               iter: It)
+                                               -> Representability
+        where It: Iterator<Item=Ty<'tcx>> {
             iter.fold(Representability::Representable,
                       |r, ty| cmp::max(r, is_type_structurally_recursive(tcx, sp, seen, ty)))
         }
 
-        fn are_inner_types_recursive<'tcx>(tcx: &TyCtxt<'tcx>, sp: Span,
-                                           seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
-                                           -> Representability {
+        fn are_inner_types_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, sp: Span,
+                                               seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
+                                               -> Representability {
             match ty.sty {
                 TyTuple(ref ts) => {
                     find_nonrepresentable(tcx, sp, seen, ts.iter().cloned())
@@ -691,10 +692,10 @@ impl<'tcx> ty::TyS<'tcx> {
 
         // Does the type `ty` directly (without indirection through a pointer)
         // contain any types on stack `seen`?
-        fn is_type_structurally_recursive<'tcx>(tcx: &TyCtxt<'tcx>,
-                                                sp: Span,
-                                                seen: &mut Vec<Ty<'tcx>>,
-                                                ty: Ty<'tcx>) -> Representability {
+        fn is_type_structurally_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                                    sp: Span,
+                                                    seen: &mut Vec<Ty<'tcx>>,
+                                                    ty: Ty<'tcx>) -> Representability {
             debug!("is_type_structurally_recursive: {:?}", ty);
 
             match ty.sty {
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index c7cd900aa9a..7fc1f159288 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -525,8 +525,8 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> {
 /// they declare `trait SomeTrait : 'static`, for example, then
 /// `'static` would appear in the list. The hard work is done by
 /// `ty::required_region_bounds`, see that for more information.
-pub fn object_region_bounds<'tcx>(
-    tcx: &TyCtxt<'tcx>,
+pub fn object_region_bounds<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx>,
     principal: &ty::PolyTraitRef<'tcx>,
     others: ty::BuiltinBounds)
     -> Vec<ty::Region>
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 728306b25dd..56c0fc248af 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -68,12 +68,12 @@ pub enum Ns {
     Value
 }
 
-fn number_of_supplied_defaults<'tcx, GG>(tcx: &ty::TyCtxt<'tcx>,
-                                         substs: &subst::Substs,
-                                         space: subst::ParamSpace,
-                                         get_generics: GG)
-                                         -> usize
-    where GG: FnOnce(&TyCtxt<'tcx>) -> ty::Generics<'tcx>
+fn number_of_supplied_defaults<'a, 'tcx, GG>(tcx: TyCtxt<'a, 'tcx>,
+                                             substs: &subst::Substs,
+                                             space: subst::ParamSpace,
+                                             get_generics: GG)
+                                             -> usize
+    where GG: FnOnce(TyCtxt<'a, 'tcx>) -> ty::Generics<'tcx>
 {
     let generics = get_generics(tcx);
 
@@ -114,7 +114,7 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
                          projections: &[ty::ProjectionPredicate],
                          get_generics: GG)
                          -> fmt::Result
-    where GG: for<'tcx> FnOnce(&TyCtxt<'tcx>) -> ty::Generics<'tcx>
+    where GG: for<'a, 'tcx> FnOnce(TyCtxt<'a, 'tcx>) -> ty::Generics<'tcx>
 {
     if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) {
         write!(f, "<{} as ", self_ty)?;
@@ -230,10 +230,10 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
     Ok(())
 }
 
-fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
-                         tcx: &TyCtxt<'tcx>,
-                         original: &ty::Binder<T>,
-                         lifted: Option<ty::Binder<U>>) -> fmt::Result
+fn in_binder<'a, 'tcx, T, U>(f: &mut fmt::Formatter,
+                             tcx: TyCtxt<'a, 'tcx>,
+                             original: &ty::Binder<T>,
+                             lifted: Option<ty::Binder<U>>) -> fmt::Result
     where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
 {
     // Replace any anonymous late-bound regions with named
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 66fac4ed228..bec645c6ae0 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -233,7 +233,7 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
 }
 
 impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
-    pub fn tcx(&self) -> &'a TyCtxt<'tcx> { self.bccx.tcx }
+    pub fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.bccx.tcx }
 
     pub fn each_issued_loan<F>(&self, node: ast::NodeId, mut op: F) -> bool where
         F: FnMut(&Loan<'tcx>) -> bool,
diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs
index 0b1c4efa9ac..4a6bc411b91 100644
--- a/src/librustc_borrowck/borrowck/fragments.rs
+++ b/src/librustc_borrowck/borrowck/fragments.rs
@@ -199,10 +199,10 @@ impl FragmentSets {
     }
 }
 
-pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
-                                       tcx: &TyCtxt<'tcx>,
-                                       sp: Span,
-                                       id: ast::NodeId) {
+pub fn instrument_move_fragments<'a, 'tcx>(this: &MoveData<'tcx>,
+                                           tcx: TyCtxt<'a, 'tcx>,
+                                           sp: Span,
+                                           id: ast::NodeId) {
     let span_err = tcx.map.attrs(id).iter()
                           .any(|a| a.check_name("rustc_move_fragments"));
     let print = tcx.sess.opts.debugging_opts.print_move_fragments;
@@ -245,7 +245,7 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
 ///
 /// Note: "left-over fragments" means paths that were not directly referenced in moves nor
 /// assignments, but must nonetheless be tracked as potential drop obligations.
-pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &TyCtxt<'tcx>) {
+pub fn fixup_fragment_sets<'a, 'tcx>(this: &MoveData<'tcx>, tcx: TyCtxt<'a, 'tcx>) {
 
     let mut fragments = this.fragments.borrow_mut();
 
@@ -346,11 +346,11 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &TyCtxt<'tcx>) {
 /// Adds all of the precisely-tracked siblings of `lp` as potential move paths of interest. For
 /// example, if `lp` represents `s.x.j`, then adds moves paths for `s.x.i` and `s.x.k`, the
 /// siblings of `s.x.j`.
-fn add_fragment_siblings<'tcx>(this: &MoveData<'tcx>,
-                               tcx: &TyCtxt<'tcx>,
-                               gathered_fragments: &mut Vec<Fragment>,
-                               lp: Rc<LoanPath<'tcx>>,
-                               origin_id: Option<ast::NodeId>) {
+fn add_fragment_siblings<'a, 'tcx>(this: &MoveData<'tcx>,
+                                   tcx: TyCtxt<'a, 'tcx>,
+                                   gathered_fragments: &mut Vec<Fragment>,
+                                   lp: Rc<LoanPath<'tcx>>,
+                                   origin_id: Option<ast::NodeId>) {
     match lp.kind {
         LpVar(_) | LpUpvar(..) => {} // Local variables have no siblings.
 
@@ -405,16 +405,16 @@ fn add_fragment_siblings<'tcx>(this: &MoveData<'tcx>,
 
 /// We have determined that `origin_lp` destructures to LpExtend(parent, original_field_name).
 /// Based on this, add move paths for all of the siblings of `origin_lp`.
-fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
-                                             tcx: &TyCtxt<'tcx>,
-                                             gathered_fragments: &mut Vec<Fragment>,
-                                             parent_lp: &Rc<LoanPath<'tcx>>,
-                                             mc: mc::MutabilityCategory,
-                                             origin_field_name: &mc::FieldName,
-                                             origin_lp: &Rc<LoanPath<'tcx>>,
-                                             origin_id: Option<ast::NodeId>,
-                                             enum_variant_info: Option<(DefId,
-                                                                        Rc<LoanPath<'tcx>>)>) {
+fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>,
+                                                 tcx: TyCtxt<'a, 'tcx>,
+                                                 gathered_fragments: &mut Vec<Fragment>,
+                                                 parent_lp: &Rc<LoanPath<'tcx>>,
+                                                 mc: mc::MutabilityCategory,
+                                                 origin_field_name: &mc::FieldName,
+                                                 origin_lp: &Rc<LoanPath<'tcx>>,
+                                                 origin_id: Option<ast::NodeId>,
+                                                 enum_variant_info: Option<(DefId,
+                                                    Rc<LoanPath<'tcx>>)>) {
     let parent_ty = parent_lp.to_type();
 
     let mut add_fragment_sibling_local = |field_name, variant_did| {
@@ -504,14 +504,15 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
 
 /// Adds the single sibling `LpExtend(parent, new_field_name)` of `origin_lp` (the original
 /// loan-path).
-fn add_fragment_sibling_core<'tcx>(this: &MoveData<'tcx>,
-                                   tcx: &TyCtxt<'tcx>,
-                                   gathered_fragments: &mut Vec<Fragment>,
-                                   parent: Rc<LoanPath<'tcx>>,
-                                   mc: mc::MutabilityCategory,
-                                   new_field_name: mc::FieldName,
-                                   origin_lp: &Rc<LoanPath<'tcx>>,
-                                   enum_variant_did: Option<DefId>) -> MovePathIndex {
+fn add_fragment_sibling_core<'a, 'tcx>(this: &MoveData<'tcx>,
+                                       tcx: TyCtxt<'a, 'tcx>,
+                                       gathered_fragments: &mut Vec<Fragment>,
+                                       parent: Rc<LoanPath<'tcx>>,
+                                       mc: mc::MutabilityCategory,
+                                       new_field_name: mc::FieldName,
+                                       origin_lp: &Rc<LoanPath<'tcx>>,
+                                       enum_variant_did: Option<DefId>)
+                                       -> MovePathIndex {
     let opt_variant_did = match parent.kind {
         LpDowncast(_, variant_did) => Some(variant_did),
         LpVar(..) | LpUpvar(..) | LpExtend(..) => enum_variant_did,
diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
index 21787505b8a..ef2fb9e4fc0 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
@@ -255,7 +255,7 @@ fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
-    pub fn tcx(&self) -> &'a TyCtxt<'tcx> { self.bccx.tcx }
+    pub fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.bccx.tcx }
 
     /// Guarantees that `cmt` is assignable, or reports an error.
     fn guarantee_assignment_valid(&mut self,
diff --git a/src/librustc_borrowck/borrowck/mir/dataflow.rs b/src/librustc_borrowck/borrowck/mir/dataflow.rs
index a8176c060a1..de47fe86ed2 100644
--- a/src/librustc_borrowck/borrowck/mir/dataflow.rs
+++ b/src/librustc_borrowck/borrowck/mir/dataflow.rs
@@ -458,8 +458,8 @@ impl<D: BitDenotation> DataflowState<D> {
 }
 
 
-impl<'tcx> DataflowState<MoveData<'tcx>> {
-    pub fn new_move_analysis(mir: &Mir<'tcx>, tcx: &TyCtxt<'tcx>) -> Self {
+impl<'a, 'tcx> DataflowState<MoveData<'tcx>> {
+    pub fn new_move_analysis(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx>) -> Self {
         let move_data = MoveData::gather_moves(mir, tcx);
         DataflowState::new(mir, move_data)
     }
diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
index 2b1b743afe9..2b835124fa1 100644
--- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
@@ -482,8 +482,8 @@ impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
     }
 }
 
-impl<'tcx> MoveData<'tcx> {
-    pub fn gather_moves(mir: &Mir<'tcx>, tcx: &TyCtxt<'tcx>) -> Self {
+impl<'a, 'tcx> MoveData<'tcx> {
+    pub fn gather_moves(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx>) -> Self {
         gather_moves(mir, tcx)
     }
 }
@@ -494,7 +494,7 @@ enum StmtKind {
     Aggregate, Drop, CallFn, CallArg, Return,
 }
 
-fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &TyCtxt<'tcx>) -> MoveData<'tcx> {
+fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx>) -> MoveData<'tcx> {
     use self::StmtKind as SK;
 
     let bbs = mir.all_basic_blocks();
@@ -667,7 +667,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &TyCtxt<'tcx>) -> MoveData<'tcx> {
 }
 
 struct BlockContext<'b, 'a: 'b, 'tcx: 'a> {
-    tcx: &'b TyCtxt<'tcx>,
+    tcx: TyCtxt<'b, 'tcx>,
     moves: &'b mut Vec<MoveOut>,
     builder: MovePathDataBuilder<'a, 'tcx>,
     path_map: &'b mut Vec<Vec<MoveOutIndex>>,
diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs
index 672faea58f5..bec5ae03d3d 100644
--- a/src/librustc_borrowck/borrowck/mir/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/mod.rs
@@ -46,11 +46,11 @@ pub fn borrowck_mir<'b, 'a: 'b, 'tcx: 'a>(
     }
 
     let mut mbcx = MirBorrowckCtxt {
+        flow_state: DataflowState::new_move_analysis(mir, bcx.tcx),
         bcx: bcx,
         mir: mir,
         node_id: id,
         attributes: attributes,
-        flow_state: DataflowState::new_move_analysis(mir, bcx.tcx),
     };
 
     for bb in mir.all_basic_blocks() {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 8518a27bd2c..c9046374464 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -100,7 +100,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
     }
 }
 
-pub fn check_crate<'tcx>(tcx: &TyCtxt<'tcx>, mir_map: &MirMap<'tcx>) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, mir_map: &MirMap<'tcx>) {
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
         mir_map: Some(mir_map),
@@ -244,7 +244,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
 /// Accessor for introspective clients inspecting `AnalysisData` and
 /// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
 pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     mir_map: Option<&'a MirMap<'tcx>>,
     fn_parts: FnParts<'a>,
     cfg: &cfg::CFG)
@@ -278,7 +278,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
 // Type definitions
 
 pub struct BorrowckCtxt<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 
     // Hacky. As we visit various fns, we have to load up the
     // free-region map for each one. This map is computed by during
@@ -412,7 +412,7 @@ pub enum LoanPathElem {
 }
 
 pub fn closure_to_block(closure_id: ast::NodeId,
-                        tcx: &TyCtxt) -> ast::NodeId {
+                        tcx: TyCtxt) -> ast::NodeId {
     match tcx.map.get(closure_id) {
         hir_map::NodeExpr(expr) => match expr.node {
             hir::ExprClosure(_, _, ref block, _) => {
@@ -426,8 +426,8 @@ pub fn closure_to_block(closure_id: ast::NodeId,
     }
 }
 
-impl<'tcx> LoanPath<'tcx> {
-    pub fn kill_scope(&self, tcx: &TyCtxt<'tcx>) -> region::CodeExtent {
+impl<'a, 'tcx> LoanPath<'tcx> {
+    pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx>) -> region::CodeExtent {
         match self.kind {
             LpVar(local_id) => tcx.region_maps.var_scope(local_id),
             LpUpvar(upvar_id) => {
@@ -1109,7 +1109,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
     }
 }
 
-fn statement_scope_span(tcx: &TyCtxt, region: ty::Region) -> Option<Span> {
+fn statement_scope_span(tcx: TyCtxt, region: ty::Region) -> Option<Span> {
     match region {
         ty::ReScope(scope) => {
             match tcx.map.find(scope.node_id(&tcx.region_maps)) {
diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs
index 80e408e9a6e..0f9e490322a 100644
--- a/src/librustc_borrowck/borrowck/move_data.rs
+++ b/src/librustc_borrowck/borrowck/move_data.rs
@@ -212,7 +212,7 @@ fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
     }
 }
 
-impl<'tcx> MoveData<'tcx> {
+impl<'a, 'tcx> MoveData<'tcx> {
     pub fn new() -> MoveData<'tcx> {
         MoveData {
             paths: RefCell::new(Vec::new()),
@@ -272,8 +272,7 @@ impl<'tcx> MoveData<'tcx> {
 
     /// Returns the existing move path index for `lp`, if any, and otherwise adds a new index for
     /// `lp` and any of its base paths that do not yet have an index.
-    pub fn move_path(&self,
-                     tcx: &TyCtxt<'tcx>,
+    pub fn move_path(&self, tcx: TyCtxt<'a, 'tcx>,
                      lp: Rc<LoanPath<'tcx>>) -> MovePathIndex {
         match self.path_map.borrow().get(&lp) {
             Some(&index) => {
@@ -364,8 +363,7 @@ impl<'tcx> MoveData<'tcx> {
     }
 
     /// Adds a new move entry for a move of `lp` that occurs at location `id` with kind `kind`.
-    pub fn add_move(&self,
-                    tcx: &TyCtxt<'tcx>,
+    pub fn add_move(&self, tcx: TyCtxt<'a, 'tcx>,
                     lp: Rc<LoanPath<'tcx>>,
                     id: ast::NodeId,
                     kind: MoveKind) {
@@ -392,8 +390,7 @@ impl<'tcx> MoveData<'tcx> {
 
     /// Adds a new record for an assignment to `lp` that occurs at location `id` with the given
     /// `span`.
-    pub fn add_assignment(&self,
-                          tcx: &TyCtxt<'tcx>,
+    pub fn add_assignment(&self, tcx: TyCtxt<'a, 'tcx>,
                           lp: Rc<LoanPath<'tcx>>,
                           assign_id: ast::NodeId,
                           span: Span,
@@ -437,8 +434,7 @@ impl<'tcx> MoveData<'tcx> {
     /// variant `lp`, that occurs at location `pattern_id`.  (One
     /// should be able to recover the span info from the
     /// `pattern_id` and the ast_map, I think.)
-    pub fn add_variant_match(&self,
-                             tcx: &TyCtxt<'tcx>,
+    pub fn add_variant_match(&self, tcx: TyCtxt<'a, 'tcx>,
                              lp: Rc<LoanPath<'tcx>>,
                              pattern_id: ast::NodeId,
                              base_lp: Rc<LoanPath<'tcx>>,
@@ -461,7 +457,7 @@ impl<'tcx> MoveData<'tcx> {
         self.variant_matches.borrow_mut().push(variant_match);
     }
 
-    fn fixup_fragment_sets(&self, tcx: &TyCtxt<'tcx>) {
+    fn fixup_fragment_sets(&self, tcx: TyCtxt<'a, 'tcx>) {
         fragments::fixup_fragment_sets(self, tcx)
     }
 
@@ -470,8 +466,7 @@ impl<'tcx> MoveData<'tcx> {
     /// Moves are generated by moves and killed by assignments and
     /// scoping. Assignments are generated by assignment to variables and
     /// killed by scoping. See `README.md` for more details.
-    fn add_gen_kills(&self,
-                     tcx: &TyCtxt<'tcx>,
+    fn add_gen_kills(&self, tcx: TyCtxt<'a, 'tcx>,
                      dfcx_moves: &mut MoveDataFlow,
                      dfcx_assign: &mut AssignDataFlow) {
         for (i, the_move) in self.moves.borrow().iter().enumerate() {
@@ -600,7 +595,7 @@ impl<'tcx> MoveData<'tcx> {
 
 impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
     pub fn new(move_data: MoveData<'tcx>,
-               tcx: &'a TyCtxt<'tcx>,
+               tcx: TyCtxt<'a, 'tcx>,
                cfg: &cfg::CFG,
                id_range: IdRange,
                decl: &hir::FnDecl,
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs
index 01cda88056f..4a88b8c7d91 100644
--- a/src/librustc_const_eval/check_match.rs
+++ b/src/librustc_const_eval/check_match.rs
@@ -106,7 +106,7 @@ impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
 
 //NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv
 pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
     pub param_env: ParameterEnvironment<'a, 'tcx>,
 }
 
@@ -153,7 +153,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt) {
+pub fn check_crate(tcx: TyCtxt) {
     tcx.visit_all_items_in_krate(DepNode::MatchCheck, &mut MatchCheckCtxt {
         tcx: tcx,
         param_env: tcx.empty_parameter_environment(),
@@ -455,13 +455,13 @@ fn const_val_to_expr(value: &ConstVal) -> P<hir::Expr> {
 }
 
 pub struct StaticInliner<'a, 'tcx: 'a> {
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
     pub failed: bool,
     pub renaming_map: Option<&'a mut FnvHashMap<(NodeId, Span), NodeId>>,
 }
 
 impl<'a, 'tcx> StaticInliner<'a, 'tcx> {
-    pub fn new<'b>(tcx: &'b TyCtxt<'tcx>,
+    pub fn new<'b>(tcx: TyCtxt<'b, 'tcx>,
                    renaming_map: Option<&'b mut FnvHashMap<(NodeId, Span), NodeId>>)
                    -> StaticInliner<'b, 'tcx> {
         StaticInliner {
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index ba29a6703e5..445cb229bdb 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -54,10 +54,10 @@ macro_rules! math {
     }
 }
 
-fn lookup_variant_by_id<'a>(tcx: &'a ty::TyCtxt,
-                            enum_def: DefId,
-                            variant_def: DefId)
-                            -> Option<&'a Expr> {
+fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                  enum_def: DefId,
+                                  variant_def: DefId)
+                                  -> Option<&'tcx Expr> {
     fn variant_expr<'a>(variants: &'a [hir::Variant], id: ast::NodeId)
                         -> Option<&'a Expr> {
         for variant in variants {
@@ -90,7 +90,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::TyCtxt,
 ///
 /// `substs` is optional and is used for associated constants.
 /// This generally happens in late/trans const evaluation.
-pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
+pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx>,
                                         def_id: DefId,
                                         substs: Option<subst::Substs<'tcx>>)
                                         -> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)> {
@@ -182,7 +182,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
     }
 }
 
-fn inline_const_fn_from_external_crate(tcx: &TyCtxt, def_id: DefId)
+fn inline_const_fn_from_external_crate(tcx: TyCtxt, def_id: DefId)
                                        -> Option<ast::NodeId> {
     match tcx.extern_const_fns.borrow().get(&def_id) {
         Some(&ast::DUMMY_NODE_ID) => return None,
@@ -205,8 +205,8 @@ fn inline_const_fn_from_external_crate(tcx: &TyCtxt, def_id: DefId)
     fn_id
 }
 
-pub fn lookup_const_fn_by_id<'tcx>(tcx: &TyCtxt<'tcx>, def_id: DefId)
-                                   -> Option<FnLikeNode<'tcx>>
+pub fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, def_id: DefId)
+                                       -> Option<FnLikeNode<'tcx>>
 {
     let fn_id = if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
         node_id
@@ -238,7 +238,7 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &TyCtxt<'tcx>, def_id: DefId)
     }
 }
 
-pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, pat_id: ast::NodeId, span: Span)
+pub fn const_expr_to_pat(tcx: TyCtxt, expr: &Expr, pat_id: ast::NodeId, span: Span)
                          -> Result<P<hir::Pat>, DefId> {
     let pat_ty = tcx.expr_ty(expr);
     debug!("expr={:?} pat_ty={:?} pat_id={}", expr, pat_ty, pat_id);
@@ -339,7 +339,7 @@ pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, pat_id: ast::NodeId, spa
     Ok(P(hir::Pat { id: expr.id, node: pat, span: span }))
 }
 
-pub fn eval_const_expr(tcx: &TyCtxt, e: &Expr) -> ConstVal {
+pub fn eval_const_expr(tcx: TyCtxt, e: &Expr) -> ConstVal {
     match eval_const_expr_partial(tcx, e, ExprTypeChecked, None) {
         Ok(r) => r,
         // non-const path still needs to be a fatal error, because enums are funky
@@ -526,10 +526,10 @@ macro_rules! signal {
 /// guaranteed to be evaluatable. `ty_hint` is usually ExprTypeChecked,
 /// but a few places need to evaluate constants during type-checking, like
 /// computing the length of an array. (See also the FIXME above EvalHint.)
-pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
-                                     e: &Expr,
-                                     ty_hint: EvalHint<'tcx>,
-                                     fn_args: FnArgMap) -> EvalResult {
+pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                         e: &Expr,
+                                         ty_hint: EvalHint<'tcx>,
+                                         fn_args: FnArgMap) -> EvalResult {
     // Try to compute the type of the expression based on the EvalHint.
     // (See also the definition of EvalHint, and the FIXME above EvalHint.)
     let ety = match ty_hint {
@@ -931,11 +931,10 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
     }
 }
 
-fn infer<'tcx>(
-    i: ConstInt,
-    tcx: &TyCtxt<'tcx>,
-    ty_hint: &ty::TypeVariants<'tcx>,
-) -> Result<ConstInt, ErrKind> {
+fn infer<'a, 'tcx>(i: ConstInt,
+                   tcx: TyCtxt<'a, 'tcx>,
+                   ty_hint: &ty::TypeVariants<'tcx>)
+                   -> Result<ConstInt, ErrKind> {
     use syntax::ast::*;
 
     match (ty_hint, i) {
@@ -997,7 +996,7 @@ fn infer<'tcx>(
     }
 }
 
-fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
+fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx>,
                                                 ti: &'tcx hir::TraitItem,
                                                 trait_id: DefId,
                                                 rcvr_substs: subst::Substs<'tcx>)
@@ -1054,7 +1053,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
     }
 }
 
-fn cast_const_int<'tcx>(tcx: &TyCtxt<'tcx>, val: ConstInt, ty: ty::Ty) -> CastResult {
+fn cast_const_int<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, val: ConstInt, ty: ty::Ty) -> CastResult {
     let v = val.to_u64_unchecked();
     match ty.sty {
         ty::TyBool if v == 0 => Ok(Bool(false)),
@@ -1099,7 +1098,7 @@ fn cast_const_int<'tcx>(tcx: &TyCtxt<'tcx>, val: ConstInt, ty: ty::Ty) -> CastRe
     }
 }
 
-fn cast_const_float<'tcx>(tcx: &TyCtxt<'tcx>, f: f64, ty: ty::Ty) -> CastResult {
+fn cast_const_float<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, f: f64, ty: ty::Ty) -> CastResult {
     match ty.sty {
         ty::TyInt(_) if f >= 0.0 => cast_const_int(tcx, Infer(f as u64), ty),
         ty::TyInt(_) => cast_const_int(tcx, InferSigned(f as i64), ty),
@@ -1110,7 +1109,7 @@ fn cast_const_float<'tcx>(tcx: &TyCtxt<'tcx>, f: f64, ty: ty::Ty) -> CastResult
     }
 }
 
-fn cast_const<'tcx>(tcx: &TyCtxt<'tcx>, val: ConstVal, ty: ty::Ty) -> CastResult {
+fn cast_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, val: ConstVal, ty: ty::Ty) -> CastResult {
     match val {
         Integral(i) => cast_const_int(tcx, i, ty),
         Bool(b) => cast_const_int(tcx, Infer(b as u64), ty),
@@ -1127,11 +1126,11 @@ fn cast_const<'tcx>(tcx: &TyCtxt<'tcx>, val: ConstVal, ty: ty::Ty) -> CastResult
     }
 }
 
-fn lit_to_const<'tcx>(lit: &ast::LitKind,
-                      tcx: &TyCtxt<'tcx>,
-                      ty_hint: Option<Ty<'tcx>>,
-                      span: Span,
-                      ) -> Result<ConstVal, ErrKind> {
+fn lit_to_const<'a, 'tcx>(lit: &ast::LitKind,
+                          tcx: TyCtxt<'a, 'tcx>,
+                          ty_hint: Option<Ty<'tcx>>,
+                          span: Span)
+                          -> Result<ConstVal, ErrKind> {
     use syntax::ast::*;
     use syntax::ast::LitIntType::*;
     match *lit {
@@ -1198,9 +1197,9 @@ pub fn compare_const_vals(a: &ConstVal, b: &ConstVal) -> Option<Ordering> {
     }
 }
 
-pub fn compare_lit_exprs<'tcx>(tcx: &TyCtxt<'tcx>,
-                               a: &Expr,
-                               b: &Expr) -> Option<Ordering> {
+pub fn compare_lit_exprs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                   a: &Expr,
+                                   b: &Expr) -> Option<Ordering> {
     let a = match eval_const_expr_partial(tcx, a, ExprTypeChecked, None) {
         Ok(a) => a,
         Err(e) => {
@@ -1220,7 +1219,7 @@ pub fn compare_lit_exprs<'tcx>(tcx: &TyCtxt<'tcx>,
 
 
 /// Returns the repeat count for a repeating vector expression.
-pub fn eval_repeat_count(tcx: &TyCtxt, count_expr: &hir::Expr) -> usize {
+pub fn eval_repeat_count(tcx: TyCtxt, count_expr: &hir::Expr) -> usize {
     let hint = UncheckedExprHint(tcx.types.usize);
     match eval_const_expr_partial(tcx, count_expr, hint, None) {
         Ok(Integral(Usize(count))) => {
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index e72204e5e22..7707376f0a0 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -367,7 +367,7 @@ pub struct CompileState<'a, 'b, 'ast: 'a, 'tcx: 'b> where 'ast: 'tcx {
     pub resolutions: Option<&'a Resolutions>,
     pub mir_map: Option<&'b MirMap<'tcx>>,
     pub analysis: Option<&'a ty::CrateAnalysis<'a>>,
-    pub tcx: Option<&'b TyCtxt<'tcx>>,
+    pub tcx: Option<TyCtxt<'b, 'tcx>>,
     pub trans: Option<&'a trans::CrateTranslation>,
 }
 
@@ -464,7 +464,7 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
                             hir_crate: &'a hir::Crate,
                             analysis: &'a ty::CrateAnalysis<'a>,
                             mir_map: Option<&'b MirMap<'tcx>>,
-                            tcx: &'b TyCtxt<'tcx>,
+                            tcx: TyCtxt<'b, 'tcx>,
                             crate_name: &'a str)
                             -> CompileState<'a, 'b, 'ast, 'tcx> {
         CompileState {
@@ -817,7 +817,10 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
                                                name: &str,
                                                f: F)
                                                -> Result<R, usize>
-    where F: FnOnce(&TyCtxt<'tcx>, Option<MirMap<'tcx>>, ty::CrateAnalysis, CompileResult) -> R
+    where F: for<'a> FnOnce(TyCtxt<'a, 'tcx>,
+                            Option<MirMap<'tcx>>,
+                            ty::CrateAnalysis,
+                            CompileResult) -> R
 {
     macro_rules! try_with_f {
         ($e: expr, ($t: expr, $m: expr, $a: expr)) => {
@@ -989,9 +992,10 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 }
 
 /// Run the translation phase to LLVM, after which the AST and analysis can
-pub fn phase_4_translate_to_llvm<'tcx>(tcx: &TyCtxt<'tcx>,
-                                       mut mir_map: MirMap<'tcx>,
-                                       analysis: ty::CrateAnalysis) -> trans::CrateTranslation {
+pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                           mut mir_map: MirMap<'tcx>,
+                                           analysis: ty::CrateAnalysis)
+                                           -> trans::CrateTranslation {
     let time_passes = tcx.sess.time_passes();
 
     time(time_passes,
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 8d8984000c7..bb90789c14a 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -469,7 +469,7 @@ impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
 
 
 struct TypedAnnotation<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 }
 
 impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
@@ -689,13 +689,13 @@ impl fold::Folder for ReplaceBodyWithLoop {
     }
 }
 
-fn print_flowgraph<'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
-                                   tcx: &TyCtxt<'tcx>,
-                                   mir_map: Option<&MirMap<'tcx>>,
-                                   code: blocks::Code,
-                                   mode: PpFlowGraphMode,
-                                   mut out: W)
-                                   -> io::Result<()> {
+fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
+                                       tcx: TyCtxt<'a, 'tcx>,
+                                       mir_map: Option<&MirMap<'tcx>>,
+                                       code: blocks::Code,
+                                       mode: PpFlowGraphMode,
+                                       mut out: W)
+                                       -> io::Result<()> {
     let cfg = match code {
         blocks::BlockCode(block) => cfg::CFG::new(tcx, &block),
         blocks::FnLikeCode(fn_like) => cfg::CFG::new(tcx, &fn_like.body()),
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 475e1f42559..c92ede68b99 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -160,7 +160,7 @@ fn test_env<F>(source_string: &str,
 }
 
 impl<'a, 'tcx> Env<'a, 'tcx> {
-    pub fn tcx(&self) -> &TyCtxt<'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs
index 88d8ed8d581..3a41a377d20 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/src/librustc_incremental/assert_dep_graph.rs
@@ -63,7 +63,7 @@ const IF_THIS_CHANGED: &'static str = "rustc_if_this_changed";
 const THEN_THIS_WOULD_NEED: &'static str = "rustc_then_this_would_need";
 const ID: &'static str = "id";
 
-pub fn assert_dep_graph(tcx: &TyCtxt) {
+pub fn assert_dep_graph(tcx: TyCtxt) {
     let _ignore = tcx.dep_graph.in_ignore();
 
     if tcx.sess.opts.debugging_opts.dump_dep_graph {
@@ -98,7 +98,7 @@ type TargetHashMap =
                FnvHashSet<(Span, InternedString, ast::NodeId, DepNode<DefId>)>>;
 
 struct IfThisChanged<'a, 'tcx:'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     if_this_changed: SourceHashMap,
     then_this_would_need: TargetHashMap,
 }
@@ -172,7 +172,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IfThisChanged<'a, 'tcx> {
     }
 }
 
-fn check_paths(tcx: &TyCtxt,
+fn check_paths(tcx: TyCtxt,
                if_this_changed: &SourceHashMap,
                then_this_would_need: &TargetHashMap)
 {
@@ -213,7 +213,7 @@ fn check_paths(tcx: &TyCtxt,
     }
 }
 
-fn dump_graph(tcx: &TyCtxt) {
+fn dump_graph(tcx: TyCtxt) {
     let path: String = env::var("RUST_DEP_GRAPH").unwrap_or_else(|_| format!("dep_graph"));
     let query = tcx.dep_graph.query();
 
diff --git a/src/librustc_incremental/calculate_svh.rs b/src/librustc_incremental/calculate_svh.rs
index ab1c6f5ace1..73af4acfe49 100644
--- a/src/librustc_incremental/calculate_svh.rs
+++ b/src/librustc_incremental/calculate_svh.rs
@@ -14,21 +14,21 @@
 use std::hash::{Hash, SipHasher, Hasher};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc::hir::svh::Svh;
-use rustc::ty;
+use rustc::ty::TyCtxt;
 use rustc::hir::intravisit::{self, Visitor};
 
 use self::svh_visitor::StrictVersionHashVisitor;
 
 pub trait SvhCalculate {
     /// Calculate the SVH for an entire krate.
-    fn calculate_krate_hash(&self) -> Svh;
+    fn calculate_krate_hash(self) -> Svh;
 
     /// Calculate the SVH for a particular item.
-    fn calculate_item_hash(&self, def_id: DefId) -> u64;
+    fn calculate_item_hash(self, def_id: DefId) -> u64;
 }
 
-impl<'tcx> SvhCalculate for ty::TyCtxt<'tcx> {
-    fn calculate_krate_hash(&self) -> Svh {
+impl<'a, 'tcx> SvhCalculate for TyCtxt<'a, 'tcx> {
+    fn calculate_krate_hash(self) -> Svh {
         // FIXME (#14132): This is better than it used to be, but it still not
         // ideal. We now attempt to hash only the relevant portions of the
         // Crate AST as well as the top-level crate attributes. (However,
@@ -75,7 +75,7 @@ impl<'tcx> SvhCalculate for ty::TyCtxt<'tcx> {
         Svh::from_hash(state.finish())
     }
 
-    fn calculate_item_hash(&self, def_id: DefId) -> u64 {
+    fn calculate_item_hash(self, def_id: DefId) -> u64 {
         assert!(def_id.is_local());
 
         let mut state = SipHasher::new();
@@ -109,7 +109,7 @@ mod svh_visitor {
     use syntax::ast::{self, Name, NodeId};
     use syntax::codemap::Span;
     use syntax::parse::token;
-    use rustc::ty;
+    use rustc::ty::TyCtxt;
     use rustc::hir;
     use rustc::hir::*;
     use rustc::hir::intravisit as visit;
@@ -118,13 +118,13 @@ mod svh_visitor {
     use std::hash::{Hash, SipHasher};
 
     pub struct StrictVersionHashVisitor<'a, 'tcx: 'a> {
-        pub tcx: &'a ty::TyCtxt<'tcx>,
+        pub tcx: TyCtxt<'a, 'tcx>,
         pub st: &'a mut SipHasher,
     }
 
     impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> {
         pub fn new(st: &'a mut SipHasher,
-                   tcx: &'a ty::TyCtxt<'tcx>)
+                   tcx: TyCtxt<'a, 'tcx>)
                    -> Self {
             StrictVersionHashVisitor { st: st, tcx: tcx }
         }
diff --git a/src/librustc_incremental/persist/directory.rs b/src/librustc_incremental/persist/directory.rs
index 796812556d2..299254959c7 100644
--- a/src/librustc_incremental/persist/directory.rs
+++ b/src/librustc_incremental/persist/directory.rs
@@ -16,7 +16,7 @@
 use rustc::dep_graph::DepNode;
 use rustc::hir::map::DefPath;
 use rustc::hir::def_id::DefId;
-use rustc::ty;
+use rustc::ty::TyCtxt;
 use rustc::util::nodemap::DefIdMap;
 use std::fmt::{self, Debug};
 
@@ -39,7 +39,7 @@ impl DefIdDirectory {
         DefIdDirectory { paths: vec![] }
     }
 
-    pub fn retrace(&self, tcx: &ty::TyCtxt) -> RetracedDefIdDirectory {
+    pub fn retrace(&self, tcx: TyCtxt) -> RetracedDefIdDirectory {
         let ids = self.paths.iter()
                             .map(|path| tcx.map.retrace_path(path))
                             .collect();
@@ -63,13 +63,13 @@ impl RetracedDefIdDirectory {
 }
 
 pub struct DefIdDirectoryBuilder<'a,'tcx:'a> {
-    tcx: &'a ty::TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     hash: DefIdMap<Option<DefPathIndex>>,
     directory: DefIdDirectory,
 }
 
 impl<'a,'tcx> DefIdDirectoryBuilder<'a,'tcx> {
-    pub fn new(tcx: &'a ty::TyCtxt<'tcx>) -> DefIdDirectoryBuilder<'a, 'tcx> {
+    pub fn new(tcx: TyCtxt<'a, 'tcx>) -> DefIdDirectoryBuilder<'a, 'tcx> {
         DefIdDirectoryBuilder {
             tcx: tcx,
             hash: DefIdMap(),
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 35fa69520b6..9c1452acb84 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -31,14 +31,14 @@ use rustc::hir::intravisit::Visitor;
 use syntax::ast::{self, Attribute, MetaItem};
 use syntax::attr::AttrMetaMethods;
 use syntax::parse::token::InternedString;
-use rustc::ty;
+use rustc::ty::TyCtxt;
 
 const DIRTY: &'static str = "rustc_dirty";
 const CLEAN: &'static str = "rustc_clean";
 const LABEL: &'static str = "label";
 const CFG: &'static str = "cfg";
 
-pub fn check_dirty_clean_annotations(tcx: &ty::TyCtxt) {
+pub fn check_dirty_clean_annotations(tcx: TyCtxt) {
     let _ignore = tcx.dep_graph.in_ignore();
     let query = tcx.dep_graph.query();
     let krate = tcx.map.krate();
@@ -49,7 +49,7 @@ pub fn check_dirty_clean_annotations(tcx: &ty::TyCtxt) {
 }
 
 pub struct DirtyCleanVisitor<'a, 'tcx:'a> {
-    tcx: &'a ty::TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     query: &'a DepGraphQuery<DefId>,
 }
 
diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs
index 196c4511b0f..fbebb732e99 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/src/librustc_incremental/persist/load.rs
@@ -15,7 +15,7 @@ use rbml::Error;
 use rbml::opaque::Decoder;
 use rustc::dep_graph::DepNode;
 use rustc::hir::def_id::DefId;
-use rustc::ty;
+use rustc::ty::TyCtxt;
 use rustc_data_structures::fnv::FnvHashSet;
 use rustc_serialize::Decodable as RustcDecodable;
 use std::io::Read;
@@ -37,7 +37,7 @@ type CleanEdges = Vec<(DepNode<DefId>, DepNode<DefId>)>;
 /// early in compilation, before we've really done any work, but
 /// actually it doesn't matter all that much.) See `README.md` for
 /// more general overview.
-pub fn load_dep_graph<'tcx>(tcx: &ty::TyCtxt<'tcx>) {
+pub fn load_dep_graph(tcx: TyCtxt) {
     let _ignore = tcx.dep_graph.in_ignore();
 
     if let Some(dep_graph) = dep_graph_path(tcx) {
@@ -47,7 +47,7 @@ pub fn load_dep_graph<'tcx>(tcx: &ty::TyCtxt<'tcx>) {
     }
 }
 
-pub fn load_dep_graph_if_exists<'tcx>(tcx: &ty::TyCtxt<'tcx>, path: &Path) {
+pub fn load_dep_graph_if_exists(tcx: TyCtxt, path: &Path) {
     if !path.exists() {
         return;
     }
@@ -74,8 +74,7 @@ pub fn load_dep_graph_if_exists<'tcx>(tcx: &ty::TyCtxt<'tcx>, path: &Path) {
     }
 }
 
-pub fn decode_dep_graph<'tcx>(tcx: &ty::TyCtxt<'tcx>, data: &[u8])
-                              -> Result<(), Error>
+pub fn decode_dep_graph(tcx: TyCtxt, data: &[u8]) -> Result<(), Error>
 {
     // Deserialize the directory and dep-graph.
     let mut decoder = Decoder::new(data, 0);
@@ -129,10 +128,10 @@ pub fn decode_dep_graph<'tcx>(tcx: &ty::TyCtxt<'tcx>, data: &[u8])
     Ok(())
 }
 
-fn initial_dirty_nodes<'tcx>(tcx: &ty::TyCtxt<'tcx>,
-                             hashed_items: &[SerializedHash],
-                             retraced: &RetracedDefIdDirectory)
-                             -> DirtyNodes {
+fn initial_dirty_nodes(tcx: TyCtxt,
+                       hashed_items: &[SerializedHash],
+                       retraced: &RetracedDefIdDirectory)
+                       -> DirtyNodes {
     let mut items_removed = false;
     let mut dirty_nodes = FnvHashSet();
     for hashed_item in hashed_items {
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index d88f9e42b08..2d40e78dee2 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -11,7 +11,7 @@
 use calculate_svh::SvhCalculate;
 use rbml::opaque::Encoder;
 use rustc::dep_graph::DepNode;
-use rustc::ty;
+use rustc::ty::TyCtxt;
 use rustc_serialize::{Encodable as RustcEncodable};
 use std::io::{self, Cursor, Write};
 use std::fs::{self, File};
@@ -20,7 +20,7 @@ use super::data::*;
 use super::directory::*;
 use super::util::*;
 
-pub fn save_dep_graph<'tcx>(tcx: &ty::TyCtxt<'tcx>) {
+pub fn save_dep_graph(tcx: TyCtxt) {
     let _ignore = tcx.dep_graph.in_ignore();
 
     if let Some(dep_graph) = dep_graph_path(tcx) {
@@ -68,10 +68,7 @@ pub fn save_dep_graph<'tcx>(tcx: &ty::TyCtxt<'tcx>) {
     }
 }
 
-pub fn encode_dep_graph<'tcx>(tcx: &ty::TyCtxt<'tcx>,
-                              encoder: &mut Encoder)
-                              -> io::Result<()>
-{
+pub fn encode_dep_graph(tcx: TyCtxt, encoder: &mut Encoder) -> io::Result<()> {
     // Here we take advantage of how RBML allows us to skip around
     // and encode the depgraph as a two-part structure:
     //
diff --git a/src/librustc_incremental/persist/util.rs b/src/librustc_incremental/persist/util.rs
index 5b4e88def01..8ebcbc0466f 100644
--- a/src/librustc_incremental/persist/util.rs
+++ b/src/librustc_incremental/persist/util.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::ty;
+use rustc::ty::TyCtxt;
 
 use std::fs;
 use std::io;
 use std::path::{PathBuf, Path};
 
-pub fn dep_graph_path<'tcx>(tcx: &ty::TyCtxt<'tcx>) -> Option<PathBuf> {
+pub fn dep_graph_path(tcx: TyCtxt) -> Option<PathBuf> {
     // For now, just save/load dep-graph from
     // directory/dep_graph.rbml
     tcx.sess.opts.incremental.as_ref().and_then(|incr_dir| {
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 55c84ed389d..c73d0f368b7 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -776,7 +776,7 @@ impl LateLintPass for UnconditionalRecursion {
         // Functions for identifying if the given Expr NodeId `id`
         // represents a call to the function `fn_id`/method `method`.
 
-        fn expr_refers_to_this_fn(tcx: &TyCtxt,
+        fn expr_refers_to_this_fn(tcx: TyCtxt,
                                   fn_id: ast::NodeId,
                                   id: ast::NodeId) -> bool {
             match tcx.map.get(id) {
@@ -792,7 +792,7 @@ impl LateLintPass for UnconditionalRecursion {
         }
 
         // Check if the expression `id` performs a call to `method`.
-        fn expr_refers_to_this_method(tcx: &TyCtxt,
+        fn expr_refers_to_this_method(tcx: TyCtxt,
                                       method: &ty::Method,
                                       id: ast::NodeId) -> bool {
             // Check for method calls and overloaded operators.
@@ -840,11 +840,11 @@ impl LateLintPass for UnconditionalRecursion {
 
         // Check if the method call to the method with the ID `callee_id`
         // and instantiated with `callee_substs` refers to method `method`.
-        fn method_call_refers_to_method<'tcx>(tcx: &TyCtxt<'tcx>,
-                                              method: &ty::Method,
-                                              callee_id: DefId,
-                                              callee_substs: &Substs<'tcx>,
-                                              expr_id: ast::NodeId) -> bool {
+        fn method_call_refers_to_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                                  method: &ty::Method,
+                                                  callee_id: DefId,
+                                                  callee_substs: &Substs<'tcx>,
+                                                  expr_id: ast::NodeId) -> bool {
             let callee_item = tcx.impl_or_trait_item(callee_id);
 
             match callee_item.container() {
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 63dc0f303ff..ebb348164e1 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -294,7 +294,7 @@ impl LateLintPass for TypeLimits {
             }
         }
 
-        fn check_limits(tcx: &TyCtxt, binop: hir::BinOp,
+        fn check_limits(tcx: TyCtxt, binop: hir::BinOp,
                         l: &hir::Expr, r: &hir::Expr) -> bool {
             let (lit, expr, swap) = match (&l.node, &r.node) {
                 (&hir::ExprLit(_), _) => (l, r, true),
@@ -375,10 +375,10 @@ enum FfiResult {
 /// to function pointers and references, but could be
 /// expanded to cover NonZero raw pointers and newtypes.
 /// FIXME: This duplicates code in trans.
-fn is_repr_nullable_ptr<'tcx>(tcx: &TyCtxt<'tcx>,
-                              def: ty::AdtDef<'tcx>,
-                              substs: &Substs<'tcx>)
-                              -> bool {
+fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                  def: ty::AdtDef<'tcx>,
+                                  substs: &Substs<'tcx>)
+                                  -> bool {
     if def.variants.len() == 2 {
         let data_idx;
 
@@ -409,7 +409,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                           ty: Ty<'tcx>)
                           -> FfiResult {
         use self::FfiResult::*;
-        let cx = &self.cx.tcx;
+        let cx = self.cx.tcx;
 
         // Protect against infinite recursion, for example
         // `struct S(*mut S);`.
diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs
index 56f6a3f7b14..377b93c28b5 100644
--- a/src/librustc_metadata/astencode.rs
+++ b/src/librustc_metadata/astencode.rs
@@ -60,7 +60,7 @@ use rustc_serialize::{Encodable, EncoderHelpers};
 #[cfg(test)] use rustc::hir::lowering::{lower_item, LoweringContext, DummyResolver};
 
 struct DecodeContext<'a, 'b, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     cdata: &'b cstore::crate_metadata,
     from_id_range: IdRange,
     to_id_range: IdRange,
@@ -122,13 +122,13 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
 
 /// Decodes an item from its AST in the cdata's metadata and adds it to the
 /// ast-map.
-pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
-                                 tcx: &TyCtxt<'tcx>,
-                                 parent_def_path: ast_map::DefPath,
-                                 parent_did: DefId,
-                                 ast_doc: rbml::Doc,
-                                 orig_did: DefId)
-                                 -> &'tcx InlinedItem {
+pub fn decode_inlined_item<'a, 'tcx>(cdata: &cstore::crate_metadata,
+                                     tcx: TyCtxt<'a, 'tcx>,
+                                     parent_def_path: ast_map::DefPath,
+                                     parent_did: DefId,
+                                     ast_doc: rbml::Doc,
+                                     orig_did: DefId)
+                                     -> &'tcx InlinedItem {
     debug!("> Decoding inlined fn: {:?}", tcx.item_path_str(orig_did));
     let mut ast_dsr = reader::Decoder::new(ast_doc);
     let from_id_range = Decodable::decode(&mut ast_dsr).unwrap();
@@ -861,21 +861,19 @@ trait rbml_decoder_decoder_helpers<'tcx> {
 
     // Versions of the type reading functions that don't need the full
     // DecodeContext.
-    fn read_ty_nodcx(&mut self,
-                     tcx: &TyCtxt<'tcx>, cdata: &cstore::crate_metadata) -> Ty<'tcx>;
-    fn read_tys_nodcx(&mut self,
-                      tcx: &TyCtxt<'tcx>,
-                      cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>>;
-    fn read_substs_nodcx(&mut self, tcx: &TyCtxt<'tcx>,
-                         cdata: &cstore::crate_metadata)
-                         -> subst::Substs<'tcx>;
+    fn read_ty_nodcx<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>,
+                         cdata: &cstore::crate_metadata) -> Ty<'tcx>;
+    fn read_tys_nodcx<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>,
+                          cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>>;
+    fn read_substs_nodcx<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>,
+                             cdata: &cstore::crate_metadata)
+                             -> subst::Substs<'tcx>;
 }
 
 impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
-    fn read_ty_nodcx(&mut self,
-                     tcx: &TyCtxt<'tcx>,
-                     cdata: &cstore::crate_metadata)
-                     -> Ty<'tcx> {
+    fn read_ty_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx>,
+                         cdata: &cstore::crate_metadata)
+                         -> Ty<'tcx> {
         self.read_opaque(|_, doc| {
             Ok(
                 tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc,
@@ -884,19 +882,17 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
         }).unwrap()
     }
 
-    fn read_tys_nodcx(&mut self,
-                      tcx: &TyCtxt<'tcx>,
-                      cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>> {
+    fn read_tys_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx>,
+                          cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>> {
         self.read_to_vec(|this| Ok(this.read_ty_nodcx(tcx, cdata)) )
             .unwrap()
             .into_iter()
             .collect()
     }
 
-    fn read_substs_nodcx(&mut self,
-                         tcx: &TyCtxt<'tcx>,
-                         cdata: &cstore::crate_metadata)
-                         -> subst::Substs<'tcx>
+    fn read_substs_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx>,
+                             cdata: &cstore::crate_metadata)
+                             -> subst::Substs<'tcx>
     {
         self.read_opaque(|_, doc| {
             Ok(
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
index e4a0731be55..70d4078a106 100644
--- a/src/librustc_metadata/csearch.rs
+++ b/src/librustc_metadata/csearch.rs
@@ -54,14 +54,14 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::get_visibility(&cdata, def.index)
     }
 
-    fn closure_kind(&self, _tcx: &TyCtxt<'tcx>, def_id: DefId) -> ty::ClosureKind
+    fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind
     {
         assert!(!def_id.is_local());
         let cdata = self.get_crate_data(def_id.krate);
         decoder::closure_kind(&cdata, def_id.index)
     }
 
-    fn closure_ty(&self, tcx: &TyCtxt<'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx>
+    fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx>
     {
         assert!(!def_id.is_local());
         let cdata = self.get_crate_data(def_id.krate);
@@ -78,22 +78,22 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::get_repr_attrs(&cdata, def.index)
     }
 
-    fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                 -> ty::TypeScheme<'tcx>
+    fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                     -> ty::TypeScheme<'tcx>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_type(&cdata, def.index, tcx)
     }
 
-    fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                       -> ty::GenericPredicates<'tcx>
+    fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                           -> ty::GenericPredicates<'tcx>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_predicates(&cdata, def.index, tcx)
     }
 
-    fn item_super_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                             -> ty::GenericPredicates<'tcx>
+    fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                                 -> ty::GenericPredicates<'tcx>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_super_predicates(&cdata, def.index, tcx)
@@ -111,13 +111,13 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::get_symbol(&cdata, def.index)
     }
 
-    fn trait_def(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::TraitDef<'tcx>
+    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_trait_def(&cdata, def.index, tcx)
     }
 
-    fn adt_def(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
+    fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_adt_def(&self.intr, &cdata, def.index, tcx)
@@ -155,8 +155,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         result
     }
 
-    fn provided_trait_methods(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                              -> Vec<Rc<ty::Method<'tcx>>>
+    fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                                  -> Vec<Rc<ty::Method<'tcx>>>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_provided_trait_methods(self.intr.clone(), &cdata, def.index, tcx)
@@ -181,8 +181,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::get_impl_polarity(&cdata, def.index)
     }
 
-    fn impl_trait_ref(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                      -> Option<ty::TraitRef<'tcx>>
+    fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                          -> Option<ty::TraitRef<'tcx>>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_impl_trait(&cdata, def.index, tcx)
@@ -196,8 +196,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
     }
 
     // FIXME: killme
-    fn associated_consts(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                         -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
+    fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                             -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_associated_consts(self.intr.clone(), &cdata, def.index, tcx)
     }
@@ -207,14 +207,14 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::get_parent_impl(&*cdata, impl_def.index)
     }
 
-    fn trait_of_item(&self, tcx: &TyCtxt<'tcx>, def_id: DefId) -> Option<DefId>
+    fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def_id: DefId) -> Option<DefId>
     {
         let cdata = self.get_crate_data(def_id.krate);
         decoder::get_trait_of_item(&cdata, def_id.index, tcx)
     }
 
-    fn impl_or_trait_item(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> Option<ty::ImplOrTraitItem<'tcx>>
+    fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> Option<ty::ImplOrTraitItem<'tcx>>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::get_impl_or_trait_item(
@@ -247,7 +247,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::is_default_impl(&cdata, impl_did.index)
     }
 
-    fn is_extern_item(&self, tcx: &TyCtxt<'tcx>, did: DefId) -> bool {
+    fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx>, did: DefId) -> bool {
         let cdata = self.get_crate_data(did.krate);
         decoder::is_extern_item(&cdata, did.index, tcx)
     }
@@ -442,15 +442,15 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         result
     }
 
-    fn maybe_get_item_ast(&'tcx self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> FoundAst<'tcx>
+    fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> FoundAst<'tcx>
     {
         let cdata = self.get_crate_data(def.krate);
         decoder::maybe_get_item_ast(&cdata, tcx, def.index)
     }
 
-    fn maybe_get_item_mir(&self, tcx: &TyCtxt<'tcx>, def: DefId)
-                          -> Option<Mir<'tcx>> {
+    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx>, def: DefId)
+                              -> Option<Mir<'tcx>> {
         let cdata = self.get_crate_data(def.krate);
         decoder::maybe_get_item_mir(&cdata, tcx, def.index)
     }
@@ -486,11 +486,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
     {
         loader::meta_section_name(target)
     }
-    fn encode_type(&self,
-                   tcx: &TyCtxt<'tcx>,
-                   ty: Ty<'tcx>,
-                   def_id_to_string: fn(&TyCtxt<'tcx>, DefId) -> String)
-                   -> Vec<u8>
+    fn encode_type<'a>(&self,
+                       tcx: TyCtxt<'a, 'tcx>,
+                       ty: Ty<'tcx>,
+                       def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx>, DefId) -> String)
+                       -> Vec<u8>
     {
         encoder::encoded_ty(tcx, ty, def_id_to_string)
     }
@@ -510,14 +510,13 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         self.do_extern_mod_stmt_cnum(emod_id)
     }
 
-    fn encode_metadata(&self,
-                       tcx: &TyCtxt<'tcx>,
-                       reexports: &def::ExportMap,
-                       item_symbols: &RefCell<NodeMap<String>>,
-                       link_meta: &LinkMeta,
-                       reachable: &NodeSet,
-                       mir_map: &MirMap<'tcx>,
-                       krate: &hir::Crate) -> Vec<u8>
+    fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx>,
+                           reexports: &def::ExportMap,
+                           item_symbols: &RefCell<NodeMap<String>>,
+                           link_meta: &LinkMeta,
+                           reachable: &NodeSet,
+                           mir_map: &MirMap<'tcx>,
+                           krate: &hir::Crate) -> Vec<u8>
     {
         let ecx = encoder::EncodeContext {
             diag: tcx.sess.diagnostic(),
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 72fbbf80515..ce0856ce5af 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -223,14 +223,14 @@ fn variant_disr_val(d: rbml::Doc) -> Option<u64> {
     })
 }
 
-fn doc_type<'tcx>(doc: rbml::Doc, tcx: &TyCtxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
+fn doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx>, cdata: Cmd) -> Ty<'tcx> {
     let tp = reader::get_doc(doc, tag_items_data_item_type);
     TyDecoder::with_doc(tcx, cdata.cnum, tp,
                         &mut |did| translate_def_id(cdata, did))
         .parse_ty()
 }
 
-fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &TyCtxt<'tcx>, cdata: Cmd) -> Option<Ty<'tcx>> {
+fn maybe_doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx>, cdata: Cmd) -> Option<Ty<'tcx>> {
     reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| {
         TyDecoder::with_doc(tcx, cdata.cnum, tp,
                             &mut |did| translate_def_id(cdata, did))
@@ -238,20 +238,20 @@ fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &TyCtxt<'tcx>, cdata: Cmd) -> Optio
     })
 }
 
-pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc,
-                       tcx: &TyCtxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
+pub fn item_type<'a, 'tcx>(_item_id: DefId, item: rbml::Doc,
+                           tcx: TyCtxt<'a, 'tcx>, cdata: Cmd) -> Ty<'tcx> {
     doc_type(item, tcx, cdata)
 }
 
-fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &TyCtxt<'tcx>, cdata: Cmd)
-                       -> ty::TraitRef<'tcx> {
+fn doc_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx>, cdata: Cmd)
+                           -> ty::TraitRef<'tcx> {
     TyDecoder::with_doc(tcx, cdata.cnum, doc,
                         &mut |did| translate_def_id(cdata, did))
         .parse_trait_ref()
 }
 
-fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &TyCtxt<'tcx>, cdata: Cmd)
-                        -> ty::TraitRef<'tcx> {
+fn item_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx>, cdata: Cmd)
+                            -> ty::TraitRef<'tcx> {
     let tp = reader::get_doc(doc, tag_item_trait_ref);
     doc_trait_ref(tp, tcx, cdata)
 }
@@ -350,9 +350,9 @@ fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
         .collect()
 }
 
-pub fn get_trait_def<'tcx>(cdata: Cmd,
-                           item_id: DefIndex,
-                           tcx: &TyCtxt<'tcx>) -> ty::TraitDef<'tcx>
+pub fn get_trait_def<'a, 'tcx>(cdata: Cmd,
+                               item_id: DefIndex,
+                               tcx: TyCtxt<'a, 'tcx>) -> ty::TraitDef<'tcx>
 {
     let item_doc = cdata.lookup_item(item_id);
     let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
@@ -367,10 +367,11 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
                       associated_type_names)
 }
 
-pub fn get_adt_def<'tcx>(intr: &IdentInterner,
-                         cdata: Cmd,
-                         item_id: DefIndex,
-                         tcx: &TyCtxt<'tcx>) -> ty::AdtDefMaster<'tcx>
+pub fn get_adt_def<'a, 'tcx>(intr: &IdentInterner,
+                             cdata: Cmd,
+                             item_id: DefIndex,
+                             tcx: TyCtxt<'a, 'tcx>)
+                             -> ty::AdtDefMaster<'tcx>
 {
     fn expect_variant_kind(family: Family) -> ty::VariantKind {
         match family_to_variant_kind(family) {
@@ -495,26 +496,26 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
     adt
 }
 
-pub fn get_predicates<'tcx>(cdata: Cmd,
-                            item_id: DefIndex,
-                            tcx: &TyCtxt<'tcx>)
-                            -> ty::GenericPredicates<'tcx>
+pub fn get_predicates<'a, 'tcx>(cdata: Cmd,
+                                item_id: DefIndex,
+                                tcx: TyCtxt<'a, 'tcx>)
+                                -> ty::GenericPredicates<'tcx>
 {
     let item_doc = cdata.lookup_item(item_id);
     doc_predicates(item_doc, tcx, cdata, tag_item_generics)
 }
 
-pub fn get_super_predicates<'tcx>(cdata: Cmd,
-                                  item_id: DefIndex,
-                                  tcx: &TyCtxt<'tcx>)
-                                  -> ty::GenericPredicates<'tcx>
+pub fn get_super_predicates<'a, 'tcx>(cdata: Cmd,
+                                      item_id: DefIndex,
+                                      tcx: TyCtxt<'a, 'tcx>)
+                                      -> ty::GenericPredicates<'tcx>
 {
     let item_doc = cdata.lookup_item(item_id);
     doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
 }
 
-pub fn get_type<'tcx>(cdata: Cmd, id: DefIndex, tcx: &TyCtxt<'tcx>)
-                      -> ty::TypeScheme<'tcx>
+pub fn get_type<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx>)
+                          -> ty::TypeScheme<'tcx>
 {
     let item_doc = cdata.lookup_item(id);
     let t = item_type(DefId { krate: cdata.cnum, index: id }, item_doc, tcx,
@@ -590,10 +591,10 @@ pub fn get_custom_coerce_unsized_kind<'tcx>(
     })
 }
 
-pub fn get_impl_trait<'tcx>(cdata: Cmd,
-                            id: DefIndex,
-                            tcx: &TyCtxt<'tcx>)
-                            -> Option<ty::TraitRef<'tcx>>
+pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd,
+                                id: DefIndex,
+                                tcx: TyCtxt<'a, 'tcx>)
+                                -> Option<ty::TraitRef<'tcx>>
 {
     let item_doc = cdata.lookup_item(id);
     let fam = item_family(item_doc);
@@ -775,8 +776,8 @@ pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Nam
     item_name(intr, cdata.lookup_item(id))
 }
 
-pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &TyCtxt<'tcx>, id: DefIndex)
-                                -> FoundAst<'tcx> {
+pub fn maybe_get_item_ast<'a, 'tcx>(cdata: Cmd, tcx: TyCtxt<'a, 'tcx>, id: DefIndex)
+                                    -> FoundAst<'tcx> {
     debug!("Looking up item: {:?}", id);
     let item_doc = cdata.lookup_item(id);
     let item_did = item_def_id(item_doc, cdata);
@@ -827,10 +828,10 @@ pub fn is_item_mir_available<'tcx>(cdata: Cmd, id: DefIndex) -> bool {
     false
 }
 
-pub fn maybe_get_item_mir<'tcx>(cdata: Cmd,
-                                tcx: &TyCtxt<'tcx>,
-                                id: DefIndex)
-                                -> Option<mir::repr::Mir<'tcx>> {
+pub fn maybe_get_item_mir<'a, 'tcx>(cdata: Cmd,
+                                    tcx: TyCtxt<'a, 'tcx>,
+                                    id: DefIndex)
+                                    -> Option<mir::repr::Mir<'tcx>> {
     let item_doc = cdata.lookup_item(id);
 
     return reader::maybe_get_doc(item_doc, tag_mir as usize).map(|mir_doc| {
@@ -943,11 +944,11 @@ pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool {
     }
 }
 
-pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
-                                    cdata: Cmd,
-                                    id: DefIndex,
-                                    tcx: &TyCtxt<'tcx>)
-                                    -> Option<ty::ImplOrTraitItem<'tcx>> {
+pub fn get_impl_or_trait_item<'a, 'tcx>(intr: Rc<IdentInterner>,
+                                        cdata: Cmd,
+                                        id: DefIndex,
+                                        tcx: TyCtxt<'a, 'tcx>)
+                                        -> Option<ty::ImplOrTraitItem<'tcx>> {
     let item_doc = cdata.lookup_item(id);
 
     let def_id = item_def_id(item_doc, cdata);
@@ -1038,11 +1039,11 @@ pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances {
     Decodable::decode(&mut decoder).unwrap()
 }
 
-pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
-                                        cdata: Cmd,
-                                        id: DefIndex,
-                                        tcx: &TyCtxt<'tcx>)
-                                        -> Vec<Rc<ty::Method<'tcx>>> {
+pub fn get_provided_trait_methods<'a, 'tcx>(intr: Rc<IdentInterner>,
+                                            cdata: Cmd,
+                                            id: DefIndex,
+                                            tcx: TyCtxt<'a, 'tcx>)
+                                            -> Vec<Rc<ty::Method<'tcx>>> {
     let item = cdata.lookup_item(id);
 
     reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
@@ -1065,11 +1066,11 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
     }).collect()
 }
 
-pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
-                                   cdata: Cmd,
-                                   id: DefIndex,
-                                   tcx: &TyCtxt<'tcx>)
-                                   -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
+pub fn get_associated_consts<'a, 'tcx>(intr: Rc<IdentInterner>,
+                                       cdata: Cmd,
+                                       id: DefIndex,
+                                       tcx: TyCtxt<'a, 'tcx>)
+                                       -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
     let item = cdata.lookup_item(id);
 
     [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
@@ -1442,7 +1443,7 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
     }
 }
 
-pub fn get_trait_of_item(cdata: Cmd, id: DefIndex, tcx: &TyCtxt)
+pub fn get_trait_of_item(cdata: Cmd, id: DefIndex, tcx: TyCtxt)
                          -> Option<DefId> {
     let item_doc = cdata.lookup_item(id);
     let parent_item_id = match item_parent_item(cdata, item_doc) {
@@ -1577,7 +1578,7 @@ pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
     }
 }
 
-pub fn is_extern_item(cdata: Cmd, id: DefIndex, tcx: &TyCtxt) -> bool {
+pub fn is_extern_item(cdata: Cmd, id: DefIndex, tcx: TyCtxt) -> bool {
     let item_doc = match cdata.get_item(id) {
         Some(doc) => doc,
         None => return false,
@@ -1612,11 +1613,11 @@ pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
     }
 }
 
-fn doc_generics<'tcx>(base_doc: rbml::Doc,
-                      tcx: &TyCtxt<'tcx>,
-                      cdata: Cmd,
-                      tag: usize)
-                      -> ty::Generics<'tcx>
+fn doc_generics<'a, 'tcx>(base_doc: rbml::Doc,
+                          tcx: TyCtxt<'a, 'tcx>,
+                          cdata: Cmd,
+                          tag: usize)
+                          -> ty::Generics<'tcx>
 {
     let doc = reader::get_doc(base_doc, tag);
 
@@ -1660,10 +1661,10 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
     ty::Generics { types: types, regions: regions }
 }
 
-fn doc_predicate<'tcx>(cdata: Cmd,
-                       doc: rbml::Doc,
-                       tcx: &TyCtxt<'tcx>)
-                       -> ty::Predicate<'tcx>
+fn doc_predicate<'a, 'tcx>(cdata: Cmd,
+                           doc: rbml::Doc,
+                           tcx: TyCtxt<'a, 'tcx>)
+                           -> ty::Predicate<'tcx>
 {
     let predicate_pos = cdata.xref_index.lookup(
         cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize;
@@ -1673,11 +1674,11 @@ fn doc_predicate<'tcx>(cdata: Cmd,
     ).parse_predicate()
 }
 
-fn doc_predicates<'tcx>(base_doc: rbml::Doc,
-                        tcx: &TyCtxt<'tcx>,
-                        cdata: Cmd,
-                        tag: usize)
-                        -> ty::GenericPredicates<'tcx>
+fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc,
+                            tcx: TyCtxt<'a, 'tcx>,
+                            cdata: Cmd,
+                            tag: usize)
+                            -> ty::GenericPredicates<'tcx>
 {
     let doc = reader::get_doc(base_doc, tag);
 
@@ -1729,8 +1730,8 @@ pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind {
     ty::ClosureKind::decode(&mut decoder).unwrap()
 }
 
-pub fn closure_ty<'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: &TyCtxt<'tcx>)
-                        -> ty::ClosureTy<'tcx> {
+pub fn closure_ty<'a, 'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: TyCtxt<'a, 'tcx>)
+                            -> ty::ClosureTy<'tcx> {
     let closure_doc = cdata.lookup_item(closure_id);
     let closure_ty_doc = reader::get_doc(closure_doc, tag_items_closure_ty);
     TyDecoder::with_doc(tcx, cdata.cnum, closure_ty_doc, &mut |did| translate_def_id(cdata, did))
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index b7de78ec912..7b39ec72ed2 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -56,7 +56,7 @@ use rustc::hir::map::DefKey;
 
 pub struct EncodeContext<'a, 'tcx: 'a> {
     pub diag: &'a Handler,
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
     pub reexports: &'a def::ExportMap,
     pub item_symbols: &'a RefCell<NodeMap<String>>,
     pub link_meta: &'a LinkMeta,
@@ -139,7 +139,7 @@ pub fn def_to_u64(did: DefId) -> u64 {
     (did.krate as u64) << 32 | (did.index.as_usize() as u64)
 }
 
-pub fn def_to_string(_tcx: &TyCtxt, did: DefId) -> String {
+pub fn def_to_string(_tcx: TyCtxt, did: DefId) -> String {
     format!("{}:{}", did.krate, did.index.as_usize())
 }
 
@@ -252,7 +252,7 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     debug!("encode_enum_variant_info(did={:?})", did);
     let repr_hints = ecx.tcx.lookup_repr_hints(did);
     let repr_type = ecx.tcx.enum_repr_type(repr_hints.get(0));
-    let mut disr_val = repr_type.initial_discriminant(&ecx.tcx);
+    let mut disr_val = repr_type.initial_discriminant(ecx.tcx);
     let def = ecx.tcx.lookup_adt_def(did);
     for variant in &def.variants {
         let vid = variant.did;
@@ -1697,7 +1697,7 @@ fn encode_struct_field_attrs(ecx: &EncodeContext,
 
 
 struct ImplVisitor<'a, 'tcx:'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     impls: FnvHashMap<DefId, Vec<DefId>>
 }
 
@@ -2016,10 +2016,10 @@ fn encode_metadata_inner(rbml_w: &mut Encoder,
 }
 
 // Get the encoded string for a type
-pub fn encoded_ty<'tcx>(tcx: &TyCtxt<'tcx>,
-                        t: Ty<'tcx>,
-                        def_id_to_string: fn(&TyCtxt<'tcx>, DefId) -> String)
-                        -> Vec<u8> {
+pub fn encoded_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                            t: Ty<'tcx>,
+                            def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx>, DefId) -> String)
+                            -> Vec<u8> {
     let mut wr = Cursor::new(Vec::new());
     tyencode::enc_ty(&mut wr, &tyencode::ctxt {
         diag: tcx.sess.diagnostic(),
diff --git a/src/librustc_metadata/tls_context.rs b/src/librustc_metadata/tls_context.rs
index 782c7cba26e..e1354307f7a 100644
--- a/src/librustc_metadata/tls_context.rs
+++ b/src/librustc_metadata/tls_context.rs
@@ -25,8 +25,8 @@ use tyencode;
 
 impl<'a, 'tcx: 'a> tls::EncodingContext<'tcx> for encoder::EncodeContext<'a, 'tcx> {
 
-    fn tcx<'s>(&'s self) -> &'s TyCtxt<'tcx> {
-        &self.tcx
+    fn tcx<'s>(&'s self) -> TyCtxt<'s, 'tcx> {
+        self.tcx
     }
 
     fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: ty::Ty<'tcx>) {
@@ -40,13 +40,13 @@ impl<'a, 'tcx: 'a> tls::EncodingContext<'tcx> for encoder::EncodeContext<'a, 'tc
 
 pub struct DecodingContext<'a, 'tcx: 'a> {
     pub crate_metadata: Cmd<'a>,
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx: 'a> tls::DecodingContext<'tcx> for DecodingContext<'a, 'tcx> {
 
-    fn tcx<'s>(&'s self) -> &'s TyCtxt<'tcx> {
-        &self.tcx
+    fn tcx<'s>(&'s self) -> TyCtxt<'s, 'tcx> {
+        self.tcx
     }
 
     fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx> {
diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs
index 9f674a20f92..7d2f86c8768 100644
--- a/src/librustc_metadata/tydecode.rs
+++ b/src/librustc_metadata/tydecode.rs
@@ -41,12 +41,12 @@ pub struct TyDecoder<'a, 'tcx: 'a> {
     data: &'a [u8],
     krate: ast::CrateNum,
     pos: usize,
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     conv_def_id: DefIdConvert<'a>,
 }
 
 impl<'a,'tcx> TyDecoder<'a,'tcx> {
-    pub fn with_doc(tcx: &'a TyCtxt<'tcx>,
+    pub fn with_doc(tcx: TyCtxt<'a, 'tcx>,
                     crate_num: ast::CrateNum,
                     doc: rbml::Doc<'a>,
                     conv: DefIdConvert<'a>)
@@ -57,7 +57,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
     pub fn new(data: &'a [u8],
                crate_num: ast::CrateNum,
                pos: usize,
-               tcx: &'a TyCtxt<'tcx>,
+               tcx: TyCtxt<'a, 'tcx>,
                conv: DefIdConvert<'a>)
                -> TyDecoder<'a, 'tcx> {
         TyDecoder {
diff --git a/src/librustc_metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs
index 57aa347847e..03f2e2cfd37 100644
--- a/src/librustc_metadata/tyencode.rs
+++ b/src/librustc_metadata/tyencode.rs
@@ -37,9 +37,9 @@ use encoder;
 pub struct ctxt<'a, 'tcx: 'a> {
     pub diag: &'a Handler,
     // Def -> str Callback:
-    pub ds: fn(&TyCtxt<'tcx>, DefId) -> String,
+    pub ds: for<'b> fn(TyCtxt<'b, 'tcx>, DefId) -> String,
     // The type context.
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
     pub abbrevs: &'a abbrev_map<'tcx>
 }
 
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 95c931df9e5..98c2ece6f39 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -662,12 +662,12 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
     block.unit()
 }
 
-fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
-                             cfg: &mut CFG<'tcx>,
-                             unit_temp: &Lvalue<'tcx>,
-                             scope: &mut Scope<'tcx>,
-                             mut target: BasicBlock)
-                             -> BasicBlock
+fn build_diverge_scope<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                 cfg: &mut CFG<'tcx>,
+                                 unit_temp: &Lvalue<'tcx>,
+                                 scope: &mut Scope<'tcx>,
+                                 mut target: BasicBlock)
+                                 -> BasicBlock
 {
     // Build up the drops in **reverse** order. The end result will
     // look like:
@@ -721,11 +721,11 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
     target
 }
 
-fn build_free<'tcx>(tcx: &TyCtxt<'tcx>,
-                    unit_temp: &Lvalue<'tcx>,
-                    data: &FreeData<'tcx>,
-                    target: BasicBlock)
-                    -> TerminatorKind<'tcx> {
+fn build_free<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                        unit_temp: &Lvalue<'tcx>,
+                        data: &FreeData<'tcx>,
+                        target: BasicBlock)
+                        -> TerminatorKind<'tcx> {
     let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
                        .unwrap_or_else(|e| tcx.sess.fatal(&e));
     let substs = tcx.mk_substs(Substs::new(
diff --git a/src/librustc_mir/graphviz.rs b/src/librustc_mir/graphviz.rs
index 069bd7826bc..bbd741c6880 100644
--- a/src/librustc_mir/graphviz.rs
+++ b/src/librustc_mir/graphviz.rs
@@ -10,13 +10,15 @@
 
 use dot;
 use rustc::mir::repr::*;
-use rustc::ty;
+use rustc::ty::{self, TyCtxt};
 use std::fmt::Debug;
 use std::io::{self, Write};
 use syntax::ast::NodeId;
 
 /// Write a graphviz DOT graph of a list of MIRs.
-pub fn write_mir_graphviz<'a, 't, W, I>(tcx: &ty::TyCtxt<'t>, iter: I, w: &mut W) -> io::Result<()>
+pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx>,
+                                              iter: I, w: &mut W)
+                                              -> io::Result<()>
 where W: Write, I: Iterator<Item=(&'a NodeId, &'a Mir<'a>)> {
     for (&nodeid, mir) in iter {
         writeln!(w, "digraph Mir_{} {{", nodeid)?;
@@ -116,7 +118,7 @@ fn write_edges<W: Write>(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result
 /// Write the graphviz DOT label for the overall graph. This is essentially a block of text that
 /// will appear below the graph, showing the type of the `fn` this MIR represents and the types of
 /// all the variables and temporaries.
-fn write_graph_label<W: Write>(tcx: &ty::TyCtxt, nid: NodeId, mir: &Mir, w: &mut W)
+fn write_graph_label<W: Write>(tcx: TyCtxt, nid: NodeId, mir: &Mir, w: &mut W)
 -> io::Result<()> {
     write!(w, "    label=<fn {}(", dot::escape_html(&tcx.node_path_str(nid)))?;
 
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 5274b5e9aba..eda0d4da4f4 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -30,7 +30,7 @@ use rustc_const_math::{ConstInt, ConstUsize};
 
 #[derive(Copy, Clone)]
 pub struct Cx<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     infcx: &'a InferCtxt<'a, 'tcx>,
     constness: hir::Constness
 }
@@ -144,7 +144,7 @@ impl<'a,'tcx:'a> Cx<'a, 'tcx> {
         self.tcx.type_needs_drop_given_env(ty, &self.infcx.parameter_environment)
     }
 
-    pub fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.tcx
     }
 }
diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs
index 64214c98bf7..0114ee3c029 100644
--- a/src/librustc_mir/mir_map.rs
+++ b/src/librustc_mir/mir_map.rs
@@ -34,7 +34,7 @@ use rustc::hir::map::blocks::FnLikeNode;
 use syntax::ast;
 use syntax::codemap::Span;
 
-pub fn build_mir_for_crate<'tcx>(tcx: &TyCtxt<'tcx>) -> MirMap<'tcx> {
+pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>) -> MirMap<'tcx> {
     let mut map = MirMap {
         map: NodeMap(),
     };
@@ -52,7 +52,7 @@ pub fn build_mir_for_crate<'tcx>(tcx: &TyCtxt<'tcx>) -> MirMap<'tcx> {
 // BuildMir -- walks a crate, looking for fn items and methods to build MIR from
 
 struct BuildMir<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     map: &'a mut MirMap<'tcx>,
 }
 
@@ -180,7 +180,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
         };
 
         let implicit_argument = if let FnKind::Closure(..) = fk {
-            Some((closure_self_ty(&self.tcx, id, body.id), None))
+            Some((closure_self_ty(self.tcx, id, body.id), None))
         } else {
             None
         };
@@ -202,10 +202,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
     }
 }
 
-fn closure_self_ty<'tcx>(tcx: &TyCtxt<'tcx>,
-                         closure_expr_id: ast::NodeId,
-                         body_id: ast::NodeId)
-                         -> Ty<'tcx> {
+fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                             closure_expr_id: ast::NodeId,
+                             body_id: ast::NodeId)
+                             -> Ty<'tcx> {
     let closure_ty = tcx.node_id_to_type(closure_expr_id);
 
     // We're just hard-coding the idea that the signature will be
diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs
index 0e082ac262e..8fb36c2e10c 100644
--- a/src/librustc_mir/pretty.rs
+++ b/src/librustc_mir/pretty.rs
@@ -36,7 +36,7 @@ const INDENT: &'static str = "    ";
 /// - `substring1&substring2,...` -- `&`-separated list of substrings
 ///   that can appear in the pass-name or the `item_path_str` for the given
 ///   node-id. If any one of the substrings match, the data is dumped out.
-pub fn dump_mir<'a, 'tcx>(tcx: &TyCtxt<'tcx>,
+pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
                           pass_name: &str,
                           disambiguator: &Display,
                           src: MirSource,
@@ -73,10 +73,10 @@ pub fn dump_mir<'a, 'tcx>(tcx: &TyCtxt<'tcx>,
 }
 
 /// Write out a human-readable textual representation for the given MIR.
-pub fn write_mir_pretty<'a, 'tcx, I>(tcx: &TyCtxt<'tcx>,
-                                     iter: I,
-                                     w: &mut Write)
-                                     -> io::Result<()>
+pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx>,
+                                         iter: I,
+                                         w: &mut Write)
+                                         -> io::Result<()>
     where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a
 {
     for (&id, mir) in iter {
@@ -95,12 +95,12 @@ enum Annotation {
     ExitScope(ScopeId),
 }
 
-pub fn write_mir_fn<'tcx>(tcx: &TyCtxt<'tcx>,
-                          src: MirSource,
-                          mir: &Mir<'tcx>,
-                          w: &mut Write,
-                          auxiliary: Option<&ScopeAuxiliaryVec>)
-                          -> io::Result<()> {
+pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                              src: MirSource,
+                              mir: &Mir<'tcx>,
+                              w: &mut Write,
+                              auxiliary: Option<&ScopeAuxiliaryVec>)
+                              -> io::Result<()> {
     // compute scope/entry exit annotations
     let mut annotations = FnvHashMap();
     if let Some(auxiliary) = auxiliary {
@@ -138,7 +138,7 @@ pub fn write_mir_fn<'tcx>(tcx: &TyCtxt<'tcx>,
 }
 
 /// Write out a human-readable textual representation for the given basic block.
-fn write_basic_block(tcx: &TyCtxt,
+fn write_basic_block(tcx: TyCtxt,
                      block: BasicBlock,
                      mir: &Mir,
                      w: &mut Write,
@@ -182,14 +182,11 @@ fn write_basic_block(tcx: &TyCtxt,
     writeln!(w, "{}}}", INDENT)
 }
 
-fn comment(tcx: &TyCtxt,
-           scope: ScopeId,
-           span: Span)
-           -> String {
+fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String {
     format!("Scope({}) at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
 }
 
-fn write_scope_tree(tcx: &TyCtxt,
+fn write_scope_tree(tcx: TyCtxt,
                     mir: &Mir,
                     auxiliary: Option<&ScopeAuxiliaryVec>,
                     scope_tree: &FnvHashMap<Option<ScopeId>, Vec<ScopeId>>,
@@ -222,7 +219,7 @@ fn write_scope_tree(tcx: &TyCtxt,
 
 /// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
 /// local variables (both user-defined bindings and compiler temporaries).
-fn write_mir_intro(tcx: &TyCtxt, src: MirSource, mir: &Mir, w: &mut Write)
+fn write_mir_intro(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write)
                    -> io::Result<()> {
     match src {
         MirSource::Fn(_) => write!(w, "fn")?,
diff --git a/src/librustc_mir/transform/break_critical_edges.rs b/src/librustc_mir/transform/break_critical_edges.rs
index ee7c9015baa..1d8b9f39662 100644
--- a/src/librustc_mir/transform/break_critical_edges.rs
+++ b/src/librustc_mir/transform/break_critical_edges.rs
@@ -42,7 +42,7 @@ pub struct BreakCriticalEdges;
  */
 
 impl<'tcx> MirPass<'tcx> for BreakCriticalEdges {
-    fn run_pass(&mut self, _: &TyCtxt<'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
         break_critical_edges(mir);
     }
 }
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 678d2c4614d..17a849c4cce 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -19,11 +19,11 @@ use rustc::mir::visit::MutVisitor;
 use rustc::mir::transform::{MirPass, MirSource, Pass};
 
 struct EraseRegionsVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx> EraseRegionsVisitor<'a, 'tcx> {
-    pub fn new(tcx: &'a TyCtxt<'tcx>) -> Self {
+    pub fn new(tcx: TyCtxt<'a, 'tcx>) -> Self {
         EraseRegionsVisitor {
             tcx: tcx
         }
@@ -46,7 +46,7 @@ pub struct EraseRegions;
 impl Pass for EraseRegions {}
 
 impl<'tcx> MirPass<'tcx> for EraseRegions {
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
         EraseRegionsVisitor::new(tcx).visit_mir(mir);
     }
 }
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index 9c9f95e2e63..1f6318ab724 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -41,7 +41,7 @@ impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
 }
 
 impl<'tcx> MirPass<'tcx> for NoLandingPads {
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
         if tcx.sess.no_landing_pads() {
             self.visit_mir(mir);
         }
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index c5ebe708eb4..0f08c4af71f 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -330,10 +330,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
     }
 }
 
-pub fn promote_candidates<'tcx>(mir: &mut Mir<'tcx>,
-                                tcx: &TyCtxt<'tcx>,
-                                mut temps: Vec<TempState>,
-                                candidates: Vec<Candidate>) {
+pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
+                                    tcx: TyCtxt<'a, 'tcx>,
+                                    mut temps: Vec<TempState>,
+                                    candidates: Vec<Candidate>) {
     // Visit candidates in reverse, in case they're nested.
     for candidate in candidates.into_iter().rev() {
         let (span, ty) = match candidate {
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 4d07e63dde6..1af9cf8376e 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -109,7 +109,7 @@ impl fmt::Display for Mode {
     }
 }
 
-fn is_const_fn(tcx: &TyCtxt, def_id: DefId) -> bool {
+fn is_const_fn(tcx: TyCtxt, def_id: DefId) -> bool {
     if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
         let fn_like = FnLikeNode::from_node(tcx.map.get(node_id));
         match fn_like.map(|f| f.kind()) {
@@ -132,7 +132,7 @@ struct Qualifier<'a, 'tcx: 'a> {
     def_id: DefId,
     mir: &'a Mir<'tcx>,
     rpo: ReversePostorder<'a, 'tcx>,
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     param_env: ty::ParameterEnvironment<'a, 'tcx>,
     qualif_map: &'a mut DefIdMap<Qualif>,
     mir_map: Option<&'a MirMap<'tcx>>,
@@ -908,11 +908,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> {
     }
 }
 
-fn qualify_const_item_cached<'tcx>(tcx: &TyCtxt<'tcx>,
-                                   qualif_map: &mut DefIdMap<Qualif>,
-                                   mir_map: Option<&MirMap<'tcx>>,
-                                   def_id: DefId)
-                                   -> Qualif {
+fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                       qualif_map: &mut DefIdMap<Qualif>,
+                                       mir_map: Option<&MirMap<'tcx>>,
+                                       def_id: DefId)
+                                       -> Qualif {
     match qualif_map.entry(def_id) {
         Entry::Occupied(entry) => return *entry.get(),
         Entry::Vacant(entry) => {
@@ -951,7 +951,7 @@ pub struct QualifyAndPromoteConstants;
 impl Pass for QualifyAndPromoteConstants {}
 
 impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, map: &mut MirMap<'tcx>) {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, map: &mut MirMap<'tcx>) {
         let mut qualif_map = DefIdMap();
 
         // First, visit `const` items, potentially recursing, to get
diff --git a/src/librustc_mir/transform/remove_dead_blocks.rs b/src/librustc_mir/transform/remove_dead_blocks.rs
index e0d05a17d43..1cd8a569fe3 100644
--- a/src/librustc_mir/transform/remove_dead_blocks.rs
+++ b/src/librustc_mir/transform/remove_dead_blocks.rs
@@ -40,7 +40,7 @@ use rustc::mir::transform::{Pass, MirPass, MirSource};
 pub struct RemoveDeadBlocks;
 
 impl<'tcx> MirPass<'tcx> for RemoveDeadBlocks {
-    fn run_pass(&mut self, _: &TyCtxt<'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
         let mut seen = BitVector::new(mir.basic_blocks.len());
         // This block is always required.
         seen.insert(START_BLOCK.index());
diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs
index a137a812867..93534a694e4 100644
--- a/src/librustc_mir/transform/simplify_cfg.rs
+++ b/src/librustc_mir/transform/simplify_cfg.rs
@@ -111,7 +111,7 @@ impl SimplifyCfg {
 }
 
 impl<'tcx> MirPass<'tcx> for SimplifyCfg {
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
         let mut counter = 0;
         let mut changed = true;
         while changed {
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index d8093f10d96..8ccc621d224 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -114,7 +114,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
         }
     }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.cx.infcx.tcx
     }
 
@@ -349,7 +349,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
     }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.infcx.tcx
     }
 
@@ -576,7 +576,7 @@ impl TypeckMir {
 }
 
 impl<'tcx> MirPass<'tcx> for TypeckMir {
-    fn run_pass(&mut self, tcx: &TyCtxt<'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
         if tcx.sess.err_count() > 0 {
             // compiling a broken program can obviously result in a
             // broken MIR, so try not to report duplicate errors.
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index 111eaf7e4fc..dfc59a6db50 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -68,7 +68,7 @@ enum Mode {
 }
 
 struct CheckCrateVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     mode: Mode,
     qualif: ConstQualif,
     rvalue_borrows: NodeMap<hir::Mutability>
@@ -663,7 +663,7 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt) {
+pub fn check_crate(tcx: TyCtxt) {
     tcx.visit_all_items_in_krate(DepNode::CheckConst, &mut CheckCrateVisitor {
         tcx: tcx,
         mode: Mode::Var,
diff --git a/src/librustc_passes/rvalues.rs b/src/librustc_passes/rvalues.rs
index c2c74a88576..11ce3a17e9e 100644
--- a/src/librustc_passes/rvalues.rs
+++ b/src/librustc_passes/rvalues.rs
@@ -23,13 +23,13 @@ use rustc::hir::intravisit;
 use syntax::ast;
 use syntax::codemap::Span;
 
-pub fn check_crate(tcx: &TyCtxt) {
+pub fn check_crate(tcx: TyCtxt) {
     let mut rvcx = RvalueContext { tcx: tcx };
     tcx.visit_all_items_in_krate(DepNode::RvalueCheck, &mut rvcx);
 }
 
 struct RvalueContext<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for RvalueContext<'a, 'tcx> {
@@ -54,7 +54,7 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for RvalueContext<'a, 'tcx> {
 }
 
 struct RvalueContextDelegate<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     param_env: &'a ty::ParameterEnvironment<'a,'tcx>,
 }
 
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 4a4b7caf478..d224c88d0ff 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -58,7 +58,7 @@ type CheckResult = Option<(Span, String, Option<(Span, String)>)>;
 ////////////////////////////////////////////////////////////////////////////////
 
 struct EmbargoVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     export_map: &'a def::ExportMap,
 
     // Accessibility levels for reachable nodes
@@ -128,7 +128,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
     fn visit_nested_item(&mut self, item: hir::ItemId) {
-        self.visit_item(self.tcx.map.expect_item(item.id))
+        let tcx = self.tcx;
+        self.visit_item(tcx.map.expect_item(item.id))
     }
 
     fn visit_item(&mut self, item: &hir::Item) {
@@ -375,7 +376,7 @@ impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor<
 ////////////////////////////////////////////////////////////////////////////////
 
 struct PrivacyVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     curitem: ast::NodeId,
     in_foreign: bool,
 }
@@ -417,7 +418,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
     fn visit_nested_item(&mut self, item: hir::ItemId) {
-        self.visit_item(self.tcx.map.expect_item(item.id))
+        let tcx = self.tcx;
+        self.visit_item(tcx.map.expect_item(item.id))
     }
 
     fn visit_item(&mut self, item: &hir::Item) {
@@ -524,7 +526,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
 ////////////////////////////////////////////////////////////////////////////////
 
 struct SanePrivacyVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
@@ -595,7 +597,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
 ///////////////////////////////////////////////////////////////////////////////
 
 struct ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     access_levels: &'a AccessLevels,
     in_variant: bool,
     // set of errors produced by this obsolete visitor
@@ -679,7 +681,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
     /// We want to visit items in the context of their containing
     /// module and so forth, so supply a crate for doing a deep walk.
     fn visit_nested_item(&mut self, item: hir::ItemId) {
-        self.visit_item(self.tcx.map.expect_item(item.id))
+        let tcx = self.tcx;
+        self.visit_item(tcx.map.expect_item(item.id))
     }
 
     fn visit_item(&mut self, item: &hir::Item) {
@@ -934,7 +937,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
 ///////////////////////////////////////////////////////////////////////////////
 
 struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     /// The visitor checks that each component type is at least this visible
     required_visibility: ty::Visibility,
     /// The visibility of the least visible component that has been visited
@@ -943,7 +946,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>, old_error_set: &'a NodeSet) -> Self {
+    fn new(tcx: TyCtxt<'a, 'tcx>, old_error_set: &'a NodeSet) -> Self {
         SearchInterfaceForPrivateItemsVisitor {
             tcx: tcx,
             min_visibility: ty::Visibility::Public,
@@ -1015,7 +1018,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
                         let item = self.tcx.map.expect_item(node_id);
                         let vis = match self.substituted_alias_visibility(item, path) {
                             Some(vis) => vis,
-                            None => ty::Visibility::from_hir(&item.vis, node_id, &self.tcx),
+                            None => ty::Visibility::from_hir(&item.vis, node_id, self.tcx),
                         };
 
                         if !vis.is_at_least(self.min_visibility, &self.tcx.map) {
@@ -1047,7 +1050,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
         let def_id = self.tcx.trait_ref_to_def_id(trait_ref);
         if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
             let item = self.tcx.map.expect_item(node_id);
-            let vis = ty::Visibility::from_hir(&item.vis, node_id, &self.tcx);
+            let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx);
 
             if !vis.is_at_least(self.min_visibility, &self.tcx.map) {
                 self.min_visibility = vis;
@@ -1079,7 +1082,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
 }
 
 struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     old_error_set: &'a NodeSet,
 }
 
@@ -1106,7 +1109,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
         };
 
         let mut check = SearchInterfaceForPrivateItemsVisitor::new(self.tcx, self.old_error_set);
-        let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, &self.tcx);
+        let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, self.tcx);
 
         match item.node {
             // Crates are always public
@@ -1125,7 +1128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
             hir::ItemForeignMod(ref foreign_mod) => {
                 for foreign_item in &foreign_mod.items {
                     check.required_visibility =
-                        ty::Visibility::from_hir(&foreign_item.vis, item.id, &self.tcx);
+                        ty::Visibility::from_hir(&foreign_item.vis, item.id, self.tcx);
                     check.visit_foreign_item(foreign_item);
                 }
             }
@@ -1135,7 +1138,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
                 check.visit_generics(generics);
 
                 for field in struct_def.fields() {
-                    let field_visibility = ty::Visibility::from_hir(&field.vis, item.id, &self.tcx);
+                    let field_visibility = ty::Visibility::from_hir(&field.vis, item.id, self.tcx);
                     check.required_visibility = min(item_visibility, field_visibility);
                     check.visit_struct_field(field);
                 }
@@ -1151,7 +1154,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
 
                 for impl_item in impl_items {
                     let impl_item_vis =
-                        ty::Visibility::from_hir(&impl_item.vis, item.id, &self.tcx);
+                        ty::Visibility::from_hir(&impl_item.vis, item.id, self.tcx);
                     check.required_visibility = min(impl_item_vis, ty_vis);
                     check.visit_impl_item(impl_item);
                 }
@@ -1170,7 +1173,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt, export_map: &def::ExportMap) -> AccessLevels {
+pub fn check_crate(tcx: TyCtxt, export_map: &def::ExportMap) -> AccessLevels {
     let _task = tcx.dep_graph.in_task(DepNode::Privacy);
 
     let krate = tcx.map.krate();
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 7a411969363..cb4a9b20dea 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -62,7 +62,7 @@ macro_rules! down_cast_data {
 pub struct DumpVisitor<'l, 'tcx: 'l, 'll, D: 'll> {
     save_ctxt: SaveContext<'l, 'tcx>,
     sess: &'l Session,
-    tcx: &'l TyCtxt<'tcx>,
+    tcx: TyCtxt<'l, 'tcx>,
     analysis: &'l ty::CrateAnalysis<'l>,
     dumper: &'ll mut D,
 
@@ -79,7 +79,7 @@ pub struct DumpVisitor<'l, 'tcx: 'l, 'll, D: 'll> {
 }
 
 impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
-    pub fn new(tcx: &'l TyCtxt<'tcx>,
+    pub fn new(tcx: TyCtxt<'l, 'tcx>,
                save_ctxt: SaveContext<'l, 'tcx>,
                analysis: &'l ty::CrateAnalysis<'l>,
                dumper: &'ll mut D)
diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs
index db4bd1d6d73..51134f8383b 100644
--- a/src/librustc_save_analysis/external_data.rs
+++ b/src/librustc_save_analysis/external_data.rs
@@ -19,7 +19,7 @@ use super::data;
 // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
 pub trait Lower {
     type Target;
-    fn lower(self, tcx: &TyCtxt) -> Self::Target;
+    fn lower(self, tcx: TyCtxt) -> Self::Target;
 }
 
 fn make_def_id(id: NodeId, map: &Map) -> DefId {
@@ -71,7 +71,7 @@ pub struct CratePreludeData {
 impl Lower for data::CratePreludeData {
     type Target = CratePreludeData;
 
-    fn lower(self, tcx: &TyCtxt) -> CratePreludeData {
+    fn lower(self, tcx: TyCtxt) -> CratePreludeData {
         CratePreludeData {
             crate_name: self.crate_name,
             crate_root: self.crate_root,
@@ -94,7 +94,7 @@ pub struct EnumData {
 impl Lower for data::EnumData {
     type Target = EnumData;
 
-    fn lower(self, tcx: &TyCtxt) -> EnumData {
+    fn lower(self, tcx: TyCtxt) -> EnumData {
         EnumData {
             id: make_def_id(self.id, &tcx.map),
             value: self.value,
@@ -119,7 +119,7 @@ pub struct ExternCrateData {
 impl Lower for data::ExternCrateData {
     type Target = ExternCrateData;
 
-    fn lower(self, tcx: &TyCtxt) -> ExternCrateData {
+    fn lower(self, tcx: TyCtxt) -> ExternCrateData {
         ExternCrateData {
             id: make_def_id(self.id, &tcx.map),
             name: self.name,
@@ -142,7 +142,7 @@ pub struct FunctionCallData {
 impl Lower for data::FunctionCallData {
     type Target = FunctionCallData;
 
-    fn lower(self, tcx: &TyCtxt) -> FunctionCallData {
+    fn lower(self, tcx: TyCtxt) -> FunctionCallData {
         FunctionCallData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.map),
@@ -165,7 +165,7 @@ pub struct FunctionData {
 impl Lower for data::FunctionData {
     type Target = FunctionData;
 
-    fn lower(self, tcx: &TyCtxt) -> FunctionData {
+    fn lower(self, tcx: TyCtxt) -> FunctionData {
         FunctionData {
             id: make_def_id(self.id, &tcx.map),
             name: self.name,
@@ -188,7 +188,7 @@ pub struct FunctionRefData {
 impl Lower for data::FunctionRefData {
     type Target = FunctionRefData;
 
-    fn lower(self, tcx: &TyCtxt) -> FunctionRefData {
+    fn lower(self, tcx: TyCtxt) -> FunctionRefData {
         FunctionRefData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.map),
@@ -208,7 +208,7 @@ pub struct ImplData {
 impl Lower for data::ImplData {
     type Target = ImplData;
 
-    fn lower(self, tcx: &TyCtxt) -> ImplData {
+    fn lower(self, tcx: TyCtxt) -> ImplData {
         ImplData {
             id: make_def_id(self.id, &tcx.map),
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
@@ -229,7 +229,7 @@ pub struct InheritanceData {
 impl Lower for data::InheritanceData {
     type Target = InheritanceData;
 
-    fn lower(self, tcx: &TyCtxt) -> InheritanceData {
+    fn lower(self, tcx: TyCtxt) -> InheritanceData {
         InheritanceData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             base_id: self.base_id,
@@ -249,7 +249,7 @@ pub struct MacroData {
 impl Lower for data::MacroData {
     type Target = MacroData;
 
-    fn lower(self, tcx: &TyCtxt) -> MacroData {
+    fn lower(self, tcx: TyCtxt) -> MacroData {
         MacroData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             name: self.name,
@@ -274,7 +274,7 @@ pub struct MacroUseData {
 impl Lower for data::MacroUseData {
     type Target = MacroUseData;
 
-    fn lower(self, tcx: &TyCtxt) -> MacroUseData {
+    fn lower(self, tcx: TyCtxt) -> MacroUseData {
         MacroUseData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             name: self.name,
@@ -298,7 +298,7 @@ pub struct MethodCallData {
 impl Lower for data::MethodCallData {
     type Target = MethodCallData;
 
-    fn lower(self, tcx: &TyCtxt) -> MethodCallData {
+    fn lower(self, tcx: TyCtxt) -> MethodCallData {
         MethodCallData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.map),
@@ -320,7 +320,7 @@ pub struct MethodData {
 impl Lower for data::MethodData {
     type Target = MethodData;
 
-    fn lower(self, tcx: &TyCtxt) -> MethodData {
+    fn lower(self, tcx: TyCtxt) -> MethodData {
         MethodData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.map),
@@ -344,7 +344,7 @@ pub struct ModData {
 impl Lower for data::ModData {
     type Target = ModData;
 
-    fn lower(self, tcx: &TyCtxt) -> ModData {
+    fn lower(self, tcx: TyCtxt) -> ModData {
         ModData {
             id: make_def_id(self.id, &tcx.map),
             name: self.name,
@@ -368,7 +368,7 @@ pub struct ModRefData {
 impl Lower for data::ModRefData {
     type Target = ModRefData;
 
-    fn lower(self, tcx: &TyCtxt) -> ModRefData {
+    fn lower(self, tcx: TyCtxt) -> ModRefData {
         ModRefData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.map),
@@ -391,7 +391,7 @@ pub struct StructData {
 impl Lower for data::StructData {
     type Target = StructData;
 
-    fn lower(self, tcx: &TyCtxt) -> StructData {
+    fn lower(self, tcx: TyCtxt) -> StructData {
         StructData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             id: make_def_id(self.id, &tcx.map),
@@ -416,7 +416,7 @@ pub struct StructVariantData {
 impl Lower for data::StructVariantData {
     type Target = StructVariantData;
 
-    fn lower(self, tcx: &TyCtxt) -> StructVariantData {
+    fn lower(self, tcx: TyCtxt) -> StructVariantData {
         StructVariantData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             id: make_def_id(self.id, &tcx.map),
@@ -440,7 +440,7 @@ pub struct TraitData {
 impl Lower for data::TraitData {
     type Target = TraitData;
 
-    fn lower(self, tcx: &TyCtxt) -> TraitData {
+    fn lower(self, tcx: TyCtxt) -> TraitData {
         TraitData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             id: make_def_id(self.id, &tcx.map),
@@ -465,7 +465,7 @@ pub struct TupleVariantData {
 impl Lower for data::TupleVariantData {
     type Target = TupleVariantData;
 
-    fn lower(self, tcx: &TyCtxt) -> TupleVariantData {
+    fn lower(self, tcx: TyCtxt) -> TupleVariantData {
         TupleVariantData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             id: make_def_id(self.id, &tcx.map),
@@ -490,7 +490,7 @@ pub struct TypedefData {
 impl Lower for data::TypedefData {
     type Target = TypedefData;
 
-    fn lower(self, tcx: &TyCtxt) -> TypedefData {
+    fn lower(self, tcx: TyCtxt) -> TypedefData {
         TypedefData {
             id: make_def_id(self.id, &tcx.map),
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
@@ -512,7 +512,7 @@ pub struct TypeRefData {
 impl Lower for data::TypeRefData {
     type Target = TypeRefData;
 
-    fn lower(self, tcx: &TyCtxt) -> TypeRefData {
+    fn lower(self, tcx: TyCtxt) -> TypeRefData {
         TypeRefData {
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
             scope: make_def_id(self.scope, &tcx.map),
@@ -534,7 +534,7 @@ pub struct UseData {
 impl Lower for data::UseData {
     type Target = UseData;
 
-    fn lower(self, tcx: &TyCtxt) -> UseData {
+    fn lower(self, tcx: TyCtxt) -> UseData {
         UseData {
             id: make_def_id(self.id, &tcx.map),
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
@@ -556,7 +556,7 @@ pub struct UseGlobData {
 impl Lower for data::UseGlobData {
     type Target = UseGlobData;
 
-    fn lower(self, tcx: &TyCtxt) -> UseGlobData {
+    fn lower(self, tcx: TyCtxt) -> UseGlobData {
         UseGlobData {
             id: make_def_id(self.id, &tcx.map),
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
@@ -581,7 +581,7 @@ pub struct VariableData {
 impl Lower for data::VariableData {
     type Target = VariableData;
 
-    fn lower(self, tcx: &TyCtxt) -> VariableData {
+    fn lower(self, tcx: TyCtxt) -> VariableData {
         VariableData {
             id: make_def_id(self.id, &tcx.map),
             name: self.name,
@@ -607,7 +607,7 @@ pub struct VariableRefData {
 impl Lower for data::VariableRefData {
     type Target = VariableRefData;
 
-    fn lower(self, tcx: &TyCtxt) -> VariableRefData {
+    fn lower(self, tcx: TyCtxt) -> VariableRefData {
         VariableRefData {
             name: self.name,
             span: SpanData::from_span(self.span, tcx.sess.codemap()),
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 906923e5cad..f64aa4347a8 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -75,7 +75,7 @@ pub mod recorder {
 }
 
 pub struct SaveContext<'l, 'tcx: 'l> {
-    tcx: &'l TyCtxt<'tcx>,
+    tcx: TyCtxt<'l, 'tcx>,
     span_utils: SpanUtils<'tcx>,
 }
 
@@ -84,12 +84,12 @@ macro_rules! option_try(
 );
 
 impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
-    pub fn new(tcx: &'l TyCtxt<'tcx>) -> SaveContext<'l, 'tcx> {
+    pub fn new(tcx: TyCtxt<'l, 'tcx>) -> SaveContext<'l, 'tcx> {
         let span_utils = SpanUtils::new(&tcx.sess);
         SaveContext::from_span_utils(tcx, span_utils)
     }
 
-    pub fn from_span_utils(tcx: &'l TyCtxt<'tcx>,
+    pub fn from_span_utils(tcx: TyCtxt<'l, 'tcx>,
                            span_utils: SpanUtils<'tcx>)
                            -> SaveContext<'l, 'tcx> {
         SaveContext {
@@ -699,7 +699,7 @@ impl Format {
     }
 }
 
-pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
+pub fn process_crate<'l, 'tcx>(tcx: TyCtxt<'l, 'tcx>,
                                krate: &ast::Crate,
                                analysis: &'l ty::CrateAnalysis<'l>,
                                cratename: &str,
diff --git a/src/librustc_trans/_match.rs b/src/librustc_trans/_match.rs
index a8c01aa6649..83a7b52dfbd 100644
--- a/src/librustc_trans/_match.rs
+++ b/src/librustc_trans/_match.rs
@@ -239,7 +239,7 @@ use syntax::ptr::P;
 struct ConstantExpr<'a>(&'a hir::Expr);
 
 impl<'a> ConstantExpr<'a> {
-    fn eq(self, other: ConstantExpr<'a>, tcx: &TyCtxt) -> bool {
+    fn eq(self, other: ConstantExpr<'a>, tcx: TyCtxt) -> bool {
         match compare_lit_exprs(tcx, self.0, other.0) {
             Some(result) => result == Ordering::Equal,
             None => bug!("compare_list_exprs: type mismatch"),
@@ -259,8 +259,8 @@ enum Opt<'a, 'tcx> {
                               DebugLoc),
 }
 
-impl<'a, 'tcx> Opt<'a, 'tcx> {
-    fn eq(&self, other: &Opt<'a, 'tcx>, tcx: &TyCtxt<'tcx>) -> bool {
+impl<'a, 'b, 'tcx> Opt<'a, 'tcx> {
+    fn eq(&self, other: &Opt<'a, 'tcx>, tcx: TyCtxt<'b, 'tcx>) -> bool {
         match (self, other) {
             (&ConstantValue(a, _), &ConstantValue(b, _)) => a.eq(b, tcx),
             (&ConstantRange(a1, a2, _), &ConstantRange(b1, b2, _)) => {
@@ -789,7 +789,7 @@ fn any_region_pat(m: &[Match], col: usize) -> bool {
     any_pat!(m, col, PatKind::Ref(..))
 }
 
-fn any_irrefutable_adt_pat(tcx: &TyCtxt, m: &[Match], col: usize) -> bool {
+fn any_irrefutable_adt_pat(tcx: TyCtxt, m: &[Match], col: usize) -> bool {
     m.iter().any(|br| {
         let pat = br.pats[col];
         match pat.node {
diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs
index 8922aa06182..ceb5f6ae9e3 100644
--- a/src/librustc_trans/adt.rs
+++ b/src/librustc_trans/adt.rs
@@ -236,9 +236,9 @@ fn dtor_to_init_u8(dtor: bool) -> u8 {
     if dtor { DTOR_NEEDED } else { 0 }
 }
 
-pub trait GetDtorType<'tcx> { fn dtor_type(&self) -> Ty<'tcx>; }
-impl<'tcx> GetDtorType<'tcx> for TyCtxt<'tcx> {
-    fn dtor_type(&self) -> Ty<'tcx> { self.types.u8 }
+pub trait GetDtorType<'tcx> { fn dtor_type(self) -> Ty<'tcx>; }
+impl<'a, 'tcx> GetDtorType<'tcx> for TyCtxt<'a, 'tcx> {
+    fn dtor_type(self) -> Ty<'tcx> { self.types.u8 }
 }
 
 fn dtor_active(flag: u8) -> bool {
@@ -442,9 +442,10 @@ struct Case<'tcx> {
 /// This represents the (GEP) indices to follow to get to the discriminant field
 pub type DiscrField = Vec<usize>;
 
-fn find_discr_field_candidate<'tcx>(tcx: &TyCtxt<'tcx>,
-                                    ty: Ty<'tcx>,
-                                    mut path: DiscrField) -> Option<DiscrField> {
+fn find_discr_field_candidate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                        ty: Ty<'tcx>,
+                                        mut path: DiscrField)
+                                        -> Option<DiscrField> {
     match ty.sty {
         // Fat &T/&mut T/Box<T> i.e. T is [T], str, or Trait
         ty::TyRef(_, ty::TypeAndMut { ty, .. }) | ty::TyBox(ty) if !type_is_sized(tcx, ty) => {
@@ -544,10 +545,10 @@ impl<'tcx> Case<'tcx> {
     }
 }
 
-fn get_cases<'tcx>(tcx: &TyCtxt<'tcx>,
-                   adt: ty::AdtDef<'tcx>,
-                   substs: &subst::Substs<'tcx>)
-                   -> Vec<Case<'tcx>> {
+fn get_cases<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                       adt: ty::AdtDef<'tcx>,
+                       substs: &subst::Substs<'tcx>)
+                       -> Vec<Case<'tcx>> {
     adt.variants.iter().map(|vi| {
         let field_tys = vi.fields.iter().map(|field| {
             monomorphize::field_ty(tcx, substs, field)
@@ -668,7 +669,7 @@ fn bounds_usable(cx: &CrateContext, ity: IntType, bounds: &IntBounds) -> bool {
     }
 }
 
-pub fn ty_of_inttype<'tcx>(tcx: &TyCtxt<'tcx>, ity: IntType) -> Ty<'tcx> {
+pub fn ty_of_inttype<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, ity: IntType) -> Ty<'tcx> {
     match ity {
         attr::SignedInt(t) => tcx.mk_mach_int(t),
         attr::UnsignedInt(t) => tcx.mk_mach_uint(t)
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 3e69bb204b9..ec728da4747 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -124,9 +124,7 @@ pub fn find_crate_name(sess: Option<&Session>,
 
 }
 
-pub fn build_link_meta(tcx: &TyCtxt,
-                       name: &str)
-                       -> LinkMeta {
+pub fn build_link_meta(tcx: TyCtxt, name: &str) -> LinkMeta {
     let r = LinkMeta {
         crate_name: name.to_owned(),
         crate_hash: tcx.calculate_krate_hash(),
diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs
index 8127d1c0e29..cc353af81f5 100644
--- a/src/librustc_trans/back/symbol_names.rs
+++ b/src/librustc_trans/back/symbol_names.rs
@@ -103,7 +103,7 @@ use util::sha2::{Digest, Sha256};
 
 use rustc::middle::cstore;
 use rustc::hir::def_id::DefId;
-use rustc::ty::{self, TypeFoldable};
+use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc::ty::item_path::{ItemPathBuffer, RootMode};
 use rustc::hir::map::definitions::{DefPath, DefPathData};
 
@@ -111,12 +111,12 @@ use std::fmt::Write;
 use syntax::parse::token::{self, InternedString};
 use serialize::hex::ToHex;
 
-pub fn def_id_to_string<'tcx>(tcx: &ty::TyCtxt<'tcx>, def_id: DefId) -> String {
+pub fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, def_id: DefId) -> String {
     let def_path = tcx.def_path(def_id);
     def_path_to_string(tcx, &def_path)
 }
 
-pub fn def_path_to_string<'tcx>(tcx: &ty::TyCtxt<'tcx>, def_path: &DefPath) -> String {
+pub fn def_path_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, def_path: &DefPath) -> String {
     let mut s = String::with_capacity(def_path.data.len() * 16);
 
     s.push_str(&tcx.crate_name(def_path.krate));
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index f095b60ac48..221d32528de 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -1308,7 +1308,7 @@ impl<'v> Visitor<'v> for FindNestedReturn {
     }
 }
 
-fn build_cfg(tcx: &TyCtxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>) {
+fn build_cfg(tcx: TyCtxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>) {
     let blk = match tcx.map.find(id) {
         Some(hir_map::NodeItem(i)) => {
             match i.node {
@@ -1364,7 +1364,7 @@ fn build_cfg(tcx: &TyCtxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>) {
 // part of a larger expression that may have already partially-filled the
 // return slot alloca. This can cause errors related to clean-up due to
 // the clobbering of the existing value in the return slot.
-fn has_nested_returns(tcx: &TyCtxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool {
+fn has_nested_returns(tcx: TyCtxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool {
     for index in cfg.graph.depth_traverse(cfg.entry) {
         let n = cfg.graph.node_data(index);
         match tcx.map.find(n.id()) {
@@ -2688,10 +2688,10 @@ pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
     }).collect()
 }
 
-pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
-                         mir_map: &MirMap<'tcx>,
-                         analysis: ty::CrateAnalysis)
-                         -> CrateTranslation {
+pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                             mir_map: &MirMap<'tcx>,
+                             analysis: ty::CrateAnalysis)
+                             -> CrateTranslation {
     let _task = tcx.dep_graph.in_task(DepNode::TransCrate);
 
     // Be careful with this krate: obviously it gives access to the
@@ -2714,7 +2714,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
         tcx.sess.opts.debug_assertions
     };
 
-    let link_meta = link::build_link_meta(&tcx, name);
+    let link_meta = link::build_link_meta(tcx, name);
 
     let shared_ccx = SharedCrateContext::new(tcx,
                                              &mir_map,
diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs
index 6c4a568a70a..fd026067b88 100644
--- a/src/librustc_trans/callee.rs
+++ b/src/librustc_trans/callee.rs
@@ -275,10 +275,10 @@ impl<'tcx> Callee<'tcx> {
 }
 
 /// Given a DefId and some Substs, produces the monomorphic item type.
-fn def_ty<'tcx>(tcx: &TyCtxt<'tcx>,
-                def_id: DefId,
-                substs: &'tcx subst::Substs<'tcx>)
-                -> Ty<'tcx> {
+fn def_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                    def_id: DefId,
+                    substs: &'tcx subst::Substs<'tcx>)
+                    -> Ty<'tcx> {
     let ty = tcx.lookup_item_type(def_id).ty;
     monomorphize::apply_param_substs(tcx, substs, &ty)
 }
@@ -442,7 +442,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     // def_id to the local id of the inlined copy.
     let def_id = inline::maybe_instantiate_inline(ccx, def_id);
 
-    fn is_named_tuple_constructor(tcx: &TyCtxt, def_id: DefId) -> bool {
+    fn is_named_tuple_constructor(tcx: TyCtxt, def_id: DefId) -> bool {
         let node_id = match tcx.map.as_local_node_id(def_id) {
             Some(n) => n,
             None => { return false; }
diff --git a/src/librustc_trans/cleanup.rs b/src/librustc_trans/cleanup.rs
index 514e6bda594..3081f055bb4 100644
--- a/src/librustc_trans/cleanup.rs
+++ b/src/librustc_trans/cleanup.rs
@@ -1176,7 +1176,7 @@ impl<'tcx> Cleanup<'tcx> for LifetimeEnd {
     }
 }
 
-pub fn temporary_scope(tcx: &TyCtxt,
+pub fn temporary_scope(tcx: TyCtxt,
                        id: ast::NodeId)
                        -> ScopeId {
     match tcx.region_maps.temporary_scope(id) {
@@ -1191,7 +1191,7 @@ pub fn temporary_scope(tcx: &TyCtxt,
     }
 }
 
-pub fn var_scope(tcx: &TyCtxt,
+pub fn var_scope(tcx: TyCtxt,
                  id: ast::NodeId)
                  -> ScopeId {
     let r = AstScope(tcx.region_maps.var_scope(id).node_id(&tcx.region_maps));
diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs
index 86a91d261fc..1bc99a9a6e9 100644
--- a/src/librustc_trans/closure.rs
+++ b/src/librustc_trans/closure.rs
@@ -119,10 +119,10 @@ impl ClosureEnv {
     }
 }
 
-fn get_self_type<'tcx>(tcx: &TyCtxt<'tcx>,
-                       closure_id: DefId,
-                       fn_ty: Ty<'tcx>)
-                       -> Ty<'tcx> {
+fn get_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                           closure_id: DefId,
+                           fn_ty: Ty<'tcx>)
+                           -> Ty<'tcx> {
     match tcx.closure_kind(closure_id) {
         ty::ClosureKind::Fn => {
             tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), fn_ty)
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index ba924d6ae3e..19b4e65b470 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -432,10 +432,10 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
     debug!("END collect_items_rec({})", starting_point.to_string(scx.tcx()));
 }
 
-fn record_references<'tcx>(tcx: &TyCtxt<'tcx>,
-                           caller: TransItem<'tcx>,
-                           callees: &[TransItem<'tcx>],
-                           reference_map: &mut ReferenceMap<'tcx>) {
+fn record_references<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                               caller: TransItem<'tcx>,
+                               callees: &[TransItem<'tcx>],
+                               reference_map: &mut ReferenceMap<'tcx>) {
     let iter = callees.into_iter()
                       .map(|callee| {
                         let is_inlining_candidate = callee.is_from_extern_crate() ||
@@ -445,10 +445,10 @@ fn record_references<'tcx>(tcx: &TyCtxt<'tcx>,
     reference_map.record_references(caller, iter);
 }
 
-fn check_recursion_limit<'tcx>(tcx: &TyCtxt<'tcx>,
-                               instance: Instance<'tcx>,
-                               recursion_depths: &mut DefIdMap<usize>)
-                               -> (DefId, usize) {
+fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                   instance: Instance<'tcx>,
+                                   recursion_depths: &mut DefIdMap<usize>)
+                                   -> (DefId, usize) {
     let recursion_depth = recursion_depths.get(&instance.def)
                                           .map(|x| *x)
                                           .unwrap_or(0);
@@ -606,9 +606,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
 
         self.super_operand(operand);
 
-        fn can_result_in_trans_item<'tcx>(tcx: &TyCtxt<'tcx>,
-                                          def_id: DefId)
-                                          -> bool {
+        fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                              def_id: DefId)
+                                              -> bool {
             if !match tcx.lookup_item_type(def_id).ty.sty {
                 ty::TyFnDef(def_id, _, _) => {
                     // Some constructors also have type TyFnDef but they are
@@ -635,9 +635,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
     }
 }
 
-fn can_have_local_instance<'tcx>(tcx: &TyCtxt<'tcx>,
-                                 def_id: DefId)
-                                 -> bool {
+fn can_have_local_instance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                     def_id: DefId)
+                                     -> bool {
     // Take a look if we have the definition available. If not, we
     // will not emit code for this item in the local crate, and thus
     // don't create a translation item for it.
@@ -960,11 +960,11 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
     }
 }
 
-fn create_fn_trans_item<'tcx>(tcx: &TyCtxt<'tcx>,
-                              def_id: DefId,
-                              fn_substs: &Substs<'tcx>,
-                              param_substs: &Substs<'tcx>)
-                              -> TransItem<'tcx> {
+fn create_fn_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                  def_id: DefId,
+                                  fn_substs: &Substs<'tcx>,
+                                  param_substs: &Substs<'tcx>)
+                                  -> TransItem<'tcx> {
     debug!("create_fn_trans_item(def_id={}, fn_substs={:?}, param_substs={:?})",
             def_id_to_string(tcx, def_id),
             fn_substs,
@@ -1146,9 +1146,9 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
     }
 }
 
-fn create_trans_items_for_default_impls<'tcx>(tcx: &TyCtxt<'tcx>,
-                                              item: &'tcx hir::Item,
-                                              output: &mut Vec<TransItem<'tcx>>) {
+fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                                  item: &'tcx hir::Item,
+                                                  output: &mut Vec<TransItem<'tcx>>) {
     match item.node {
         hir::ItemImpl(_,
                       _,
@@ -1225,9 +1225,9 @@ fn create_trans_items_for_default_impls<'tcx>(tcx: &TyCtxt<'tcx>,
 
 /// Same as `unique_type_name()` but with the result pushed onto the given
 /// `output` parameter.
-pub fn push_unique_type_name<'tcx>(tcx: &TyCtxt<'tcx>,
-                                   t: ty::Ty<'tcx>,
-                                   output: &mut String) {
+pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                       t: ty::Ty<'tcx>,
+                                       output: &mut String) {
     match t.sty {
         ty::TyBool              => output.push_str("bool"),
         ty::TyChar              => output.push_str("char"),
@@ -1363,7 +1363,7 @@ pub fn push_unique_type_name<'tcx>(tcx: &TyCtxt<'tcx>,
     }
 }
 
-fn push_item_name(tcx: &TyCtxt,
+fn push_item_name(tcx: TyCtxt,
                   def_id: DefId,
                   output: &mut String) {
     let def_path = tcx.def_path(def_id);
@@ -1384,10 +1384,10 @@ fn push_item_name(tcx: &TyCtxt,
     output.pop();
 }
 
-fn push_type_params<'tcx>(tcx: &TyCtxt<'tcx>,
-                          types: &'tcx subst::VecPerParamSpace<Ty<'tcx>>,
-                          projections: &[ty::PolyProjectionPredicate<'tcx>],
-                          output: &mut String) {
+fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                              types: &'tcx subst::VecPerParamSpace<Ty<'tcx>>,
+                              projections: &[ty::PolyProjectionPredicate<'tcx>],
+                              output: &mut String) {
     if types.is_empty() && projections.is_empty() {
         return;
     }
@@ -1414,30 +1414,29 @@ fn push_type_params<'tcx>(tcx: &TyCtxt<'tcx>,
     output.push('>');
 }
 
-fn push_instance_as_string<'tcx>(tcx: &TyCtxt<'tcx>,
-                                 instance: Instance<'tcx>,
-                                 output: &mut String) {
+fn push_instance_as_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                     instance: Instance<'tcx>,
+                                     output: &mut String) {
     push_item_name(tcx, instance.def, output);
     push_type_params(tcx, &instance.substs.types, &[], output);
 }
 
-pub fn def_id_to_string(tcx: &TyCtxt, def_id: DefId) -> String {
+pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String {
     let mut output = String::new();
     push_item_name(tcx, def_id, &mut output);
     output
 }
 
-fn type_to_string<'tcx>(tcx: &TyCtxt<'tcx>,
-                        ty: ty::Ty<'tcx>)
-                        -> String {
+fn type_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                            ty: ty::Ty<'tcx>)
+                            -> String {
     let mut output = String::new();
     push_unique_type_name(tcx, ty, &mut output);
     output
 }
 
-impl<'tcx> TransItem<'tcx> {
-
-    pub fn requests_inline(&self, tcx: &TyCtxt<'tcx>) -> bool {
+impl<'a, 'tcx> TransItem<'tcx> {
+    pub fn requests_inline(&self, tcx: TyCtxt<'a, 'tcx>) -> bool {
         match *self {
             TransItem::Fn(ref instance) => {
                 let attributes = tcx.get_attrs(instance.def);
@@ -1464,7 +1463,7 @@ impl<'tcx> TransItem<'tcx> {
         }
     }
 
-    pub fn explicit_linkage(&self, tcx: &TyCtxt<'tcx>) -> Option<llvm::Linkage> {
+    pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx>) -> Option<llvm::Linkage> {
         let def_id = match *self {
             TransItem::Fn(ref instance) => instance.def,
             TransItem::Static(node_id) => tcx.map.local_def_id(node_id),
@@ -1488,7 +1487,7 @@ impl<'tcx> TransItem<'tcx> {
         }
     }
 
-    pub fn to_string(&self, tcx: &TyCtxt<'tcx>) -> String {
+    pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx>) -> String {
         let hir_map = &tcx.map;
 
         return match *self {
@@ -1511,10 +1510,10 @@ impl<'tcx> TransItem<'tcx> {
             },
         };
 
-        fn to_string_internal<'tcx>(tcx: &TyCtxt<'tcx>,
-                                    prefix: &str,
-                                    instance: Instance<'tcx>)
-                                    -> String {
+        fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                        prefix: &str,
+                                        instance: Instance<'tcx>)
+                                        -> String {
             let mut result = String::with_capacity(32);
             result.push_str(prefix);
             push_instance_as_string(tcx, instance, &mut result);
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index bab18e1469d..5e69c775634 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -58,11 +58,11 @@ use syntax::parse::token;
 pub use context::{CrateContext, SharedCrateContext};
 
 /// Is the type's representation size known at compile time?
-pub fn type_is_sized<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
+pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
     ty.is_sized(&tcx.empty_parameter_environment(), DUMMY_SP)
 }
 
-pub fn type_is_fat_ptr<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
+pub fn type_is_fat_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
     match ty.sty {
         ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
         ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
@@ -164,8 +164,8 @@ pub struct VariantInfo<'tcx> {
     pub fields: Vec<Field<'tcx>>
 }
 
-impl<'tcx> VariantInfo<'tcx> {
-    pub fn from_ty(tcx: &TyCtxt<'tcx>,
+impl<'a, 'tcx> VariantInfo<'tcx> {
+    pub fn from_ty(tcx: TyCtxt<'a, 'tcx>,
                    ty: Ty<'tcx>,
                    opt_def: Option<Def>)
                    -> Self
@@ -201,7 +201,7 @@ impl<'tcx> VariantInfo<'tcx> {
     }
 
     /// Return the variant corresponding to a given node (e.g. expr)
-    pub fn of_node(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>, id: ast::NodeId) -> Self {
+    pub fn of_node(tcx: TyCtxt<'a, 'tcx>, ty: Ty<'tcx>, id: ast::NodeId) -> Self {
         let node_def = tcx.def_map.borrow().get(&id).map(|v| v.full_def());
         Self::from_ty(tcx, ty, node_def)
     }
@@ -568,7 +568,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
     pub fn fcx(&self) -> &'blk FunctionContext<'blk, 'tcx> {
         self.fcx
     }
-    pub fn tcx(&self) -> &'blk TyCtxt<'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'blk, 'tcx> {
         self.fcx.ccx.tcx()
     }
     pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
@@ -694,7 +694,7 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
     pub fn fcx(&self) -> &'blk FunctionContext<'blk, 'tcx> {
         self.bcx.fcx()
     }
-    pub fn tcx(&self) -> &'blk TyCtxt<'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'blk, 'tcx> {
         self.bcx.tcx()
     }
     pub fn sess(&self) -> &'blk Session {
@@ -1119,9 +1119,9 @@ pub fn fulfill_obligation<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
 /// returns false, then either normalize encountered an error or one
 /// of the predicates did not hold. Used when creating vtables to
 /// check for unsatisfiable methods.
-pub fn normalize_and_test_predicates<'tcx>(tcx: &TyCtxt<'tcx>,
-                                           predicates: Vec<ty::Predicate<'tcx>>)
-                                           -> bool
+pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                               predicates: Vec<ty::Predicate<'tcx>>)
+                                               -> bool
 {
     debug!("normalize_and_test_predicates(predicates={:?})",
            predicates);
diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs
index 2811148abd6..3fc9e89098c 100644
--- a/src/librustc_trans/consts.rs
+++ b/src/librustc_trans/consts.rs
@@ -472,7 +472,7 @@ fn check_unary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
     Ok(())
 }
 
-pub fn to_const_int(value: ValueRef, t: Ty, tcx: &TyCtxt) -> Option<ConstInt> {
+pub fn to_const_int(value: ValueRef, t: Ty, tcx: TyCtxt) -> Option<ConstInt> {
     match t.sty {
         ty::TyInt(int_type) => const_to_opt_int(value).and_then(|input| match int_type {
             ast::IntTy::I8 => {
diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs
index 24095929f4f..49b71ae5889 100644
--- a/src/librustc_trans/context.rs
+++ b/src/librustc_trans/context.rs
@@ -73,7 +73,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
     item_symbols: RefCell<NodeMap<String>>,
     link_meta: LinkMeta,
     symbol_hasher: RefCell<Sha256>,
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     stats: Stats,
     check_overflow: bool,
     check_drop_flag_for_sanity: bool,
@@ -331,7 +331,7 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
 }
 
 impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
-    pub fn new(tcx: &'b TyCtxt<'tcx>,
+    pub fn new(tcx: TyCtxt<'b, 'tcx>,
                mir_map: &'b MirMap<'tcx>,
                export_map: ExportMap,
                symbol_hasher: Sha256,
@@ -450,7 +450,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
         &self.link_meta
     }
 
-    pub fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx> {
+    pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx> {
         self.tcx
     }
 
@@ -640,7 +640,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         }
     }
 
-    pub fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx> {
+    pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx> {
         self.shared.tcx
     }
 
diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs
index edb3d167dde..a5416c2fed1 100644
--- a/src/librustc_trans/expr.rs
+++ b/src/librustc_trans/expr.rs
@@ -722,7 +722,7 @@ fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                               base: &hir::Expr,
                               get_idx: F)
                               -> DatumBlock<'blk, 'tcx, Expr> where
-    F: FnOnce(&'blk TyCtxt<'tcx>, &VariantInfo<'tcx>) -> usize,
+    F: FnOnce(TyCtxt<'blk, 'tcx>, &VariantInfo<'tcx>) -> usize,
 {
     let mut bcx = bcx;
     let _icx = push_ctxt("trans_rec_field");
@@ -1826,11 +1826,11 @@ fn trans_binary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn cast_is_noop<'tcx>(tcx: &TyCtxt<'tcx>,
-                          expr: &hir::Expr,
-                          t_in: Ty<'tcx>,
-                          t_out: Ty<'tcx>)
-                          -> bool {
+pub fn cast_is_noop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                              expr: &hir::Expr,
+                              t_in: Ty<'tcx>,
+                              t_out: Ty<'tcx>)
+                              -> bool {
     if let Some(&CastKind::CoercionCast) = tcx.cast_kinds.borrow().get(&expr.id) {
         return true;
     }
@@ -2185,7 +2185,7 @@ impl OverflowOpViaIntrinsic {
         let name = self.to_intrinsic_name(bcx.tcx(), lhs_ty);
         bcx.ccx().get_intrinsic(&name)
     }
-    fn to_intrinsic_name(&self, tcx: &TyCtxt, ty: Ty) -> &'static str {
+    fn to_intrinsic_name(&self, tcx: TyCtxt, ty: Ty) -> &'static str {
         use syntax::ast::IntTy::*;
         use syntax::ast::UintTy::*;
         use rustc::ty::{TyInt, TyUint};
@@ -2377,7 +2377,7 @@ enum ExprKind {
     RvalueStmt
 }
 
-fn expr_kind(tcx: &TyCtxt, expr: &hir::Expr) -> ExprKind {
+fn expr_kind(tcx: TyCtxt, expr: &hir::Expr) -> ExprKind {
     if tcx.is_method_call(expr.id) {
         // Overloaded operations are generally calls, and hence they are
         // generated via DPS, but there are a few exceptions:
diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs
index e82821f478f..660ce0e0fce 100644
--- a/src/librustc_trans/glue.rs
+++ b/src/librustc_trans/glue.rs
@@ -89,12 +89,12 @@ pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn type_needs_drop<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
+pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
     tcx.type_needs_drop_given_env(ty, &tcx.empty_parameter_environment())
 }
 
-pub fn get_drop_glue_type<'tcx>(tcx: &TyCtxt<'tcx>,
-                                t: Ty<'tcx>) -> Ty<'tcx> {
+pub fn get_drop_glue_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                    t: Ty<'tcx>) -> Ty<'tcx> {
     // Even if there is no dtor for t, there might be one deeper down and we
     // might need to pass in the vtable ptr.
     if !type_is_sized(tcx, t) {
@@ -110,11 +110,11 @@ pub fn get_drop_glue_type<'tcx>(tcx: &TyCtxt<'tcx>,
     // returned `tcx.types.i8` does not appear unsound. The impact on
     // code quality is unknown at this time.)
 
-    if !type_needs_drop(&tcx, t) {
+    if !type_needs_drop(tcx, t) {
         return tcx.types.i8;
     }
     match t.sty {
-        ty::TyBox(typ) if !type_needs_drop(&tcx, typ)
+        ty::TyBox(typ) if !type_needs_drop(tcx, typ)
                          && type_is_sized(tcx, typ) => {
             let infcx = InferCtxt::normalizing(tcx,
                                                &tcx.tables,
diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs
index 937c6ede603..e5f0f358f96 100644
--- a/src/librustc_trans/meth.rs
+++ b/src/librustc_trans/meth.rs
@@ -215,10 +215,10 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     vtable
 }
 
-pub fn get_vtable_methods<'tcx>(tcx: &TyCtxt<'tcx>,
-                                impl_id: DefId,
-                                substs: &'tcx subst::Substs<'tcx>)
-                                -> Vec<Option<ImplMethod<'tcx>>>
+pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                    impl_id: DefId,
+                                    substs: &'tcx subst::Substs<'tcx>)
+                                    -> Vec<Option<ImplMethod<'tcx>>>
 {
     debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);
 
@@ -304,11 +304,11 @@ pub struct ImplMethod<'tcx> {
 }
 
 /// Locates the applicable definition of a method, given its name.
-pub fn get_impl_method<'tcx>(tcx: &TyCtxt<'tcx>,
-                             impl_def_id: DefId,
-                             substs: &'tcx Substs<'tcx>,
-                             name: Name)
-                             -> ImplMethod<'tcx>
+pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                 impl_def_id: DefId,
+                                 substs: &'tcx Substs<'tcx>,
+                                 name: Name)
+                                 -> ImplMethod<'tcx>
 {
     assert!(!substs.types.needs_infer());
 
diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs
index ee94d6fa48e..97e9af5fb6e 100644
--- a/src/librustc_trans/monomorphize.rs
+++ b/src/librustc_trans/monomorphize.rs
@@ -182,17 +182,17 @@ impl<'tcx> Instance<'tcx> {
         assert!(substs.regions.iter().all(|&r| r == ty::ReStatic));
         Instance { def: def_id, substs: substs }
     }
-    pub fn mono(tcx: &TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
-        Instance::new(def_id, &tcx.mk_substs(Substs::empty()))
+    pub fn mono<'a>(tcx: TyCtxt<'a, 'tcx>, def_id: DefId) -> Instance<'tcx> {
+        Instance::new(def_id, tcx.mk_substs(Substs::empty()))
     }
 }
 
 /// Monomorphizes a type from the AST by first applying the in-scope
 /// substitutions and then normalizing any associated types.
-pub fn apply_param_substs<'tcx,T>(tcx: &TyCtxt<'tcx>,
-                                  param_substs: &Substs<'tcx>,
-                                  value: &T)
-                                  -> T
+pub fn apply_param_substs<'a, 'tcx, T>(tcx: TyCtxt<'a, 'tcx>,
+                                       param_substs: &Substs<'tcx>,
+                                       value: &T)
+                                       -> T
     where T : TypeFoldable<'tcx>
 {
     let substituted = value.subst(tcx, param_substs);
@@ -201,10 +201,10 @@ pub fn apply_param_substs<'tcx,T>(tcx: &TyCtxt<'tcx>,
 
 
 /// Returns the normalized type of a struct field
-pub fn field_ty<'tcx>(tcx: &TyCtxt<'tcx>,
-                      param_substs: &Substs<'tcx>,
-                      f: ty::FieldDef<'tcx>)
-                      -> Ty<'tcx>
+pub fn field_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                          param_substs: &Substs<'tcx>,
+                          f: ty::FieldDef<'tcx>)
+                          -> Ty<'tcx>
 {
     tcx.normalize_associated_type(&f.ty(tcx, param_substs))
 }
diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs
index 7b21b612097..efeb0abe28c 100644
--- a/src/librustc_trans/partitioning.rs
+++ b/src/librustc_trans/partitioning.rs
@@ -153,11 +153,11 @@ pub enum PartitioningStrategy {
 // Anything we can't find a proper codegen unit for goes into this.
 const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
 
-pub fn partition<'tcx, I>(tcx: &TyCtxt<'tcx>,
-                          trans_items: I,
-                          strategy: PartitioningStrategy,
-                          reference_map: &ReferenceMap<'tcx>)
-                          -> Vec<CodegenUnit<'tcx>>
+pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx>,
+                              trans_items: I,
+                              strategy: PartitioningStrategy,
+                              reference_map: &ReferenceMap<'tcx>)
+                              -> Vec<CodegenUnit<'tcx>>
     where I: Iterator<Item = TransItem<'tcx>>
 {
     // In the first step, we place all regular translation items into their
@@ -193,9 +193,9 @@ struct PreInliningPartitioning<'tcx> {
 struct PostInliningPartitioning<'tcx>(Vec<CodegenUnit<'tcx>>);
 struct PostDeclarationsPartitioning<'tcx>(Vec<CodegenUnit<'tcx>>);
 
-fn place_root_translation_items<'tcx, I>(tcx: &TyCtxt<'tcx>,
-                                         trans_items: I)
-                                         -> PreInliningPartitioning<'tcx>
+fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx>,
+                                             trans_items: I)
+                                             -> PreInliningPartitioning<'tcx>
     where I: Iterator<Item = TransItem<'tcx>>
 {
     let mut roots = FnvHashSet();
@@ -375,9 +375,9 @@ fn place_declarations<'tcx>(codegen_units: PostInliningPartitioning<'tcx>,
     PostDeclarationsPartitioning(codegen_units)
 }
 
-fn characteristic_def_id_of_trans_item<'tcx>(tcx: &TyCtxt<'tcx>,
-                                             trans_item: TransItem<'tcx>)
-                                             -> Option<DefId> {
+fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                                 trans_item: TransItem<'tcx>)
+                                                 -> Option<DefId> {
     match trans_item {
         TransItem::Fn(instance) => {
             // If this is a method, we want to put it into the same module as
@@ -410,10 +410,10 @@ fn characteristic_def_id_of_trans_item<'tcx>(tcx: &TyCtxt<'tcx>,
     }
 }
 
-fn compute_codegen_unit_name<'tcx>(tcx: &TyCtxt<'tcx>,
-                                   def_id: DefId,
-                                   volatile: bool)
-                                   -> InternedString {
+fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                                       def_id: DefId,
+                                       volatile: bool)
+                                       -> InternedString {
     // Unfortunately we cannot just use the `ty::item_path` infrastructure here
     // because we need paths to modules and the DefIds of those are not
     // available anymore for external items.
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 0ddbfe3310f..1ed09be8ae9 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -79,7 +79,7 @@ use rustc::hir;
 use rustc_back::slice;
 
 pub trait AstConv<'tcx> {
-    fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>;
+    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx>;
 
     /// Identify the type scheme for an item with a type, like a type
     /// alias, fn, or struct. This allows you to figure out the set of
@@ -162,7 +162,7 @@ pub trait AstConv<'tcx> {
     fn set_tainted_by_errors(&self);
 }
 
-pub fn ast_region_to_region(tcx: &TyCtxt, lifetime: &hir::Lifetime)
+pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime)
                             -> ty::Region {
     let r = match tcx.named_region_map.get(&lifetime.id) {
         None => {
@@ -1175,7 +1175,7 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>,
     tcx.mk_trait(object.principal, object.bounds)
 }
 
-fn report_ambiguous_associated_type(tcx: &TyCtxt,
+fn report_ambiguous_associated_type(tcx: TyCtxt,
                                     span: Span,
                                     type_str: &str,
                                     trait_str: &str,
@@ -2159,7 +2159,7 @@ pub struct PartitionedBounds<'a> {
 
 /// Divides a list of bounds from the AST into three groups: builtin bounds (Copy, Sized etc),
 /// general trait bounds, and region bounds.
-pub fn partition_bounds<'a>(tcx: &TyCtxt,
+pub fn partition_bounds<'a>(tcx: TyCtxt,
                             _span: Span,
                             ast_bounds: &'a [hir::TyParamBound])
                             -> PartitionedBounds<'a>
@@ -2208,7 +2208,7 @@ pub fn partition_bounds<'a>(tcx: &TyCtxt,
     }
 }
 
-fn check_type_argument_count(tcx: &TyCtxt, span: Span, supplied: usize,
+fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
                              required: usize, accepted: usize) {
     if supplied < required {
         let expected = if required < accepted {
@@ -2233,7 +2233,7 @@ fn check_type_argument_count(tcx: &TyCtxt, span: Span, supplied: usize,
     }
 }
 
-fn report_lifetime_number_error(tcx: &TyCtxt, span: Span, number: usize, expected: usize) {
+fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
     span_err!(tcx.sess, span, E0107,
               "wrong number of lifetime parameters: expected {}, found {}",
               expected, number);
@@ -2249,11 +2249,9 @@ pub struct Bounds<'tcx> {
     pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
 }
 
-impl<'tcx> Bounds<'tcx> {
-    pub fn predicates(&self,
-        tcx: &TyCtxt<'tcx>,
-        param_ty: Ty<'tcx>)
-        -> Vec<ty::Predicate<'tcx>>
+impl<'a, 'tcx> Bounds<'tcx> {
+    pub fn predicates(&self, tcx: TyCtxt<'a, 'tcx>, param_ty: Ty<'tcx>)
+                      -> Vec<ty::Predicate<'tcx>>
     {
         let mut vec = Vec::new();
 
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index d414effcda0..d534e48dd05 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -107,7 +107,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         }
     }
 
-    fn tcx(&self) -> &TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'f, 'tcx> {
         self.fcx.tcx()
     }
 
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 0b4dc55fbf7..ab5342bfa1a 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -617,7 +617,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
     ///////////////////////////////////////////////////////////////////////////
     // MISCELLANY
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.fcx.tcx()
     }
 
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 56f1f4677c6..3e997bc140f 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -267,7 +267,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         self.private_candidate = None;
     }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.fcx.tcx()
     }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 686d33b5e53..76b0e9342bd 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -365,7 +365,7 @@ pub struct FnCtxt<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> Inherited<'a, 'tcx> {
-    fn new(tcx: &'a TyCtxt<'tcx>,
+    fn new(tcx: TyCtxt<'a, 'tcx>,
            tables: &'a RefCell<ty::Tables<'tcx>>,
            param_env: ty::ParameterEnvironment<'a, 'tcx>)
            -> Inherited<'a, 'tcx> {
@@ -902,7 +902,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
 }
 
-fn report_forbidden_specialization(tcx: &TyCtxt,
+fn report_forbidden_specialization(tcx: TyCtxt,
                                    impl_item: &hir::ImplItem,
                                    parent_impl: DefId)
 {
@@ -925,8 +925,8 @@ fn report_forbidden_specialization(tcx: &TyCtxt,
     err.emit();
 }
 
-fn check_specialization_validity<'tcx>(tcx: &TyCtxt<'tcx>, trait_def: &ty::TraitDef<'tcx>,
-                                       impl_id: DefId, impl_item: &hir::ImplItem)
+fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>, trait_def: &ty::TraitDef<'tcx>,
+                                           impl_id: DefId, impl_item: &hir::ImplItem)
 {
     let ancestors = trait_def.ancestors(impl_id);
 
@@ -1143,7 +1143,7 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
 /// Checks whether a type can be represented in memory. In particular, it
 /// identifies types that contain themselves without indirection through a
 /// pointer, which would mean their size is unbounded.
-pub fn check_representable(tcx: &TyCtxt,
+pub fn check_representable(tcx: TyCtxt,
                            sp: Span,
                            item_id: ast::NodeId,
                            _designation: &str) -> bool {
@@ -1165,7 +1165,7 @@ pub fn check_representable(tcx: &TyCtxt,
     return true
 }
 
-pub fn check_simd(tcx: &TyCtxt, sp: Span, id: ast::NodeId) {
+pub fn check_simd(tcx: TyCtxt, sp: Span, id: ast::NodeId) {
     let t = tcx.node_id_to_type(id);
     match t.sty {
         ty::TyStruct(def, substs) => {
@@ -1253,7 +1253,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
 }
 
 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> { self.infcx().tcx }
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.infcx().tcx }
 
     fn get_item_type_scheme(&self, _: Span, id: DefId)
                             -> Result<ty::TypeScheme<'tcx>, ErrorReported>
@@ -1438,7 +1438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn tcx(&self) -> &TyCtxt<'tcx> { self.infcx().tcx }
+    pub fn tcx(&self) -> TyCtxt<'a, 'tcx> { self.infcx().tcx }
 
     pub fn infcx(&self) -> &InferCtxt<'a,'tcx> {
         &self.inh.infcx
@@ -4688,7 +4688,7 @@ pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
 }
 
 // Returns true if b contains a break that can exit from b
-pub fn may_break(tcx: &TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
+pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
     // First: is there an unlabeled break immediately
     // inside the loop?
     (loop_query(&b, |e| {
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 3af0a3f66e6..3972bfce3fa 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -207,7 +207,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.fcx.tcx()
     }
 
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 629b3035404..940e662d5ce 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -109,7 +109,7 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> {
         SeedBorrowKind { fcx: fcx, closures_with_inferred_kinds: HashSet::new() }
     }
 
-    fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.fcx.tcx()
     }
 
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 9e8cfa42f4e..53c47b85fbe 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -40,7 +40,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         }
     }
 
-    fn tcx(&self) -> &TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'ccx, 'tcx> {
         self.ccx.tcx
     }
 
@@ -511,7 +511,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
     }
 }
 
-fn reject_shadowing_type_parameters(tcx: &TyCtxt, span: Span, generics: &ty::Generics) {
+fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) {
     let impl_params = generics.types.get_slice(subst::TypeSpace).iter()
         .map(|tp| tp.name).collect::<HashSet<_>>();
 
@@ -615,7 +615,7 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
                      "parameter `{}` is never used", param_name)
 }
 
-fn error_194(tcx: &TyCtxt, span: Span, name: ast::Name) {
+fn error_194(tcx: TyCtxt, span: Span, name: ast::Name) {
     span_err!(tcx.sess, span, E0194,
               "type parameter `{}` shadows another type parameter of the same name",
               name);
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index c84707ecbce..16e9297ec15 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -83,7 +83,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         WritebackCx { fcx: fcx }
     }
 
-    fn tcx(&self) -> &'cx TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'cx, 'tcx> {
         self.fcx.tcx()
     }
 
@@ -379,7 +379,7 @@ enum ResolveReason {
 }
 
 impl ResolveReason {
-    fn span(&self, tcx: &TyCtxt) -> Span {
+    fn span(&self, tcx: TyCtxt) -> Span {
         match *self {
             ResolvingExpr(s) => s,
             ResolvingLocal(s) => s,
@@ -409,7 +409,7 @@ impl ResolveReason {
 // unresolved types and so forth.
 
 struct Resolver<'cx, 'tcx: 'cx> {
-    tcx: &'cx TyCtxt<'tcx>,
+    tcx: TyCtxt<'cx, 'tcx>,
     infcx: &'cx infer::InferCtxt<'cx, 'tcx>,
     writeback_errors: &'cx Cell<bool>,
     reason: ResolveReason,
@@ -481,7 +481,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
 }
 
 impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
-    fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx> {
+    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx> {
         self.tcx
     }
 
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index 3c594ebdf0b..7f3ff367994 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -19,7 +19,7 @@ use rustc::hir;
 use rustc::hir::intravisit::Visitor;
 
 struct UnusedTraitImportVisitor<'a, 'tcx: 'a> {
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx> UnusedTraitImportVisitor<'a, 'tcx> {
@@ -57,7 +57,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for UnusedTraitImportVisitor<'a, 'tcx> {
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt) {
+pub fn check_crate(tcx: TyCtxt) {
     let _task = tcx.dep_graph.in_task(DepNode::UnusedTraitCheck);
     let mut visitor = UnusedTraitImportVisitor { tcx: tcx };
     tcx.map.krate().visit_all_items(&mut visitor);
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index c7e8629cdf9..95b7ce63e20 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -485,7 +485,7 @@ fn get_base_type_def_id(&self, span: Span, ty: Ty<'tcx>) -> Option<DefId> {
     }
 }
 
-fn enforce_trait_manually_implementable(tcx: &TyCtxt, sp: Span, trait_def_id: DefId) {
+fn enforce_trait_manually_implementable(tcx: TyCtxt, sp: Span, trait_def_id: DefId) {
     if tcx.sess.features.borrow().unboxed_closures {
         // the feature gate allows all of them
         return
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index f3d63957018..7426b5ce277 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -21,13 +21,13 @@ use rustc::dep_graph::DepNode;
 use rustc::hir::intravisit;
 use rustc::hir;
 
-pub fn check(tcx: &TyCtxt) {
+pub fn check(tcx: TyCtxt) {
     let mut orphan = OrphanChecker { tcx: tcx };
     tcx.visit_all_items_in_krate(DepNode::CoherenceOrphanCheck, &mut orphan);
 }
 
 struct OrphanChecker<'cx, 'tcx:'cx> {
-    tcx: &'cx TyCtxt<'tcx>
+    tcx: TyCtxt<'cx, 'tcx>
 }
 
 impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index ea87b870694..d71ca657b81 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -23,7 +23,7 @@ use rustc::hir::intravisit;
 use util::nodemap::DefIdMap;
 use lint;
 
-pub fn check(tcx: &TyCtxt) {
+pub fn check(tcx: TyCtxt) {
     let mut overlap = OverlapChecker { tcx: tcx,
                                        default_impls: DefIdMap() };
 
@@ -33,7 +33,7 @@ pub fn check(tcx: &TyCtxt) {
 }
 
 struct OverlapChecker<'cx, 'tcx:'cx> {
-    tcx: &'cx TyCtxt<'tcx>,
+    tcx: TyCtxt<'cx, 'tcx>,
 
     // maps from a trait def-id to an impl id
     default_impls: DefIdMap<ast::NodeId>,
@@ -44,7 +44,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
         #[derive(Copy, Clone, PartialEq)]
         enum Namespace { Type, Value }
 
-        fn name_and_namespace(tcx: &TyCtxt, item: &ty::ImplOrTraitItemId)
+        fn name_and_namespace(tcx: TyCtxt, item: &ty::ImplOrTraitItemId)
                               -> (ast::Name, Namespace)
         {
             let name = tcx.impl_or_trait_item(item.def_id()).name();
@@ -58,10 +58,10 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
         let impl_items = self.tcx.impl_items.borrow();
 
         for item1 in &impl_items[&impl1] {
-            let (name, namespace) = name_and_namespace(&self.tcx, item1);
+            let (name, namespace) = name_and_namespace(self.tcx, item1);
 
             for item2 in &impl_items[&impl2] {
-                if (name, namespace) == name_and_namespace(&self.tcx, item2) {
+                if (name, namespace) == name_and_namespace(self.tcx, item2) {
                     let msg = format!("duplicate definitions with name `{}`", name);
                     let node_id = self.tcx.map.as_local_node_id(item1.def_id()).unwrap();
                     self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index b042e23e0ac..d5912e224bc 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -15,13 +15,13 @@ use rustc::ty::TyCtxt;
 use rustc::hir::intravisit;
 use rustc::hir;
 
-pub fn check(tcx: &TyCtxt) {
+pub fn check(tcx: TyCtxt) {
     let mut orphan = UnsafetyChecker { tcx: tcx };
     tcx.map.krate().visit_all_items(&mut orphan);
 }
 
 struct UnsafetyChecker<'cx, 'tcx:'cx> {
-    tcx: &'cx TyCtxt<'tcx>
+    tcx: TyCtxt<'cx, 'tcx>
 }
 
 impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 9393dd1bce7..4b1be8b9a5e 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -296,7 +296,7 @@ impl<'a,'tcx> ItemCtxt<'a,'tcx> {
 }
 
 impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
-    fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx> { self.ccx.tcx }
 
     fn get_item_type_scheme(&self, span: Span, id: DefId)
                             -> Result<ty::TypeScheme<'tcx>, ErrorReported>
@@ -498,10 +498,10 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
 /// parameter with id `param_id`. We use this so as to avoid running
 /// `ast_ty_to_ty`, because we want to avoid triggering an all-out
 /// conversion of the type to avoid inducing unnecessary cycles.
-fn is_param<'tcx>(tcx: &TyCtxt<'tcx>,
-                  ast_ty: &hir::Ty,
-                  param_id: ast::NodeId)
-                  -> bool
+fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx>,
+                      ast_ty: &hir::Ty,
+                      param_id: ast::NodeId)
+                      -> bool
 {
     if let hir::TyPath(None, _) = ast_ty.node {
         let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index b28a7302d5f..a86595bbc4e 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -149,7 +149,7 @@ pub struct CrateCtxt<'a, 'tcx: 'a> {
     /// Note that these cycles can cross multiple items.
     pub stack: RefCell<Vec<collect::AstConvRequest>>,
 
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
 }
 
 // Functions that write types into the node type table
@@ -173,7 +173,7 @@ fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }
 }
 
-fn lookup_full_def(tcx: &TyCtxt, sp: Span, id: ast::NodeId) -> Def {
+fn lookup_full_def(tcx: TyCtxt, sp: Span, id: ast::NodeId) -> Def {
     match tcx.def_map.borrow().get(&id) {
         Some(x) => x.full_def(),
         None => {
@@ -182,7 +182,7 @@ fn lookup_full_def(tcx: &TyCtxt, sp: Span, id: ast::NodeId) -> Def {
     }
 }
 
-fn require_c_abi_if_variadic(tcx: &TyCtxt,
+fn require_c_abi_if_variadic(tcx: TyCtxt,
                              decl: &hir::FnDecl,
                              abi: Abi,
                              span: Span) {
@@ -329,7 +329,7 @@ fn check_for_entry_fn(ccx: &CrateCtxt) {
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt, trait_map: hir::TraitMap) -> CompileResult {
+pub fn check_crate(tcx: TyCtxt, trait_map: hir::TraitMap) -> CompileResult {
     let time_passes = tcx.sess.time_passes();
     let ccx = CrateCtxt {
         trait_map: trait_map,
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 3b03a713a5b..7ee56e7cb00 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -127,7 +127,7 @@ fn is_lifetime(map: &hir_map::Map, param_id: ast::NodeId) -> bool {
 }
 
 impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
-    fn tcx(&self) -> &'a TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'a, 'tcx> {
         self.terms_cx.tcx
     }
 
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index ee9f317f20f..08d61d19fe6 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -27,7 +27,7 @@ mod solve;
 /// Code for transforming variances.
 mod xform;
 
-pub fn infer_variance(tcx: &TyCtxt) {
+pub fn infer_variance(tcx: TyCtxt) {
     let mut arena = arena::TypedArena::new();
     let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena);
     let constraints_cx = constraints::add_constraints_from_crate(terms_cx);
diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs
index 413dc83e638..270f79e7ed7 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/src/librustc_typeck/variance/terms.rs
@@ -59,7 +59,7 @@ impl<'a> fmt::Debug for VarianceTerm<'a> {
 // The first pass over the crate simply builds up the set of inferreds.
 
 pub struct TermsContext<'a, 'tcx: 'a> {
-    pub tcx: &'a TyCtxt<'tcx>,
+    pub tcx: TyCtxt<'a, 'tcx>,
     pub arena: &'a TypedArena<VarianceTerm<'a>>,
 
     pub empty_variances: Rc<ty::ItemVariances>,
@@ -98,7 +98,7 @@ pub struct InferredInfo<'a> {
 }
 
 pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
-    tcx: &'a TyCtxt<'tcx>,
+    tcx: TyCtxt<'a, 'tcx>,
     arena: &'a mut TypedArena<VarianceTerm<'a>>)
     -> TermsContext<'a, 'tcx>
 {
@@ -125,7 +125,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
     terms_cx
 }
 
-fn lang_items(tcx: &TyCtxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
+fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
     let all = vec![
         (tcx.lang_items.phantom_data(), vec![ty::Covariant]),
         (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 97a56e50176..b592d94fff3 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -68,7 +68,7 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Name>)
     })
 }
 
-fn try_inline_def(cx: &DocContext, tcx: &TyCtxt,
+fn try_inline_def(cx: &DocContext, tcx: TyCtxt,
                   def: Def) -> Option<Vec<clean::Item>> {
     let mut ret = Vec::new();
     let did = def.def_id();
@@ -130,7 +130,7 @@ fn try_inline_def(cx: &DocContext, tcx: &TyCtxt,
     Some(ret)
 }
 
-pub fn load_attrs(cx: &DocContext, tcx: &TyCtxt,
+pub fn load_attrs(cx: &DocContext, tcx: TyCtxt,
                   did: DefId) -> Vec<clean::Attribute> {
     tcx.get_attrs(did).iter().map(|a| a.clean(cx)).collect()
 }
@@ -150,7 +150,7 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
     }
 }
 
-pub fn build_external_trait(cx: &DocContext, tcx: &TyCtxt,
+pub fn build_external_trait(cx: &DocContext, tcx: TyCtxt,
                             did: DefId) -> clean::Trait {
     let def = tcx.lookup_trait_def(did);
     let trait_items = tcx.trait_items(did).clean(cx);
@@ -166,7 +166,7 @@ pub fn build_external_trait(cx: &DocContext, tcx: &TyCtxt,
     }
 }
 
-fn build_external_function(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::Function {
+fn build_external_function(cx: &DocContext, tcx: TyCtxt, did: DefId) -> clean::Function {
     let t = tcx.lookup_item_type(did);
     let (decl, style, abi) = match t.ty.sty {
         ty::TyFnDef(_, _, ref f) => ((did, &f.sig).clean(cx), f.unsafety, f.abi),
@@ -189,7 +189,7 @@ fn build_external_function(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::
     }
 }
 
-fn build_struct(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::Struct {
+fn build_struct(cx: &DocContext, tcx: TyCtxt, did: DefId) -> clean::Struct {
     let t = tcx.lookup_item_type(did);
     let predicates = tcx.lookup_predicates(did);
     let variant = tcx.lookup_adt_def(did).struct_variant();
@@ -207,7 +207,7 @@ fn build_struct(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::Struct {
     }
 }
 
-fn build_type(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::ItemEnum {
+fn build_type(cx: &DocContext, tcx: TyCtxt, did: DefId) -> clean::ItemEnum {
     let t = tcx.lookup_item_type(did);
     let predicates = tcx.lookup_predicates(did);
     match t.ty.sty {
@@ -228,7 +228,7 @@ fn build_type(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::ItemEnum {
 }
 
 pub fn build_impls(cx: &DocContext,
-                   tcx: &TyCtxt,
+                   tcx: TyCtxt,
                    did: DefId) -> Vec<clean::Item> {
     tcx.populate_inherent_implementations_for_type_if_necessary(did);
     let mut impls = Vec::new();
@@ -252,7 +252,7 @@ pub fn build_impls(cx: &DocContext,
             populate_impls(cx, tcx, item.def, &mut impls);
         }
 
-        fn populate_impls(cx: &DocContext, tcx: &TyCtxt,
+        fn populate_impls(cx: &DocContext, tcx: TyCtxt,
                           def: cstore::DefLike,
                           impls: &mut Vec<clean::Item>) {
             match def {
@@ -271,7 +271,7 @@ pub fn build_impls(cx: &DocContext,
 }
 
 pub fn build_impl(cx: &DocContext,
-                  tcx: &TyCtxt,
+                  tcx: TyCtxt,
                   did: DefId,
                   ret: &mut Vec<clean::Item>) {
     if !cx.renderinfo.borrow_mut().inlined.insert(did) {
@@ -441,7 +441,7 @@ pub fn build_impl(cx: &DocContext,
     });
 }
 
-fn build_module(cx: &DocContext, tcx: &TyCtxt,
+fn build_module(cx: &DocContext, tcx: TyCtxt,
                 did: DefId) -> clean::Module {
     let mut items = Vec::new();
     fill_in(cx, tcx, did, &mut items);
@@ -450,7 +450,7 @@ fn build_module(cx: &DocContext, tcx: &TyCtxt,
         is_crate: false,
     };
 
-    fn fill_in(cx: &DocContext, tcx: &TyCtxt, did: DefId,
+    fn fill_in(cx: &DocContext, tcx: TyCtxt, did: DefId,
                items: &mut Vec<clean::Item>) {
         // If we're reexporting a reexport it may actually reexport something in
         // two namespaces, so the target may be listed twice. Make sure we only
@@ -476,7 +476,7 @@ fn build_module(cx: &DocContext, tcx: &TyCtxt,
     }
 }
 
-fn build_const(cx: &DocContext, tcx: &TyCtxt,
+fn build_const(cx: &DocContext, tcx: TyCtxt,
                did: DefId) -> clean::Constant {
     let (expr, ty) = lookup_const_by_id(tcx, did, None).unwrap_or_else(|| {
         panic!("expected lookup_const_by_id to succeed for {:?}", did);
@@ -491,7 +491,7 @@ fn build_const(cx: &DocContext, tcx: &TyCtxt,
     }
 }
 
-fn build_static(cx: &DocContext, tcx: &TyCtxt,
+fn build_static(cx: &DocContext, tcx: TyCtxt,
                 did: DefId,
                 mutable: bool) -> clean::Static {
     clean::Static {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index e5fc84037ce..245ebcdfe4f 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -42,7 +42,7 @@ pub use rustc::session::search_paths::SearchPaths;
 
 /// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
 pub enum MaybeTyped<'a, 'tcx: 'a> {
-    Typed(&'a TyCtxt<'tcx>),
+    Typed(TyCtxt<'a, 'tcx>),
     NotTyped(&'a session::Session)
 }
 
@@ -74,14 +74,14 @@ impl<'b, 'tcx> DocContext<'b, 'tcx> {
         }
     }
 
-    pub fn tcx_opt<'a>(&'a self) -> Option<&'a TyCtxt<'tcx>> {
+    pub fn tcx_opt<'a>(&'a self) -> Option<TyCtxt<'a, 'tcx>> {
         match self.maybe_typed {
             Typed(tcx) => Some(tcx),
             NotTyped(_) => None
         }
     }
 
-    pub fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx> {
+    pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx> {
         let tcx_opt = self.tcx_opt();
         tcx_opt.expect("tcx not present")
     }
diff --git a/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs b/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
index 600df1c778b..79226515ce3 100644
--- a/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
@@ -21,7 +21,7 @@ extern crate syntax;
 use rustc::mir::transform::{self, MirPass, MirSource};
 use rustc::mir::repr::{Mir, Literal};
 use rustc::mir::visit::MutVisitor;
-use rustc::ty;
+use rustc::ty::TyCtxt;
 use rustc::middle::const_val::ConstVal;
 use rustc_const_math::ConstInt;
 use rustc_plugin::Registry;
@@ -30,7 +30,7 @@ struct Pass;
 
 impl transform::Pass for Pass {}
 impl<'tcx> MirPass<'tcx> for Pass {
-    fn run_pass(&mut self, _: &ty::TyCtxt<'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
         Visitor.visit_mir(mir)
     }
 }