about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-06-14 01:49:28 +0300
committerEduard Burtescu <edy.burt@gmail.com>2015-06-19 01:18:42 +0300
commit2e997ef2d487525ea41e78ba793cb6e7c61cb204 (patch)
tree457e0d33787eaa096babe492b44fa6f72ce909e3
parentff8fee180be6f4ffdefecc0d13fb52d3ae625eb3 (diff)
downloadrust-2e997ef2d487525ea41e78ba793cb6e7c61cb204.tar.gz
rust-2e997ef2d487525ea41e78ba793cb6e7c61cb204.zip
rustc: remove ownership of tcx from trans' context.
-rw-r--r--src/librustc/middle/ty.rs3
-rw-r--r--src/librustc_driver/driver.rs43
-rw-r--r--src/librustc_driver/lib.rs10
-rw-r--r--src/librustc_driver/pretty.rs34
-rw-r--r--src/librustc_trans/save/dump_csv.rs116
-rw-r--r--src/librustc_trans/save/mod.rs88
-rw-r--r--src/librustc_trans/trans/base.rs13
-rw-r--r--src/librustc_trans/trans/context.rs28
-rw-r--r--src/librustdoc/core.rs18
-rw-r--r--src/test/run-make/execution-engine/test.rs4
10 files changed, 161 insertions, 196 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index f5fcb72c5c1..fa7b1aa4fbe 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -101,11 +101,10 @@ pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
 
 /// The complete set of all analyses described in this module. This is
 /// produced by the driver and fed to trans and later passes.
-pub struct CrateAnalysis<'tcx> {
+pub struct CrateAnalysis {
     pub export_map: ExportMap,
     pub exported_items: middle::privacy::ExportedItems,
     pub public_items: middle::privacy::PublicItems,
-    pub ty_cx: ty::ctxt<'tcx>,
     pub reachable: NodeSet,
     pub name: String,
     pub glob_map: Option<GlobMap>,
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index eaac1eb6f2c..7297d9c00b4 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -119,26 +119,26 @@ pub fn compile_input(sess: Session,
                                                                      &ast_map.krate(),
                                                                      &id[..]));
 
-        let analysis = phase_3_run_analysis_passes(sess,
-                                                   ast_map,
-                                                   &arenas,
-                                                   id,
-                                                   control.make_glob_map);
+        let (tcx, analysis) = phase_3_run_analysis_passes(sess,
+                                                          ast_map,
+                                                          &arenas,
+                                                          id,
+                                                          control.make_glob_map);
 
         controller_entry_point!(after_analysis,
-                                analysis.ty_cx.sess,
+                                tcx.sess,
                                 CompileState::state_after_analysis(input,
-                                                                   &analysis.ty_cx.sess,
+                                                                   &tcx.sess,
                                                                    outdir,
-                                                                   analysis.ty_cx.map.krate(),
+                                                                   tcx.map.krate(),
                                                                    &analysis,
-                                                                   &analysis.ty_cx));
+                                                                   &tcx));
 
         if log_enabled!(::log::INFO) {
             println!("Pre-trans");
-            analysis.ty_cx.print_debug_stats();
+            tcx.print_debug_stats();
         }
-        let (tcx, trans) = phase_4_translate_to_llvm(analysis);
+        let trans = phase_4_translate_to_llvm(&tcx, analysis);
 
         if log_enabled!(::log::INFO) {
             println!("Post-trans");
@@ -240,7 +240,7 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
     pub out_dir: Option<&'a Path>,
     pub expanded_crate: Option<&'a ast::Crate>,
     pub ast_map: Option<&'a ast_map::Map<'ast>>,
-    pub analysis: Option<&'a ty::CrateAnalysis<'tcx>>,
+    pub analysis: Option<&'a ty::CrateAnalysis>,
     pub tcx: Option<&'a ty::ctxt<'tcx>>,
     pub trans: Option<&'a trans::CrateTranslation>,
 }
@@ -309,7 +309,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
                             session: &'a Session,
                             out_dir: &'a Option<PathBuf>,
                             expanded_crate: &'a ast::Crate,
-                            analysis: &'a ty::CrateAnalysis<'tcx>,
+                            analysis: &'a ty::CrateAnalysis,
                             tcx: &'a ty::ctxt<'tcx>)
                             -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
@@ -583,7 +583,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
                                          arenas: &'tcx ty::CtxtArenas<'tcx>,
                                          name: String,
                                          make_glob_map: resolve::MakeGlobMap)
-                                         -> ty::CrateAnalysis<'tcx> {
+                                         -> (ty::ctxt<'tcx>, ty::CrateAnalysis) {
     let time_passes = sess.time_passes();
     let krate = ast_map.krate();
 
@@ -704,29 +704,28 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     // The above three passes generate errors w/o aborting
     ty_cx.sess.abort_if_errors();
 
-    ty::CrateAnalysis {
+    (ty_cx, ty::CrateAnalysis {
         export_map: export_map,
-        ty_cx: ty_cx,
         exported_items: exported_items,
         public_items: public_items,
         reachable: reachable_map,
         name: name,
         glob_map: glob_map,
-    }
+    })
 }
 
 /// Run the translation phase to LLVM, after which the AST and analysis can
 /// be discarded.
