about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-06-14 04:50:23 +0300
committerEduard Burtescu <edy.burt@gmail.com>2015-06-19 01:18:42 +0300
commitbc383f62941ae079188a9725eb49f3b8a42e35ae (patch)
treee27b379c1846874c850d4addb539f3fb9540302f /src
parent84b49b2d355e49c429703eade10f93680cc3bd47 (diff)
downloadrust-bc383f62941ae079188a9725eb49f3b8a42e35ae.tar.gz
rust-bc383f62941ae079188a9725eb49f3b8a42e35ae.zip
rustc: enforce stack discipline on ty::ctxt.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/ty.rs26
-rw-r--r--src/librustc_driver/driver.rs249
-rw-r--r--src/librustc_driver/pretty.rs38
-rw-r--r--src/librustc_driver/test.rs30
-rw-r--r--src/librustdoc/core.rs103
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/test/run-make/execution-engine/test.rs27
7 files changed, 255 insertions, 222 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index fa7b1aa4fbe..6cbfe761614 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2810,20 +2810,22 @@ impl<'tcx> CommonTypes<'tcx> {
     }
 }
 
-pub fn mk_ctxt<'tcx>(s: Session,
-                     arenas: &'tcx CtxtArenas<'tcx>,
-                     def_map: DefMap,
-                     named_region_map: resolve_lifetime::NamedRegionMap,
-                     map: ast_map::Map<'tcx>,
-                     freevars: RefCell<FreevarMap>,
-                     region_maps: RegionMaps,
-                     lang_items: middle::lang_items::LanguageItems,
-                     stability: stability::Index<'tcx>) -> ctxt<'tcx>
+pub fn with_ctxt<'tcx, F, R>(s: Session,
+                             arenas: &'tcx CtxtArenas<'tcx>,
+                             def_map: DefMap,
+                             named_region_map: resolve_lifetime::NamedRegionMap,
+                             map: ast_map::Map<'tcx>,
+                             freevars: RefCell<FreevarMap>,
+                             region_maps: RegionMaps,
+                             lang_items: middle::lang_items::LanguageItems,
+                             stability: stability::Index<'tcx>,
+                             f: F) -> (Session, R)
+                             where F: FnOnce(&ctxt<'tcx>) -> R
 {
     let mut interner = FnvHashMap();
     let common_types = CommonTypes::new(&arenas.type_, &mut interner);
 
-    ctxt {
+    let tcx = ctxt {
         arenas: arenas,
         interner: RefCell::new(interner),
         substs_interner: RefCell::new(FnvHashMap()),
@@ -2885,7 +2887,9 @@ pub fn mk_ctxt<'tcx>(s: Session,
         const_qualif_map: RefCell::new(NodeMap()),
         custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
         cast_kinds: RefCell::new(NodeMap()),
-   }
+   };
+   let result = f(&tcx);
+   (tcx.sess, result)
 }
 
 // Type constructors
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 8640bcfe506..a834ed4cb5f 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -65,7 +65,7 @@ pub fn compile_input(sess: Session,
     // We need nested scopes here, because the intermediate results can keep
     // large chunks of memory alive and we want to free them as soon as
     // possible to keep the peak memory usage low
-    let (outputs, trans, sess) = {
+    let (sess, result) = {
         let (outputs, expanded_crate, id) = {
             let krate = phase_1_parse_input(&sess, cfg, input);
 
@@ -119,37 +119,52 @@ pub fn compile_input(sess: Session,
                                                                      &ast_map.krate(),
                                                                      &id[..]));
 
-        let (tcx, analysis) = phase_3_run_analysis_passes(sess,
-                                                          ast_map,
-                                                          &arenas,
-                                                          id,
-                                                          control.make_glob_map);
-
-        controller_entry_point!(after_analysis,
-                                tcx.sess,
-                                CompileState::state_after_analysis(input,
-                                                                   &tcx.sess,
-                                                                   outdir,
-                                                                   tcx.map.krate(),
-                                                                   &analysis,
-                                                                   &tcx));
-
-        if log_enabled!(::log::INFO) {
-            println!("Pre-trans");
-            tcx.print_debug_stats();
-        }
-        let trans = phase_4_translate_to_llvm(&tcx, analysis);
+        phase_3_run_analysis_passes(sess,
+                                    ast_map,
+                                    &arenas,
+                                    id,
+                                    control.make_glob_map,
+                                    |tcx, analysis| {
+
+            {
+                let state = CompileState::state_after_analysis(input,
+                                                               &tcx.sess,
+                                                               outdir,
+                                                               tcx.map.krate(),
+                                                               &analysis,
+                                                               tcx);
+                (control.after_analysis.callback)(state);
+
+                tcx.sess.abort_if_errors();
+                if control.after_analysis.stop == Compilation::Stop {
+                    return Err(());
+                }
+            }
 
-        if log_enabled!(::log::INFO) {
-            println!("Post-trans");
-            tcx.print_debug_stats();
-        }
+            if log_enabled!(::log::INFO) {
+                println!("Pre-trans");
+                tcx.print_debug_stats();
+            }
+            let trans = phase_4_translate_to_llvm(tcx, analysis);
+
+            if log_enabled!(::log::INFO) {
+                println!("Post-trans");
+                tcx.print_debug_stats();
+            }
 
-        // Discard interned strings as they are no longer required.
-        token::get_ident_interner().clear();
+            // Discard interned strings as they are no longer required.
+            token::get_ident_interner().clear();
 
-        (outputs, trans, tcx.sess)
+            Ok((outputs, trans))
+        })
     };
+
+    let (outputs, trans) = if let Ok(out) = result {
+        out
+    } else {
+        return;
+    };
+
     phase_5_run_llvm_passes(&sess, &trans, &outputs);
 
     controller_entry_point!(after_llvm,
@@ -578,12 +593,16 @@ pub fn assign_node_ids_and_map<'ast>(sess: &Session,
 /// Run the resolution, typechecking, region checking and other
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
-pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
-                                         ast_map: ast_map::Map<'tcx>,
-                                         arenas: &'tcx ty::CtxtArenas<'tcx>,
-                                         name: String,
-                                         make_glob_map: resolve::MakeGlobMap)
-                                         -> (ty::ctxt<'tcx>, ty::CrateAnalysis) {
+pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
+                                               ast_map: ast_map::Map<'tcx>,
+                                               arenas: &'tcx ty::CtxtArenas<'tcx>,
+                                               name: String,
+                                               make_glob_map: resolve::MakeGlobMap,
+                                               f: F)
+                                               -> (Session, R)
+                                               where F: FnOnce(&ty::ctxt<'tcx>,
+                                                               ty::CrateAnalysis) -> R
+{
     let time_passes = sess.time_passes();
     let krate = ast_map.krate();
 
@@ -627,86 +646,88 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     time(time_passes, "static item recursion checking", (), |_|
          middle::check_static_recursion::check_crate(&sess, krate, &def_map, &ast_map));
 
-    let ty_cx = ty::mk_ctxt(sess,
-                            arenas,
-                            def_map,
-                            named_region_map,
-                            ast_map,
-                            freevars,
-                            region_map,
-                            lang_items,
-                            stability::Index::new(krate));
-
-    // passes are timed inside typeck
-    typeck::check_crate(&ty_cx, trait_map);
-
-    time(time_passes, "const checking", (), |_|
-         middle::check_const::check_crate(&ty_cx));
-
-    let (exported_items, public_items) =
-            time(time_passes, "privacy checking", (), |_|
-                 rustc_privacy::check_crate(&ty_cx, &export_map, external_exports));
-
-    // Do not move this check past lint
-    time(time_passes, "stability index", (), |_|
-         ty_cx.stability.borrow_mut().build(&ty_cx, krate, &public_items));
-
-    time(time_passes, "intrinsic checking", (), |_|
-         middle::intrinsicck::check_crate(&ty_cx));
-
-    time(time_passes, "effect checking", (), |_|
-         middle::effect::check_crate(&ty_cx));
-
-    time(time_passes, "match checking", (), |_|
-         middle::check_match::check_crate(&ty_cx));
-
-    time(time_passes, "liveness checking", (), |_|
-         middle::liveness::check_crate(&ty_cx));
-
-    time(time_passes, "borrow checking", (), |_|
-         borrowck::check_crate(&ty_cx));
-
-    time(time_passes, "rvalue checking", (), |_|
-         middle::check_rvalues::check_crate(&ty_cx, krate));
-
-    // Avoid overwhelming user with errors if type checking failed.
-    // I'm not sure how helpful this is, to be honest, but it avoids a
-    // lot of annoying errors in the compile-fail tests (basically,
-    // lint warnings and so on -- kindck used to do this abort, but
-    // kindck is gone now). -nmatsakis
-    ty_cx.sess.abort_if_errors();
-
-    let reachable_map =
-        time(time_passes, "reachability checking", (), |_|
-             reachable::find_reachable(&ty_cx, &exported_items));
-
-    time(time_passes, "death checking", (), |_| {
-        middle::dead::check_crate(&ty_cx,
-                                  &exported_items,
-                                  &reachable_map)
-    });
-
-    let ref lib_features_used =
-        time(time_passes, "stability checking", (), |_|
-             stability::check_unstable_api_usage(&ty_cx));
-
-    time(time_passes, "unused lib feature checking", (), |_|
-         stability::check_unused_or_stable_features(
-             &ty_cx.sess, lib_features_used));
-
-    time(time_passes, "lint checking", (), |_|
-         lint::check_crate(&ty_cx, &exported_items));
-
-    // The above three passes generate errors w/o aborting
-    ty_cx.sess.abort_if_errors();
-
-    (ty_cx, ty::CrateAnalysis {
-        export_map: export_map,
-        exported_items: exported_items,
-        public_items: public_items,
-        reachable: reachable_map,
-        name: name,
-        glob_map: glob_map,
+    ty::with_ctxt(sess,
+                  arenas,
+                  def_map,
+                  named_region_map,
+                  ast_map,
+                  freevars,
+                  region_map,
+                  lang_items,
+                  stability::Index::new(krate),
+                  |tcx| {
+
+        // passes are timed inside typeck
+        typeck::check_crate(tcx, trait_map);
+
+        time(time_passes, "const checking", (), |_|
+            middle::check_const::check_crate(tcx));
+
+        let (exported_items, public_items) =
+                time(time_passes, "privacy checking", (), |_|
+                    rustc_privacy::check_crate(tcx, &export_map, external_exports));
+
+        // Do not move this check past lint
+        time(time_passes, "stability index", (), |_|
+            tcx.stability.borrow_mut().build(tcx, krate, &public_items));
+
+        time(time_passes, "intrinsic checking", (), |_|
+            middle::intrinsicck::check_crate(tcx));
+
+        time(time_passes, "effect checking", (), |_|
+            middle::effect::check_crate(tcx));
+
+        time(time_passes, "match checking", (), |_|
+            middle::check_match::check_crate(tcx));
+
+        time(time_passes, "liveness checking", (), |_|
+            middle::liveness::check_crate(tcx));
+
+        time(time_passes, "borrow checking", (), |_|
+            borrowck::check_crate(tcx));
+
+        time(time_passes, "rvalue checking", (), |_|
+            middle::check_rvalues::check_crate(tcx, krate));
+
+        // Avoid overwhelming user with errors if type checking failed.
+        // I'm not sure how helpful this is, to be honest, but it avoids a
+        // lot of annoying errors in the compile-fail tests (basically,
+        // lint warnings and so on -- kindck used to do this abort, but
+        // kindck is gone now). -nmatsakis
+        tcx.sess.abort_if_errors();
+
+        let reachable_map =
+            time(time_passes, "reachability checking", (), |_|
+                reachable::find_reachable(tcx, &exported_items));
+
+        time(time_passes, "death checking", (), |_| {
+            middle::dead::check_crate(tcx,
+                                      &exported_items,
+                                      &reachable_map)
+        });
+
+        let ref lib_features_used =
+            time(time_passes, "stability checking", (), |_|
+                stability::check_unstable_api_usage(tcx));
+
+        time(time_passes, "unused lib feature checking", (), |_|
+            stability::check_unused_or_stable_features(
+                &tcx.sess, lib_features_used));
+
+        time(time_passes, "lint checking", (), |_|
+            lint::check_crate(tcx, &exported_items));
+
+        // The above three passes generate errors w/o aborting
+        tcx.sess.abort_if_errors();
+
+        f(tcx, ty::CrateAnalysis {
+            export_map: export_map,
+            exported_items: exported_items,
+            public_items: public_items,
+            reachable: reachable_map,
+            name: name,
+            glob_map: glob_map,
+        })
     })
 }
 
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 0dc636eb3ec..b5ae498bedf 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -148,13 +148,15 @@ impl PpSourceMode {
             }
             PpmTyped => {
                 let ast_map = ast_map.expect("--pretty=typed missing ast_map");
-                let (tcx, _) = driver::phase_3_run_analysis_passes(sess,
-                                                                   ast_map,
-                                                                   arenas,
-                                                                   id,
-                                                                   resolve::MakeGlobMap::No);
-                let annotation = TypedAnnotation { tcx: tcx };
-                f(&annotation, payload)
+                driver::phase_3_run_analysis_passes(sess,
+                                                    ast_map,
+                                                    arenas,
+                                                    id,
+                                                    resolve::MakeGlobMap::No,
+                                                    |tcx, _| {
+                    let annotation = TypedAnnotation { tcx: tcx };
+                    f(&annotation, payload)
+                }).1
             }
         }
     }
@@ -284,11 +286,11 @@ impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
 }
 
 
-struct TypedAnnotation<'tcx> {
-    tcx: ty::ctxt<'tcx>,
+struct TypedAnnotation<'a, 'tcx: 'a> {
+    tcx: &'a ty::ctxt<'tcx>,
 }
 
-impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
+impl<'b, 'tcx> PrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
     fn sess<'a>(&'a self) -> &'a Session { &self.tcx.sess }
 
     fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'tcx>> {
