Skip to content

Commit 2a99216

Browse files
committed
Auto merge of #43015 - arielb1:every-error-counts, r=eddyb
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
2 parents c3a130c + fb7ab9e commit 2a99216

File tree

295 files changed

+412
-379
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

295 files changed

+412
-379
lines changed

src/librustc/middle/resolve_lifetime.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use syntax::attr;
2828
use syntax::ptr::P;
2929
use syntax_pos::Span;
3030
use errors::DiagnosticBuilder;
31+
use util::common::ErrorReported;
3132
use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap};
3233
use rustc_back::slice;
3334

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

256257
pub fn krate(sess: &Session,
257258
hir_map: &Map)
258-
-> Result<NamedRegionMap, usize> {
259+
-> Result<NamedRegionMap, ErrorReported> {
259260
let krate = hir_map.krate();
260261
let mut map = NamedRegionMap {
261262
defs: NodeMap(),

src/librustc/session/mod.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use session::search_paths::PathKind;
2121
use session::config::DebugInfoLevel;
2222
use ty::tls;
2323
use util::nodemap::{FxHashMap, FxHashSet};
24-
use util::common::duration_to_secs_str;
24+
use util::common::{duration_to_secs_str, ErrorReported};
2525

2626
use syntax::ast::NodeId;
2727
use errors::{self, DiagnosticBuilder};
@@ -255,7 +255,10 @@ impl Session {
255255
pub fn abort_if_errors(&self) {
256256
self.diagnostic().abort_if_errors();
257257
}
258-
pub fn track_errors<F, T>(&self, f: F) -> Result<T, usize>
258+
pub fn compile_status(&self) -> Result<(), CompileIncomplete> {
259+
compile_result_from_err_count(self.err_count())
260+
}
261+
pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorReported>
259262
where F: FnOnce() -> T
260263
{
261264
let old_count = self.err_count();
@@ -264,7 +267,7 @@ impl Session {
264267
if errors == 0 {
265268
Ok(result)
266269
} else {
267-
Err(errors)
270+
Err(ErrorReported)
268271
}
269272
}
270273
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
@@ -802,15 +805,23 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
802805
handler.emit(&MultiSpan::new(), msg, errors::Level::Warning);
803806
}
804807

805-
// Err(0) means compilation was stopped, but no errors were found.
806-
// This would be better as a dedicated enum, but using try! is so convenient.
807-
pub type CompileResult = Result<(), usize>;
808+
#[derive(Copy, Clone, Debug)]
809+
pub enum CompileIncomplete {
810+
Stopped,
811+
Errored(ErrorReported)
812+
}
813+
impl From<ErrorReported> for CompileIncomplete {
814+
fn from(err: ErrorReported) -> CompileIncomplete {
815+
CompileIncomplete::Errored(err)
816+
}
817+
}
818+
pub type CompileResult = Result<(), CompileIncomplete>;
808819

809820
pub fn compile_result_from_err_count(err_count: usize) -> CompileResult {
810821
if err_count == 0 {
811822
Ok(())
812823
} else {
813-
Err(err_count)
824+
Err(CompileIncomplete::Errored(ErrorReported))
814825
}
815826
}
816827

src/librustc_driver/driver.rs

+14-20
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use rustc::hir::lowering::lower_crate;
1313
use rustc::ich::Fingerprint;
1414
use rustc_data_structures::stable_hasher::StableHasher;
1515
use rustc_mir as mir;
16-
use rustc::session::{Session, CompileResult, compile_result_from_err_count};
16+
use rustc::session::{Session, CompileResult};
17+
use rustc::session::CompileIncomplete;
1718
use rustc::session::config::{self, Input, OutputFilenames, OutputType,
1819
OutputTypes};
1920
use rustc::session::search_paths::PathKind;
@@ -23,7 +24,7 @@ use rustc::middle::privacy::AccessLevels;
2324
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes};
2425
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
2526
use rustc::traits;
26-
use rustc::util::common::time;
27+
use rustc::util::common::{ErrorReported, time};
2728
use rustc::util::nodemap::NodeSet;
2829
use rustc::util::fs::rename_or_copy_remove;
2930
use rustc_borrowck as borrowck;
@@ -78,7 +79,9 @@ pub fn compile_input(sess: &Session,
7879
}
7980

8081
if control.$point.stop == Compilation::Stop {
81-
return compile_result_from_err_count($tsess.err_count());
82+
// FIXME: shouldn't this return Err(CompileIncomplete::Stopped)
83+
// if there are no errors?
84+
return $tsess.compile_status();
8285
}
8386
}}
8487
}
@@ -91,7 +94,7 @@ pub fn compile_input(sess: &Session,
9194
Ok(krate) => krate,
9295
Err(mut parse_error) => {
9396
parse_error.emit();
94-
return Err(1);
97+
return Err(CompileIncomplete::Errored(ErrorReported));
9598
}
9699
};
97100

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

196199
if control.after_analysis.stop == Compilation::Stop {
197-
return result.and_then(|_| Err(0usize));
200+
return result.and_then(|_| Err(CompileIncomplete::Stopped));
198201
}
199202
}
200203

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

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

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

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

1038-
// The above three passes generate errors w/o aborting
1039-
if sess.err_count() > 0 {
1040-
return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
1041-
}
1042-
1043-
Ok(f(tcx, analysis, incremental_hashes_map, Ok(())))
1041+
return Ok(f(tcx, analysis, incremental_hashes_map, tcx.sess.compile_status()));
10441042
})
10451043
}
10461044

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

1119-
if sess.err_count() > 0 {
1120-
Err(sess.err_count())
1121-
} else {
1122-
Ok(())
1123-
}
1117+
sess.compile_status()
11241118
}
11251119

