From cdd805506e7a01d60906f8b153afb697d687609d Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 7 Sep 2019 09:57:11 -0400 Subject: Replace DiagnosticBuilder with Diagnostic when emitting error --- .../annotate_snippet_emitter_writer.rs | 12 ++++++++---- src/librustc_errors/emitter.rs | 20 ++++++++++++++------ src/librustc_errors/lib.rs | 3 ++- 3 files changed, 24 insertions(+), 11 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index c626dd0434d..0281d10fd93 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -7,7 +7,7 @@ use syntax_pos::{SourceFile, MultiSpan, Loc}; use crate::{ - Level, CodeSuggestion, DiagnosticBuilder, Emitter, + Level, CodeSuggestion, Diagnostic, Emitter, SourceMapperDyn, SubDiagnostic, DiagnosticId }; use crate::emitter::FileWithAnnotatedLines; @@ -25,11 +25,13 @@ pub struct AnnotateSnippetEmitterWriter { short_message: bool, /// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs. ui_testing: bool, + + external_macro_backtrace: bool, } impl Emitter for AnnotateSnippetEmitterWriter { /// The entry point for the diagnostics generation - fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) { + fn emit_diagnostic(&mut self, db: &Diagnostic) { let mut children = db.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&db); @@ -37,7 +39,7 @@ impl Emitter for AnnotateSnippetEmitterWriter { &mut primary_span, &mut children, &db.level, - db.handler().flags.external_macro_backtrace); + self.external_macro_backtrace); self.emit_messages_default(&db.level, db.message(), @@ -163,12 +165,14 @@ impl<'a> DiagnosticConverter<'a> { impl AnnotateSnippetEmitterWriter { pub fn new( source_map: Option>, - short_message: bool + short_message: bool, + external_macro_backtrace: bool, ) -> Self { Self { source_map, short_message, ui_testing: false, + external_macro_backtrace, } } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 66608361c8d..c5274c7e99a 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -12,7 +12,7 @@ use Destination::*; use syntax_pos::{SourceFile, Span, MultiSpan}; use crate::{ - Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic, + Level, CodeSuggestion, Diagnostic, SubDiagnostic, SuggestionStyle, SourceMapperDyn, DiagnosticId, }; use crate::Level::Error; @@ -52,10 +52,12 @@ impl HumanReadableErrorType { source_map: Option>, teach: bool, terminal_width: Option, + external_macro_backtrace: bool, ) -> EmitterWriter { let (short, color_config) = self.unzip(); let color = color_config.suggests_using_colors(); - EmitterWriter::new(dst, source_map, short, teach, color, terminal_width) + EmitterWriter::new(dst, source_map, short, teach, color, terminal_width, + external_macro_backtrace) } } @@ -180,7 +182,7 @@ const ANONYMIZED_LINE_NUM: &str = "LL"; /// Emitter trait for emitting errors. pub trait Emitter { /// Emit a structured diagnostic. - fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>); + fn emit_diagnostic(&mut self, db: &Diagnostic); /// Emit a notification that an artifact has been output. /// This is currently only supported for the JSON format, @@ -204,7 +206,7 @@ pub trait Emitter { /// we return the original `primary_span` and the original suggestions. fn primary_span_formatted<'a>( &mut self, - db: &'a DiagnosticBuilder<'_> + db: &'a Diagnostic ) -> (MultiSpan, &'a [CodeSuggestion]) { let mut primary_span = db.span.clone(); if let Some((sugg, rest)) = db.suggestions.split_first() { @@ -377,7 +379,7 @@ pub trait Emitter { } impl Emitter for EmitterWriter { - fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) { + fn emit_diagnostic(&mut self, db: &Diagnostic) { let mut children = db.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&db); @@ -385,7 +387,7 @@ impl Emitter for EmitterWriter { &mut primary_span, &mut children, &db.level, - db.handler().flags.external_macro_backtrace); + self.external_macro_backtrace); self.emit_messages_default(&db.level, &db.styled_message(), @@ -449,6 +451,8 @@ pub struct EmitterWriter { teach: bool, ui_testing: bool, terminal_width: Option, + + external_macro_backtrace: bool, } #[derive(Debug)] @@ -465,6 +469,7 @@ impl EmitterWriter { short_message: bool, teach: bool, terminal_width: Option, + external_macro_backtrace: bool, ) -> EmitterWriter { let dst = Destination::from_stderr(color_config); EmitterWriter { @@ -474,6 +479,7 @@ impl EmitterWriter { teach, ui_testing: false, terminal_width, + external_macro_backtrace, } } @@ -484,6 +490,7 @@ impl EmitterWriter { teach: bool, colored: bool, terminal_width: Option, + external_macro_backtrace: bool, ) -> EmitterWriter { EmitterWriter { dst: Raw(dst, colored), @@ -492,6 +499,7 @@ impl EmitterWriter { teach, ui_testing: false, terminal_width, + external_macro_backtrace, } } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index c1fba416d64..4ff18578bca 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -383,7 +383,8 @@ impl Handler { cm: Option>, flags: HandlerFlags) -> Handler { - let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false, false, None)); + let emitter = Box::new(EmitterWriter::stderr( + color_config, cm, false, false, None, flags.external_macro_backtrace)); Handler::with_emitter_and_flags(emitter, flags) } -- cgit 1.4.1-3-g733a5 From 0b586b436d6ea2dddc213c18bf17f2314441c32f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 7 Sep 2019 10:03:15 -0400 Subject: Take Diagnostic in Handler::emit_diagnostic --- src/librustc/session/config.rs | 2 +- src/librustc_errors/diagnostic_builder.rs | 10 +--------- src/librustc_errors/lib.rs | 14 ++++++++------ 3 files changed, 10 insertions(+), 16 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 723855c7c29..5eda3df3781 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1855,7 +1855,7 @@ pub fn rustc_optgroups() -> Vec { struct NullEmitter; impl errors::emitter::Emitter for NullEmitter { - fn emit_diagnostic(&mut self, _: &errors::DiagnosticBuilder<'_>) {} + fn emit_diagnostic(&mut self, _: &errors::Diagnostic) {} } // Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`. diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 7b8902f125a..25ffb146da7 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -99,17 +99,9 @@ impl<'a> DerefMut for DiagnosticBuilder<'a> { } impl<'a> DiagnosticBuilder<'a> { - pub fn handler(&self) -> &'a Handler{ - self.0.handler - } - /// Emit the diagnostic. pub fn emit(&mut self) { - if self.cancelled() { - return; - } - - self.0.handler.emit_db(&self); + self.0.handler.emit_diagnostic(&self); self.cancel(); } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 4ff18578bca..11e2265cf36 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -589,7 +589,7 @@ impl Handler { } fn delay_as_bug(&self, diagnostic: Diagnostic) { if self.flags.report_delayed_bugs { - DiagnosticBuilder::new_diagnostic(self, diagnostic.clone()).emit(); + self.emit_diagnostic(&diagnostic); } self.delayed_span_bugs.borrow_mut().push(diagnostic); } @@ -747,8 +747,10 @@ impl Handler { db.cancel(); } - fn emit_db(&self, db: &DiagnosticBuilder<'_>) { - let diagnostic = &**db; + fn emit_diagnostic(&self, diagnostic: &Diagnostic) { + if diagnostic.cancelled() { + return; + } TRACK_DIAGNOSTICS.with(|track_diagnostics| { track_diagnostics.get()(diagnostic); @@ -768,12 +770,12 @@ impl Handler { // Only emit the diagnostic if we haven't already emitted an equivalent // one: if self.emitted_diagnostics.borrow_mut().insert(diagnostic_hash) { - self.emitter.borrow_mut().emit_diagnostic(db); - if db.is_error() { + self.emitter.borrow_mut().emit_diagnostic(diagnostic); + if diagnostic.is_error() { self.deduplicated_err_count.fetch_add(1, SeqCst); } } - if db.is_error() { + if diagnostic.is_error() { self.bump_err_count(); } } -- cgit 1.4.1-3-g733a5 From 2a3930d43ced5204f53a6e1eebd741a81c4c1e9a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 7 Sep 2019 10:20:56 -0400 Subject: Privatize DiagnosticBuilder constructors --- src/librustc/dep_graph/graph.rs | 4 ++-- src/librustc/ty/query/plumbing.rs | 7 +++---- src/librustc_errors/diagnostic_builder.rs | 5 +++-- src/librustc_errors/lib.rs | 5 ++--- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_typeck/check/writeback.rs | 3 +-- src/libsyntax/ext/proc_macro_server.rs | 4 ++-- src/libsyntax/lib.rs | 4 ++-- src/libsyntax/parse/mod.rs | 2 +- 9 files changed, 17 insertions(+), 19 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 7eea336cbbf..e76a70350b3 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -1,4 +1,4 @@ -use errors::{Diagnostic, DiagnosticBuilder}; +use errors::Diagnostic; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; @@ -819,7 +819,7 @@ impl DepGraph { let handle = tcx.sess.diagnostic(); for diagnostic in diagnostics { - DiagnosticBuilder::new_diagnostic(handle, diagnostic).emit(); + handle.emit_diagnostic(&diagnostic); } // Mark the node as green now that diagnostics are emitted diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index d199a26475b..a1828bb5ab7 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -330,14 +330,13 @@ impl<'tcx> TyCtxt<'tcx> { let mut i = 0; while let Some(query) = current_query { - let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(), - Level::FailureNote, + let mut diag = Diagnostic::new(Level::FailureNote, &format!("#{} [{}] {}", i, query.info.query.name(), query.info.query.describe(icx.tcx))); - db.set_span(icx.tcx.sess.source_map().def_span(query.info.span)); - icx.tcx.sess.diagnostic().force_print_db(db); + diag.span = icx.tcx.sess.source_map().def_span(query.info.span).into(); + icx.tcx.sess.diagnostic().force_print_diagnostic(diag); current_query = query.parent.clone(); i += 1; diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 25ffb146da7..e85388bfea2 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -346,7 +346,7 @@ impl<'a> DiagnosticBuilder<'a> { /// Convenience function for internal use, clients should use one of the /// struct_* methods on Handler. - pub fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> { + crate fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> { DiagnosticBuilder::new_with_code(handler, level, None, message) } @@ -363,7 +363,8 @@ impl<'a> DiagnosticBuilder<'a> { /// Creates a new `DiagnosticBuilder` with an already constructed /// diagnostic. - pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> { + crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) + -> DiagnosticBuilder<'a> { DiagnosticBuilder(Box::new(DiagnosticBuilderInner { handler, diagnostic, diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 11e2265cf36..51309f37e17 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -742,12 +742,11 @@ impl Handler { self.taught_diagnostics.borrow_mut().insert(code.clone()) } - pub fn force_print_db(&self, mut db: DiagnosticBuilder<'_>) { + pub fn force_print_diagnostic(&self, db: Diagnostic) { self.emitter.borrow_mut().emit_diagnostic(&db); - db.cancel(); } - fn emit_diagnostic(&self, diagnostic: &Diagnostic) { + pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) { if diagnostic.cancelled() { return; } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 1d3576244c4..32c6dd67a4b 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -402,7 +402,7 @@ fn do_mir_borrowck<'a, 'tcx>( } for diag in mbcx.errors_buffer.drain(..) { - DiagnosticBuilder::new_diagnostic(mbcx.infcx.tcx.sess.diagnostic(), diag).emit(); + mbcx.infcx.tcx.sess.diagnostic().emit_diagnostic(&diag); } } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 487dc8ec2ae..1cc71ea5649 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -3,7 +3,6 @@ // substitutions. use crate::check::FnCtxt; -use errors::DiagnosticBuilder; use rustc::hir; use rustc::hir::def_id::{DefId, DefIndex}; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; @@ -407,7 +406,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { if !errors_buffer.is_empty() { errors_buffer.sort_by_key(|diag| diag.span.primary_span()); for diag in errors_buffer.drain(..) { - DiagnosticBuilder::new_diagnostic(self.tcx().sess.diagnostic(), diag).emit(); + self.tcx().sess.diagnostic().emit_diagnostic(&diag); } } } diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs index 544ec789d80..dfec9ee2880 100644 --- a/src/libsyntax/ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -4,7 +4,7 @@ use crate::parse::{self, token, ParseSess}; use crate::parse::lexer::comments; use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}; -use errors::{Diagnostic, DiagnosticBuilder}; +use errors::Diagnostic; use rustc_data_structures::sync::Lrc; use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span}; use syntax_pos::symbol::{kw, sym, Symbol}; @@ -650,7 +650,7 @@ impl server::Diagnostic for Rustc<'_> { diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None); } fn emit(&mut self, diag: Self::Diagnostic) { - DiagnosticBuilder::new_diagnostic(&self.sess.span_diagnostic, diag).emit() + self.sess.span_diagnostic.emit_diagnostic(&diag); } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index aaf6f3e537e..b4ae1e87bca 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -60,12 +60,12 @@ macro_rules! panictry { macro_rules! panictry_buffer { ($handler:expr, $e:expr) => ({ use std::result::Result::{Ok, Err}; - use errors::{FatalError, DiagnosticBuilder}; + use errors::FatalError; match $e { Ok(e) => e, Err(errs) => { for e in errs { - DiagnosticBuilder::new_diagnostic($handler, e).emit(); + $handler.emit_diagnostic(&e); } FatalError.raise() } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 2441a027f99..c4f31bcd9b0 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -306,7 +306,7 @@ fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option) match try_file_to_source_file(sess, path, spanopt) { Ok(source_file) => source_file, Err(d) => { - DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, d).emit(); + sess.span_diagnostic.emit_diagnostic(&d); FatalError.raise(); } } -- cgit 1.4.1-3-g733a5 From 998df0d70b0c837d52a1c8100773409390df840c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 7 Sep 2019 10:38:02 -0400 Subject: Remove Handler::cancel --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc_errors/lib.rs | 4 ---- src/libsyntax/parse/attr.rs | 4 ++-- src/libsyntax/parse/diagnostics.rs | 8 +------- src/libsyntax/parse/parser/expr.rs | 2 +- src/libsyntax/parse/parser/pat.rs | 2 +- src/libsyntax/parse/parser/stmt.rs | 2 +- 7 files changed, 7 insertions(+), 17 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index ab24b3f2f05..0b6740d7bbb 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1119,7 +1119,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Some((expected, found)) => Some((expected, found)), None => { // Derived error. Cancel the emitter. - self.tcx.sess.diagnostic().cancel(diag); + diag.cancel(); return; } }; diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 51309f37e17..47ac2e5a667 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -520,10 +520,6 @@ impl Handler { DiagnosticBuilder::new(self, Level::Fatal, msg) } - pub fn cancel(&self, err: &mut DiagnosticBuilder<'_>) { - err.cancel(); - } - fn panic_if_treat_err_as_bug(&self) { if self.treat_err_as_bug() { let s = match (self.err_count(), self.flags.treat_err_as_bug.unwrap_or(0)) { diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 9aa1ec0b14f..9fbed66854c 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -309,14 +309,14 @@ impl<'a> Parser<'a> { Ok(lit) => { return Ok(ast::NestedMetaItem::Literal(lit)) } - Err(ref mut err) => self.diagnostic().cancel(err) + Err(ref mut err) => err.cancel(), } match self.parse_meta_item() { Ok(mi) => { return Ok(ast::NestedMetaItem::MetaItem(mi)) } - Err(ref mut err) => self.diagnostic().cancel(err) + Err(ref mut err) => err.cancel(), } let found = self.this_token_to_string(); diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index b74f2492c35..1e7058ff715 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -197,10 +197,6 @@ impl<'a> Parser<'a> { self.sess.span_diagnostic.span_bug(sp, m) } - crate fn cancel(&self, err: &mut DiagnosticBuilder<'_>) { - self.sess.span_diagnostic.cancel(err) - } - crate fn diagnostic(&self) -> &'a errors::Handler { &self.sess.span_diagnostic } @@ -426,15 +422,13 @@ impl<'a> Parser<'a> { /// Eats and discards tokens until one of `kets` is encountered. Respects token trees, /// passes through any errors encountered. Used for error recovery. crate fn eat_to_tokens(&mut self, kets: &[&TokenKind]) { - let handler = self.diagnostic(); - if let Err(ref mut err) = self.parse_seq_to_before_tokens( kets, SeqSep::none(), TokenExpectType::Expect, |p| Ok(p.parse_token_tree()), ) { - handler.cancel(err); + err.cancel(); } } diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index 31b28443abb..5764934b3cd 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -770,7 +770,7 @@ impl<'a> Parser<'a> { ex = ExprKind::Lit(literal); } Err(mut err) => { - self.cancel(&mut err); + err.cancel(); return Err(self.expected_expression_found()); } } diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs index 08ee3a6bd86..3c624959ead 100644 --- a/src/libsyntax/parse/parser/pat.rs +++ b/src/libsyntax/parse/parser/pat.rs @@ -537,7 +537,7 @@ impl<'a> Parser<'a> { mut err: DiagnosticBuilder<'a>, expected: Expected, ) -> PResult<'a, P> { - self.cancel(&mut err); + err.cancel(); let expected = expected.unwrap_or("pattern"); let msg = format!("expected {}, found {}", expected, self.this_token_descr()); diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs index 04bd61a4cfb..02da56f6e35 100644 --- a/src/libsyntax/parse/parser/stmt.rs +++ b/src/libsyntax/parse/parser/stmt.rs @@ -361,7 +361,7 @@ impl<'a> Parser<'a> { } Err(mut e) => { self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); - self.cancel(&mut e); + e.cancel(); } _ => () } -- cgit 1.4.1-3-g733a5 From b304e60131a081930382a6bf327aa11c6432698c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 7 Sep 2019 11:21:17 -0400 Subject: Remove Handler::{emit, emit_with_code} --- src/librustc/session/mod.rs | 4 +-- src/librustc_codegen_ssa/back/write.rs | 18 +++-------- src/librustc_driver/lib.rs | 12 +++---- src/librustc_errors/lib.rs | 59 ++++++++++++++++------------------ 4 files changed, 40 insertions(+), 53 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index af9cb5a0941..afaea540060 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1394,7 +1394,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { Box::new(JsonEmitter::basic(pretty, json_rendered, false)), }; let handler = errors::Handler::with_emitter(true, None, emitter); - handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal); + handler.struct_fatal(msg).emit(); errors::FatalError.raise(); } @@ -1408,7 +1408,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) { Box::new(JsonEmitter::basic(pretty, json_rendered, false)), }; let handler = errors::Handler::with_emitter(true, None, emitter); - handler.emit(&MultiSpan::new(), msg, errors::Level::Warning); + handler.struct_warn(msg).emit(); } pub type CompileResult = Result<(), ErrorReported>; diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 38a0818d290..1bba479c1fd 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -27,7 +27,6 @@ use rustc_errors::emitter::{Emitter}; use rustc_target::spec::MergeFunctions; use syntax::attr; use syntax::ext::hygiene::ExpnId; -use syntax_pos::MultiSpan; use syntax_pos::symbol::{Symbol, sym}; use jobserver::{Client, Acquired}; @@ -1760,19 +1759,12 @@ impl SharedEmitterMain { match message { Ok(SharedEmitterMessage::Diagnostic(diag)) => { let handler = sess.diagnostic(); - match diag.code { - Some(ref code) => { - handler.emit_with_code(&MultiSpan::new(), - &diag.msg, - code.clone(), - diag.lvl); - } - None => { - handler.emit(&MultiSpan::new(), - &diag.msg, - diag.lvl); - } + let mut d = rustc_errors::Diagnostic::new(diag.lvl, &diag.msg); + if let Some(code) = diag.code { + d.code(code); } + handler.emit_diagnostic(&d); + handler.abort_if_errors_and_should_abort(); } Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => { sess.span_err(ExpnId::from_u32(cookie).expn_data().call_site, &msg) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3a09f459e9c..f99e65b4494 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -66,7 +66,7 @@ use syntax::source_map::FileLoader; use syntax::feature_gate::{GatedCfg, UnstableFeatures}; use syntax::parse::{self, PResult}; use syntax::symbol::sym; -use syntax_pos::{DUMMY_SP, MultiSpan, FileName}; +use syntax_pos::{DUMMY_SP, FileName}; pub mod pretty; mod args; @@ -1203,9 +1203,9 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // a .span_bug or .bug call has already printed what // it wants to print. if !info.payload().is::() { - handler.emit(&MultiSpan::new(), - "unexpected panic", - errors::Level::Bug); + let d = errors::Diagnostic::new(errors::Level::Bug, "unexpected panic"); + handler.emit_diagnostic(&d); + handler.abort_if_errors_and_should_abort(); } let mut xs: Vec> = vec![ @@ -1225,9 +1225,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { } for note in &xs { - handler.emit(&MultiSpan::new(), - note, - errors::Level::Note); + handler.note_without_error(¬e); } // If backtraces are enabled, also print the query stack diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 47ac2e5a667..b74a6035032 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -539,7 +539,8 @@ impl Handler { } pub fn span_fatal>(&self, sp: S, msg: &str) -> FatalError { - self.emit(&sp.into(), msg, Fatal); + self.emit_diagnostic(Diagnostic::new(Fatal, msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); FatalError } pub fn span_fatal_with_code>(&self, @@ -547,11 +548,13 @@ impl Handler { msg: &str, code: DiagnosticId) -> FatalError { - self.emit_with_code(&sp.into(), msg, code, Fatal); + self.emit_diagnostic(Diagnostic::new_with_code(Fatal, Some(code), msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); FatalError } pub fn span_err>(&self, sp: S, msg: &str) { - self.emit(&sp.into(), msg, Error); + self.emit_diagnostic(Diagnostic::new(Error, msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); } pub fn mut_span_err>(&self, sp: S, @@ -562,16 +565,20 @@ impl Handler { result } pub fn span_err_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { - self.emit_with_code(&sp.into(), msg, code, Error); + self.emit_diagnostic(Diagnostic::new_with_code(Error, Some(code), msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); } pub fn span_warn>(&self, sp: S, msg: &str) { - self.emit(&sp.into(), msg, Warning); + self.emit_diagnostic(Diagnostic::new(Warning, msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); } pub fn span_warn_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { - self.emit_with_code(&sp.into(), msg, code, Warning); + self.emit_diagnostic(Diagnostic::new_with_code(Warning, Some(code), msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); } pub fn span_bug>(&self, sp: S, msg: &str) -> ! { - self.emit(&sp.into(), msg, Bug); + self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); panic!(ExplicitBug); } pub fn delay_span_bug>(&self, sp: S, msg: &str) { @@ -590,10 +597,12 @@ impl Handler { self.delayed_span_bugs.borrow_mut().push(diagnostic); } pub fn span_bug_no_panic>(&self, sp: S, msg: &str) { - self.emit(&sp.into(), msg, Bug); + self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); } pub fn span_note_without_error>(&self, sp: S, msg: &str) { - self.emit(&sp.into(), msg, Note); + self.emit_diagnostic(Diagnostic::new(Note, msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); } pub fn span_note_diag(&self, sp: Span, @@ -701,31 +710,15 @@ impl Handler { } } - pub fn abort_if_errors(&self) { - if self.has_errors() { + pub fn abort_if_errors_and_should_abort(&self) { + if self.has_errors() && !self.continue_after_error.load(SeqCst) { FatalError.raise(); } } - pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) { - if lvl == Warning && !self.flags.can_emit_warnings { - return; - } - let mut db = DiagnosticBuilder::new(self, lvl, msg); - db.set_span(msp.clone()); - db.emit(); - if !self.continue_after_error.load(SeqCst) { - self.abort_if_errors(); - } - } - pub fn emit_with_code(&self, msp: &MultiSpan, msg: &str, code: DiagnosticId, lvl: Level) { - if lvl == Warning && !self.flags.can_emit_warnings { - return; - } - let mut db = DiagnosticBuilder::new_with_code(self, lvl, Some(code), msg); - db.set_span(msp.clone()); - db.emit(); - if !self.continue_after_error.load(SeqCst) { - self.abort_if_errors(); + + pub fn abort_if_errors(&self) { + if self.has_errors() { + FatalError.raise(); } } @@ -747,6 +740,10 @@ impl Handler { return; } + if diagnostic.level == Warning && !self.flags.can_emit_warnings { + return; + } + TRACK_DIAGNOSTICS.with(|track_diagnostics| { track_diagnostics.get()(diagnostic); }); -- cgit 1.4.1-3-g733a5 From 2a767eec0cae5aedb197d8fb823df67d93257fbd Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 7 Sep 2019 11:26:32 -0400 Subject: Remove unused methods from Handler --- src/librustc/session/mod.rs | 6 ------ src/librustc_errors/lib.rs | 6 ------ src/libsyntax/ext/base.rs | 3 --- 3 files changed, 15 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index afaea540060..a24fed8f21c 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -365,12 +365,6 @@ impl Session { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.diagnostic().span_note_without_error(sp, msg) } - pub fn span_unimpl>(&self, sp: S, msg: &str) -> ! { - self.diagnostic().span_unimpl(sp, msg) - } - pub fn unimpl(&self, msg: &str) -> ! { - self.diagnostic().unimpl(msg) - } pub fn buffer_lint>( &self, diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index b74a6035032..bd57cc41ef3 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -612,9 +612,6 @@ impl Handler { db.set_span(sp); db } - pub fn span_unimpl>(&self, sp: S, msg: &str) -> ! { - self.span_bug(sp, &format!("unimplemented {}", msg)); - } pub fn failure(&self, msg: &str) { DiagnosticBuilder::new(self, FailureNote, msg).emit() } @@ -648,9 +645,6 @@ impl Handler { db.emit(); panic!(ExplicitBug); } - pub fn unimpl(&self, msg: &str) -> ! { - self.bug(&format!("unimplemented {}", msg)); - } fn bump_err_count(&self) { self.err_count.fetch_add(1, SeqCst); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 384c0555c85..a6be5b10178 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1048,9 +1048,6 @@ impl<'a> ExtCtxt<'a> { pub fn span_warn>(&self, sp: S, msg: &str) { self.parse_sess.span_diagnostic.span_warn(sp, msg); } - pub fn span_unimpl>(&self, sp: S, msg: &str) -> ! { - self.parse_sess.span_diagnostic.span_unimpl(sp, msg); - } pub fn span_bug>(&self, sp: S, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_bug(sp, msg); } -- cgit 1.4.1-3-g733a5 From 4cc5aaada2f8ffd444a7fbb10394b83ba3156525 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 7 Sep 2019 12:09:52 -0400 Subject: Protect error handler fields with single lock This avoids concurrency-related bugs when locks are acquired for too short a time and similar cases. --- src/librustc/session/config/tests.rs | 6 +- src/librustc_errors/lib.rs | 336 +++++++++++++++++++++-------------- 2 files changed, 207 insertions(+), 135 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc/session/config/tests.rs b/src/librustc/session/config/tests.rs index 3d6312548a4..9eb68056bfd 100644 --- a/src/librustc/session/config/tests.rs +++ b/src/librustc/session/config/tests.rs @@ -87,7 +87,7 @@ fn test_can_print_warnings() { let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); - assert!(!sess.diagnostic().flags.can_emit_warnings); + assert!(!sess.diagnostic().can_emit_warnings()); }); syntax::with_default_globals(|| { @@ -97,7 +97,7 @@ fn test_can_print_warnings() { let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); - assert!(sess.diagnostic().flags.can_emit_warnings); + assert!(sess.diagnostic().can_emit_warnings()); }); syntax::with_default_globals(|| { @@ -105,7 +105,7 @@ fn test_can_print_warnings() { let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); - assert!(sess.diagnostic().flags.can_emit_warnings); + assert!(sess.diagnostic().can_emit_warnings()); }); } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index bd57cc41ef3..a1a63664a4b 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -16,7 +16,7 @@ use Level::*; use emitter::{Emitter, EmitterWriter}; use registry::Registry; -use rustc_data_structures::sync::{self, Lrc, Lock, AtomicUsize, AtomicBool, SeqCst}; +use rustc_data_structures::sync::{self, Lrc, Lock}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stable_hasher::StableHasher; @@ -298,30 +298,34 @@ pub use diagnostic_builder::DiagnosticBuilder; /// Certain errors (fatal, bug, unimpl) may cause immediate exit, /// others log errors for later reporting. pub struct Handler { - pub flags: HandlerFlags, + flags: HandlerFlags, + inner: Lock, +} +struct HandlerInner { + flags: HandlerFlags, /// The number of errors that have been emitted, including duplicates. /// /// This is not necessarily the count that's reported to the user once /// compilation ends. - err_count: AtomicUsize, - deduplicated_err_count: AtomicUsize, - emitter: Lock>, - continue_after_error: AtomicBool, - delayed_span_bugs: Lock>, + err_count: usize, + deduplicated_err_count: usize, + emitter: Box, + continue_after_error: bool, + delayed_span_bugs: Vec, /// This set contains the `DiagnosticId` of all emitted diagnostics to avoid /// emitting the same diagnostic with extended help (`--teach`) twice, which /// would be uneccessary repetition. - taught_diagnostics: Lock>, + taught_diagnostics: FxHashSet, /// Used to suggest rustc --explain - emitted_diagnostic_codes: Lock>, + emitted_diagnostic_codes: FxHashSet, /// This set contains a hash of every diagnostic that has been emitted by /// this handler. These hashes is used to avoid emitting the same error /// twice. - emitted_diagnostics: Lock>, + emitted_diagnostics: FxHashSet, } fn default_track_diagnostic(_: &Diagnostic) {} @@ -329,7 +333,7 @@ fn default_track_diagnostic(_: &Diagnostic) {} thread_local!(pub static TRACK_DIAGNOSTICS: Cell = Cell::new(default_track_diagnostic)); -#[derive(Default)] +#[derive(Copy, Clone, Default)] pub struct HandlerFlags { /// If false, warning-level lints are suppressed. /// (rustc: see `--allow warnings` and `--cap-lints`) @@ -348,13 +352,13 @@ pub struct HandlerFlags { pub external_macro_backtrace: bool, } -impl Drop for Handler { +impl Drop for HandlerInner { fn drop(&mut self) { - if !self.has_errors() { - let mut bugs = self.delayed_span_bugs.borrow_mut(); + if self.err_count == 0 { + let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new()); let has_bugs = !bugs.is_empty(); - for bug in bugs.drain(..) { - DiagnosticBuilder::new_diagnostic(self, bug).emit(); + for bug in bugs { + self.emit_diagnostic(&bug); } if has_bugs { panic!("no errors encountered even though `delay_span_bug` issued"); @@ -405,19 +409,28 @@ impl Handler { { Handler { flags, - err_count: AtomicUsize::new(0), - deduplicated_err_count: AtomicUsize::new(0), - emitter: Lock::new(e), - continue_after_error: AtomicBool::new(true), - delayed_span_bugs: Lock::new(Vec::new()), - taught_diagnostics: Default::default(), - emitted_diagnostic_codes: Default::default(), - emitted_diagnostics: Default::default(), + inner: Lock::new(HandlerInner { + flags, + err_count: 0, + deduplicated_err_count: 0, + emitter: e, + continue_after_error: true, + delayed_span_bugs: Vec::new(), + taught_diagnostics: Default::default(), + emitted_diagnostic_codes: Default::default(), + emitted_diagnostics: Default::default(), + }), } } pub fn set_continue_after_error(&self, continue_after_error: bool) { - self.continue_after_error.store(continue_after_error, SeqCst); + self.inner.borrow_mut().continue_after_error = continue_after_error; + } + + // This is here to not allow mutation of flags; + // as of this writing it's only used in tests in librustc. + pub fn can_emit_warnings(&self) -> bool { + self.flags.can_emit_warnings } /// Resets the diagnostic error count as well as the cached emitted diagnostics. @@ -425,11 +438,13 @@ impl Handler { /// NOTE: *do not* call this function from rustc. It is only meant to be called from external /// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as /// the overall count of emitted error diagnostics. + // FIXME: this does not clear inner entirely pub fn reset_err_count(&self) { + let mut inner = self.inner.borrow_mut(); // actually frees the underlying memory (which `clear` would not do) - *self.emitted_diagnostics.borrow_mut() = Default::default(); - self.deduplicated_err_count.store(0, SeqCst); - self.err_count.store(0, SeqCst); + inner.emitted_diagnostics = Default::default(); + inner.deduplicated_err_count = 0; + inner.err_count = 0; } pub fn struct_dummy(&self) -> DiagnosticBuilder<'_> { @@ -520,24 +535,6 @@ impl Handler { DiagnosticBuilder::new(self, Level::Fatal, msg) } - fn panic_if_treat_err_as_bug(&self) { - if self.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); - } - } - pub fn span_fatal>(&self, sp: S, msg: &str) -> FatalError { self.emit_diagnostic(Diagnostic::new(Fatal, msg).set_span(sp)); self.abort_if_errors_and_should_abort(); @@ -577,24 +574,10 @@ impl Handler { self.abort_if_errors_and_should_abort(); } pub fn span_bug>(&self, sp: S, msg: &str) -> ! { - self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp)); - self.abort_if_errors_and_should_abort(); - panic!(ExplicitBug); + self.inner.borrow_mut().span_bug(sp, msg) } pub fn delay_span_bug>(&self, sp: S, msg: &str) { - if self.treat_err_as_bug() { - // FIXME: don't abort here if report_delayed_bugs is off - self.span_bug(sp, msg); - } - let mut diagnostic = Diagnostic::new(Level::Bug, msg); - diagnostic.set_span(sp.into()); - self.delay_as_bug(diagnostic); - } - fn delay_as_bug(&self, diagnostic: Diagnostic) { - if self.flags.report_delayed_bugs { - self.emit_diagnostic(&diagnostic); - } - self.delayed_span_bugs.borrow_mut().push(diagnostic); + self.inner.borrow_mut().delay_span_bug(sp, msg) } pub fn span_bug_no_panic>(&self, sp: S, msg: &str) { self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp)); @@ -613,46 +596,28 @@ impl Handler { db } pub fn failure(&self, msg: &str) { - DiagnosticBuilder::new(self, FailureNote, msg).emit() + self.inner.borrow_mut().failure(msg); } pub fn fatal(&self, msg: &str) -> FatalError { - if self.treat_err_as_bug() { - self.bug(msg); - } - DiagnosticBuilder::new(self, Fatal, msg).emit(); - FatalError + self.inner.borrow_mut().fatal(msg) } pub fn err(&self, msg: &str) { - if self.treat_err_as_bug() { - self.bug(msg); - } - let mut db = DiagnosticBuilder::new(self, Error, msg); - db.emit(); + self.inner.borrow_mut().err(msg); } pub fn warn(&self, msg: &str) { 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(); } pub fn bug(&self, msg: &str) -> ! { - let mut db = DiagnosticBuilder::new(self, Bug, msg); - db.emit(); - panic!(ExplicitBug); - } - - fn bump_err_count(&self) { - self.err_count.fetch_add(1, SeqCst); - self.panic_if_treat_err_as_bug(); + self.inner.borrow_mut().bug(msg) } pub fn err_count(&self) -> usize { - self.err_count.load(SeqCst) + self.inner.borrow().err_count } pub fn has_errors(&self) -> bool { @@ -660,7 +625,99 @@ impl Handler { } pub fn print_error_count(&self, registry: &Registry) { - let s = match self.deduplicated_err_count.load(SeqCst) { + self.inner.borrow_mut().print_error_count(registry) + } + + pub fn abort_if_errors(&self) { + self.inner.borrow().abort_if_errors() + } + + pub fn abort_if_errors_and_should_abort(&self) { + self.inner.borrow().abort_if_errors_and_should_abort() + } + + pub fn must_teach(&self, code: &DiagnosticId) -> bool { + self.inner.borrow_mut().must_teach(code) + } + + pub fn force_print_diagnostic(&self, db: Diagnostic) { + self.inner.borrow_mut().force_print_diagnostic(db) + } + + pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) { + self.inner.borrow_mut().emit_diagnostic(diagnostic) + } + + pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { + self.inner.borrow_mut().emit_artifact_notification(path, artifact_type) + } + + pub fn delay_as_bug(&self, diagnostic: Diagnostic) { + self.inner.borrow_mut().delay_as_bug(diagnostic) + } +} + +impl HandlerInner { + /// `true` if we haven't taught a diagnostic with this code already. + /// The caller must then teach the user about such a diagnostic. + /// + /// Used to suppress emitting the same error multiple times with extended explanation when + /// calling `-Zteach`. + fn must_teach(&mut self, code: &DiagnosticId) -> bool { + self.taught_diagnostics.insert(code.clone()) + } + + fn force_print_diagnostic(&mut self, db: Diagnostic) { + self.emitter.emit_diagnostic(&db); + } + + fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) { + if diagnostic.cancelled() { + return; + } + + if diagnostic.level == Warning && !self.flags.can_emit_warnings { + return; + } + + TRACK_DIAGNOSTICS.with(|track_diagnostics| { + track_diagnostics.get()(diagnostic); + }); + + if let Some(ref code) = diagnostic.code { + self.emitted_diagnostic_codes.insert(code.clone()); + } + + let diagnostic_hash = { + use std::hash::Hash; + let mut hasher = StableHasher::new(); + diagnostic.hash(&mut hasher); + hasher.finish() + }; + + // Only emit the diagnostic if we haven't already emitted an equivalent + // one: + if self.emitted_diagnostics.insert(diagnostic_hash) { + self.emitter.emit_diagnostic(diagnostic); + if diagnostic.is_error() { + self.deduplicated_err_count += 1; + } + } + if diagnostic.is_error() { + self.bump_err_count(); + } + } + + fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) { + self.emitter.emit_artifact_notification(path, artifact_type); + } + + fn treat_err_as_bug(&self) -> bool { + self.flags.treat_err_as_bug.map(|c| self.err_count >= c).unwrap_or(false) + } + + fn print_error_count(&mut self, registry: &Registry) { + let s = match self.deduplicated_err_count { 0 => return, 1 => "aborting due to previous error".to_string(), count => format!("aborting due to {} previous errors", count) @@ -671,12 +728,11 @@ impl Handler { 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(); + let can_show_explain = self.emitter.should_show_explain(); + let are_there_diagnostics = !self.emitted_diagnostic_codes.is_empty(); if can_show_explain && are_there_diagnostics { let mut error_codes = self .emitted_diagnostic_codes - .borrow() .iter() .filter_map(|x| match &x { DiagnosticId::Error(s) if registry.find_description(s).is_some() => { @@ -704,70 +760,86 @@ impl Handler { } } - pub fn abort_if_errors_and_should_abort(&self) { - if self.has_errors() && !self.continue_after_error.load(SeqCst) { + fn abort_if_errors_and_should_abort(&self) { + if self.err_count > 0 && !self.continue_after_error { FatalError.raise(); } } - pub fn abort_if_errors(&self) { - if self.has_errors() { + fn abort_if_errors(&self) { + if self.err_count > 0 { FatalError.raise(); } } - /// `true` if we haven't taught a diagnostic with this code already. - /// The caller must then teach the user about such a diagnostic. - /// - /// Used to suppress emitting the same error multiple times with extended explanation when - /// calling `-Zteach`. - pub fn must_teach(&self, code: &DiagnosticId) -> bool { - self.taught_diagnostics.borrow_mut().insert(code.clone()) + fn span_bug>(&mut self, sp: S, msg: &str) -> ! { + self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp)); + self.abort_if_errors_and_should_abort(); + panic!(ExplicitBug); } - pub fn force_print_diagnostic(&self, db: Diagnostic) { - self.emitter.borrow_mut().emit_diagnostic(&db); + fn delay_span_bug>(&mut self, sp: S, msg: &str) { + if self.treat_err_as_bug() { + // FIXME: don't abort here if report_delayed_bugs is off + self.span_bug(sp, msg); + } + let mut diagnostic = Diagnostic::new(Level::Bug, msg); + diagnostic.set_span(sp.into()); + self.delay_as_bug(diagnostic) } - pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) { - if diagnostic.cancelled() { - return; - } + fn failure(&mut self, msg: &str) { + self.emit_diagnostic(&Diagnostic::new(FailureNote, msg)); + } - if diagnostic.level == Warning && !self.flags.can_emit_warnings { - return; + fn fatal(&mut self, msg: &str) -> FatalError { + if self.treat_err_as_bug() { + self.bug(msg); } + self.emit_diagnostic(&Diagnostic::new(Fatal, msg)); + FatalError + } - TRACK_DIAGNOSTICS.with(|track_diagnostics| { - track_diagnostics.get()(diagnostic); - }); - - if let Some(ref code) = diagnostic.code { - self.emitted_diagnostic_codes.borrow_mut().insert(code.clone()); + fn err(&mut self, msg: &str) { + if self.treat_err_as_bug() { + self.bug(msg); } + self.emit_diagnostic(&Diagnostic::new(Error, msg)); + } - let diagnostic_hash = { - use std::hash::Hash; - let mut hasher = StableHasher::new(); - diagnostic.hash(&mut hasher); - hasher.finish() - }; + fn bug(&mut self, msg: &str) -> ! { + self.emit_diagnostic(&Diagnostic::new(Bug, msg)); + panic!(ExplicitBug); + } - // Only emit the diagnostic if we haven't already emitted an equivalent - // one: - if self.emitted_diagnostics.borrow_mut().insert(diagnostic_hash) { - self.emitter.borrow_mut().emit_diagnostic(diagnostic); - if diagnostic.is_error() { - self.deduplicated_err_count.fetch_add(1, SeqCst); - } - } - if diagnostic.is_error() { - self.bump_err_count(); + fn delay_as_bug(&mut self, diagnostic: Diagnostic) { + if self.flags.report_delayed_bugs { + self.emit_diagnostic(&diagnostic); } + self.delayed_span_bugs.push(diagnostic); } - pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { - self.emitter.borrow_mut().emit_artifact_notification(path, artifact_type); + fn bump_err_count(&mut self) { + self.err_count += 1; + self.panic_if_treat_err_as_bug(); + } + + fn panic_if_treat_err_as_bug(&self) { + if self.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); + } } } -- cgit 1.4.1-3-g733a5