From 7a55a004fa3b3eb933637a4aeec9b8576b31a033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 6 Mar 2019 19:49:39 -0800 Subject: [PATCH 1/8] Make `-Z treat-err-as-bug` take a number of errors to be emitted `-Z treat-err-as-bug=0` will cause `rustc` to panic after the first error is reported. `-Z treat-err-as-bug=2` will cause `rustc` to panic after 3 errors have been reported. --- src/librustc/session/config.rs | 4 ++-- src/librustc/session/mod.rs | 4 ++-- src/librustc_codegen_ssa/back/write.rs | 2 +- src/librustc_driver/lib.rs | 4 ++-- src/librustc_errors/diagnostic_builder.rs | 2 +- src/librustc_errors/lib.rs | 27 +++++++++++++++-------- src/librustdoc/core.rs | 2 +- src/libsyntax/parse/mod.rs | 2 +- 8 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 774ab0333db54..dfd8e4dd571b5 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1234,7 +1234,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "parse only; do not compile, assemble, or link"), no_codegen: bool = (false, parse_bool, [TRACKED], "run all passes except codegen; no output"), - treat_err_as_bug: bool = (false, parse_bool, [TRACKED], + treat_err_as_bug: Option = (None, parse_opt_uint, [TRACKED], "treat all errors that occur as bugs"), report_delayed_bugs: bool = (false, parse_bool, [TRACKED], "immediately print bugs registered with `delay_span_bug`"), @@ -3212,7 +3212,7 @@ mod tests { assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.treat_err_as_bug = true; + opts.debugging_opts.treat_err_as_bug = Some(1); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 774bc8b450b59..751fa7e95e3a8 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1315,7 +1315,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { Box::new(EmitterWriter::stderr(color_config, None, true, false)) } }; - let handler = errors::Handler::with_emitter(true, false, emitter); + let handler = errors::Handler::with_emitter(true, None, emitter); handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal); errors::FatalError.raise(); } @@ -1330,7 +1330,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) { Box::new(EmitterWriter::stderr(color_config, None, true, false)) } }; - let handler = errors::Handler::with_emitter(true, false, emitter); + let handler = errors::Handler::with_emitter(true, None, emitter); handler.emit(&MultiSpan::new(), msg, errors::Level::Warning); } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 4bccc2a6d1f7b..c84b38cde8185 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -247,7 +247,7 @@ pub struct CodegenContext { impl CodegenContext { pub fn create_diag_handler(&self) -> Handler { - Handler::with_emitter(true, false, Box::new(self.diag_emitter.clone())) + Handler::with_emitter(true, None, Box::new(self.diag_emitter.clone())) } pub fn config(&self, kind: ModuleKind) -> &ModuleConfig { diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cc1b8916c1074..656d8e463dbd0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -148,7 +148,7 @@ pub fn run(run_compiler: F) -> isize true, false ); - let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); + let handler = errors::Handler::with_emitter(true, None, Box::new(emitter)); handler.emit(&MultiSpan::new(), "aborting due to previous error(s)", errors::Level::Fatal); @@ -1327,7 +1327,7 @@ pub fn monitor(f: F) -> Result<(), CompilationFail None, false, false)); - let handler = errors::Handler::with_emitter(true, false, emitter); + let handler = errors::Handler::with_emitter(true, None, emitter); // a .span_bug or .bug call has already printed what // it wants to print. diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 0c808a07f9bac..a995d808bc41e 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -103,7 +103,7 @@ impl<'a> DiagnosticBuilder<'a> { /// Buffers the diagnostic for later emission, unless handler /// has disabled such buffering. pub fn buffer(mut self, buffered_diagnostics: &mut Vec) { - if self.handler.flags.dont_buffer_diagnostics || self.handler.flags.treat_err_as_bug { + if self.handler.flags.dont_buffer_diagnostics || self.handler.treat_err_as_bug() { self.emit(); return; } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 87b4751526835..ae634018b9353 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -330,7 +330,7 @@ pub struct HandlerFlags { pub can_emit_warnings: bool, /// If true, error-level diagnostics are upgraded to bug-level. /// (rustc: see `-Z treat-err-as-bug`) - pub treat_err_as_bug: bool, + pub treat_err_as_bug: Option, /// If true, immediately emit diagnostics that would otherwise be buffered. /// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`) pub dont_buffer_diagnostics: bool, @@ -360,7 +360,7 @@ impl Drop for Handler { impl Handler { pub fn with_tty_emitter(color_config: ColorConfig, can_emit_warnings: bool, - treat_err_as_bug: bool, + treat_err_as_bug: Option, cm: Option>) -> Handler { Handler::with_tty_emitter_and_flags( @@ -382,7 +382,7 @@ impl Handler { } pub fn with_emitter(can_emit_warnings: bool, - treat_err_as_bug: bool, + treat_err_as_bug: Option, e: Box) -> Handler { Handler::with_emitter_and_flags( @@ -516,7 +516,7 @@ impl Handler { } fn panic_if_treat_err_as_bug(&self) { - if self.flags.treat_err_as_bug { + if self.treat_err_as_bug() { panic!("encountered error with `-Z treat_err_as_bug"); } } @@ -558,7 +558,7 @@ impl Handler { panic!(ExplicitBug); } pub fn delay_span_bug>(&self, sp: S, msg: &str) { - if self.flags.treat_err_as_bug { + if self.treat_err_as_bug() { // FIXME: don't abort here if report_delayed_bugs is off self.span_bug(sp, msg); } @@ -593,14 +593,14 @@ impl Handler { DiagnosticBuilder::new(self, FailureNote, msg).emit() } pub fn fatal(&self, msg: &str) -> FatalError { - if self.flags.treat_err_as_bug { + if self.treat_err_as_bug() { self.bug(msg); } DiagnosticBuilder::new(self, Fatal, msg).emit(); FatalError } pub fn err(&self, msg: &str) { - if self.flags.treat_err_as_bug { + if self.treat_err_as_bug() { self.bug(msg); } let mut db = DiagnosticBuilder::new(self, Error, msg); @@ -610,6 +610,9 @@ impl Handler { let mut db = DiagnosticBuilder::new(self, Warning, msg); db.emit(); } + fn treat_err_as_bug(&self) -> bool { + self.flags.treat_err_as_bug.map(|c| self.err_count() >= c).unwrap_or(false) + } pub fn note_without_error(&self, msg: &str) { let mut db = DiagnosticBuilder::new(self, Note, msg); db.emit(); @@ -624,8 +627,8 @@ impl Handler { } fn bump_err_count(&self) { - self.panic_if_treat_err_as_bug(); self.err_count.fetch_add(1, SeqCst); + self.panic_if_treat_err_as_bug(); } pub fn err_count(&self) -> usize { @@ -643,7 +646,13 @@ impl Handler { _ => format!("aborting due to {} previous errors", self.err_count()) }; - let _ = self.fatal(&s); + let _ = if self.treat_err_as_bug() { + self.fatal(&s) + } else { + // only emit one backtrace when using `-Z treat-err-as-bug=X` + DiagnosticBuilder::new(self, Fatal, &s).emit(); + FatalError + }; let can_show_explain = self.emitter.borrow().should_show_explain(); let are_there_diagnostics = !self.emitted_diagnostic_codes.borrow().is_empty(); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index fdb071638b799..f4074bcdba6f2 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -266,7 +266,7 @@ impl DocAccessLevels for AccessLevels { /// will be created for the handler. pub fn new_handler(error_format: ErrorOutputType, source_map: Option>, - treat_err_as_bug: bool, + treat_err_as_bug: Option, ui_testing: bool, ) -> errors::Handler { // rustdoc doesn't override (or allow to override) anything from this that is relevant here, so diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index b2d4d97d57d89..9cfcfcd6241ad 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -53,7 +53,7 @@ impl ParseSess { let cm = Lrc::new(SourceMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, - false, + None, Some(cm.clone())); ParseSess::with_span_handler(handler, cm) } From 7694ca1105b55d4f1ce9d7b6fc6feb9c3c9033c5 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 6 Mar 2019 19:57:04 -0800 Subject: [PATCH 2/8] Fix incorrect default --- src/librustc/session/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index dfd8e4dd571b5..70cf36c38691b 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -3212,7 +3212,7 @@ mod tests { assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.treat_err_as_bug = Some(1); + opts.debugging_opts.treat_err_as_bug = Some(0); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); From 754037de130c79e4be6b48e27203dcae58e91f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Mar 2019 00:27:41 -0800 Subject: [PATCH 3/8] fix bad use of with_emitter --- src/librustdoc/test.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index c3c0875bc7d24..3dd2c4a477a63 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -272,7 +272,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, false); // Compile the code - let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); + let diagnostic_handler = errors::Handler::with_emitter(true, None, box emitter); let mut sess = session::build_session_( sessopts, None, diagnostic_handler, source_map, Default::default(), @@ -424,7 +424,7 @@ pub fn make_test(s: &str, // send all the errors that libsyntax emits directly into a `Sink` instead of stderr. let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let emitter = EmitterWriter::new(box io::sink(), None, false, false); - let handler = Handler::with_emitter(false, false, box emitter); + let handler = Handler::with_emitter(false, None, box emitter); let sess = ParseSess::with_span_handler(handler, cm); let mut found_main = false; From c41ddf177380e96e873d625cb7ce87468eed85e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Mar 2019 01:54:53 -0800 Subject: [PATCH 4/8] Keep current behavior while accepting error count --- src/librustc/session/config.rs | 13 +++++++++++-- src/librustc_errors/lib.rs | 26 ++++++++++++++++++-------- src/librustdoc/test.rs | 2 +- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 70cf36c38691b..77fbe467ce010 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -816,6 +816,8 @@ macro_rules! options { Some("crate=integer"); pub const parse_unpretty: Option<&str> = Some("`string` or `string=string`"); + pub const parse_treat_err_as_bug: Option<&str> = + Some("either no value or a number bigger than 0"); pub const parse_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \ `fat`, or omitted"); @@ -1022,6 +1024,13 @@ macro_rules! options { } } + fn parse_treat_err_as_bug(slot: &mut Option, v: Option<&str>) -> bool { + match v { + Some(s) => { *slot = s.parse().ok().filter(|&x| x != 0); slot.unwrap_or(0) != 0 } + None => { *slot = Some(1); true } + } + } + fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool { if v.is_some() { let mut bool_arg = None; @@ -1234,7 +1243,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "parse only; do not compile, assemble, or link"), no_codegen: bool = (false, parse_bool, [TRACKED], "run all passes except codegen; no output"), - treat_err_as_bug: Option = (None, parse_opt_uint, [TRACKED], + treat_err_as_bug: Option = (None, parse_treat_err_as_bug, [TRACKED], "treat all errors that occur as bugs"), report_delayed_bugs: bool = (false, parse_bool, [TRACKED], "immediately print bugs registered with `delay_span_bug`"), @@ -3212,7 +3221,7 @@ mod tests { assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.treat_err_as_bug = Some(0); + opts.debugging_opts.treat_err_as_bug = Some(1); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index ae634018b9353..3992d2908c789 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -517,7 +517,19 @@ impl Handler { fn panic_if_treat_err_as_bug(&self) { if self.treat_err_as_bug() { - panic!("encountered error with `-Z treat_err_as_bug"); + let s = match (self.err_count(), self.flags.treat_err_as_bug.unwrap_or(0)) { + (0, _) => return, + (1, 1) => "aborting due to `-Z treat-err-as-bug=1`".to_string(), + (1, _) => return, + (count, as_bug) => { + format!( + "aborting after {} errors due to `-Z treat-err-as-bug={}`", + count, + as_bug, + ) + } + }; + panic!(s); } } @@ -645,14 +657,12 @@ impl Handler { 1 => "aborting due to previous error".to_string(), _ => format!("aborting due to {} previous errors", self.err_count()) }; + let err_as_bug = self.flags.treat_err_as_bug.unwrap_or(0); + if self.err_count() >= err_as_bug { + return; + } - let _ = if self.treat_err_as_bug() { - self.fatal(&s) - } else { - // only emit one backtrace when using `-Z treat-err-as-bug=X` - DiagnosticBuilder::new(self, Fatal, &s).emit(); - FatalError - }; + let _ = self.fatal(&s); let can_show_explain = self.emitter.borrow().should_show_explain(); let are_there_diagnostics = !self.emitted_diagnostic_codes.borrow().is_empty(); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 3dd2c4a477a63..856365847ae17 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -67,7 +67,7 @@ pub fn run(mut options: Options) -> isize { let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping())); let handler = errors::Handler::with_tty_emitter(ColorConfig::Auto, - true, false, + true, None, Some(source_map.clone())); let mut sess = session::build_session_( From a7563a30c0576761a0770b196e9effbaaf846be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Mar 2019 08:09:41 -0800 Subject: [PATCH 5/8] fix bad logic --- src/librustc_errors/diagnostic_builder.rs | 4 +++- src/librustc_errors/lib.rs | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index a995d808bc41e..c8d47339fb365 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -103,7 +103,9 @@ impl<'a> DiagnosticBuilder<'a> { /// Buffers the diagnostic for later emission, unless handler /// has disabled such buffering. pub fn buffer(mut self, buffered_diagnostics: &mut Vec) { - if self.handler.flags.dont_buffer_diagnostics || self.handler.treat_err_as_bug() { + if self.handler.flags.dont_buffer_diagnostics || + self.handler.flags.treat_err_as_bug.is_some() + { self.emit(); return; } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 3992d2908c789..7c7698ddd3d73 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -657,8 +657,7 @@ impl Handler { 1 => "aborting due to previous error".to_string(), _ => format!("aborting due to {} previous errors", self.err_count()) }; - let err_as_bug = self.flags.treat_err_as_bug.unwrap_or(0); - if self.err_count() >= err_as_bug { + if self.treat_err_as_bug() { return; } From bc9b93629051979cec6fd078511954388bd4e9f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Mar 2019 11:15:47 -0800 Subject: [PATCH 6/8] Fix with_emitter callers --- src/librustc_driver/test.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 2 +- src/libsyntax/test_snippet.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 65f8ce75bd113..3d52f1d44ba29 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -113,7 +113,7 @@ fn test_env_with_pool( ) where F: FnOnce(Env), { - let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter); + let diagnostic_handler = errors::Handler::with_emitter(true, None, emitter); let sess = session::build_session_( options, None, diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index a7cde5fbb92cd..db5b8dcda4eab 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1920,7 +1920,7 @@ mod tests { false, false); ParseSess { - span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)), + span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)), unstable_features: UnstableFeatures::from_environment(), config: CrateConfig::default(), included_mod_stack: Lock::new(Vec::new()), diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index cf39090e1888b..2b3d18835d543 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -58,7 +58,7 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & Some(source_map.clone()), false, false); - let handler = Handler::with_emitter(true, false, Box::new(emitter)); + let handler = Handler::with_emitter(true, None, Box::new(emitter)); handler.span_err(msp, "foo"); assert!(expected_output.chars().next() == Some('\n'), From e3299f2c0d1802be5bef67666469670629612e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Mar 2019 11:18:05 -0800 Subject: [PATCH 7/8] Update treat-err-as-bug help text --- src/librustc/session/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 77fbe467ce010..7f48fd8a4012f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1244,7 +1244,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, no_codegen: bool = (false, parse_bool, [TRACKED], "run all passes except codegen; no output"), treat_err_as_bug: Option = (None, parse_treat_err_as_bug, [TRACKED], - "treat all errors that occur as bugs"), + "treat error number `val` that occurs as bug"), report_delayed_bugs: bool = (false, parse_bool, [TRACKED], "immediately print bugs registered with `delay_span_bug`"), external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], From 29716ef4f75e0d5cb11f788c2e449db4ea3989ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Mar 2019 13:13:13 -0800 Subject: [PATCH 8/8] update treat-err-as-bug test --- src/test/run-make-fulldeps/treat-err-as-bug/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/treat-err-as-bug/Makefile b/src/test/run-make-fulldeps/treat-err-as-bug/Makefile index f99e4611174ca..9b3bcef2faf32 100644 --- a/src/test/run-make-fulldeps/treat-err-as-bug/Makefile +++ b/src/test/run-make-fulldeps/treat-err-as-bug/Makefile @@ -2,4 +2,4 @@ all: $(RUSTC) err.rs -Z treat-err-as-bug 2>&1 \ - | $(CGREP) "panicked at 'encountered error with \`-Z treat_err_as_bug'" + | $(CGREP) "panicked at 'aborting due to \`-Z treat-err-as-bug=1\`'"