Skip to content

Commit

Permalink
Auto merge of #43015 - arielb1:every-error-counts, r=eddyb
Browse files Browse the repository at this point in the history
report the total number of errors on compilation failure

Prior to this PR, when we aborted because a "critical pass" failed, we displayed the number of errors from that critical pass. While that's the number of errors that caused compilation to abort in *that place*, that's not what people really want to know. Instead, always report the total number of errors, and don't bother to track the number of errors from the last pass that failed.

This changes the compiler driver API to handle errors more smoothly, therefore is a compiler-api-[breaking-change].

Fixes #42793.

r? @eddyb
  • Loading branch information
bors committed Jul 2, 2017
2 parents c3a130c + fb7ab9e commit 2a99216
Show file tree
Hide file tree
Showing 295 changed files with 412 additions and 379 deletions.
3 changes: 2 additions & 1 deletion src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use syntax::attr;
use syntax::ptr::P;
use syntax_pos::Span;
use errors::DiagnosticBuilder;
use util::common::ErrorReported;
use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap};
use rustc_back::slice;

Expand Down Expand Up @@ -255,7 +256,7 @@ const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;

pub fn krate(sess: &Session,
hir_map: &Map)
-> Result<NamedRegionMap, usize> {
-> Result<NamedRegionMap, ErrorReported> {
let krate = hir_map.krate();
let mut map = NamedRegionMap {
defs: NodeMap(),
Expand Down
25 changes: 18 additions & 7 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use session::search_paths::PathKind;
use session::config::DebugInfoLevel;
use ty::tls;
use util::nodemap::{FxHashMap, FxHashSet};
use util::common::duration_to_secs_str;
use util::common::{duration_to_secs_str, ErrorReported};

use syntax::ast::NodeId;
use errors::{self, DiagnosticBuilder};
Expand Down Expand Up @@ -255,7 +255,10 @@ impl Session {
pub fn abort_if_errors(&self) {
self.diagnostic().abort_if_errors();
}
pub fn track_errors<F, T>(&self, f: F) -> Result<T, usize>
pub fn compile_status(&self) -> Result<(), CompileIncomplete> {
compile_result_from_err_count(self.err_count())
}
pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorReported>
where F: FnOnce() -> T
{
let old_count = self.err_count();
Expand All @@ -264,7 +267,7 @@ impl Session {
if errors == 0 {
Ok(result)
} else {
Err(errors)
Err(ErrorReported)
}
}
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
Expand Down Expand Up @@ -802,15 +805,23 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
handler.emit(&MultiSpan::new(), msg, 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>;
#[derive(Copy, Clone, Debug)]
pub enum CompileIncomplete {
Stopped,
Errored(ErrorReported)
}
impl From<ErrorReported> for CompileIncomplete {
fn from(err: ErrorReported) -> CompileIncomplete {
CompileIncomplete::Errored(err)
}
}
pub type CompileResult = Result<(), CompileIncomplete>;

pub fn compile_result_from_err_count(err_count: usize) -> CompileResult {
if err_count == 0 {
Ok(())
} else {
Err(err_count)
Err(CompileIncomplete::Errored(ErrorReported))
}
}

Expand Down
34 changes: 14 additions & 20 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use rustc::hir::lowering::lower_crate;
use rustc::ich::Fingerprint;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_mir as mir;
use rustc::session::{Session, CompileResult, compile_result_from_err_count};
use rustc::session::{Session, CompileResult};
use rustc::session::CompileIncomplete;
use rustc::session::config::{self, Input, OutputFilenames, OutputType,
OutputTypes};
use rustc::session::search_paths::PathKind;
Expand All @@ -23,7 +24,7 @@ use rustc::middle::privacy::AccessLevels;
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes};
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
use rustc::traits;
use rustc::util::common::time;
use rustc::util::common::{ErrorReported, time};
use rustc::util::nodemap::NodeSet;
use rustc::util::fs::rename_or_copy_remove;
use rustc_borrowck as borrowck;
Expand Down Expand Up @@ -78,7 +79,9 @@ pub fn compile_input(sess: &Session,
}

if control.$point.stop == Compilation::Stop {
return compile_result_from_err_count($tsess.err_count());
// FIXME: shouldn't this return Err(CompileIncomplete::Stopped)
// if there are no errors?
return $tsess.compile_status();
}
}}
}
Expand All @@ -91,7 +94,7 @@ pub fn compile_input(sess: &Session,
Ok(krate) => krate,
Err(mut parse_error) => {
parse_error.emit();
return Err(1);
return Err(CompileIncomplete::Errored(ErrorReported));
}
};

Expand Down Expand Up @@ -194,7 +197,7 @@ pub fn compile_input(sess: &Session,
(control.after_analysis.callback)(&mut state);

if control.after_analysis.stop == Compilation::Stop {
return result.and_then(|_| Err(0usize));
return result.and_then(|_| Err(CompileIncomplete::Stopped));
}
}

Expand Down Expand Up @@ -564,7 +567,7 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
addl_plugins: Option<Vec<String>>,
make_glob_map: MakeGlobMap,
after_expand: F)
-> Result<ExpansionResult, usize>
-> Result<ExpansionResult, CompileIncomplete>
where F: FnOnce(&ast::Crate) -> CompileResult,
{
let time_passes = sess.time_passes();
Expand Down Expand Up @@ -636,7 +639,7 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
super::describe_lints(&sess.lint_store.borrow(), true);
return Err(0);
return Err(CompileIncomplete::Stopped);
}
sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;

Expand Down Expand Up @@ -839,7 +842,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
arenas: &'tcx GlobalArenas<'tcx>,
name: &str,
f: F)
-> Result<R, usize>
-> Result<R, CompileIncomplete>
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
ty::CrateAnalysis,
IncrementalHashesMap,
Expand Down Expand Up @@ -1019,7 +1022,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
if sess.err_count() > 0 {
return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
return Ok(f(tcx, analysis, incremental_hashes_map, sess.compile_status()));
}