-pub fn phase_4_translate_to_llvm<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
-                                       -> (ty::ctxt<'tcx>, trans::CrateTranslation) {
-    let time_passes = analysis.ty_cx.sess.time_passes();
+pub fn phase_4_translate_to_llvm(tcx: &ty::ctxt, analysis: ty::CrateAnalysis)
+                                 -> trans::CrateTranslation {
+    let time_passes = tcx.sess.time_passes();
 
     time(time_passes, "resolving dependency formats", (), |_|
-         dependency_format::calculate(&analysis.ty_cx));
+         dependency_format::calculate(tcx));
 
     // Option dance to work around the lack of stack once closures.
     time(time_passes, "translation", analysis, |analysis|
-         trans::trans_crate(analysis))
+         trans::trans_crate(tcx, analysis))
 }
 
 /// Run LLVM itself, producing a bitcode file, assembly file or object file
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index fe3ffe97981..96d1ab23ad5 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -377,12 +377,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
         if sess.opts.debugging_opts.save_analysis {
             control.after_analysis.callback = box |state| {
                 time(state.session.time_passes(),
-                     "save analysis",
-                     state.expanded_crate.unwrap(),
-                     |krate| save::process_crate(state.session,
-                                                 krate,
-                                                 state.analysis.unwrap(),
-                                                 state.out_dir));
+                     "save analysis", (),
+                     |_| save::process_crate(state.tcx.unwrap(),
+                                             state.analysis.unwrap(),
+                                             state.out_dir));
             };
             control.make_glob_map = resolve::MakeGlobMap::Yes;
         }
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index c98052825e1..0dc636eb3ec 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -148,12 +148,12 @@ impl PpSourceMode {
             }
             PpmTyped => {
                 let ast_map = ast_map.expect("--pretty=typed missing ast_map");
-                let analysis = driver::phase_3_run_analysis_passes(sess,
+                let (tcx, _) = driver::phase_3_run_analysis_passes(sess,
                                                                    ast_map,
                                                                    arenas,
                                                                    id,
                                                                    resolve::MakeGlobMap::No);
-                let annotation = TypedAnnotation { analysis: analysis };
+                let annotation = TypedAnnotation { tcx: tcx };
                 f(&annotation, payload)
             }
         }
@@ -285,14 +285,14 @@ impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
 
 
 struct TypedAnnotation<'tcx> {
-    analysis: ty::CrateAnalysis<'tcx>,
+    tcx: ty::ctxt<'tcx>,
 }
 
 impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
-    fn sess<'a>(&'a self) -> &'a Session { &self.analysis.ty_cx.sess }
+    fn sess<'a>(&'a self) -> &'a Session { &self.tcx.sess }
 
     fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'tcx>> {
-        Some(&self.analysis.ty_cx.map)
+        Some(&self.tcx.map)
     }
 
     fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
@@ -310,7 +310,6 @@ impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
     fn post(&self,
             s: &mut pprust::State,
             node: pprust::AnnNode) -> io::Result<()> {
-        let tcx = &self.analysis.ty_cx;
         match node {
             pprust::NodeExpr(expr) => {
                 try!(pp::space(&mut s.s));
@@ -318,8 +317,8 @@ impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
                 try!(pp::space(&mut s.s));
                 try!(pp::word(&mut s.s,
                               &ppaux::ty_to_string(
-                                  tcx,
-                                  ty::expr_ty(tcx, expr))));
+                                  &self.tcx,
+                                  ty::expr_ty(&self.tcx, expr))));
                 s.pclose()
             }
             _ => Ok(())
