From 82e17504143e7f26427269fabfb99129a602c8b9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 15 Sep 2018 06:27:55 +0200 Subject: [PATCH] Add -Z dont-buffer-diagnostics, a way to force NLL to immediately emit its diagnostics. This is mainly intended for `rustc` developers who want to see a diagnostic in its original context in the control flow. Two uses cases for that are: * `-Z treat-err-as-bug` which then allows extraction of a stack-trace to the origin of the error (a case that is so important that we make that flag imply this one, effectively). * `RUST_LOG=... rustc`, in which case it is often useful to see the logging statements that occurred immediately prior to the point where the diagnostic was signalled. Drive-by: Added some documentation pointing future devs at HandlerFlags, and documented the fields of `HandlerFlags` itself. --- src/librustc/session/config.rs | 2 ++ src/librustc/session/mod.rs | 2 ++ src/librustc_errors/diagnostic_builder.rs | 14 ++++++++++++-- src/librustc_errors/lib.rs | 11 +++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2a9732bf02c98..25698129d82b3 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1331,6 +1331,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "disable user provided type assertion in NLL"), nll_dont_emit_read_for_match: bool = (false, parse_bool, [UNTRACKED], "in match codegen, do not include ReadForMatch statements (used by mir-borrowck)"), + dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], + "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting)."), polonius: bool = (false, parse_bool, [UNTRACKED], "enable polonius-based borrow-checker"), codegen_time_graph: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 619262abb0bf5..52e1ab477038d 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1012,6 +1012,7 @@ pub fn build_session_with_source_map( let can_emit_warnings = !(warnings_allow || cap_lints_allow); let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug; + let dont_buffer_diagnostics = sopts.debugging_opts.dont_buffer_diagnostics; let report_delayed_bugs = sopts.debugging_opts.report_delayed_bugs; let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace; @@ -1059,6 +1060,7 @@ pub fn build_session_with_source_map( can_emit_warnings, treat_err_as_bug, report_delayed_bugs, + dont_buffer_diagnostics, external_macro_backtrace, ..Default::default() }, diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 1b34898b99084..5e962a4af32f6 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -21,6 +21,10 @@ use std::thread::panicking; use syntax_pos::{MultiSpan, Span}; /// Used for emitting structured error messages and other diagnostic information. +/// +/// If there is some state in a downstream crate you would like to +/// access in the methods of `DiagnosticBuilder` here, consider +/// extending `HandlerFlags`, accessed via `self.handler.flags`. #[must_use] #[derive(Clone)] pub struct DiagnosticBuilder<'a> { @@ -89,8 +93,14 @@ impl<'a> DiagnosticBuilder<'a> { self.cancel(); } - /// Buffers the diagnostic for later emission. - pub fn buffer(self, buffered_diagnostics: &mut Vec) { + /// 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 { + self.emit(); + return; + } + // We need to use `ptr::read` because `DiagnosticBuilder` // implements `Drop`. let diagnostic; diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 3582c2359c8b9..d0ea6fba5ebb3 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -303,9 +303,20 @@ thread_local!(pub static TRACK_DIAGNOSTICS: Cell = #[derive(Default)] pub struct HandlerFlags { + /// If false, warning-level lints are suppressed. + /// (rustc: see `--allow warnings` and `--cap-lints`) 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, + /// 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, + /// If true, immediately print bugs registered with `delay_span_bug`. + /// (rustc: see `-Z report-delayed-bugs`) pub report_delayed_bugs: bool, + /// show macro backtraces even for non-local macros. + /// (rustc: see `-Z external-macro-backtrace`) pub external_macro_backtrace: bool, }