analysis.reachable =
Expand All @@ -1035,12 +1038,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,

time(time_passes, "lint checking", || lint::check_crate(tcx));

// The above three passes generate errors w/o aborting
if sess.err_count() > 0 {
return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
}

Ok(f(tcx, analysis, incremental_hashes_map, Ok(())))
return Ok(f(tcx, analysis, incremental_hashes_map, tcx.sess.compile_status()));
})
}

Expand Down Expand Up @@ -1116,11 +1114,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
"serialize work products",
move || rustc_incremental::save_work_products(sess));

if sess.err_count() > 0 {
Err(sess.err_count())
} else {
Ok(())
}
sess.compile_status()
}

/// Run the linker on any artifacts that resulted from the LLVM run.
Expand Down
48 changes: 23 additions & 25 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ use rustc_trans::back::link;
use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config, Session, build_session, CompileResult};
use rustc::session::CompileIncomplete;
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
use rustc::session::config::nightly_options;
use rustc::session::{early_error, early_warn};
use rustc::lint::Lint;
use rustc::lint;
use rustc_metadata::locator;
use rustc_metadata::cstore::CStore;
use rustc::util::common::time;
use rustc::util::common::{time, ErrorReported};

use serialize::json::ToJson;

Expand Down Expand Up @@ -109,18 +110,14 @@ mod derive_registrar;
const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
md#bug-reports";

#[inline]
fn abort_msg(err_count: usize) -> String {
match err_count {
0 => "aborting with no errors (maybe a bug?)".to_owned(),
_ => "aborting due to previous error(s)".to_owned(),
}
}

