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 --- src/librustc/session/mod.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/librustc') diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 8656ebb2e6d..af9cb5a0941 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1040,6 +1040,7 @@ fn default_emitter( source_map: &Lrc, emitter_dest: Option>, ) -> Box { + let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace; match (sopts.error_format, emitter_dest) { (config::ErrorOutputType::HumanReadable(kind), dst) => { let (short, color_config) = kind.unzip(); @@ -1048,6 +1049,7 @@ fn default_emitter( let emitter = AnnotateSnippetEmitterWriter::new( Some(source_map.clone()), short, + external_macro_backtrace, ); Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing)) } else { @@ -1058,6 +1060,7 @@ fn default_emitter( short, sopts.debugging_opts.teach, sopts.debugging_opts.terminal_width, + external_macro_backtrace, ), Some(dst) => EmitterWriter::new( dst, @@ -1066,6 +1069,7 @@ fn default_emitter( false, // no teach messages when writing to a buffer false, // no colors when writing to a buffer None, // no terminal width + external_macro_backtrace, ), }; Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing)) @@ -1077,6 +1081,7 @@ fn default_emitter( source_map.clone(), pretty, json_rendered, + external_macro_backtrace, ).ui_testing(sopts.debugging_opts.ui_testing), ), (config::ErrorOutputType::Json { pretty, json_rendered }, Some(dst)) => Box::new( @@ -1086,6 +1091,7 @@ fn default_emitter( source_map.clone(), pretty, json_rendered, + external_macro_backtrace, ).ui_testing(sopts.debugging_opts.ui_testing), ), } @@ -1382,10 +1388,10 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); - Box::new(EmitterWriter::stderr(color_config, None, short, false, None)) + Box::new(EmitterWriter::stderr(color_config, None, short, false, None, false)) } config::ErrorOutputType::Json { pretty, json_rendered } => - Box::new(JsonEmitter::basic(pretty, json_rendered)), + 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); @@ -1396,10 +1402,10 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); - Box::new(EmitterWriter::stderr(color_config, None, short, false, None)) + Box::new(EmitterWriter::stderr(color_config, None, short, false, None, false)) } config::ErrorOutputType::Json { pretty, json_rendered } => - Box::new(JsonEmitter::basic(pretty, json_rendered)), + 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); -- 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') 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') 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') 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') 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') 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') 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