11261120
/// Run the linker on any artifacts that resulted from the LLVM run.

src/librustc_driver/lib.rs

+23-25
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,15 @@ use rustc_trans::back::link;
6767
use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
6868
use rustc::dep_graph::DepGraph;
6969
use rustc::session::{self, config, Session, build_session, CompileResult};
70+
use rustc::session::CompileIncomplete;
7071
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
7172
use rustc::session::config::nightly_options;
7273
use rustc::session::{early_error, early_warn};
7374
use rustc::lint::Lint;
7475
use rustc::lint;
7576
use rustc_metadata::locator;
7677
use rustc_metadata::cstore::CStore;
77-
use rustc::util::common::time;
78+
use rustc::util::common::{time, ErrorReported};
7879

7980
use serialize::json::ToJson;
8081

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

112-
#[inline]
113-
fn abort_msg(err_count: usize) -> String {
114-
match err_count {
115-
0 => "aborting with no errors (maybe a bug?)".to_owned(),
116-
_ => "aborting due to previous error(s)".to_owned(),
117-
}
118-
}
119-
120-
pub fn abort_on_err<T>(result: Result<T, usize>, sess: &Session) -> T {
113+
pub fn abort_on_err<T>(result: Result<T, CompileIncomplete>, sess: &Session) -> T {
121114
match result {
122-
Err(err_count) => {
123-
sess.fatal(&abort_msg(err_count));
115+
Err(CompileIncomplete::Errored(ErrorReported)) => {
116+
sess.abort_if_errors();
117+
panic!("error reported but abort_if_errors didn't abort???");
118+
}
119+
Err(CompileIncomplete::Stopped) => {
120+
sess.fatal("compilation terminated");
124121
}
125122
Ok(x) => x,
126123
}
@@ -131,19 +128,20 @@ pub fn run<F>(run_compiler: F) -> isize
131128
{
132129
monitor(move || {
133130
let (result, session) = run_compiler();
134-
if let Err(err_count) = result {
135-
if err_count > 0 {
136-
match session {
137-
Some(sess) => sess.fatal(&abort_msg(err_count)),
138-
None => {
139-
let emitter =
140-
errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
141-
let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
142-
handler.emit(&MultiSpan::new(),
143-
&abort_msg(err_count),
144-
errors::Level::Fatal);
145-
exit_on_err();
146-
}
131+
if let Err(CompileIncomplete::Errored(_)) = result {
132+
match session {
133+
Some(sess) => {
134+
sess.abort_if_errors();
135+
panic!("error reported but abort_if_errors didn't abort???");
136+
}
137+
None => {
138+
let emitter =
139+
errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
140+
let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
141+
handler.emit(&MultiSpan::new(),
142+
"aborting due to previous error(s)",
143+
errors::Level::Fatal);
144+
exit_on_err();
147145
}
148146
}
149147
}

src/librustc_errors/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,10 @@ impl Handler {
506506

507507
return;
508508
}
509-
_ => s = "aborting due to previous error(s)".to_string(),
509+
1 => s = "aborting due to previous error".to_string(),
510+
_ => {
511+
s = format!("aborting due to {} previous errors", self.err_count.get());
512+
}
510513
}
511514

512515
panic!(self.fatal(&s));

src/librustc_passes/static_recursion.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
// recursively.
1313

1414
use rustc::hir::map as hir_map;
15-
use rustc::session::{CompileResult, Session};
15+
use rustc::session::Session;
1616
use rustc::hir::def::{Def, CtorKind};
17+
use rustc::util::common::ErrorReported;
1718
use rustc::util::nodemap::{NodeMap, NodeSet};
1819

1920
use syntax::ast;
@@ -86,7 +87,9 @@ impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> {
8687
}
8788
}
8889

89-
pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>) -> CompileResult {
90+
pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>)
91+
-> Result<(), ErrorReported>
92+
{
9093
let mut visitor = CheckCrateVisitor {
9194
sess: sess,
9295
hir_map: hir_map,

src/librustc_typeck/check/mod.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ use rustc::ty::maps::Providers;
102102
use rustc::ty::util::{Representability, IntTypeExt};
103103
use errors::DiagnosticBuilder;
104104
use require_c_abi_if_variadic;
105-
use session::{Session, CompileResult};
105+
use session::{CompileIncomplete, Session};
106106
use TypeAndSubsts;
107107
use lint;
108108
use util::common::{ErrorReported, indenter};
@@ -691,30 +691,32 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
691691
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
692692
}
693693

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

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

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

711-
fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
711+
fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
712+
-> Result<(), CompileIncomplete>
713+
{
712714
debug_assert!(crate_num == LOCAL_CRATE);
713-
tcx.sess.track_errors(|| {
715+
Ok(tcx.sess.track_errors(|| {
714716
for body_owner_def_id in tcx.body_owners() {
715717
tcx.typeck_tables_of(body_owner_def_id);
716718
}
717-
})
719+
})?)
718720
}
719721

720722
pub fn provide(providers: &mut Providers) {

src/librustc_typeck/lib.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ use rustc::ty::subst::Substs;
108108
use rustc::ty::{self, Ty, TyCtxt};
109109
use rustc::ty::maps::Providers;
110110
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
111-
use session::config;
111+
use session::{CompileIncomplete, config};
112112
use util::common::time;
113113

114114
use syntax::ast;
@@ -293,7 +293,8 @@ pub fn provide(providers: &mut Providers) {
293293
}
294294

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

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

331-
let err_count = tcx.sess.err_count();
332-
if err_count == 0 {
333-
Ok(())
334-
} else {
335-
Err(err_count)
336-
}
332+
tcx.sess.compile_status()
337333
}
338334

339335
/// A quasi-deprecated helper used in rustdoc and save-analysis to get

0 commit comments

Comments
 (0)