@@ -298,7 +300,7 @@ impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
     fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
 }
 
-impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
+impl<'a, 'tcx> pprust::PpAnn for TypedAnnotation<'a, 'tcx> {
     fn pre(&self,
            s: &mut pprust::State,
            node: pprust::AnnNode) -> io::Result<()> {
@@ -645,12 +647,14 @@ pub fn pretty_print_input(sess: Session,
             match code {
                 Some(code) => {
                     let variants = gather_flowgraph_variants(&sess);
-                    let (tcx, _) = driver::phase_3_run_analysis_passes(sess,
-                                                                       ast_map,
-                                                                       &arenas,
-                                                                       id,
-                                                                       resolve::MakeGlobMap::No);
-                    print_flowgraph(variants, &tcx, code, mode, out)
+                    driver::phase_3_run_analysis_passes(sess,
+                                                        ast_map,
+                                                        &arenas,
+                                                        id,
+                                                        resolve::MakeGlobMap::No,
+                                                        |tcx, _| {
+                        print_flowgraph(variants, tcx, code, mode, out)
+                    }).1
                 }
                 None => {
                     let message = format!("--pretty=flowgraph needs \
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 5991fc5c193..4668b3d1c25 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -129,20 +129,22 @@ fn test_env<F>(source_string: &str,
         resolve::resolve_crate(&sess, &ast_map, resolve::MakeGlobMap::No);
     let named_region_map = resolve_lifetime::krate(&sess, krate, &def_map);
     let region_map = region::resolve_crate(&sess, krate);
-    let tcx = ty::mk_ctxt(sess,
-                          &arenas,
-                          def_map,
-                          named_region_map,
-                          ast_map,
-                          freevars,
-                          region_map,
-                          lang_items,
-                          stability::Index::new(krate));
-    let infcx = infer::new_infer_ctxt(&tcx);
-    body(Env { infcx: &infcx });
-    let free_regions = FreeRegionMap::new();
-    infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID);
-    assert_eq!(tcx.sess.err_count(), expected_err_count);
+    ty::with_ctxt(sess,
+                  &arenas,
+                  def_map,
+                  named_region_map,
+                  ast_map,
+                  freevars,
+                  region_map,
+                  lang_items,
+                  stability::Index::new(krate),
+                  |tcx| {
+        let infcx = infer::new_infer_ctxt(tcx);
+        body(Env { infcx: &infcx });
+        let free_regions = FreeRegionMap::new();
+        infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID);
+        assert_eq!(tcx.sess.err_count(), expected_err_count);
+    });
 }
 
 impl<'a, 'tcx> Env<'a, 'tcx> {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 7d66253b378..13022fd43ef 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -32,17 +32,17 @@ pub use rustc::session::config::Input;
 pub use rustc::session::search_paths::SearchPaths;
 
 /// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
-pub enum MaybeTyped<'tcx> {
-    Typed(ty::ctxt<'tcx>),
+pub enum MaybeTyped<'a, 'tcx: 'a> {
+    Typed(&'a ty::ctxt<'tcx>),
     NotTyped(session::Session)
 }
 
 pub type ExternalPaths = RefCell<Option<HashMap<ast::DefId,
                                                 (Vec<String>, clean::TypeKind)>>>;
 
-pub struct DocContext<'tcx> {
+pub struct DocContext<'a, 'tcx: 'a> {
     pub krate: &'tcx ast::Crate,
-    pub maybe_typed: MaybeTyped<'tcx>,
+    pub maybe_typed: MaybeTyped<'a, 'tcx>,
     pub input: Input,
     pub external_paths: ExternalPaths,
     pub external_traits: RefCell<Option<HashMap<ast::DefId, clean::Trait>>>,
@@ -52,17 +52,17 @@ pub struct DocContext<'tcx> {
     pub deref_trait_did: Cell<Option<ast::DefId>>,
 }
 
-impl<'tcx> DocContext<'tcx> {
+impl<'b, 'tcx> DocContext<'b, 'tcx> {
     pub fn sess<'a>(&'a self) -> &'a session::Session {
         match self.maybe_typed {
-            Typed(ref tcx) => &tcx.sess,
+            Typed(tcx) => &tcx.sess,
             NotTyped(ref sess) => sess
         }
     }
 
     pub fn tcx_opt<'a>(&'a self) -> Option<&'a ty::ctxt<'tcx>> {
         match self.maybe_typed {
-            Typed(ref tcx) => Some(tcx),
+            Typed(tcx) => Some(tcx),
             NotTyped(_) => None
         }
     }
@@ -133,48 +133,49 @@ 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 (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: tcx.map.krate(),
-        maybe_typed: Typed(tcx),
-        input: input,
-        external_traits: RefCell::new(Some(HashMap::new())),
-        external_typarams: RefCell::new(Some(HashMap::new())),
-        external_paths: RefCell::new(Some(HashMap::new())),
-        inlined: RefCell::new(Some(HashSet::new())),
-        populated_crate_impls: RefCell::new(HashSet::new()),
-        deref_trait_did: Cell::new(None),
-    };
-    debug!("crate: {:?}", ctxt.krate);
-
-    let mut analysis = CrateAnalysis {
-        exported_items: exported_items,
-        public_items: public_items,
-        external_paths: RefCell::new(None),
-        external_typarams: RefCell::new(None),
-        inlined: RefCell::new(None),
-        deref_trait_did: None,
-    };
-
-    let krate = {
-        let mut v = RustdocVisitor::new(&ctxt, Some(&analysis));
-        v.visit(ctxt.krate);
-        v.clean(&ctxt)
-    };
-
-    let external_paths = ctxt.external_paths.borrow_mut().take();
-    *analysis.external_paths.borrow_mut() = external_paths;
-    let map = ctxt.external_typarams.borrow_mut().take();
-    *analysis.external_typarams.borrow_mut() = map;
-    let map = ctxt.inlined.borrow_mut().take();
-    *analysis.inlined.borrow_mut() = map;
-    analysis.deref_trait_did = ctxt.deref_trait_did.get();
-    (krate, analysis)
+    driver::phase_3_run_analysis_passes(sess,
+                                        ast_map,
+                                        &arenas,
+                                        name,
+                                        resolve::MakeGlobMap::No,
+                                        |tcx, analysis| {
+        let ty::CrateAnalysis { exported_items, public_items, .. } = analysis;
+
+        let ctxt = DocContext {
+            krate: tcx.map.krate(),
+            maybe_typed: Typed(tcx),
+            input: input,
+            external_traits: RefCell::new(Some(HashMap::new())),
+            external_typarams: RefCell::new(Some(HashMap::new())),
+            external_paths: RefCell::new(Some(HashMap::new())),
+            inlined: RefCell::new(Some(HashSet::new())),
+            populated_crate_impls: RefCell::new(HashSet::new()),
+            deref_trait_did: Cell::new(None),
+        };
+        debug!("crate: {:?}", ctxt.krate);
+
+        let mut analysis = CrateAnalysis {
+            exported_items: exported_items,
+            public_items: public_items,
+            external_paths: RefCell::new(None),
+            external_typarams: RefCell::new(None),
+            inlined: RefCell::new(None),
+            deref_trait_did: None,
+        };
+
+        let krate = {
+            let mut v = RustdocVisitor::new(&ctxt, Some(&analysis));
+            v.visit(ctxt.krate);
+            v.clean(&ctxt)
+        };
+
+        let external_paths = ctxt.external_paths.borrow_mut().take();
+        *analysis.external_paths.borrow_mut() = external_paths;
+        let map = ctxt.external_typarams.borrow_mut().take();
+        *analysis.external_typarams.borrow_mut() = map;
+        let map = ctxt.inlined.borrow_mut().take();
+        *analysis.inlined.borrow_mut() = map;
+        analysis.deref_trait_did = ctxt.deref_trait_did.get();
+        (krate, analysis)
+    }).1
 }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ff058fa908d..305747d1282 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -38,14 +38,14 @@ use doctree::*;
 pub struct RustdocVisitor<'a, 'tcx: 'a> {
     pub module: Module,
     pub attrs: Vec<ast::Attribute>,
-    pub cx: &'a core::DocContext<'tcx>,
+    pub cx: &'a core::DocContext<'a, 'tcx>,
     pub analysis: Option<&'a core::CrateAnalysis>,
     view_item_stack: HashSet<ast::NodeId>,
     inlining_from_glob: bool,
 }
 
 impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