@@ -646,12 +645,12 @@ pub fn pretty_print_input(sess: Session,
             match code {
                 Some(code) => {
                     let variants = gather_flowgraph_variants(&sess);
-                    let analysis = driver::phase_3_run_analysis_passes(sess,
+                    let (tcx, _) = driver::phase_3_run_analysis_passes(sess,
                                                                        ast_map,
                                                                        &arenas,
                                                                        id,
                                                                        resolve::MakeGlobMap::No);
-                    print_flowgraph(variants, analysis, code, mode, out)
+                    print_flowgraph(variants, &tcx, code, mode, out)
                 }
                 None => {
                     let message = format!("--pretty=flowgraph needs \
@@ -682,18 +681,17 @@ pub fn pretty_print_input(sess: Session,
 }
 
 fn print_flowgraph<W: Write>(variants: Vec<borrowck_dot::Variant>,
-                             analysis: ty::CrateAnalysis,
+                             tcx: &ty::ctxt,
                              code: blocks::Code,
                              mode: PpFlowGraphMode,
                              mut out: W) -> io::Result<()> {
-    let ty_cx = &analysis.ty_cx;
     let cfg = match code {
-        blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
-        blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, &*fn_like.body()),
+        blocks::BlockCode(block) => cfg::CFG::new(tcx, &*block),
+        blocks::FnLikeCode(fn_like) => cfg::CFG::new(tcx, &*fn_like.body()),
     };
     let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges;
     let lcfg = LabelledCFG {
-        ast_map: &ty_cx.map,
+        ast_map: &tcx.map,
         cfg: &cfg,
         name: format!("node_{}", code.id()),
         labelled_edges: labelled_edges,
@@ -705,14 +703,14 @@ fn print_flowgraph<W: Write>(variants: Vec<borrowck_dot::Variant>,
             return expand_err_details(r);
         }
         blocks::BlockCode(_) => {
-            ty_cx.sess.err("--pretty flowgraph with -Z flowgraph-print \
-                            annotations requires fn-like node id.");
+            tcx.sess.err("--pretty flowgraph with -Z flowgraph-print \
+                          annotations requires fn-like node id.");
             return Ok(())
         }
         blocks::FnLikeCode(fn_like) => {
             let fn_parts = borrowck::FnPartsWithCFG::from_fn_like(&fn_like, &cfg);
             let (bccx, analysis_data) =
-                borrowck::build_borrowck_dataflow_data_for_fn(ty_cx, fn_parts);
+                borrowck::build_borrowck_dataflow_data_for_fn(tcx, fn_parts);
 
             let lcfg = borrowck_dot::DataflowLabeller {
                 inner: lcfg,
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index cbc40af4b52..f68024656e0 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -67,7 +67,8 @@ macro_rules! down_cast_data {
 pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
     save_ctxt: SaveContext<'l, 'tcx>,
     sess: &'l Session,
-    analysis: &'l ty::CrateAnalysis<'tcx>,
+    tcx: &'l ty::ctxt<'tcx>,
+    analysis: &'l ty::CrateAnalysis,
 
     span: SpanUtils<'l>,
     fmt: FmtStrs<'l>,
@@ -76,28 +77,23 @@ pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
 }
 
 impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
-    pub fn new(sess: &'l Session,
-               analysis: &'l ty::CrateAnalysis<'tcx>,
+    pub fn new(tcx: &'l ty::ctxt<'tcx>,
+               analysis: &'l ty::CrateAnalysis,
                output_file: Box<File>) -> DumpCsvVisitor<'l, 'tcx> {
+        let span_utils = SpanUtils {
+            sess: &tcx.sess,
+            err_count: Cell::new(0)
+        };
         DumpCsvVisitor {
-            sess: sess,
-            save_ctxt: SaveContext::new(sess, analysis, SpanUtils {
-                sess: sess,
-                err_count: Cell::new(0)
-            }),
+            sess: &tcx.sess,
+            tcx: tcx,
+            save_ctxt: SaveContext::new(tcx, span_utils.clone()),
             analysis: analysis,
-            span: SpanUtils {
-                sess: sess,
-                err_count: Cell::new(0)
-            },
+            span: span_utils.clone(),
             fmt: FmtStrs::new(box Recorder {
                                 out: output_file,
                                 dump_spans: false,
-                            },
-                            SpanUtils {
-                                sess: sess,
-                                err_count: Cell::new(0)
-                            }),
+                              }, span_utils),
             cur_scope: 0
         }
     }
@@ -237,11 +233,11 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
 
     // looks up anything, not just a type
     fn lookup_type_ref(&self, ref_id: NodeId) -> Option<DefId> {
-        if !self.analysis.ty_cx.def_map.borrow().contains_key(&ref_id) {
+        if !self.tcx.def_map.borrow().contains_key(&ref_id) {
             self.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
                                   ref_id));
         }
-        let def = self.analysis.ty_cx.def_map.borrow().get(&ref_id).unwrap().full_def();
+        let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def();
         match def {
             def::DefPrimTy(_) => None,
             _ => Some(def.def_id()),
@@ -249,7 +245,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
     }
 
     fn lookup_def_kind(&self, ref_id: NodeId, span: Span) -> Option<recorder::Row> {
-        let def_map = self.analysis.ty_cx.def_map.borrow();
+        let def_map = self.tcx.def_map.borrow();
         if !def_map.contains_key(&ref_id) {
             self.sess.span_bug(span, &format!("def_map has no key for {} in lookup_def_kind",
                                              ref_id));
@@ -293,8 +289,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             for &(id, ref p, _, _) in &collector.collected_paths {
                 let typ =
                     ppaux::ty_to_string(
-                        &self.analysis.ty_cx,
-                        *self.analysis.ty_cx.node_types().get(&id).unwrap());
+                        self.tcx,
+                        *self.tcx.node_types().get(&id).unwrap());
                 // get the span only for the name of the variable (I hope the path is only ever a
                 // variable name, but who knows?)
                 self.fmt.formal_str(p.span,
@@ -320,9 +316,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         let mut scope_id;
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
-        let qualname = match ty::impl_of_method(&self.analysis.ty_cx,
-                                                ast_util::local_def(id)) {
-            Some(impl_id) => match self.analysis.ty_cx.map.get(impl_id.node) {
+        let qualname = match ty::impl_of_method(self.tcx, ast_util::local_def(id)) {
+            Some(impl_id) => match self.tcx.map.get(impl_id.node) {
                 NodeItem(item) => {
                     scope_id = item.id;
                     match item.node {
@@ -330,12 +325,11 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                             let mut result = String::from("<");
                             result.push_str(&ty_to_string(&**ty));
 
-                            match ty::trait_of_item(&self.analysis.ty_cx,
-                                                    ast_util::local_def(id)) {
+                            match ty::trait_of_item(self.tcx, ast_util::local_def(id)) {
                                 Some(def_id) => {
                                     result.push_str(" as ");
                                     result.push_str(
-                                        &ty::item_path_str(&self.analysis.ty_cx, def_id));
+                                        &ty::item_path_str(self.tcx, def_id));
                                 },
                                 None => {}
                             }
@@ -352,16 +346,15 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                 _ => {
                     self.sess.span_bug(span,
                         &format!("Container {} for method {} is not a node item {:?}",
-                                 impl_id.node, id, self.analysis.ty_cx.map.get(impl_id.node)));
+                                 impl_id.node, id, self.tcx.map.get(impl_id.node)));
                 },
             },
-            None => match ty::trait_of_item(&self.analysis.ty_cx,
-                                            ast_util::local_def(id)) {
+            None => match ty::trait_of_item(self.tcx, ast_util::local_def(id)) {
                 Some(def_id) => {
                     scope_id = def_id.node;
-                    match self.analysis.ty_cx.map.get(def_id.node) {
+                    match self.tcx.map.get(def_id.node) {
                         NodeItem(_) => {
-                            format!("::{}", ty::item_path_str(&self.analysis.ty_cx, def_id))
+                            format!("::{}", ty::item_path_str(self.tcx, def_id))
                         }
                         _ => {
                             self.sess.span_bug(span,
@@ -380,8 +373,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         let qualname = &format!("{}::{}", qualname, &token::get_name(name));
 
         // record the decl for this def (if it has one)
-        let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
-                                             ast_util::local_def(id))
+        let decl_id = ty::trait_item_of_item(self.tcx, ast_util::local_def(id))
             .and_then(|new_id| {
                 let def_id = new_id.def_id();
                 if def_id.node != 0 && def_id != ast_util::local_def(id) {
@@ -538,7 +530,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                      typ: &ast::Ty,
                      expr: &ast::Expr)
     {
-        let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(id));
+        let qualname = format!("::{}", self.tcx.map.path_to_string(id));
 
         let sub_span = self.span.sub_span_after_keyword(span,
                                                         keywords::Const);
@@ -561,7 +553,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                       item: &ast::Item,
                       def: &ast::StructDef,
                       ty_params: &ast::Generics) {
-        let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+        let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
 
         let ctor_id = match def.ctor_id {
             Some(node_id) => node_id,
@@ -691,7 +683,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                      generics: &ast::Generics,
                      trait_refs: &OwnedSlice<ast::TyParamBound>,
                      methods: &[P<ast::TraitItem>]) {
-        let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+        let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
         let val = self.span.snippet(item.span);
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
         self.fmt.trait_str(item.span,
@@ -758,7 +750,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             return
         }
 
-        let def_map = self.analysis.ty_cx.def_map.borrow();
+        let def_map = self.tcx.def_map.borrow();
         if !def_map.contains_key(&id) {
             self.sess.span_bug(span,
                                &format!("def_map has no key for {} in visit_expr", id));
@@ -789,12 +781,10 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             def::DefMethod(declid, provenence) => {
                 let sub_span = self.span.sub_span_for_meth_name(span);
                 let defid = if declid.krate == ast::LOCAL_CRATE {
-                    let ti = ty::impl_or_trait_item(&self.analysis.ty_cx,
-                                                    declid);
+                    let ti = ty::impl_or_trait_item(self.tcx, declid);
                     match provenence {
                         def::FromTrait(def_id) => {
-                            Some(ty::trait_items(&self.analysis.ty_cx,
-                                                 def_id)
+                            Some(ty::trait_items(self.tcx, def_id)
                                     .iter()
                                     .find(|mr| {
                                         mr.name() == ti.name()
@@ -803,16 +793,13 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                                     .def_id())
                         }
                         def::FromImpl(def_id) => {
-                            let impl_items = self.analysis
-                                                 .ty_cx
-                                                 .impl_items
-                                                 .borrow();
+                            let impl_items = self.tcx.impl_items.borrow();
                             Some(impl_items.get(&def_id)
                                            .unwrap()
                                            .iter()
                                            .find(|mr| {
                                                 ty::impl_or_trait_item(
-                                                    &self.analysis.ty_cx,
+                                                    self.tcx,
                                                     mr.def_id()
                                                 ).name() == ti.name()
                                             })
@@ -844,7 +831,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         // modules or types in the path prefix
         match def {
             def::DefMethod(did, _) => {
-                let ti = ty::impl_or_trait_item(&self.analysis.ty_cx, did);
+                let ti = ty::impl_or_trait_item(self.tcx, did);
                 if let ty::MethodTraitItem(m) = ti {
                     if m.explicit_self == ty::StaticExplicitSelfCategory {
                         self.write_sub_path_trait_truncated(path);
@@ -906,24 +893,21 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
     fn process_method_call(&mut self,
                            ex: &ast::Expr,
                            args: &Vec<P<ast::Expr>>) {
-        let method_map = self.analysis.ty_cx.method_map.borrow();
+        let method_map = self.tcx.method_map.borrow();
         let method_callee = method_map.get(&ty::MethodCall::expr(ex.id)).unwrap();
         let (def_id, decl_id) = match method_callee.origin {
             ty::MethodStatic(def_id) |
             ty::MethodStaticClosure(def_id) => {
                 // method invoked on an object with a concrete type (not a static method)
                 let decl_id =
-                    match ty::trait_item_of_item(&self.analysis.ty_cx,
-                                                 def_id) {
+                    match ty::trait_item_of_item(self.tcx, def_id) {
                         None => None,
                         Some(decl_id) => Some(decl_id.def_id()),
                     };
 
                 // This incantation is required if the method referenced is a
                 // trait's default implementation.
-                let def_id = match ty::impl_or_trait_item(&self.analysis
-                                                               .ty_cx,
-                                                          def_id) {
+                let def_id = match ty::impl_or_trait_item(self.tcx, def_id) {
                     ty::MethodTraitItem(method) => {
                         method.provided_source.unwrap_or(def_id)
                     }
@@ -936,14 +920,14 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             }
             ty::MethodTypeParam(ref mp) => {
                 // method invoked on a type parameter
-                let trait_item = ty::trait_item(&self.analysis.ty_cx,
+                let trait_item = ty::trait_item(self.tcx,
                                                 mp.trait_ref.def_id,
                                                 mp.method_num);
                 (None, Some(trait_item.def_id()))
             }
             ty::MethodTraitObject(ref mo) => {
                 // method invoked on a trait instance
-                let trait_item = ty::trait_item(&self.analysis.ty_cx,
+                let trait_item = ty::trait_item(self.tcx,
                                                 mo.trait_ref.def_id,
                                                 mo.method_num);
                 (None, Some(trait_item.def_id()))
@@ -969,12 +953,12 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             ast::PatStruct(ref path, ref fields, _) => {
                 visit::walk_path(self, path);
 
-                let def = self.analysis.ty_cx.def_map.borrow().get(&p.id).unwrap().full_def();
+                let def = self.tcx.def_map.borrow().get(&p.id).unwrap().full_def();
                 let struct_def = match def {
                     def::DefConst(..) | def::DefAssociatedConst(..) => None,
                     def::DefVariant(_, variant_id, _) => Some(variant_id),
                     _ => {
-                        match ty::ty_to_def_id(ty::node_id_to_type(&self.analysis.ty_cx, p.id)) {
+                        match ty::ty_to_def_id(ty::node_id_to_type(self.tcx, p.id)) {
                             None => {
                                 self.sess.span_bug(p.span,
                                                    &format!("Could not find struct_def for `{}`",
@@ -986,7 +970,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                 };
 
                 if let Some(struct_def) = struct_def {
-                    let struct_fields = ty::lookup_struct_fields(&self.analysis.ty_cx, struct_def);
+                    let struct_fields = ty::lookup_struct_fields(self.tcx, struct_def);
                     for &Spanned { node: ref field, span } in fields {
                         let sub_span = self.span.span_for_first_ident(span);
                         for f in &struct_fields {
@@ -1145,7 +1129,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                 self.nest(item.id, |v| visit::walk_mod(v, m));
             }
             ast::ItemTy(ref ty, ref ty_params) => {
-                let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
                 let value = ty_to_string(&**ty);
                 let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
                 self.fmt.typedef_str(item.span,
@@ -1273,10 +1257,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
 
                 self.visit_expr(&**sub_ex);
 
-                let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex).sty;
+                let ty = &ty::expr_ty_adjusted(self.tcx, &**sub_ex).sty;
                 match *ty {
                     ty::TyStruct(def_id, _) => {
-                        let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
+                        let fields = ty::lookup_struct_fields(self.tcx, def_id);
                         for (i, f) in fields.iter().enumerate() {
                             if i == idx.node {
                                 let sub_span = self.span.sub_span_after_token(ex.span, token::Dot);
@@ -1342,7 +1326,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
         let mut paths_to_process = vec![];
         // process collected paths
         for &(id, ref p, immut, ref_kind) in &collector.collected_paths {
-            let def_map = self.analysis.ty_cx.def_map.borrow();
+            let def_map = self.tcx.def_map.borrow();
             if !def_map.contains_key(&id) {
                 self.sess.span_bug(p.span,
                                    &format!("def_map has no key for {} in visit_arm",
@@ -1410,8 +1394,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
             } else {
                 "<mutable>".to_string()
             };
-            let types = self.analysis.ty_cx.node_types();
-            let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&id).unwrap());
+            let types = self.tcx.node_types();
+            let typ = ppaux::ty_to_string(self.tcx, *types.get(&id).unwrap());
             // Get the span only for the name of the variable (I hope the path
             // is only ever a variable name, but who knows?).
             let sub_span = self.span.span_for_last_ident(p.span);
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 3ea628704eb..5d5dbbd90a7 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use session::Session;
 use middle::ty;
 use middle::def;
 
@@ -35,8 +34,7 @@ mod recorder;
 mod dump_csv;
 
 pub struct SaveContext<'l, 'tcx: 'l> {
-    sess: &'l Session,
-    analysis: &'l ty::CrateAnalysis<'tcx>,
+    tcx: &'l ty::ctxt<'tcx>,
     span_utils: SpanUtils<'l>,
 }
 
@@ -143,13 +141,11 @@ pub struct TypeRefData {
 
 
 impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
-    pub fn new(sess: &'l Session,
-               analysis: &'l ty::CrateAnalysis<'tcx>,
+    pub fn new(tcx: &'l ty::ctxt<'tcx>,
                span_utils: SpanUtils<'l>)
                -> SaveContext<'l, 'tcx> {
         SaveContext {
-            sess: sess,
-            analysis: analysis,
+            tcx: tcx,
             span_utils: span_utils,
         }
     }
@@ -158,7 +154,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_external_crates(&self) -> Vec<CrateData> {
         let mut result = Vec::new();
 
-        self.sess.cstore.iter_crate_data(|n, cmd| {
+        self.tcx.sess.cstore.iter_crate_data(|n, cmd| {
             result.push(CrateData { name: cmd.name.clone(), number: n });
         });
 
@@ -168,7 +164,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_item_data(&self, item: &ast::Item) -> Data {
         match item.node {
             ast::ItemFn(..) => {
-                let name = self.analysis.ty_cx.map.path_to_string(item.id);
+                let name = self.tcx.map.path_to_string(item.id);
                 let qualname = format!("::{}", name);
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn);
 
@@ -178,11 +174,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     qualname: qualname,
                     declaration: None,
                     span: sub_span.unwrap(),
-                    scope: self.analysis.ty_cx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_parent(item.id),
                 })
             }
             ast::ItemStatic(ref typ, mt, ref expr) => {
-                let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
 
                 // If the variable is immutable, save the initialising expression.
                 let (value, keyword) = match mt {
@@ -197,13 +193,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     name: get_ident(item.ident).to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
-                    scope: self.analysis.ty_cx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_parent(item.id),
                     value: value,
                     type_value: ty_to_string(&typ),
                 })
             }
             ast::ItemConst(ref typ, ref expr) => {
-                let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Const);
 
                 Data::VariableData(VariableData {
@@ -211,15 +207,15 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     name: get_ident(item.ident).to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
-                    scope: self.analysis.ty_cx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_parent(item.id),
                     value: self.span_utils.snippet(expr.span),
                     type_value: ty_to_string(&typ),
                 })
             }
             ast::ItemMod(ref m) => {
-                let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+                let qualname = format!("::{}", self.tcx.map.path_to_string(item.id));
 
-                let cm = self.sess.codemap();
+                let cm = self.tcx.sess.codemap();
                 let filename = cm.span_to_filename(m.inner);
 
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Mod);
@@ -229,12 +225,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     name: get_ident(item.ident).to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
-                    scope: self.analysis.ty_cx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_parent(item.id),
                     filename: filename,
                 })
             },
             ast::ItemEnum(..) => {
-                let enum_name = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
+                let enum_name = format!("::{}", self.tcx.map.path_to_string(item.id));
                 let val = self.span_utils.snippet(item.span);
                 let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Enum);
 
@@ -243,14 +239,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     value: val,
                     span: sub_span.unwrap(),
                     qualname: enum_name,
-                    scope: self.analysis.ty_cx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_parent(item.id),
                 })
             },
             ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => {
                 let mut type_data = None;
                 let sub_span;
 
-                let parent = self.analysis.ty_cx.map.get_parent(item.id);
+                let parent = self.tcx.map.get_parent(item.id);
 
                 match typ.node {
                     // Common case impl for a struct or something basic.
@@ -294,10 +290,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             ast::NamedField(ident, _) => {
                 let name = get_ident(ident);
                 let qualname = format!("::{}::{}",
-                                       self.analysis.ty_cx.map.path_to_string(parent),
+                                       self.tcx.map.path_to_string(parent),
                                        name);
-                let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
-                                              *self.analysis.ty_cx.node_types()
+                let typ = ppaux::ty_to_string(&self.tcx,
+                                              *self.tcx.node_types()
                                                   .get(&field.node.id).unwrap());
                 let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
                 Some(Data::VariableData(VariableData {
@@ -334,26 +330,25 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
         match expr.node {
             ast::ExprField(ref sub_ex, ident) => {
-                let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &sub_ex).sty;
+                let ty = &ty::expr_ty_adjusted(self.tcx, &sub_ex).sty;
                 match *ty {
                     ty::TyStruct(def_id, _) => {
-                        let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
+                        let fields = ty::lookup_struct_fields(self.tcx, def_id);
                         for f in &fields {
                             if f.name == ident.node.name {
                                 let sub_span = self.span_utils.span_for_last_ident(expr.span);
                                 return Some(Data::VariableRefData(VariableRefData {
                                     name: get_ident(ident.node).to_string(),
                                     span: sub_span.unwrap(),
-                                    scope: self.analysis.ty_cx.map.get_parent(expr.id),
+                                    scope: self.tcx.map.get_parent(expr.id),
                                     ref_id: f.id,
                                 }));
                             }
                         }
 
-                        self.sess.span_bug(expr.span,
-                                           &format!("Couldn't find field {} on {:?}",
-                                                    &get_ident(ident.node),
-                                                    ty))
+                        self.tcx.sess.span_bug(expr.span,
+                                               &format!("Couldn't find field {} on {:?}",
+                                                        &get_ident(ident.node), ty))
                     }
                     _ => {
                         debug!("Expected struct type, found {:?}", ty);
@@ -362,13 +357,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 }
             }
             ast::ExprStruct(ref path, _, _) => {
-                let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, expr).sty;
+                let ty = &ty::expr_ty_adjusted(&self.tcx, expr).sty;
                 match *ty {
                     ty::TyStruct(def_id, _) => {
                         let sub_span = self.span_utils.span_for_last_ident(path.span);
                         Some(Data::TypeRefData(TypeRefData {
                             span: sub_span.unwrap(),
-                            scope: self.analysis.ty_cx.map.get_parent(expr.id),
+                            scope: self.tcx.map.get_parent(expr.id),
                             ref_id: def_id,
                         }))
                     }
@@ -392,7 +387,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                               struct_id: DefId,
                               parent: NodeId)
                               -> VariableRefData {
-        let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, struct_id);
+        let fields = ty::lookup_struct_fields(&self.tcx, struct_id);
         let field_name = get_ident(field_ref.ident.node).to_string();
         for f in &fields {
             if f.name == field_ref.ident.node.name {
@@ -407,8 +402,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             }
         }
 
-        self.sess.span_bug(field_ref.span,
-                           &format!("Couldn't find field {}", field_name));
+        self.tcx.sess.span_bug(field_ref.span,
+                               &format!("Couldn't find field {}", field_name));
     }
 
     pub fn get_data_for_id(&self, _id: &NodeId) -> Data {
@@ -417,11 +412,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     }
 
     fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
-        if !self.analysis.ty_cx.def_map.borrow().contains_key(&ref_id) {
-            self.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
-                                  ref_id));
+        if !self.tcx.def_map.borrow().contains_key(&ref_id) {
+            self.tcx.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
+                                       ref_id));
         }
-        let def = self.analysis.ty_cx.def_map.borrow().get(&ref_id).unwrap().full_def();
+        let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def();
         match def {
             def::DefPrimTy(_) => None,
             _ => Some(def.def_id()),
@@ -484,10 +479,10 @@ impl<'v> Visitor<'v> for PathCollector {
 }
 
 #[allow(deprecated)]
-pub fn process_crate(sess: &Session,
-                     krate: &ast::Crate,
+pub fn process_crate(tcx: &ty::ctxt,
                      analysis: &ty::CrateAnalysis,
                      odir: Option<&Path>) {
+    let krate = tcx.map.krate();
     if generated_code(krate.span) {
         return;
     }
@@ -512,10 +507,9 @@ pub fn process_crate(sess: &Session,
         },
     };
 
-    match fs::create_dir_all(&root_path) {
-        Err(e) => sess.err(&format!("Could not create directory {}: {}",
-                           root_path.display(), e)),
-        _ => (),
+    if let Err(e) = fs::create_dir_all(&root_path) {
+        tcx.sess.err(&format!("Could not create directory {}: {}",
+                              root_path.display(), e));
     }
 
     {
@@ -531,12 +525,12 @@ pub fn process_crate(sess: &Session,
         Ok(f) => box f,
         Err(e) => {
             let disp = root_path.display();
-            sess.fatal(&format!("Could not open {}: {}", disp, e));
+            tcx.sess.fatal(&format!("Could not open {}: {}", disp, e));
         }
     };
     root_path.pop();
 
-    let mut visitor = dump_csv::DumpCsvVisitor::new(sess, analysis, output_file);
+    let mut visitor = dump_csv::DumpCsvVisitor::new(tcx, analysis, output_file);
 
     visitor.dump_crate_info(&cratename, krate);
     visit::walk_crate(&mut visitor, krate);
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index c2293dcc6d4..ec92076d9c1 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -2491,7 +2491,7 @@ fn register_method(ccx: &CrateContext, id: ast::NodeId,
     }
 }
 
-pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
+pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'a, 'tcx>,
                                             ie: encoder::EncodeInlinedItem<'a>)
                                             -> encoder::EncodeParams<'a, 'tcx> {
     encoder::EncodeParams {
@@ -2627,9 +2627,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
     }
 }
 
-pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
-                         -> (ty::ctxt<'tcx>, CrateTranslation) {
-    let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
+pub fn trans_crate(tcx: &ty::ctxt, analysis: ty::CrateAnalysis) -> CrateTranslation {
+    let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis;
     let krate = tcx.map.krate();
 
     let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
@@ -2769,7 +2768,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     let formats = shared_ccx.tcx().dependency_formats.borrow().clone();
     let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
 
-    let translation = CrateTranslation {
+    CrateTranslation {
         modules: modules,
         metadata_module: metadata_module,
         link: link_meta,
@@ -2777,7 +2776,5 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
         reachable: reachable,
         crate_formats: formats,
         no_builtins: no_builtins,
-    };
-
-    (shared_ccx.take_tcx(), translation)
+    }
 }
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 663a01e19f3..6bb6916176d 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -57,7 +57,7 @@ pub struct Stats {
 /// per crate.  The data here is shared between all compilation units of the
 /// crate, so it must not contain references to any LLVM data structures
 /// (aside from metadata-related ones).
-pub struct SharedCrateContext<'tcx> {
+pub struct SharedCrateContext<'a, 'tcx: 'a> {
     local_ccxs: Vec<LocalCrateContext<'tcx>>,
 
     metadata_llmod: ModuleRef,
@@ -68,7 +68,7 @@ pub struct SharedCrateContext<'tcx> {
     item_symbols: RefCell<NodeMap<String>>,
     link_meta: LinkMeta,
     symbol_hasher: RefCell<Sha256>,
-    tcx: ty::ctxt<'tcx>,
+    tcx: &'a ty::ctxt<'tcx>,
     stats: Stats,
     check_overflow: bool,
     check_drop_flag_for_sanity: bool,
@@ -159,7 +159,7 @@ pub struct LocalCrateContext<'tcx> {
 }
 
 pub struct CrateContext<'a, 'tcx: 'a> {
-    shared: &'a SharedCrateContext<'tcx>,
+    shared: &'a SharedCrateContext<'a, 'tcx>,
     local: &'a LocalCrateContext<'tcx>,
     /// The index of `local` in `shared.local_ccxs`.  This is used in
     /// `maybe_iter(true)` to identify the original `LocalCrateContext`.
@@ -167,7 +167,7 @@ pub struct CrateContext<'a, 'tcx: 'a> {
 }
 
 pub struct CrateContextIterator<'a, 'tcx: 'a> {
-    shared: &'a SharedCrateContext<'tcx>,
+    shared: &'a SharedCrateContext<'a, 'tcx>,
     index: usize,
 }
 
@@ -192,7 +192,7 @@ impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> {
 
 /// The iterator produced by `CrateContext::maybe_iter`.
 pub struct CrateContextMaybeIterator<'a, 'tcx: 'a> {
-    shared: &'a SharedCrateContext<'tcx>,
+    shared: &'a SharedCrateContext<'a, 'tcx>,
     index: usize,
     single: bool,
     origin: usize,
@@ -237,17 +237,17 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
     (llcx, llmod)
 }
 
-impl<'tcx> SharedCrateContext<'tcx> {
+impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
     pub fn new(crate_name: &str,
                local_count: usize,
-               tcx: ty::ctxt<'tcx>,
+               tcx: &'b ty::ctxt<'tcx>,
                export_map: ExportMap,
                symbol_hasher: Sha256,
                link_meta: LinkMeta,
                reachable: NodeSet,
                check_overflow: bool,
                check_drop_flag_for_sanity: bool)
-               -> SharedCrateContext<'tcx> {
+               -> SharedCrateContext<'b, 'tcx> {
         let (metadata_llcx, metadata_llmod) = unsafe {
             create_context_and_module(&tcx.sess, "metadata")
         };
@@ -397,10 +397,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
     }
 
     pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
-        &self.tcx
-    }
-
-    pub fn take_tcx(self) -> ty::ctxt<'tcx> {
         self.tcx
     }
 
@@ -418,7 +414,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
 }
 
 impl<'tcx> LocalCrateContext<'tcx> {
-    fn new(shared: &SharedCrateContext<'tcx>,
+    fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
            name: &str)
            -> LocalCrateContext<'tcx> {
         unsafe {
@@ -505,7 +501,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
     /// This is used in the `LocalCrateContext` constructor to allow calling
     /// functions that expect a complete `CrateContext`, even before the local
     /// portion is fully initialized and attached to the `SharedCrateContext`.
-    fn dummy_ccx<'a>(&'a self, shared: &'a SharedCrateContext<'tcx>)
+    fn dummy_ccx<'a>(&'a self, shared: &'a SharedCrateContext<'a, 'tcx>)
                      -> CrateContext<'a, 'tcx> {
         CrateContext {
             shared: shared,
@@ -516,7 +512,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
 }
 
 impl<'b, 'tcx> CrateContext<'b, 'tcx> {
-    pub fn shared(&self) -> &'b SharedCrateContext<'tcx> {
+    pub fn shared(&self) -> &'b SharedCrateContext<'b, 'tcx> {
         self.shared
     }
 
@@ -548,7 +544,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
 
 
     pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
-        &self.shared.tcx
+        self.shared.tcx
     }
 
     pub fn sess<'a>(&'a self) -> &'a Session {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 3183307250c..7d66253b378 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -133,17 +133,17 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
     let arenas = ty::CtxtArenas::new();
     let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
 
-    let ty::CrateAnalysis {
-        exported_items, public_items, ty_cx, ..
-    } = driver::phase_3_run_analysis_passes(sess,
-                                            ast_map,
-                                            &arenas,
-                                            name,
-                                            resolve::MakeGlobMap::No);
+    let (tcx, ty::CrateAnalysis {
+        exported_items, public_items, ..
+    }) = driver::phase_3_run_analysis_passes(sess,
+                                             ast_map,
+                                             &arenas,
+                                             name,
+                                             resolve::MakeGlobMap::No);
 
     let ctxt = DocContext {
-        krate: ty_cx.map.krate(),
-        maybe_typed: Typed(ty_cx),
+        krate: tcx.map.krate(),
+        maybe_typed: Typed(tcx),
         input: input,
         external_traits: RefCell::new(Some(HashMap::new())),
         external_typarams: RefCell::new(Some(HashMap::new())),
diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs
index 5c15a56c6ef..64f66a6ea07 100644
--- a/src/test/run-make/execution-engine/test.rs
+++ b/src/test/run-make/execution-engine/test.rs
@@ -221,10 +221,10 @@ fn compile_program(input: &str, sysroot: PathBuf)
         let arenas = ty::CtxtArenas::new();
         let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
 
-        let analysis = driver::phase_3_run_analysis_passes(
+        let (tcx, analysis) = driver::phase_3_run_analysis_passes(
             sess, ast_map, &arenas, id, MakeGlobMap::No);
 
-        let (tcx, trans) = driver::phase_4_translate_to_llvm(analysis);
+        let trans = driver::phase_4_translate_to_llvm(&tcx, analysis);
 
         let crates = tcx.sess.cstore.get_used_crates(RequireDynamic);