diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-03-03 06:20:26 +0100 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-04-17 16:43:30 +0200 |
| commit | bf06a532654515f2ea0536164adb991e8295be56 (patch) | |
| tree | 59c598635aca7a019820b4151009d199a8029147 /src/librustc_errors | |
| parent | 8728c7a726f3e8854f5a80b474d1a8bacab10304 (diff) | |
| download | rust-bf06a532654515f2ea0536164adb991e8295be56.tar.gz rust-bf06a532654515f2ea0536164adb991e8295be56.zip | |
Make Handler more thread-safe
Diffstat (limited to 'src/librustc_errors')
| -rw-r--r-- | src/librustc_errors/lib.rs | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 8d5f9ac93f0..ce3efef08cc 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -33,12 +33,12 @@ use self::Level::*; 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; @@ -262,19 +262,22 @@ pub struct Handler { 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) {} @@ -315,7 +318,7 @@ impl Handler { 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, @@ -326,15 +329,16 @@ impl Handler { }) } - 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()), } } @@ -348,7 +352,7 @@ impl Handler { /// 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); } @@ -568,10 +572,10 @@ impl Handler { 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 { @@ -630,12 +634,13 @@ impl Handler { } } - /// `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) { @@ -651,7 +656,7 @@ impl Handler { }); 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 = { |