-    pub fn new(cx: &'a core::DocContext<'tcx>,
+    pub fn new(cx: &'a core::DocContext<'a, 'tcx>,
                analysis: Option<&'a core::CrateAnalysis>) -> RustdocVisitor<'a, 'tcx> {
         // If the root is reexported, terminate all recursion.
         let mut stack = HashSet::new();
diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs
index 64f66a6ea07..8af3844e62e 100644
--- a/src/test/run-make/execution-engine/test.rs
+++ b/src/test/run-make/execution-engine/test.rs
@@ -221,25 +221,26 @@ 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 (tcx, analysis) = driver::phase_3_run_analysis_passes(
-            sess, ast_map, &arenas, id, MakeGlobMap::No);
+        driver::phase_3_run_analysis_passes(
+            sess, ast_map, &arenas, id, MakeGlobMap::No, |tcx, analysis| {
 
-        let trans = driver::phase_4_translate_to_llvm(&tcx, analysis);
+            let trans = driver::phase_4_translate_to_llvm(tcx, analysis);
 
-        let crates = tcx.sess.cstore.get_used_crates(RequireDynamic);
+            let crates = tcx.sess.cstore.get_used_crates(RequireDynamic);
 
-        // Collect crates used in the session.
-        // Reverse order finds dependencies first.
-        let deps = crates.into_iter().rev()
-            .filter_map(|(_, p)| p).collect();
+            // Collect crates used in the session.
+            // Reverse order finds dependencies first.
+            let deps = crates.into_iter().rev()
+                .filter_map(|(_, p)| p).collect();
 
-        assert_eq!(trans.modules.len(), 1);
-        let llmod = trans.modules[0].llmod;
+            assert_eq!(trans.modules.len(), 1);
+            let llmod = trans.modules[0].llmod;
 
-        // Workaround because raw pointers do not impl Send
-        let modp = llmod as usize;
+            // Workaround because raw pointers do not impl Send
+            let modp = llmod as usize;
 
-        (modp, deps)
+            (modp, deps)
+        }).1
     }).unwrap();
 
     match handle.join() {