use util::common::{duration_to_secs_str, ErrorReported};
use util::common::ProfileQueriesMsg;
-use rustc_data_structures::sync::{Lrc, Lock, LockCell, OneThread, Once, RwLock};
+use rustc_data_structures::sync::{self, Lrc, Lock, LockCell, OneThread, Once, RwLock};
use syntax::ast::NodeId;
use errors::{self, DiagnosticBuilder, DiagnosticId};
}
pub fn teach(&self, code: &DiagnosticId) -> bool {
- self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code)
+ self.opts.debugging_opts.teach && self.parse_sess.span_diagnostic.must_teach(code)
}
/// Are we allowed to use features from the Rust 2018 edition?
let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace;
- let emitter: Box<dyn Emitter> =
+ let emitter: Box<dyn Emitter + sync::Send> =
match (sopts.error_format, emitter_dest) {
(config::ErrorOutputType::HumanReadable(color_config), None) => Box::new(
EmitterWriter::stderr(
}
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
- let emitter: Box<dyn Emitter> = match output {
+ let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, false, false))
}
}
pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
- let emitter: Box<dyn Emitter> = match output {
+ let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config, None, false, false))
}
use rustc::hir::map as hir_map;
use rustc::session::{self, config};
use rustc::session::config::{OutputFilenames, OutputTypes};
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{self, Lrc};
use syntax;
use syntax::ast;
use syntax::abi::Abi;
}
}
-fn errors(msgs: &[&str]) -> (Box<Emitter + Send>, usize) {
+fn errors(msgs: &[&str]) -> (Box<Emitter + sync::Send>, usize) {
let v = msgs.iter().map(|m| m.to_string()).collect();
- (box ExpectErrorEmitter { messages: v } as Box<Emitter + Send>, msgs.len())
+ (box ExpectErrorEmitter { messages: v } as Box<Emitter + sync::Send>, msgs.len())
}
fn test_env<F>(source_string: &str,
- args: (Box<Emitter + Send>, usize),
+ args: (Box<Emitter + sync::Send>, usize),
body: F)
where F: FnOnce(Env)
{
}
fn test_env_impl<F>(source_string: &str,
- (emitter, expected_err_count): (Box<Emitter + Send>, usize),
+ (emitter, expected_err_count): (Box<Emitter + sync::Send>, usize),
body: F)
where F: FnOnce(Env)
{
use emitter::{Emitter, EmitterWriter};
-use rustc_data_structures::sync::{self, Lrc};
+use rustc_data_structures::sync::{self, Lrc, Lock, LockCell};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stable_hasher::StableHasher;
use std::borrow::Cow;
-use std::cell::{RefCell, Cell};
+use std::cell::Cell;
use std::{error, fmt};
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
pub flags: HandlerFlags,
err_count: AtomicUsize,
- emitter: RefCell<Box<Emitter>>,
- continue_after_error: Cell<bool>,
- delayed_span_bug: RefCell<Option<Diagnostic>>,
+ emitter: Lock<Box<Emitter + sync::Send>>,
+ continue_after_error: LockCell<bool>,
+ delayed_span_bug: Lock<Option<Diagnostic>>,
// 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.
- tracked_diagnostic_codes: RefCell<FxHashSet<DiagnosticId>>,
+ taught_diagnostics: Lock<FxHashSet<DiagnosticId>>,
+
+ /// Used to suggest rustc --explain <error code>
+ emitted_diagnostic_codes: Lock<FxHashSet<DiagnosticId>>,
// 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: RefCell<FxHashSet<u128>>,
+ emitted_diagnostics: Lock<FxHashSet<u128>>,
}
fn default_track_diagnostic(_: &Diagnostic) {}
pub fn with_emitter(can_emit_warnings: bool,
treat_err_as_bug: bool,
- e: Box<Emitter>)
+ e: Box<Emitter + sync::Send>)
-> Handler {
Handler::with_emitter_and_flags(
e,
})
}
- pub fn with_emitter_and_flags(e: Box<Emitter>, flags: HandlerFlags) -> Handler {
+ pub fn with_emitter_and_flags(e: Box<Emitter + sync::Send>, flags: HandlerFlags) -> Handler {
Handler {
flags,
err_count: AtomicUsize::new(0),
- emitter: RefCell::new(e),
- continue_after_error: Cell::new(true),
- delayed_span_bug: RefCell::new(None),
- tracked_diagnostic_codes: RefCell::new(FxHashSet()),
- emitted_diagnostics: RefCell::new(FxHashSet()),
+ emitter: Lock::new(e),
+ continue_after_error: LockCell::new(true),
+ delayed_span_bug: Lock::new(None),
+ taught_diagnostics: Lock::new(FxHashSet()),
+ emitted_diagnostic_codes: Lock::new(FxHashSet()),
+ emitted_diagnostics: Lock::new(FxHashSet()),
}
}
/// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
/// the overall count of emitted error diagnostics.
pub fn reset_err_count(&self) {
- self.emitted_diagnostics.replace(FxHashSet());
+ *self.emitted_diagnostics.borrow_mut() = FxHashSet();
self.err_count.store(0, SeqCst);
}
let _ = self.fatal(&s);
let can_show_explain = self.emitter.borrow().should_show_explain();
- let are_there_diagnostics = !self.tracked_diagnostic_codes.borrow().is_empty();
+ let are_there_diagnostics = !self.emitted_diagnostic_codes.borrow().is_empty();
if can_show_explain && are_there_diagnostics {
let mut error_codes =
- self.tracked_diagnostic_codes.borrow()
+ self.emitted_diagnostic_codes.borrow()
.clone()
.into_iter()
.filter_map(|x| match x {
}
}
- /// `true` if a diagnostic with this code has already been emitted in this handler.
+ /// `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 code_emitted(&self, code: &DiagnosticId) -> bool {
- self.tracked_diagnostic_codes.borrow().contains(code)
+ pub fn must_teach(&self, code: &DiagnosticId) -> bool {
+ self.taught_diagnostics.borrow_mut().insert(code.clone())
}
pub fn force_print_db(&self, mut db: DiagnosticBuilder) {
});
if let Some(ref code) = diagnostic.code {
- self.tracked_diagnostic_codes.borrow_mut().insert(code.clone());
+ self.emitted_diagnostic_codes.borrow_mut().insert(code.clone());
}
let diagnostic_hash = {