rustc: enforce stack discipline on ty::ctxt.
This commit is contained in:
parent
84b49b2d35
commit
bc383f6294
7 changed files with 231 additions and 198 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
phase_3_run_analysis_passes(sess,
|
||||
ast_map,
|
||||
&arenas,
|
||||
id,
|
||||
control.make_glob_map,
|
||||
|tcx, analysis| {
|
||||
|
||||
controller_entry_point!(after_analysis,
|
||||
tcx.sess,
|
||||
CompileState::state_after_analysis(input,
|
||||
&tcx.sess,
|
||||
outdir,
|
||||
tcx.map.krate(),
|
||||
&analysis,
|
||||
&tcx));
|
||||
{
|
||||
let state = CompileState::state_after_analysis(input,
|
||||
&tcx.sess,
|
||||
outdir,
|
||||
tcx.map.krate(),
|
||||
&analysis,
|
||||
tcx);
|
||||
(control.after_analysis.callback)(state);
|
||||
|
||||
if log_enabled!(::log::INFO) {
|
||||
println!("Pre-trans");
|
||||
tcx.print_debug_stats();
|
||||
}
|
||||
let trans = phase_4_translate_to_llvm(&tcx, analysis);
|
||||
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);
|
||||
|
||||
// Discard interned strings as they are no longer required.
|
||||
token::get_ident_interner().clear();
|
||||
if log_enabled!(::log::INFO) {
|
||||
println!("Post-trans");
|
||||
tcx.print_debug_stats();
|
||||
}
|
||||
|
||||
(outputs, trans, tcx.sess)
|
||||
// Discard interned strings as they are no longer required.
|
||||
token::get_ident_interner().clear();
|
||||
|
||||
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));
|
||||
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(&ty_cx, trait_map);
|
||||
// passes are timed inside typeck
|
||||
typeck::check_crate(tcx, trait_map);
|
||||
|
||||
time(time_passes, "const checking", (), |_|
|
||||
middle::check_const::check_crate(&ty_cx));
|
||||
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(&ty_cx, &export_map, external_exports));
|
||||
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", (), |_|
|
||||
ty_cx.stability.borrow_mut().build(&ty_cx, krate, &public_items));
|
||||
// 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(&ty_cx));
|
||||
time(time_passes, "intrinsic checking", (), |_|
|
||||
middle::intrinsicck::check_crate(tcx));
|
||||
|
||||
time(time_passes, "effect checking", (), |_|
|
||||
middle::effect::check_crate(&ty_cx));
|
||||
time(time_passes, "effect checking", (), |_|
|
||||
middle::effect::check_crate(tcx));
|
||||
|
||||
time(time_passes, "match checking", (), |_|
|
||||
middle::check_match::check_crate(&ty_cx));
|
||||
time(time_passes, "match checking", (), |_|
|
||||
middle::check_match::check_crate(tcx));
|
||||
|
||||
time(time_passes, "liveness checking", (), |_|
|
||||
middle::liveness::check_crate(&ty_cx));
|
||||
time(time_passes, "liveness checking", (), |_|
|
||||
middle::liveness::check_crate(tcx));
|
||||
|
||||
time(time_passes, "borrow checking", (), |_|
|
||||
borrowck::check_crate(&ty_cx));
|
||||
time(time_passes, "borrow checking", (), |_|
|
||||
borrowck::check_crate(tcx));
|
||||
|
||||
time(time_passes, "rvalue checking", (), |_|
|
||||
middle::check_rvalues::check_crate(&ty_cx, krate));
|
||||
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
|
||||
ty_cx.sess.abort_if_errors();
|
||||
// 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(&ty_cx, &exported_items));
|
||||
let reachable_map =
|
||||
time(time_passes, "reachability checking", (), |_|
|
||||
reachable::find_reachable(tcx, &exported_items));
|
||||
|
||||
time(time_passes, "death checking", (), |_| {
|
||||
middle::dead::check_crate(&ty_cx,
|
||||
&exported_items,
|
||||
&reachable_map)
|
||||
});
|
||||
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(&ty_cx));
|
||||
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(
|
||||
&ty_cx.sess, lib_features_used));
|
||||
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(&ty_cx, &exported_items));
|
||||
time(time_passes, "lint checking", (), |_|
|
||||
lint::check_crate(tcx, &exported_items));
|
||||
|
||||
// The above three passes generate errors w/o aborting
|
||||
ty_cx.sess.abort_if_errors();
|
||||
// The above three passes generate errors w/o aborting
|
||||
tcx.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,
|
||||
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,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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 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 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 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)
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue