Skip to content

Commit 3973d9f

Browse files
committed
Remove FromDyn::from and add check_dyn_thread_safe
1 parent 15f42e2 commit 3973d9f

File tree

3 files changed

+50
-41
lines changed

3 files changed

+50
-41
lines changed

‎compiler/rustc_data_structures/src/sync.rs‎

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ pub use self::atomic::AtomicU64;
3434
pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard};
3535
#[doc(no_inline)]
3636
pub use self::lock::{Lock, LockGuard, Mode};
37-
pub use self::mode::{is_dyn_thread_safe, FromDyn, set_dyn_thread_safe_mode};
37+
pub use self::mode::{
38+
FromDyn, check_dyn_thread_safe, is_dyn_thread_safe, set_dyn_thread_safe_mode,
39+
};
3840
pub use self::parallel::{
3941
broadcast, par_fns, par_for_each_in, par_join, par_map, parallel_guard, spawn,
4042
try_par_for_each_in,
@@ -72,6 +74,12 @@ mod mode {
7274

7375
static DYN_THREAD_SAFE_MODE: AtomicU8 = AtomicU8::new(UNINITIALIZED);
7476

77+
// Whether thread safety is enabled (due to running under multiple threads).
78+
#[inline]
79+
pub fn check_dyn_thread_safe() -> Option<FromDyn<()>> {
80+
is_dyn_thread_safe().then_some(FromDyn(()))
81+
}
82+
7583
// Whether thread safety is enabled (due to running under multiple threads).
7684
#[inline]
7785
pub fn is_dyn_thread_safe() -> bool {
@@ -106,15 +114,6 @@ mod mode {
106114
pub struct FromDyn<T>(T);
107115

108116
impl<T> FromDyn<T> {
109-
#[inline(always)]
110-
pub fn from(val: T) -> Self {
111-
// Check that `sync::is_dyn_thread_safe()` is true on creation so we can
112-
// implement `Send` and `Sync` for this structure when `T`
113-
// implements `DynSend` and `DynSync` respectively.
114-
assert!(crate::sync::is_dyn_thread_safe());
115-
FromDyn(val)
116-
}
117-
118117
#[inline(always)]
119118
pub fn derive<O>(&self, val: O) -> FromDyn<O> {
120119
// We already did the check for `sync::is_dyn_thread_safe()` when creating `Self`

‎compiler/rustc_data_structures/src/sync/parallel.rs‎

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ where
5757
}
5858

5959
pub fn spawn(func: impl FnOnce() + DynSend + 'static) {
60-
if mode::is_dyn_thread_safe() {
61-
let func = FromDyn::from(func);
60+
if let Some(proof) = mode::check_dyn_thread_safe() {
61+
let func = proof.derive(func);
6262
rustc_thread_pool::spawn(|| {
6363
(func.into_inner())();
6464
});
@@ -73,8 +73,8 @@ pub fn spawn(func: impl FnOnce() + DynSend + 'static) {
7373
/// Use that for the longest running function for better scheduling.
7474
pub fn par_fns(funcs: &mut [&mut (dyn FnMut() + DynSend)]) {
7575
parallel_guard(|guard: &ParallelGuard| {
76-
if mode::is_dyn_thread_safe() {
77-
let funcs = FromDyn::from(funcs);
76+
if let Some(proof) = mode::check_dyn_thread_safe() {
77+
let funcs = proof.derive(funcs);
7878
rustc_thread_pool::scope(|s| {
7979
let Some((first, rest)) = funcs.into_inner().split_at_mut_checked(1) else {
8080
return;
@@ -84,7 +84,7 @@ pub fn par_fns(funcs: &mut [&mut (dyn FnMut() + DynSend)]) {
8484
// order when using a single thread. This ensures the execution order matches
8585
// that of a single threaded rustc.
8686
for f in rest.iter_mut().rev() {
87-
let f = FromDyn::from(f);
87+
let f = proof.derive(f);
8888
s.spawn(|_| {
8989
guard.run(|| (f.into_inner())());
9090
});
@@ -108,13 +108,13 @@ where
108108
A: FnOnce() -> RA + DynSend,
109109
B: FnOnce() -> RB + DynSend,
110110
{
111-
if mode::is_dyn_thread_safe() {
112-
let oper_a = FromDyn::from(oper_a);
113-
let oper_b = FromDyn::from(oper_b);
111+
if let Some(proof) = mode::check_dyn_thread_safe() {
112+
let oper_a = proof.derive(oper_a);
113+
let oper_b = proof.derive(oper_b);
114114
let (a, b) = parallel_guard(|guard| {
115115
rustc_thread_pool::join(
116-
move || guard.run(move || FromDyn::from(oper_a.into_inner()())),
117-
move || guard.run(move || FromDyn::from(oper_b.into_inner()())),
116+
move || guard.run(move || proof.derive(oper_a.into_inner()())),
117+
move || guard.run(move || proof.derive(oper_b.into_inner()())),
118118
)
119119
});
120120
(a.unwrap().into_inner(), b.unwrap().into_inner())
@@ -127,8 +127,9 @@ fn par_slice<I: DynSend>(
127127
items: &mut [I],
128128
guard: &ParallelGuard,
129129
for_each: impl Fn(&mut I) + DynSync + DynSend,
130+
proof: FromDyn<()>,
130131
) {
131-
let for_each = FromDyn::from(for_each);
132+
let for_each = proof.derive(for_each);
132133
let mut items = for_each.derive(items);
133134
rustc_thread_pool::scope(|s| {
134135
let proof = items.derive(());
@@ -150,9 +151,9 @@ pub fn par_for_each_in<I: DynSend, T: IntoIterator<Item = I>>(
150151
for_each: impl Fn(&I) + DynSync + DynSend,
151152
) {
152153
parallel_guard(|guard| {
153-
if mode::is_dyn_thread_safe() {
154+
if let Some(proof) = mode::check_dyn_thread_safe() {
154155
let mut items: Vec<_> = t.into_iter().collect();
155-
par_slice(&mut items, guard, |i| for_each(&*i))
156+
par_slice(&mut items, guard, |i| for_each(&*i), proof)
156157
} else {
157158
t.into_iter().for_each(|i| {
158159
guard.run(|| for_each(&i));
@@ -173,16 +174,21 @@ where
173174
<T as IntoIterator>::Item: DynSend,
174175
{
175176
parallel_guard(|guard| {
176-
if mode::is_dyn_thread_safe() {
177+
if let Some(proof) = mode::check_dyn_thread_safe() {
177178
let mut items: Vec<_> = t.into_iter().collect();
178179

179180
let error = Mutex::new(None);
180181

181-
par_slice(&mut items, guard, |i| {
182-
if let Err(err) = for_each(&*i) {
183-
*error.lock() = Some(err);
184-
}
185-
});
182+
par_slice(
183+
&mut items,
184+
guard,
185+
|i| {
186+
if let Err(err) = for_each(&*i) {
187+
*error.lock() = Some(err);
188+
}
189+
},
190+
proof,
191+
);
186192

187193
if let Some(err) = error.into_inner() { Err(err) } else { Ok(()) }
188194
} else {
@@ -196,15 +202,20 @@ pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterato
196202
map: impl Fn(I) -> R + DynSync + DynSend,
197203
) -> C {
198204
parallel_guard(|guard| {
199-
if mode::is_dyn_thread_safe() {
200-
let map = FromDyn::from(map);
205+
if let Some(proof) = mode::check_dyn_thread_safe() {
206+
let map = proof.derive(map);
201207

202208
let mut items: Vec<(Option<I>, Option<R>)> =
203209
t.into_iter().map(|i| (Some(i), None)).collect();
204210

205-
par_slice(&mut items, guard, |i| {
206-
i.1 = Some(map(i.0.take().unwrap()));
207-
});
211+
par_slice(
212+
&mut items,
213+
guard,
214+
|i| {
215+
i.1 = Some(map(i.0.take().unwrap()));
216+
},
217+
proof,
218+
);
208219

209220
items.into_iter().filter_map(|i| i.1).collect()
210221
} else {
@@ -214,8 +225,8 @@ pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterato
214225
}
215226

216227
pub fn broadcast<R: DynSend>(op: impl Fn(usize) -> R + DynSync) -> Vec<R> {
217-
if mode::is_dyn_thread_safe() {
218-
let op = FromDyn::from(op);
228+
if let Some(proof) = mode::check_dyn_thread_safe() {
229+
let op = proof.derive(op);
219230
let results = rustc_thread_pool::broadcast(|context| op.derive(op(context.index())));
220231
results.into_iter().map(|r| r.into_inner()).collect()
221232
} else {

‎compiler/rustc_interface/src/util.rs‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,14 @@ pub(crate) fn run_in_thread_pool_with_globals<
183183
use std::process;
184184

185185
use rustc_data_structures::defer;
186-
use rustc_data_structures::sync::FromDyn;
187186
use rustc_middle::ty::tls;
188187
use rustc_query_impl::break_query_cycles;
189188

190189
let thread_stack_size = init_stack_size(thread_builder_diag);
191190

192191
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());
193192

194-
if !sync::is_dyn_thread_safe() {
193+
let Some(proof) = sync::check_dyn_thread_safe() else {
195194
return run_in_thread_with_globals(
196195
thread_stack_size,
197196
edition,
@@ -204,9 +203,9 @@ pub(crate) fn run_in_thread_pool_with_globals<
204203
f(current_gcx, jobserver_proxy)
205204
},
206205
);
207-
}
206+
};
208207

209-
let current_gcx = FromDyn::from(CurrentGcx::new());
208+
let current_gcx = proof.derive(CurrentGcx::new());
210209
let current_gcx2 = current_gcx.clone();
211210

212211
let proxy = Proxy::new();
@@ -278,7 +277,7 @@ internal compiler error: query cycle handler thread panicked, aborting process";
278277
// `Send` in the parallel compiler.
279278
rustc_span::create_session_globals_then(edition, extra_symbols, Some(sm_inputs), || {
280279
rustc_span::with_session_globals(|session_globals| {
281-
let session_globals = FromDyn::from(session_globals);
280+
let session_globals = proof.derive(session_globals);
282281
builder
283282
.build_scoped(
284283
// Initialize each new worker thread when created.

0 commit comments

Comments
 (0)