pub fn abort_on_err<T>(result: Result<T, usize>, sess: &Session) -> T {
pub fn abort_on_err<T>(result: Result<T, CompileIncomplete>, sess: &Session) -> T {
match result {
Err(err_count) => {
sess.fatal(&abort_msg(err_count));
Err(CompileIncomplete::Errored(ErrorReported)) => {
sess.abort_if_errors();
panic!("error reported but abort_if_errors didn't abort???");
}
Err(CompileIncomplete::Stopped) => {
sess.fatal("compilation terminated");
}
Ok(x) => x,
}
Expand All @@ -131,19 +128,20 @@ pub fn run<F>(run_compiler: F) -> isize
{
monitor(move || {
let (result, session) = run_compiler();
if let Err(err_count) = result {
if err_count > 0 {
match session {
Some(sess) => sess.fatal(&abort_msg(err_count)),
None => {
let emitter =
errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
handler.emit(&MultiSpan::new(),
&abort_msg(err_count),
errors::Level::Fatal);
exit_on_err();
}
if let Err(CompileIncomplete::Errored(_)) = result {
match session {
Some(sess) => {
sess.abort_if_errors();
panic!("error reported but abort_if_errors didn't abort???");
}
None => {
let emitter =
errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
handler.emit(&MultiSpan::new(),
"aborting due to previous error(s)",
errors::Level::Fatal);
exit_on_err();
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,10 @@ impl Handler {

return;
}
_ => s = "aborting due to previous error(s)".to_string(),
1 => s = "aborting due to previous error".to_string(),
_ => {
s = format!("aborting due to {} previous errors", self.err_count.get());
}
}

panic!(self.fatal(&s));
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_passes/static_recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
// recursively.

use rustc::hir::map as hir_map;
use rustc::session::{CompileResult, Session};
use rustc::session::Session;
use rustc::hir::def::{Def, CtorKind};
use rustc::util::common::ErrorReported;
use rustc::util::nodemap::{NodeMap, NodeSet};

use syntax::ast;
Expand Down Expand Up @@ -86,7 +87,9 @@ impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> {
}
}

pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>) -> CompileResult {
pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>)
-> Result<(), ErrorReported>
{
let mut visitor = CheckCrateVisitor {
sess: sess,
hir_map: hir_map,
Expand Down
16 changes: 9 additions & 7 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ use rustc::ty::maps::Providers;
use rustc::ty::util::{Representability, IntTypeExt};
use errors::DiagnosticBuilder;
use require_c_abi_if_variadic;
use session::{Session, CompileResult};
use session::{CompileIncomplete, Session};
use TypeAndSubsts;
use lint;
use util::common::{ErrorReported, indenter};
Expand Down Expand Up @@ -691,30 +691,32 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
}

pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
tcx.sess.track_errors(|| {
let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
})
}

pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> {
tcx.sess.track_errors(|| {
tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
})
}

pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> {
tcx.typeck_item_bodies(LOCAL_CRATE)
}

fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
-> Result<(), CompileIncomplete>
{
debug_assert!(crate_num == LOCAL_CRATE);
tcx.sess.track_errors(|| {
Ok(tcx.sess.track_errors(|| {
for body_owner_def_id in tcx.body_owners() {
tcx.typeck_tables_of(body_owner_def_id);
}
})
})?)
}

pub fn provide(providers: &mut Providers) {
Expand Down
12 changes: 4 additions & 8 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
use session::config;
use session::{CompileIncomplete, config};
use util::common::time;

use syntax::ast;
Expand Down Expand Up @@ -293,7 +293,8 @@ pub fn provide(providers: &mut Providers) {
}

pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> Result<(), usize> {
-> Result<(), CompileIncomplete>
{
let time_passes = tcx.sess.time_passes();

// this ensures that later parts of type checking can assume that items
Expand Down Expand Up @@ -328,12 +329,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
check_unused::check_crate(tcx);
check_for_entry_fn(tcx);

let err_count = tcx.sess.err_count();
if err_count == 0 {
Ok(())
} else {
Err(err_count)
}
tcx.sess.compile_status()
}

/// A quasi-deprecated helper used in rustdoc and save-analysis to get
Expand Down
Loading

0 comments on commit 2a99216

Please sign in to comment.