Auto merge of #31250 - nrc:more-aborts, r=@nikomatsakis
With this PR we can save-analysis on code with errors, essential foundation work for IDE support.
This commit is contained in:
commit
b94cd7a5bd
|
@ -93,9 +93,12 @@ type Scope<'a> = &'a ScopeChain<'a>;
|
||||||
|
|
||||||
static ROOT_SCOPE: ScopeChain<'static> = RootScope;
|
static ROOT_SCOPE: ScopeChain<'static> = RootScope;
|
||||||
|
|
||||||
pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap {
|
pub fn krate(sess: &Session,
|
||||||
|
krate: &hir::Crate,
|
||||||
|
def_map: &DefMap)
|
||||||
|
-> Result<NamedRegionMap, usize> {
|
||||||
let mut named_region_map = NodeMap();
|
let mut named_region_map = NodeMap();
|
||||||
sess.abort_if_new_errors(|| {
|
try!(sess.track_errors(|| {
|
||||||
krate.visit_all_items(&mut LifetimeContext {
|
krate.visit_all_items(&mut LifetimeContext {
|
||||||
sess: sess,
|
sess: sess,
|
||||||
named_region_map: &mut named_region_map,
|
named_region_map: &mut named_region_map,
|
||||||
|
@ -104,8 +107,8 @@ pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegio
|
||||||
trait_ref_hack: false,
|
trait_ref_hack: false,
|
||||||
labels_in_fn: vec![],
|
labels_in_fn: vec![],
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
named_region_map
|
Ok(named_region_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||||
|
|
|
@ -1915,6 +1915,16 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn expr_ty_adjusted_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
|
||||||
|
self.expr_ty_opt(expr).map(|t| t.adjust(self,
|
||||||
|
expr.span,
|
||||||
|
expr.id,
|
||||||
|
self.tables.borrow().adjustments.get(&expr.id),
|
||||||
|
|method_call| {
|
||||||
|
self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expr_span(&self, id: NodeId) -> Span {
|
pub fn expr_span(&self, id: NodeId) -> Span {
|
||||||
match self.map.find(id) {
|
match self.map.find(id) {
|
||||||
Some(ast_map::NodeExpr(e)) => {
|
Some(ast_map::NodeExpr(e)) => {
|
||||||
|
|
|
@ -179,24 +179,13 @@ impl Session {
|
||||||
pub fn track_errors<F, T>(&self, f: F) -> Result<T, usize>
|
pub fn track_errors<F, T>(&self, f: F) -> Result<T, usize>
|
||||||
where F: FnOnce() -> T
|
where F: FnOnce() -> T
|
||||||
{
|
{
|
||||||
let count = self.err_count();
|
let old_count = self.err_count();
|
||||||
let result = f();
|
let result = f();
|
||||||
let count = self.err_count() - count;
|
let errors = self.err_count() - old_count;
|
||||||
if count == 0 {
|
if errors == 0 {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
} else {
|
} else {
|
||||||
Err(count)
|
Err(errors)
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn abort_if_new_errors<F, T>(&self, f: F) -> T
|
|
||||||
where F: FnOnce() -> T
|
|
||||||
{
|
|
||||||
match self.track_errors(f) {
|
|
||||||
Ok(result) => result,
|
|
||||||
Err(_) => {
|
|
||||||
self.abort_if_errors();
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||||
|
@ -515,3 +504,15 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
|
||||||
};
|
};
|
||||||
emitter.emit(None, msg, None, errors::Level::Warning);
|
emitter.emit(None, msg, None, errors::Level::Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Err(0) means compilation was stopped, but no errors were found.
|
||||||
|
// This would be better as a dedicated enum, but using try! is so convenient.
|
||||||
|
pub type CompileResult = Result<(), usize>;
|
||||||
|
|
||||||
|
pub fn compile_result_from_err_count(err_count: usize) -> CompileResult {
|
||||||
|
if err_count == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(err_count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,14 +12,15 @@ use rustc::front;
|
||||||
use rustc::front::map as hir_map;
|
use rustc::front::map as hir_map;
|
||||||
use rustc_mir as mir;
|
use rustc_mir as mir;
|
||||||
use rustc_mir::mir_map::MirMap;
|
use rustc_mir::mir_map::MirMap;
|
||||||
use rustc::session::Session;
|
use rustc::session::{Session, CompileResult, compile_result_from_err_count};
|
||||||
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
|
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
|
||||||
use rustc::session::search_paths::PathKind;
|
use rustc::session::search_paths::PathKind;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::middle::{stability, ty, reachable};
|
use rustc::middle::{dependency_format, stability, ty, reachable};
|
||||||
use rustc::middle::dependency_format;
|
use rustc::middle::privacy::AccessLevels;
|
||||||
use rustc::middle;
|
use rustc::middle;
|
||||||
use rustc::util::common::time;
|
use rustc::util::common::time;
|
||||||
|
use rustc::util::nodemap::NodeSet;
|
||||||
use rustc_borrowck as borrowck;
|
use rustc_borrowck as borrowck;
|
||||||
use rustc_resolve as resolve;
|
use rustc_resolve as resolve;
|
||||||
use rustc_metadata::macro_import;
|
use rustc_metadata::macro_import;
|
||||||
|
@ -35,7 +36,7 @@ use rustc_plugin as plugin;
|
||||||
use rustc_front::hir;
|
use rustc_front::hir;
|
||||||
use rustc_front::lowering::{lower_crate, LoweringContext};
|
use rustc_front::lowering::{lower_crate, LoweringContext};
|
||||||
use rustc_passes::{no_asm, loops, consts, const_fn, rvalues, static_recursion};
|
use rustc_passes::{no_asm, loops, consts, const_fn, rvalues, static_recursion};
|
||||||
use super::{Compilation, CompileResult, compile_result_from_err_count};
|
use super::Compilation;
|
||||||
|
|
||||||
use serialize::json;
|
use serialize::json;
|
||||||
|
|
||||||
|
@ -57,15 +58,6 @@ use syntax::visit;
|
||||||
use syntax;
|
use syntax;
|
||||||
use syntax_ext;
|
use syntax_ext;
|
||||||
|
|
||||||
macro_rules! throw_if_errors {
|
|
||||||
($tsess: expr) => {{
|
|
||||||
let err_count = $tsess.err_count();
|
|
||||||
if err_count > 0 {
|
|
||||||
return Err(err_count);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn compile_input(sess: &Session,
|
pub fn compile_input(sess: &Session,
|
||||||
cstore: &CStore,
|
cstore: &CStore,
|
||||||
cfg: ast::CrateConfig,
|
cfg: ast::CrateConfig,
|
||||||
|
@ -74,14 +66,19 @@ pub fn compile_input(sess: &Session,
|
||||||
output: &Option<PathBuf>,
|
output: &Option<PathBuf>,
|
||||||
addl_plugins: Option<Vec<String>>,
|
addl_plugins: Option<Vec<String>>,
|
||||||
control: CompileController) -> CompileResult {
|
control: CompileController) -> CompileResult {
|
||||||
macro_rules! controller_entry_point{($point: ident, $tsess: expr, $make_state: expr) => ({
|
macro_rules! controller_entry_point {
|
||||||
|
($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
|
||||||
let state = $make_state;
|
let state = $make_state;
|
||||||
|
let phase_result: &CompileResult = &$phase_result;
|
||||||
|
if phase_result.is_ok() || control.$point.run_callback_on_error {
|
||||||
(control.$point.callback)(state);
|
(control.$point.callback)(state);
|
||||||
|
}
|
||||||
|
|
||||||
if control.$point.stop == Compilation::Stop {
|
if control.$point.stop == Compilation::Stop {
|
||||||
return compile_result_from_err_count($tsess.err_count());
|
return compile_result_from_err_count($tsess.err_count());
|
||||||
}
|
}
|
||||||
})}
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
// We need nested scopes here, because the intermediate results can keep
|
// 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
|
// large chunks of memory alive and we want to free them as soon as
|
||||||
|
@ -92,7 +89,8 @@ pub fn compile_input(sess: &Session,
|
||||||
|
|
||||||
controller_entry_point!(after_parse,
|
controller_entry_point!(after_parse,
|
||||||
sess,
|
sess,
|
||||||
CompileState::state_after_parse(input, sess, outdir, &krate));
|
CompileState::state_after_parse(input, sess, outdir, &krate),
|
||||||
|
Ok(()));
|
||||||
|
|
||||||
let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
|
let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
|
||||||
let id = link::find_crate_name(Some(sess), &krate.attrs, input);
|
let id = link::find_crate_name(Some(sess), &krate.attrs, input);
|
||||||
|
@ -111,7 +109,8 @@ pub fn compile_input(sess: &Session,
|
||||||
sess,
|
sess,
|
||||||
outdir,
|
outdir,
|
||||||
&expanded_crate,
|
&expanded_crate,
|
||||||
&id[..]));
|
&id[..]),
|
||||||
|
Ok(()));
|
||||||
|
|
||||||
let expanded_crate = assign_node_ids(sess, expanded_crate);
|
let expanded_crate = assign_node_ids(sess, expanded_crate);
|
||||||
// Lower ast -> hir.
|
// Lower ast -> hir.
|
||||||
|
@ -140,7 +139,8 @@ pub fn compile_input(sess: &Session,
|
||||||
&expanded_crate,
|
&expanded_crate,
|
||||||
&hir_map.krate(),
|
&hir_map.krate(),
|
||||||
&id[..],
|
&id[..],
|
||||||
&lcx));
|
&lcx),
|
||||||
|
Ok(()));
|
||||||
|
|
||||||
time(sess.time_passes(), "attribute checking", || {
|
time(sess.time_passes(), "attribute checking", || {
|
||||||
front::check_attr::check_crate(sess, &expanded_crate);
|
front::check_attr::check_crate(sess, &expanded_crate);
|
||||||
|
@ -164,33 +164,33 @@ pub fn compile_input(sess: &Session,
|
||||||
&arenas,
|
&arenas,
|
||||||
&id,
|
&id,
|
||||||
control.make_glob_map,
|
control.make_glob_map,
|
||||||
|tcx, mir_map, analysis| {
|
|tcx, mir_map, analysis, result| {
|
||||||
{
|
{
|
||||||
let state =
|
let state = CompileState::state_after_analysis(input,
|
||||||
CompileState::state_after_analysis(input,
|
|
||||||
&tcx.sess,
|
&tcx.sess,
|
||||||
outdir,
|
outdir,
|
||||||
opt_crate,
|
opt_crate,
|
||||||
tcx.map.krate(),
|
tcx.map.krate(),
|
||||||
&analysis,
|
&analysis,
|
||||||
&mir_map,
|
mir_map.as_ref(),
|
||||||
tcx,
|
tcx,
|
||||||
&lcx,
|
&lcx,
|
||||||
&id);
|
&id);
|
||||||
(control.after_analysis.callback)(state);
|
(control.after_analysis.callback)(state);
|
||||||
|
|
||||||
throw_if_errors!(tcx.sess);
|
|
||||||
if control.after_analysis.stop == Compilation::Stop {
|
if control.after_analysis.stop == Compilation::Stop {
|
||||||
return Err(0usize);
|
return Err(0usize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try!(result);
|
||||||
|
|
||||||
if log_enabled!(::log::INFO) {
|
if log_enabled!(::log::INFO) {
|
||||||
println!("Pre-trans");
|
println!("Pre-trans");
|
||||||
tcx.print_debug_stats();
|
tcx.print_debug_stats();
|
||||||
}
|
}
|
||||||
let trans = phase_4_translate_to_llvm(tcx,
|
let trans = phase_4_translate_to_llvm(tcx,
|
||||||
mir_map,
|
mir_map.unwrap(),
|
||||||
analysis);
|
analysis);
|
||||||
|
|
||||||
if log_enabled!(::log::INFO) {
|
if log_enabled!(::log::INFO) {
|
||||||
|
@ -205,17 +205,20 @@ pub fn compile_input(sess: &Session,
|
||||||
})))
|
})))
|
||||||
};
|
};
|
||||||
|
|
||||||
try!(phase_5_run_llvm_passes(sess, &trans, &outputs));
|
let phase5_result = phase_5_run_llvm_passes(sess, &trans, &outputs);
|
||||||
|
|
||||||
controller_entry_point!(after_llvm,
|
controller_entry_point!(after_llvm,
|
||||||
sess,
|
sess,
|
||||||
CompileState::state_after_llvm(input, sess, outdir, &trans));
|
CompileState::state_after_llvm(input, sess, outdir, &trans),
|
||||||
|
phase5_result);
|
||||||
|
try!(phase5_result);
|
||||||
|
|
||||||
phase_6_link_output(sess, &trans, &outputs);
|
phase_6_link_output(sess, &trans, &outputs);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// The name used for source code that doesn't originate in a file
|
/// The name used for source code that doesn't originate in a file
|
||||||
/// (e.g. source from stdin or a string)
|
/// (e.g. source from stdin or a string)
|
||||||
pub fn anon_src() -> String {
|
pub fn anon_src() -> String {
|
||||||
|
@ -269,6 +272,9 @@ impl<'a> CompileController<'a> {
|
||||||
|
|
||||||
pub struct PhaseController<'a> {
|
pub struct PhaseController<'a> {
|
||||||
pub stop: Compilation,
|
pub stop: Compilation,
|
||||||
|
// If true then the compiler will try to run the callback even if the phase
|
||||||
|
// ends with an error. Note that this is not always possible.
|
||||||
|
pub run_callback_on_error: bool,
|
||||||
pub callback: Box<Fn(CompileState) -> () + 'a>,
|
pub callback: Box<Fn(CompileState) -> () + 'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,6 +282,7 @@ impl<'a> PhaseController<'a> {
|
||||||
pub fn basic() -> PhaseController<'a> {
|
pub fn basic() -> PhaseController<'a> {
|
||||||
PhaseController {
|
PhaseController {
|
||||||
stop: Compilation::Continue,
|
stop: Compilation::Continue,
|
||||||
|
run_callback_on_error: false,
|
||||||
callback: box |_| {},
|
callback: box |_| {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,14 +379,14 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
||||||
krate: Option<&'a ast::Crate>,
|
krate: Option<&'a ast::Crate>,
|
||||||
hir_crate: &'a hir::Crate,
|
hir_crate: &'a hir::Crate,
|
||||||
analysis: &'a ty::CrateAnalysis,
|
analysis: &'a ty::CrateAnalysis,
|
||||||
mir_map: &'a MirMap<'tcx>,
|
mir_map: Option<&'a MirMap<'tcx>>,
|
||||||
tcx: &'a ty::ctxt<'tcx>,
|
tcx: &'a ty::ctxt<'tcx>,
|
||||||
lcx: &'a LoweringContext<'a>,
|
lcx: &'a LoweringContext<'a>,
|
||||||
crate_name: &'a str)
|
crate_name: &'a str)
|
||||||
-> CompileState<'a, 'ast, 'tcx> {
|
-> CompileState<'a, 'ast, 'tcx> {
|
||||||
CompileState {
|
CompileState {
|
||||||
analysis: Some(analysis),
|
analysis: Some(analysis),
|
||||||
mir_map: Some(mir_map),
|
mir_map: mir_map,
|
||||||
tcx: Some(tcx),
|
tcx: Some(tcx),
|
||||||
krate: krate,
|
krate: krate,
|
||||||
hir_crate: Some(hir_crate),
|
hir_crate: Some(hir_crate),
|
||||||
|
@ -659,9 +666,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
time(time_passes,
|
try!(time(time_passes,
|
||||||
"const fn bodies and arguments",
|
"const fn bodies and arguments",
|
||||||
|| const_fn::check_crate(sess, &krate));
|
|| const_fn::check_crate(sess, &krate)));
|
||||||
|
|
||||||
if sess.opts.debugging_opts.input_stats {
|
if sess.opts.debugging_opts.input_stats {
|
||||||
println!("Post-expansion node count: {}", count_nodes(&krate));
|
println!("Post-expansion node count: {}", count_nodes(&krate));
|
||||||
|
@ -713,8 +720,20 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||||
make_glob_map: resolve::MakeGlobMap,
|
make_glob_map: resolve::MakeGlobMap,
|
||||||
f: F)
|
f: F)
|
||||||
-> Result<R, usize>
|
-> Result<R, usize>
|
||||||
where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>, MirMap<'tcx>, ty::CrateAnalysis) -> R
|
where F: FnOnce(&ty::ctxt<'tcx>, Option<MirMap<'tcx>>, ty::CrateAnalysis, CompileResult) -> R
|
||||||
{
|
{
|
||||||
|
macro_rules! try_with_f {
|
||||||
|
($e: expr, ($t: expr, $m: expr, $a: expr)) => {
|
||||||
|
match $e {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(x) => {
|
||||||
|
f($t, $m, $a, Err(x));
|
||||||
|
return Err(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let time_passes = sess.time_passes();
|
let time_passes = sess.time_passes();
|
||||||
let krate = hir_map.krate();
|
let krate = hir_map.krate();
|
||||||
|
|
||||||
|
@ -739,9 +758,19 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||||
"resolution",
|
"resolution",
|
||||||
|| resolve::resolve_crate(sess, &hir_map, make_glob_map));
|
|| resolve::resolve_crate(sess, &hir_map, make_glob_map));
|
||||||
|
|
||||||
let named_region_map = time(time_passes,
|
let mut analysis = ty::CrateAnalysis {
|
||||||
|
export_map: export_map,
|
||||||
|
access_levels: AccessLevels::default(),
|
||||||
|
reachable: NodeSet(),
|
||||||
|
name: name,
|
||||||
|
glob_map: glob_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
let named_region_map = try!(time(time_passes,
|
||||||
"lifetime resolution",
|
"lifetime resolution",
|
||||||
|| middle::resolve_lifetime::krate(sess, krate, &def_map.borrow()));
|
|| middle::resolve_lifetime::krate(sess,
|
||||||
|
krate,
|
||||||
|
&def_map.borrow())));
|
||||||
|
|
||||||
time(time_passes,
|
time(time_passes,
|
||||||
"looking for entry point",
|
"looking for entry point",
|
||||||
|
@ -759,9 +788,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||||
"loop checking",
|
"loop checking",
|
||||||
|| loops::check_crate(sess, krate));
|
|| loops::check_crate(sess, krate));
|
||||||
|
|
||||||
time(time_passes,
|
try!(time(time_passes,
|
||||||
"static item recursion checking",
|
"static item recursion checking",
|
||||||
|| static_recursion::check_crate(sess, krate, &def_map.borrow(), &hir_map));
|
|| static_recursion::check_crate(sess, krate, &def_map.borrow(), &hir_map)));
|
||||||
|
|
||||||
ty::ctxt::create_and_enter(sess,
|
ty::ctxt::create_and_enter(sess,
|
||||||
arenas,
|
arenas,
|
||||||
|
@ -774,22 +803,22 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||||
stability::Index::new(krate),
|
stability::Index::new(krate),
|
||||||
|tcx| {
|
|tcx| {
|
||||||
// passes are timed inside typeck
|
// passes are timed inside typeck
|
||||||
typeck::check_crate(tcx, trait_map);
|
try_with_f!(typeck::check_crate(tcx, trait_map), (tcx, None, analysis));
|
||||||
|
|
||||||
time(time_passes,
|
time(time_passes,
|
||||||
"const checking",
|
"const checking",
|
||||||
|| consts::check_crate(tcx));
|
|| consts::check_crate(tcx));
|
||||||
|
|
||||||
let access_levels =
|
analysis.access_levels =
|
||||||
time(time_passes, "privacy checking", || {
|
time(time_passes, "privacy checking", || {
|
||||||
rustc_privacy::check_crate(tcx,
|
rustc_privacy::check_crate(tcx,
|
||||||
&export_map,
|
&analysis.export_map,
|
||||||
external_exports)
|
external_exports)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Do not move this check past lint
|
// Do not move this check past lint
|
||||||
time(time_passes, "stability index", || {
|
time(time_passes, "stability index", || {
|
||||||
tcx.stability.borrow_mut().build(tcx, krate, &access_levels)
|
tcx.stability.borrow_mut().build(tcx, krate, &analysis.access_levels)
|
||||||
});
|
});
|
||||||
|
|
||||||
time(time_passes,
|
time(time_passes,
|
||||||
|
@ -827,15 +856,17 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||||
// lot of annoying errors in the compile-fail tests (basically,
|
// lot of annoying errors in the compile-fail tests (basically,
|
||||||
// lint warnings and so on -- kindck used to do this abort, but
|
// lint warnings and so on -- kindck used to do this abort, but
|
||||||
// kindck is gone now). -nmatsakis
|
// kindck is gone now). -nmatsakis
|
||||||
throw_if_errors!(tcx.sess);
|
if sess.err_count() > 0 {
|
||||||
|
return Ok(f(tcx, Some(mir_map), analysis, Err(sess.err_count())));
|
||||||
|
}
|
||||||
|
|
||||||
let reachable_map =
|
analysis.reachable =
|
||||||
time(time_passes,
|
time(time_passes,
|
||||||
"reachability checking",
|
"reachability checking",
|
||||||
|| reachable::find_reachable(tcx, &access_levels));
|
|| reachable::find_reachable(tcx, &analysis.access_levels));
|
||||||
|
|
||||||
time(time_passes, "death checking", || {
|
time(time_passes, "death checking", || {
|
||||||
middle::dead::check_crate(tcx, &access_levels);
|
middle::dead::check_crate(tcx, &analysis.access_levels);
|
||||||
});
|
});
|
||||||
|
|
||||||
let ref lib_features_used =
|
let ref lib_features_used =
|
||||||
|
@ -850,20 +881,14 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||||
|
|
||||||
time(time_passes,
|
time(time_passes,
|
||||||
"lint checking",
|
"lint checking",
|
||||||
|| lint::check_crate(tcx, &access_levels));
|
|| lint::check_crate(tcx, &analysis.access_levels));
|
||||||
|
|
||||||
// The above three passes generate errors w/o aborting
|
// The above three passes generate errors w/o aborting
|
||||||
throw_if_errors!(tcx.sess);
|
if sess.err_count() > 0 {
|
||||||
|
return Ok(f(tcx, Some(mir_map), analysis, Err(sess.err_count())));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(f(tcx,
|
Ok(f(tcx, Some(mir_map), analysis, Ok(())))
|
||||||
mir_map,
|
|
||||||
ty::CrateAnalysis {
|
|
||||||
export_map: export_map,
|
|
||||||
access_levels: access_levels,
|
|
||||||
reachable: reachable_map,
|
|
||||||
name: name,
|
|
||||||
glob_map: glob_map,
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,9 +938,12 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
|
||||||
|| write::run_passes(sess, trans, &sess.opts.output_types, outputs));
|
|| write::run_passes(sess, trans, &sess.opts.output_types, outputs));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw_if_errors!(sess);
|
if sess.err_count() > 0 {
|
||||||
|
Err(sess.err_count())
|
||||||
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run the linker on any artifacts that resulted from the LLVM run.
|
/// Run the linker on any artifacts that resulted from the LLVM run.
|
||||||
/// This should produce either a finished executable or library.
|
/// This should produce either a finished executable or library.
|
||||||
|
|
|
@ -63,7 +63,7 @@ use pretty::{PpMode, UserIdentifiedItem};
|
||||||
use rustc_resolve as resolve;
|
use rustc_resolve as resolve;
|
||||||
use rustc_trans::back::link;
|
use rustc_trans::back::link;
|
||||||
use rustc_trans::save;
|
use rustc_trans::save;
|
||||||
use rustc::session::{config, Session, build_session};
|
use rustc::session::{config, Session, build_session, CompileResult};
|
||||||
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
|
||||||
use rustc::middle::cstore::CrateStore;
|
use rustc::middle::cstore::CrateStore;
|
||||||
use rustc::lint::Lint;
|
use rustc::lint::Lint;
|
||||||
|
@ -105,18 +105,6 @@ pub mod target_features;
|
||||||
const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
|
const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
|
||||||
md#bug-reports";
|
md#bug-reports";
|
||||||
|
|
||||||
// Err(0) means compilation was stopped, but no errors were found.
|
|
||||||
// This would be better as a dedicated enum, but using try! is so convenient.
|
|
||||||
pub type CompileResult = Result<(), usize>;
|
|
||||||
|
|
||||||
pub fn compile_result_from_err_count(err_count: usize) -> CompileResult {
|
|
||||||
if err_count == 0 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(err_count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abort_msg(err_count: usize) -> String {
|
fn abort_msg(err_count: usize) -> String {
|
||||||
match err_count {
|
match err_count {
|
||||||
|
@ -146,7 +134,7 @@ pub fn run(args: Vec<String>) -> isize {
|
||||||
let mut emitter =
|
let mut emitter =
|
||||||
errors::emitter::BasicEmitter::stderr(errors::ColorConfig::Auto);
|
errors::emitter::BasicEmitter::stderr(errors::ColorConfig::Auto);
|
||||||
emitter.emit(None, &abort_msg(err_count), None, errors::Level::Fatal);
|
emitter.emit(None, &abort_msg(err_count), None, errors::Level::Fatal);
|
||||||
panic!(errors::FatalError);
|
exit_on_err();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -462,6 +450,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
||||||
state.out_dir)
|
state.out_dir)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
control.after_analysis.run_callback_on_error = true;
|
||||||
control.make_glob_map = resolve::MakeGlobMap::Yes;
|
control.make_glob_map = resolve::MakeGlobMap::Yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,14 +936,18 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
|
||||||
println!("{}", str::from_utf8(&data.lock().unwrap()).unwrap());
|
println!("{}", str::from_utf8(&data.lock().unwrap()).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit_on_err();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exit_on_err() -> ! {
|
||||||
// Panic so the process returns a failure code, but don't pollute the
|
// Panic so the process returns a failure code, but don't pollute the
|
||||||
// output with some unnecessary panic messages, we've already
|
// output with some unnecessary panic messages, we've already
|
||||||
// printed everything that we needed to.
|
// printed everything that we needed to.
|
||||||
io::set_panic(box io::sink());
|
io::set_panic(box io::sink());
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn diagnostics_registry() -> diagnostics::registry::Registry {
|
pub fn diagnostics_registry() -> diagnostics::registry::Registry {
|
||||||
use syntax::diagnostics::registry::Registry;
|
use syntax::diagnostics::registry::Registry;
|
||||||
|
|
|
@ -200,7 +200,7 @@ impl PpSourceMode {
|
||||||
arenas,
|
arenas,
|
||||||
id,
|
id,
|
||||||
resolve::MakeGlobMap::No,
|
resolve::MakeGlobMap::No,
|
||||||
|tcx, _, _| {
|
|tcx, _, _, _| {
|
||||||
let annotation = TypedAnnotation {
|
let annotation = TypedAnnotation {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
};
|
};
|
||||||
|
@ -824,7 +824,7 @@ pub fn pretty_print_input(sess: Session,
|
||||||
&arenas,
|
&arenas,
|
||||||
&id,
|
&id,
|
||||||
resolve::MakeGlobMap::No,
|
resolve::MakeGlobMap::No,
|
||||||
|tcx, _, _| {
|
|tcx, _, _, _| {
|
||||||
print_flowgraph(variants,
|
print_flowgraph(variants,
|
||||||
tcx,
|
tcx,
|
||||||
code,
|
code,
|
||||||
|
|
|
@ -132,7 +132,7 @@ fn test_env<F>(source_string: &str,
|
||||||
ty::ctxt::create_and_enter(&sess,
|
ty::ctxt::create_and_enter(&sess,
|
||||||
&arenas,
|
&arenas,
|
||||||
def_map,
|
def_map,
|
||||||
named_region_map,
|
named_region_map.unwrap(),
|
||||||
ast_map,
|
ast_map,
|
||||||
freevars,
|
freevars,
|
||||||
region_map,
|
region_map,
|
||||||
|
|
|
@ -11,16 +11,16 @@
|
||||||
//! Verifies that const fn arguments are immutable by value bindings
|
//! Verifies that const fn arguments are immutable by value bindings
|
||||||
//! and the const fn body doesn't contain any statements
|
//! and the const fn body doesn't contain any statements
|
||||||
|
|
||||||
use rustc::session::Session;
|
use rustc::session::{Session, CompileResult};
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::visit::{self, Visitor, FnKind};
|
use syntax::visit::{self, Visitor, FnKind};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
|
|
||||||
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
|
pub fn check_crate(sess: &Session, krate: &ast::Crate) -> CompileResult {
|
||||||
sess.abort_if_new_errors(|| {
|
sess.track_errors(|| {
|
||||||
visit::walk_crate(&mut CheckConstFn{ sess: sess }, krate);
|
visit::walk_crate(&mut CheckConstFn{ sess: sess }, krate);
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CheckConstFn<'a> {
|
struct CheckConstFn<'a> {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// recursively.
|
// recursively.
|
||||||
|
|
||||||
use rustc::front::map as ast_map;
|
use rustc::front::map as ast_map;
|
||||||
use rustc::session::Session;
|
use rustc::session::{Session, CompileResult};
|
||||||
use rustc::middle::def::{Def, DefMap};
|
use rustc::middle::def::{Def, DefMap};
|
||||||
use rustc::util::nodemap::NodeMap;
|
use rustc::util::nodemap::NodeMap;
|
||||||
|
|
||||||
|
@ -92,16 +92,16 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> {
|
||||||
pub fn check_crate<'ast>(sess: &Session,
|
pub fn check_crate<'ast>(sess: &Session,
|
||||||
krate: &'ast hir::Crate,
|
krate: &'ast hir::Crate,
|
||||||
def_map: &DefMap,
|
def_map: &DefMap,
|
||||||
ast_map: &ast_map::Map<'ast>) {
|
ast_map: &ast_map::Map<'ast>) -> CompileResult {
|
||||||
let mut visitor = CheckCrateVisitor {
|
let mut visitor = CheckCrateVisitor {
|
||||||
sess: sess,
|
sess: sess,
|
||||||
def_map: def_map,
|
def_map: def_map,
|
||||||
ast_map: ast_map,
|
ast_map: ast_map,
|
||||||
discriminant_map: RefCell::new(NodeMap()),
|
discriminant_map: RefCell::new(NodeMap()),
|
||||||
};
|
};
|
||||||
sess.abort_if_new_errors(|| {
|
sess.track_errors(|| {
|
||||||
krate.visit_all_items(&mut visitor);
|
krate.visit_all_items(&mut visitor);
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
|
struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
|
||||||
|
|
|
@ -801,7 +801,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
||||||
"<mutable>".to_string()
|
"<mutable>".to_string()
|
||||||
};
|
};
|
||||||
let types = self.tcx.node_types();
|
let types = self.tcx.node_types();
|
||||||
let typ = types.get(&id).unwrap().to_string();
|
let typ = types.get(&id).map(|t| t.to_string()).unwrap_or(String::new());
|
||||||
// Get the span only for the name of the variable (I hope the path
|
// Get the span only for the name of the variable (I hope the path
|
||||||
// is only ever a variable name, but who knows?).
|
// is only ever a variable name, but who knows?).
|
||||||
let sub_span = self.span.span_for_last_ident(p.span);
|
let sub_span = self.span.span_for_last_ident(p.span);
|
||||||
|
|
|
@ -463,11 +463,15 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
|
pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
|
||||||
|
let hir_node = lowering::lower_expr(self.lcx, expr);
|
||||||
|
let ty = self.tcx.expr_ty_adjusted_opt(&hir_node);
|
||||||
|
if ty.is_none() || ty.unwrap().sty == ty::TyError {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprField(ref sub_ex, ident) => {
|
ast::ExprField(ref sub_ex, ident) => {
|
||||||
let hir_node = lowering::lower_expr(self.lcx, sub_ex);
|
let hir_node = lowering::lower_expr(self.lcx, sub_ex);
|
||||||
let ty = &self.tcx.expr_ty_adjusted(&hir_node).sty;
|
match self.tcx.expr_ty_adjusted(&hir_node).sty {
|
||||||
match *ty {
|
|
||||||
ty::TyStruct(def, _) => {
|
ty::TyStruct(def, _) => {
|
||||||
let f = def.struct_variant().field_named(ident.node.name);
|
let f = def.struct_variant().field_named(ident.node.name);
|
||||||
let sub_span = self.span_utils.span_for_last_ident(expr.span);
|
let sub_span = self.span_utils.span_for_last_ident(expr.span);
|
||||||
|
@ -487,8 +491,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
}
|
}
|
||||||
ast::ExprStruct(ref path, _, _) => {
|
ast::ExprStruct(ref path, _, _) => {
|
||||||
let hir_node = lowering::lower_expr(self.lcx, expr);
|
let hir_node = lowering::lower_expr(self.lcx, expr);
|
||||||
let ty = &self.tcx.expr_ty_adjusted(&hir_node).sty;
|
match self.tcx.expr_ty_adjusted(&hir_node).sty {
|
||||||
match *ty {
|
|
||||||
ty::TyStruct(def, _) => {
|
ty::TyStruct(def, _) => {
|
||||||
let sub_span = self.span_utils.span_for_last_ident(path.span);
|
let sub_span = self.span_utils.span_for_last_ident(path.span);
|
||||||
filter!(self.span_utils, sub_span, path.span, None);
|
filter!(self.span_utils, sub_span, path.span, None);
|
||||||
|
|
|
@ -105,7 +105,7 @@ use middle::ty::fold::{TypeFolder, TypeFoldable};
|
||||||
use middle::ty::util::Representability;
|
use middle::ty::util::Representability;
|
||||||
use require_c_abi_if_variadic;
|
use require_c_abi_if_variadic;
|
||||||
use rscope::{ElisionFailureInfo, RegionScope};
|
use rscope::{ElisionFailureInfo, RegionScope};
|
||||||
use session::Session;
|
use session::{Session, CompileResult};
|
||||||
use {CrateCtxt, lookup_full_def};
|
use {CrateCtxt, lookup_full_def};
|
||||||
use TypeAndSubsts;
|
use TypeAndSubsts;
|
||||||
use lint;
|
use lint;
|
||||||
|
@ -383,29 +383,29 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_wf_new(ccx: &CrateCtxt) {
|
pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult {
|
||||||
ccx.tcx.sess.abort_if_new_errors(|| {
|
ccx.tcx.sess.track_errors(|| {
|
||||||
let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
|
let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
|
||||||
ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
|
ccx.tcx.visit_all_items_in_krate(DepNode::WfCheck, &mut visit);
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_item_types(ccx: &CrateCtxt) {
|
pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult {
|
||||||
ccx.tcx.sess.abort_if_new_errors(|| {
|
ccx.tcx.sess.track_errors(|| {
|
||||||
let mut visit = CheckItemTypesVisitor { ccx: ccx };
|
let mut visit = CheckItemTypesVisitor { ccx: ccx };
|
||||||
ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
|
ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemType, &mut visit);
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_item_bodies(ccx: &CrateCtxt) {
|
pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult {
|
||||||
ccx.tcx.sess.abort_if_new_errors(|| {
|
ccx.tcx.sess.track_errors(|| {
|
||||||
let mut visit = CheckItemBodiesVisitor { ccx: ccx };
|
let mut visit = CheckItemBodiesVisitor { ccx: ccx };
|
||||||
ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
|
ccx.tcx.visit_all_items_in_krate(DepNode::TypeckItemBody, &mut visit);
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_drop_impls(ccx: &CrateCtxt) {
|
pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
|
||||||
ccx.tcx.sess.abort_if_new_errors(|| {
|
ccx.tcx.sess.track_errors(|| {
|
||||||
let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
|
let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck);
|
||||||
let drop_trait = match ccx.tcx.lang_items.drop_trait() {
|
let drop_trait = match ccx.tcx.lang_items.drop_trait() {
|
||||||
Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
|
Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
|
||||||
|
@ -421,7 +421,7 @@ pub fn check_drop_impls(ccx: &CrateCtxt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
|
|
|
@ -105,7 +105,7 @@ use middle::def::Def;
|
||||||
use middle::infer::{self, TypeOrigin};
|
use middle::infer::{self, TypeOrigin};
|
||||||
use middle::subst;
|
use middle::subst;
|
||||||
use middle::ty::{self, Ty, TypeFoldable};
|
use middle::ty::{self, Ty, TypeFoldable};
|
||||||
use session::config;
|
use session::{config, CompileResult};
|
||||||
use util::common::time;
|
use util::common::time;
|
||||||
use rustc_front::hir;
|
use rustc_front::hir;
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ fn check_for_entry_fn(ccx: &CrateCtxt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
|
pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) -> CompileResult {
|
||||||
let time_passes = tcx.sess.time_passes();
|
let time_passes = tcx.sess.time_passes();
|
||||||
let ccx = CrateCtxt {
|
let ccx = CrateCtxt {
|
||||||
trait_map: trait_map,
|
trait_map: trait_map,
|
||||||
|
@ -333,34 +333,40 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
|
||||||
|
|
||||||
// this ensures that later parts of type checking can assume that items
|
// this ensures that later parts of type checking can assume that items
|
||||||
// have valid types and not error
|
// have valid types and not error
|
||||||
tcx.sess.abort_if_new_errors(|| {
|
try!(tcx.sess.track_errors(|| {
|
||||||
time(time_passes, "type collecting", ||
|
time(time_passes, "type collecting", ||
|
||||||
collect::collect_item_types(tcx));
|
collect::collect_item_types(tcx));
|
||||||
|
|
||||||
});
|
}));
|
||||||
|
|
||||||
time(time_passes, "variance inference", ||
|
time(time_passes, "variance inference", ||
|
||||||
variance::infer_variance(tcx));
|
variance::infer_variance(tcx));
|
||||||
|
|
||||||
tcx.sess.abort_if_new_errors(|| {
|
try!(tcx.sess.track_errors(|| {
|
||||||
time(time_passes, "coherence checking", ||
|
time(time_passes, "coherence checking", ||
|
||||||
coherence::check_coherence(&ccx));
|
coherence::check_coherence(&ccx));
|
||||||
});
|
}));
|
||||||
|
|
||||||
time(time_passes, "wf checking", ||
|
try!(time(time_passes, "wf checking", ||
|
||||||
check::check_wf_new(&ccx));
|
check::check_wf_new(&ccx)));
|
||||||
|
|
||||||
time(time_passes, "item-types checking", ||
|
try!(time(time_passes, "item-types checking", ||
|
||||||
check::check_item_types(&ccx));
|
check::check_item_types(&ccx)));
|
||||||
|
|
||||||
time(time_passes, "item-bodies checking", ||
|
try!(time(time_passes, "item-bodies checking", ||
|
||||||
check::check_item_bodies(&ccx));
|
check::check_item_bodies(&ccx)));
|
||||||
|
|
||||||
time(time_passes, "drop-impl checking", ||
|
try!(time(time_passes, "drop-impl checking", ||
|
||||||
check::check_drop_impls(&ccx));
|
check::check_drop_impls(&ccx)));
|
||||||
|
|
||||||
check_for_entry_fn(&ccx);
|
check_for_entry_fn(&ccx);
|
||||||
tcx.sess.abort_if_errors();
|
|
||||||
|
let err_count = tcx.sess.err_count();
|
||||||
|
if err_count == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(err_count)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }
|
__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }
|
||||||
|
|
|
@ -153,7 +153,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
|
||||||
&arenas,
|
&arenas,
|
||||||
&name,
|
&name,
|
||||||
resolve::MakeGlobMap::No,
|
resolve::MakeGlobMap::No,
|
||||||
|tcx, _, analysis| {
|
|tcx, _, analysis, _| {
|
||||||
let _ignore = tcx.dep_graph.in_ignore();
|
let _ignore = tcx.dep_graph.in_ignore();
|
||||||
let ty::CrateAnalysis { access_levels, .. } = analysis;
|
let ty::CrateAnalysis { access_levels, .. } = analysis;
|
||||||
|
|
||||||
|
|
|
@ -2483,8 +2483,7 @@ impl<'a> Parser<'a> {
|
||||||
float.trunc() as usize,
|
float.trunc() as usize,
|
||||||
format!(".{}", fstr.splitn(2, ".").last().unwrap())));
|
format!(".{}", fstr.splitn(2, ".").last().unwrap())));
|
||||||
}
|
}
|
||||||
err.emit();
|
return Err(err);
|
||||||
self.abort_if_errors();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -4117,9 +4116,7 @@ impl<'a> Parser<'a> {
|
||||||
or did you mean the comma-separated arguments \
|
or did you mean the comma-separated arguments \
|
||||||
'a, Type?");
|
'a, Type?");
|
||||||
err.span_note(mk_sp(span_lo, span_hi), &msg);
|
err.span_note(mk_sp(span_lo, span_hi), &msg);
|
||||||
err.emit();
|
return Err(err);
|
||||||
|
|
||||||
self.abort_if_errors()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First parse types.
|
// First parse types.
|
||||||
|
@ -5189,8 +5186,7 @@ impl<'a> Parser<'a> {
|
||||||
of possibly redeclaring it",
|
of possibly redeclaring it",
|
||||||
paths.name));
|
paths.name));
|
||||||
}
|
}
|
||||||
err.emit();
|
return Err(err);
|
||||||
self.abort_if_errors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match paths.result {
|
match paths.result {
|
||||||
|
|
|
@ -242,9 +242,9 @@ fn compile_program(input: &str, sysroot: PathBuf)
|
||||||
|
|
||||||
abort_on_err(driver::phase_3_run_analysis_passes(
|
abort_on_err(driver::phase_3_run_analysis_passes(
|
||||||
&sess, &cstore, ast_map, &arenas, &id,
|
&sess, &cstore, ast_map, &arenas, &id,
|
||||||
MakeGlobMap::No, |tcx, mir_map, analysis| {
|
MakeGlobMap::No, |tcx, mir_map, analysis, _| {
|
||||||
|
|
||||||
let trans = driver::phase_4_translate_to_llvm(tcx, mir_map, analysis);
|
let trans = driver::phase_4_translate_to_llvm(tcx, mir_map.unwrap(), analysis);
|
||||||
|
|
||||||
let crates = tcx.sess.cstore.used_crates(LinkagePreference::RequireDynamic);
|
let crates = tcx.sess.cstore.used_crates(LinkagePreference::RequireDynamic);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue