Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce an option for disabling deduplication of diagnostics #67709

Merged
merged 4 commits into from
Jan 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ pub struct HandlerFlags {
/// show macro backtraces even for non-local macros.
/// (rustc: see `-Z external-macro-backtrace`)
pub external_macro_backtrace: bool,
/// If true, identical diagnostics are reported only once.
pub deduplicate_diagnostics: bool,
}

impl Drop for HandlerInner {
Expand Down Expand Up @@ -736,16 +738,17 @@ impl HandlerInner {
self.emitted_diagnostic_codes.insert(code.clone());
}

let diagnostic_hash = {
let already_emitted = |this: &mut Self| {
use std::hash::Hash;
let mut hasher = StableHasher::new();
diagnostic.hash(&mut hasher);
hasher.finish()
let diagnostic_hash = hasher.finish();
!this.emitted_diagnostics.insert(diagnostic_hash)
};

// Only emit the diagnostic if we haven't already emitted an equivalent
// one:
if self.emitted_diagnostics.insert(diagnostic_hash) {
// Only emit the diagnostic if we've been asked to deduplicate and
// haven't already emitted an equivalent diagnostic.
if !(self.flags.deduplicate_diagnostics && already_emitted(self)) {
self.emitter.emit_diagnostic(diagnostic);
if diagnostic.is_error() {
self.deduplicated_err_count += 1;
Expand Down
13 changes: 12 additions & 1 deletion src/librustc_session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use rustc_span::source_map::{FileName, FilePathMapping};
use rustc_span::symbol::{sym, Symbol};

use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, FatalError, Handler};
use rustc_errors::{ColorConfig, FatalError, Handler, HandlerFlags};

use getopts;

Expand Down Expand Up @@ -597,6 +597,17 @@ impl DebuggingOptions {
pub fn ui_testing(&self) -> bool {
self.ui_testing.unwrap_or(false)
}

pub fn diagnostic_handler_flags(&self, can_emit_warnings: bool) -> HandlerFlags {
HandlerFlags {
can_emit_warnings,
treat_err_as_bug: self.treat_err_as_bug,
dont_buffer_diagnostics: self.dont_buffer_diagnostics,
report_delayed_bugs: self.report_delayed_bugs,
external_macro_backtrace: self.external_macro_backtrace,
deduplicate_diagnostics: self.deduplicate_diagnostics.unwrap_or(true),
}
}
}

// The type of entry function, so users can have their own entry functions
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_session/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,4 +946,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
insert_sideeffect: bool = (false, parse_bool, [TRACKED],
"fix undefined behavior when a thread doesn't eventually make progress \
(such as entering an empty infinite loop) by inserting llvm.sideeffect"),
deduplicate_diagnostics: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
"deduplicate identical diagnostics"),
}
16 changes: 1 addition & 15 deletions src/librustc_session/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -941,15 +941,8 @@ pub fn build_session_with_source_map(
.last()
.unwrap_or(false);
let cap_lints_allow = sopts.lint_cap.map_or(false, |cap| cap == lint::Allow);

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;

let write_dest = match diagnostics_output {
DiagnosticOutput::Default => None,
DiagnosticOutput::Raw(write) => Some(write),
Expand All @@ -958,14 +951,7 @@ pub fn build_session_with_source_map(

let diagnostic_handler = rustc_errors::Handler::with_emitter_and_flags(
emitter,
rustc_errors::HandlerFlags {
can_emit_warnings,
treat_err_as_bug,
report_delayed_bugs,
dont_buffer_diagnostics,
external_macro_backtrace,
..Default::default()
},
sopts.debugging_opts.diagnostic_handler_flags(can_emit_warnings),
);

build_session_(sopts, local_crate_source_file, diagnostic_handler, source_map, lint_caps)
Expand Down
7 changes: 1 addition & 6 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,7 @@ impl Options {
let codegen_options = build_codegen_options(matches, error_format);
let debugging_options = build_debugging_options(matches, error_format);

let diag = new_handler(
error_format,
None,
debugging_options.treat_err_as_bug,
debugging_options.ui_testing(),
);
let diag = new_handler(error_format, None, &debugging_options);

// check for deprecated options
check_deprecated_options(&matches, &diag);
Expand Down
29 changes: 8 additions & 21 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::html::render::RenderInfo;

use crate::passes;

pub use rustc::session::config::{CodegenOptions, Input, Options};
pub use rustc::session::config::{CodegenOptions, DebuggingOptions, Input, Options};
pub use rustc::session::search_paths::SearchPath;

pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
Expand Down Expand Up @@ -170,12 +170,8 @@ impl<'tcx> DocContext<'tcx> {
pub fn new_handler(
error_format: ErrorOutputType,
source_map: Option<Lrc<source_map::SourceMap>>,
treat_err_as_bug: Option<usize>,
ui_testing: bool,
debugging_opts: &DebuggingOptions,
) -> errors::Handler {
// rustdoc doesn't override (or allow to override) anything from this that is relevant here, so
// stick to the defaults
let sessopts = Options::default();
let emitter: Box<dyn Emitter + sync::Send> = match error_format {
ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
Expand All @@ -184,34 +180,25 @@ pub fn new_handler(
color_config,
source_map.map(|cm| cm as _),
short,
sessopts.debugging_opts.teach,
sessopts.debugging_opts.terminal_width,
debugging_opts.teach,
debugging_opts.terminal_width,
false,
)
.ui_testing(ui_testing),
.ui_testing(debugging_opts.ui_testing()),
)
}
ErrorOutputType::Json { pretty, json_rendered } => {
let source_map = source_map.unwrap_or_else(|| {
Lrc::new(source_map::SourceMap::new(sessopts.file_path_mapping()))
Lrc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty()))
});
Box::new(
JsonEmitter::stderr(None, source_map, pretty, json_rendered, false)
.ui_testing(ui_testing),
.ui_testing(debugging_opts.ui_testing()),
)
}
};

errors::Handler::with_emitter_and_flags(
emitter,
errors::HandlerFlags {
can_emit_warnings: true,
treat_err_as_bug,
report_delayed_bugs: false,
external_macro_backtrace: false,
..Default::default()
},
)
errors::Handler::with_emitter_and_flags(emitter, debugging_opts.diagnostic_handler_flags(true))
}

pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions) {
Expand Down
18 changes: 4 additions & 14 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,7 @@ fn main_args(args: &[String]) -> i32 {
}

fn main_options(options: config::Options) -> i32 {
let diag = core::new_handler(
options.error_format,
None,
options.debugging_options.treat_err_as_bug,
options.debugging_options.ui_testing(),
);
let diag = core::new_handler(options.error_format, None, &options.debugging_options);

match (options.should_test, options.markdown_input()) {
(true, true) => return markdown::test(options, &diag),
Expand All @@ -463,12 +458,7 @@ fn main_options(options: config::Options) -> i32 {

// need to move these items separately because we lose them by the time the closure is called,
// but we can't crates the Handler ahead of time because it's not Send
let diag_opts = (
options.error_format,
options.debugging_options.treat_err_as_bug,
options.debugging_options.ui_testing(),
options.edition,
);
let diag_opts = (options.error_format, options.edition, options.debugging_options.clone());
let show_coverage = options.show_coverage;
rust_input(options, move |out| {
if show_coverage {
Expand All @@ -479,8 +469,8 @@ fn main_options(options: config::Options) -> i32 {

let Output { krate, renderinfo, renderopts } = out;
info!("going to format");
let (error_format, treat_err_as_bug, ui_testing, edition) = diag_opts;
let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
let (error_format, edition, debugging_options) = diag_opts;
let diag = core::new_handler(error_format, None, &debugging_options);
match html::render::run(krate, renderopts, renderinfo, &diag, edition) {
Ok(_) => rustc_driver::EXIT_SUCCESS,
Err(e) => {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/miri_unleashed/mutable_const2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant
LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:345:17
thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:347:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

error: internal compiler error: unexpected panic
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/deduplicate-diagnostics.deduplicate.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: cannot find derive macro `Unresolved` in this scope
--> $DIR/deduplicate-diagnostics.rs:4:10
|
LL | #[derive(Unresolved)]
| ^^^^^^^^^^

error: aborting due to previous error

14 changes: 14 additions & 0 deletions src/test/ui/deduplicate-diagnostics.duplicate.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: cannot find derive macro `Unresolved` in this scope
--> $DIR/deduplicate-diagnostics.rs:4:10
|
LL | #[derive(Unresolved)]
| ^^^^^^^^^^

error: cannot find derive macro `Unresolved` in this scope
--> $DIR/deduplicate-diagnostics.rs:4:10
|
LL | #[derive(Unresolved)]
| ^^^^^^^^^^

error: aborting due to 2 previous errors

8 changes: 8 additions & 0 deletions src/test/ui/deduplicate-diagnostics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// revisions: duplicate deduplicate
//[duplicate] compile-flags: -Z deduplicate-diagnostics=no

#[derive(Unresolved)] //~ ERROR cannot find derive macro `Unresolved` in this scope
//[duplicate]~| ERROR cannot find derive macro `Unresolved` in this scope
struct S;

fn main() {}