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
|
|
@ -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> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue