correct literals for dyn thread safe
This commit is contained in:
parent
9f8ab2a8d3
commit
089a38880b
11 changed files with 48 additions and 41 deletions
|
@ -48,7 +48,7 @@ pub enum TokenTree {
|
||||||
Delimited(DelimSpan, Delimiter, TokenStream),
|
Delimited(DelimSpan, Delimiter, TokenStream),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure all fields of `TokenTree` is `DynSend` and `DynSync`.
|
// Ensure all fields of `TokenTree` are `DynSend` and `DynSync`.
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
fn _dummy()
|
fn _dummy()
|
||||||
where
|
where
|
||||||
|
|
|
@ -8,20 +8,20 @@ cfg_if!(
|
||||||
} else {
|
} else {
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
message = "`{Self}` doesn't implement `DynSend`. \
|
message = "`{Self}` doesn't implement `DynSend`. \
|
||||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Send`"
|
Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`"
|
||||||
)]
|
)]
|
||||||
// This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
|
// This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
|
||||||
// is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a
|
// is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a
|
||||||
// `Send` type in `IntoDyn` will create a `DynSend` type.
|
// `Send` type in `IntoDynSyncSend` will create a `DynSend` type.
|
||||||
pub unsafe auto trait DynSend {}
|
pub unsafe auto trait DynSend {}
|
||||||
|
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
message = "`{Self}` doesn't implement `DynSync`. \
|
message = "`{Self}` doesn't implement `DynSync`. \
|
||||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Sync`"
|
Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Sync`"
|
||||||
)]
|
)]
|
||||||
// This is an auto trait for types which can be shared across threads if `sync::is_dyn_thread_safe()`
|
// This is an auto trait for types which can be shared across threads if `sync::is_dyn_thread_safe()`
|
||||||
// is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a
|
// is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a
|
||||||
// `Sync` type in `IntoDyn` will create a `DynSync` type.
|
// `Sync` type in `IntoDynSyncSend` will create a `DynSync` type.
|
||||||
pub unsafe auto trait DynSync {}
|
pub unsafe auto trait DynSync {}
|
||||||
|
|
||||||
// Same with `Sync` and `Send`.
|
// Same with `Sync` and `Send`.
|
||||||
|
@ -234,15 +234,18 @@ impl<T> const std::ops::Deref for FromDyn<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A wrapper to convert a struct that is already a `Send` or `Sync` into
|
||||||
|
// an instance of `DynSend` and `DynSync`, since the compiler cannot infer
|
||||||
|
// it automatically in some cases. (e.g. Box<dyn Send / Sync>)
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct IntoDyn<T: ?Sized>(pub T);
|
pub struct IntoDynSyncSend<T: ?Sized>(pub T);
|
||||||
|
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
unsafe impl<T: ?Sized + Send> DynSend for IntoDyn<T> {}
|
unsafe impl<T: ?Sized + Send> DynSend for IntoDynSyncSend<T> {}
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
unsafe impl<T: ?Sized + Sync> DynSync for IntoDyn<T> {}
|
unsafe impl<T: ?Sized + Sync> DynSync for IntoDynSyncSend<T> {}
|
||||||
|
|
||||||
impl<T> const std::ops::Deref for IntoDyn<T> {
|
impl<T> const std::ops::Deref for IntoDynSyncSend<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
|
@ -250,7 +253,7 @@ impl<T> const std::ops::Deref for IntoDyn<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> const std::ops::DerefMut for IntoDyn<T> {
|
impl<T> const std::ops::DerefMut for IntoDynSyncSend<T> {
|
||||||
fn deref_mut(&mut self) -> &mut T {
|
fn deref_mut(&mut self) -> &mut T {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,25 +61,25 @@ mod mode {
|
||||||
use std::sync::atomic::AtomicU8;
|
use std::sync::atomic::AtomicU8;
|
||||||
|
|
||||||
const UNINITIALIZED: u8 = 0;
|
const UNINITIALIZED: u8 = 0;
|
||||||
const DYN_NOT_SYNC: u8 = 1;
|
const DYN_NOT_THREAD_SAFE: u8 = 1;
|
||||||
const DYN_SYNC: u8 = 2;
|
const DYN_THREAD_SAFE: u8 = 2;
|
||||||
|
|
||||||
static DYN_SYNC_MODE: AtomicU8 = AtomicU8::new(UNINITIALIZED);
|
static DYN_THREAD_SAFE_MODE: AtomicU8 = AtomicU8::new(UNINITIALIZED);
|
||||||
|
|
||||||
// Weather control thread safety dynamically
|
// Whether thread safety is enabled (due to running under multiple threads).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_dyn_thread_safe() -> bool {
|
pub fn is_dyn_thread_safe() -> bool {
|
||||||
match DYN_SYNC_MODE.load(Ordering::Relaxed) {
|
match DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) {
|
||||||
DYN_NOT_SYNC => false,
|
DYN_NOT_THREAD_SAFE => false,
|
||||||
DYN_SYNC => true,
|
DYN_THREAD_SAFE => true,
|
||||||
_ => panic!("uninitialized parallel mode!"),
|
_ => panic!("uninitialized dyn_thread_safe mode!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only set by the `-Z threads` compile option
|
// Only set by the `-Z threads` compile option
|
||||||
pub fn set_dyn_thread_safe_mode(parallel: bool) {
|
pub fn set_dyn_thread_safe_mode(mode: bool) {
|
||||||
let set: u8 = if parallel { DYN_SYNC } else { DYN_NOT_SYNC };
|
let set: u8 = if mode { DYN_THREAD_SAFE } else { DYN_NOT_THREAD_SAFE };
|
||||||
let previous = DYN_SYNC_MODE.compare_exchange(
|
let previous = DYN_THREAD_SAFE_MODE.compare_exchange(
|
||||||
UNINITIALIZED,
|
UNINITIALIZED,
|
||||||
set,
|
set,
|
||||||
Ordering::Relaxed,
|
Ordering::Relaxed,
|
||||||
|
@ -401,7 +401,7 @@ cfg_if! {
|
||||||
if rustc_data_structures::sync::is_dyn_thread_safe() {
|
if rustc_data_structures::sync::is_dyn_thread_safe() {
|
||||||
// Reverse the order of the later blocks since Rayon executes them in reverse order
|
// Reverse the order of the later blocks since Rayon executes them in reverse order
|
||||||
// when using a single thread. This ensures the execution order matches that
|
// when using a single thread. This ensures the execution order matches that
|
||||||
// of a single threaded rustc
|
// of a single threaded rustc.
|
||||||
parallel!(impl $fblock [] [$($blocks),*]);
|
parallel!(impl $fblock [] [$($blocks),*]);
|
||||||
} else {
|
} else {
|
||||||
// We catch panics here ensuring that all the blocks execute.
|
// We catch panics here ensuring that all the blocks execute.
|
||||||
|
|
|
@ -255,8 +255,8 @@ fn run_compiler(
|
||||||
|
|
||||||
let sopts = config::build_session_options(&matches);
|
let sopts = config::build_session_options(&matches);
|
||||||
|
|
||||||
// Set parallel mode before thread pool creation as the session will already create locks.
|
// Set parallel mode before thread pool creation, which will create `Lock`s.
|
||||||
interface::set_parallel_mode(&sopts.unstable_opts);
|
interface::set_thread_safe_mode(&sopts.unstable_opts);
|
||||||
|
|
||||||
if let Some(ref code) = matches.opt_str("explain") {
|
if let Some(ref code) = matches.opt_str("explain") {
|
||||||
handle_explain(diagnostics_registry(), code, sopts.error_format);
|
handle_explain(diagnostics_registry(), code, sopts.error_format);
|
||||||
|
|
|
@ -11,7 +11,7 @@ extern crate tracing;
|
||||||
use fluent_bundle::FluentResource;
|
use fluent_bundle::FluentResource;
|
||||||
use fluent_syntax::parser::ParserError;
|
use fluent_syntax::parser::ParserError;
|
||||||
use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
|
use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
|
||||||
use rustc_data_structures::sync::{IntoDyn, Lrc};
|
use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
|
||||||
use rustc_fluent_macro::fluent_messages;
|
use rustc_fluent_macro::fluent_messages;
|
||||||
use rustc_macros::{Decodable, Encodable};
|
use rustc_macros::{Decodable, Encodable};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -38,16 +38,16 @@ pub use unic_langid::{langid, LanguageIdentifier};
|
||||||
fluent_messages! { "../messages.ftl" }
|
fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
pub type FluentBundle =
|
pub type FluentBundle =
|
||||||
IntoDyn<fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>>;
|
IntoDynSyncSend<fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>>;
|
||||||
|
|
||||||
#[cfg(not(parallel_compiler))]
|
#[cfg(not(parallel_compiler))]
|
||||||
fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
|
fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
|
||||||
IntoDyn(fluent_bundle::bundle::FluentBundle::new(locales))
|
IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new(locales))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
|
fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
|
||||||
IntoDyn(fluent_bundle::bundle::FluentBundle::new_concurrent(locales))
|
IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new_concurrent(locales))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -32,7 +32,7 @@ use emitter::{is_case_difference, Emitter, EmitterWriter};
|
||||||
use registry::Registry;
|
use registry::Registry;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
|
||||||
use rustc_data_structures::sync::{self, IntoDyn, Lock, Lrc};
|
use rustc_data_structures::sync::{self, IntoDynSyncSend, Lock, Lrc};
|
||||||
use rustc_data_structures::AtomicRef;
|
use rustc_data_structures::AtomicRef;
|
||||||
pub use rustc_error_messages::{
|
pub use rustc_error_messages::{
|
||||||
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
|
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
|
||||||
|
@ -409,7 +409,7 @@ struct HandlerInner {
|
||||||
err_count: usize,
|
err_count: usize,
|
||||||
warn_count: usize,
|
warn_count: usize,
|
||||||
deduplicated_err_count: usize,
|
deduplicated_err_count: usize,
|
||||||
emitter: IntoDyn<Box<dyn Emitter + sync::Send>>,
|
emitter: IntoDynSyncSend<Box<dyn Emitter + sync::Send>>,
|
||||||
delayed_span_bugs: Vec<DelayedDiagnostic>,
|
delayed_span_bugs: Vec<DelayedDiagnostic>,
|
||||||
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
|
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
|
||||||
/// This flag indicates that an expected diagnostic was emitted and suppressed.
|
/// This flag indicates that an expected diagnostic was emitted and suppressed.
|
||||||
|
@ -605,7 +605,7 @@ impl Handler {
|
||||||
warn_count: 0,
|
warn_count: 0,
|
||||||
deduplicated_err_count: 0,
|
deduplicated_err_count: 0,
|
||||||
deduplicated_warn_count: 0,
|
deduplicated_warn_count: 0,
|
||||||
emitter: IntoDyn(emitter),
|
emitter: IntoDynSyncSend(emitter),
|
||||||
delayed_span_bugs: Vec::new(),
|
delayed_span_bugs: Vec::new(),
|
||||||
delayed_good_path_bugs: Vec::new(),
|
delayed_good_path_bugs: Vec::new(),
|
||||||
suppressed_expected_diag: false,
|
suppressed_expected_diag: false,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::error::{TranslateError, TranslateErrorKind};
|
||||||
use crate::fluent_bundle::*;
|
use crate::fluent_bundle::*;
|
||||||
use crate::translation::Translate;
|
use crate::translation::Translate;
|
||||||
use crate::FluentBundle;
|
use crate::FluentBundle;
|
||||||
use rustc_data_structures::sync::{IntoDyn, Lrc};
|
use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
|
||||||
use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError};
|
use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError};
|
||||||
use rustc_error_messages::langid;
|
use rustc_error_messages::langid;
|
||||||
use rustc_error_messages::DiagnosticMessage;
|
use rustc_error_messages::DiagnosticMessage;
|
||||||
|
@ -28,11 +28,13 @@ fn make_dummy(ftl: &'static str) -> Dummy {
|
||||||
|
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
let mut bundle: FluentBundle =
|
let mut bundle: FluentBundle =
|
||||||
IntoDyn(crate::fluent_bundle::bundle::FluentBundle::new_concurrent(vec![langid_en]));
|
IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new_concurrent(vec![
|
||||||
|
langid_en,
|
||||||
|
]));
|
||||||
|
|
||||||
#[cfg(not(parallel_compiler))]
|
#[cfg(not(parallel_compiler))]
|
||||||
let mut bundle: FluentBundle =
|
let mut bundle: FluentBundle =
|
||||||
IntoDyn(crate::fluent_bundle::bundle::FluentBundle::new(vec![langid_en]));
|
IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new(vec![langid_en]));
|
||||||
|
|
||||||
bundle.add_resource(resource).expect("Failed to add FTL resources to the bundle.");
|
bundle.add_resource(resource).expect("Failed to add FTL resources to the bundle.");
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(rustc::bad_opt_access)]
|
#[allow(rustc::bad_opt_access)]
|
||||||
pub fn set_parallel_mode(sopts: &config::UnstableOptions) {
|
pub fn set_thread_safe_mode(sopts: &config::UnstableOptions) {
|
||||||
rustc_data_structures::sync::set_dyn_thread_safe_mode(sopts.threads > 1);
|
rustc_data_structures::sync::set_dyn_thread_safe_mode(sopts.threads > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ impl<'a, T: Copy> IntoIterator for &'a List<T> {
|
||||||
|
|
||||||
unsafe impl<T: Sync> Sync for List<T> {}
|
unsafe impl<T: Sync> Sync for List<T> {}
|
||||||
|
|
||||||
// We need this since `List` uses extern type `OpaqueListContents`
|
// We need this since `List` uses extern type `OpaqueListContents`.
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
use rustc_data_structures::sync::DynSync;
|
use rustc_data_structures::sync::DynSync;
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
|
|
|
@ -14,7 +14,9 @@ pub use crate::*;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stable_hasher::{Hash128, Hash64, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, Hash64, StableHasher};
|
||||||
use rustc_data_structures::sync::{AtomicU32, IntoDyn, Lrc, MappedReadGuard, ReadGuard, RwLock};
|
use rustc_data_structures::sync::{
|
||||||
|
AtomicU32, IntoDynSyncSend, Lrc, MappedReadGuard, ReadGuard, RwLock,
|
||||||
|
};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::path::{self, Path, PathBuf};
|
use std::path::{self, Path, PathBuf};
|
||||||
|
@ -176,7 +178,7 @@ pub struct SourceMap {
|
||||||
used_address_space: AtomicU32,
|
used_address_space: AtomicU32,
|
||||||
|
|
||||||
files: RwLock<SourceMapFiles>,
|
files: RwLock<SourceMapFiles>,
|
||||||
file_loader: IntoDyn<Box<dyn FileLoader + Sync + Send>>,
|
file_loader: IntoDynSyncSend<Box<dyn FileLoader + Sync + Send>>,
|
||||||
// This is used to apply the file path remapping as specified via
|
// This is used to apply the file path remapping as specified via
|
||||||
// `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
|
// `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
|
||||||
path_mapping: FilePathMapping,
|
path_mapping: FilePathMapping,
|
||||||
|
@ -202,7 +204,7 @@ impl SourceMap {
|
||||||
SourceMap {
|
SourceMap {
|
||||||
used_address_space: AtomicU32::new(0),
|
used_address_space: AtomicU32::new(0),
|
||||||
files: Default::default(),
|
files: Default::default(),
|
||||||
file_loader: IntoDyn(file_loader),
|
file_loader: IntoDynSyncSend(file_loader),
|
||||||
path_mapping,
|
path_mapping,
|
||||||
hash_kind,
|
hash_kind,
|
||||||
}
|
}
|
||||||
|
|
|
@ -730,8 +730,8 @@ fn main_args(at_args: &[String]) -> MainResult {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set parallel mode early as the error handler will already create locks.
|
// Set parallel mode before error handler creation, which will create `Lock`s.
|
||||||
interface::set_parallel_mode(&options.unstable_opts);
|
interface::set_thread_safe_mode(&options.unstable_opts);
|
||||||
|
|
||||||
let diag = core::new_handler(
|
let diag = core::new_handler(
|
||||||
options.error_format,
|
options.error_format,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue