about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src/sync
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@users.noreply.github.com>2024-11-28 06:54:16 +0000
committerGitHub <noreply@github.com>2024-11-28 06:54:16 +0000
commit8cf30c235619f60c0a0f0a0779bd17e7e70bf0fb (patch)
tree564950531f457ebbe2a114e486cb2c8c72bf9ed0 /compiler/rustc_data_structures/src/sync
parent4e3354ef925d9711c125470097643236c3a983d0 (diff)
parent1a435ed7edc19812c29006701b0106a0d0802542 (diff)
downloadrust-8cf30c235619f60c0a0f0a0779bd17e7e70bf0fb.tar.gz
rust-8cf30c235619f60c0a0f0a0779bd17e7e70bf0fb.zip
Merge pull request #18566 from lnicola/sync-from-rust
minor: Sync from downstream
Diffstat (limited to 'compiler/rustc_data_structures/src/sync')
-rw-r--r--compiler/rustc_data_structures/src/sync/freeze.rs5
-rw-r--r--compiler/rustc_data_structures/src/sync/lock.rs309
-rw-r--r--compiler/rustc_data_structures/src/sync/parallel.rs236
-rw-r--r--compiler/rustc_data_structures/src/sync/vec.rs21
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs44
5 files changed, 230 insertions, 385 deletions
diff --git a/compiler/rustc_data_structures/src/sync/freeze.rs b/compiler/rustc_data_structures/src/sync/freeze.rs
index fad5f583d1c..5236c9fe156 100644
--- a/compiler/rustc_data_structures/src/sync/freeze.rs
+++ b/compiler/rustc_data_structures/src/sync/freeze.rs
@@ -5,9 +5,7 @@ use std::ops::{Deref, DerefMut};
 use std::ptr::NonNull;
 use std::sync::atomic::Ordering;
 
-use crate::sync::{AtomicBool, ReadGuard, RwLock, WriteGuard};
-#[cfg(parallel_compiler)]
-use crate::sync::{DynSend, DynSync};
+use crate::sync::{AtomicBool, DynSend, DynSync, ReadGuard, RwLock, WriteGuard};
 
 /// A type which allows mutation using a lock until
 /// the value is frozen and can be accessed lock-free.
@@ -22,7 +20,6 @@ pub struct FreezeLock<T> {
     lock: RwLock<()>,
 }
 
-#[cfg(parallel_compiler)]
 unsafe impl<T: DynSync + DynSend> DynSync for FreezeLock<T> {}
 
 impl<T> FreezeLock<T> {
diff --git a/compiler/rustc_data_structures/src/sync/lock.rs b/compiler/rustc_data_structures/src/sync/lock.rs
index 012ee7f900e..2ccf06ccd4f 100644
--- a/compiler/rustc_data_structures/src/sync/lock.rs
+++ b/compiler/rustc_data_structures/src/sync/lock.rs
@@ -1,236 +1,177 @@
 //! This module implements a lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
 //! It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync` traits.
-//!
-//! When `cfg(parallel_compiler)` is not set, the lock is instead a wrapper around `RefCell`.
 
 #![allow(dead_code)]
 
 use std::fmt;
 
-#[cfg(parallel_compiler)]
-pub use maybe_sync::*;
-#[cfg(not(parallel_compiler))]
-pub use no_sync::*;
-
 #[derive(Clone, Copy, PartialEq)]
 pub enum Mode {
     NoSync,
     Sync,
 }
 
-mod maybe_sync {
-    use std::cell::{Cell, UnsafeCell};
-    use std::intrinsics::unlikely;
-    use std::marker::PhantomData;
-    use std::mem::ManuallyDrop;
-    use std::ops::{Deref, DerefMut};
+use std::cell::{Cell, UnsafeCell};
+use std::intrinsics::unlikely;
+use std::marker::PhantomData;
+use std::mem::ManuallyDrop;
+use std::ops::{Deref, DerefMut};
 
-    use parking_lot::RawMutex;
-    use parking_lot::lock_api::RawMutex as _;
+use parking_lot::RawMutex;
+use parking_lot::lock_api::RawMutex as _;
 
-    use super::Mode;
-    use crate::sync::mode;
-    #[cfg(parallel_compiler)]
-    use crate::sync::{DynSend, DynSync};
+use crate::sync::{DynSend, DynSync, mode};
 
-    /// A guard holding mutable access to a `Lock` which is in a locked state.
-    #[must_use = "if unused the Lock will immediately unlock"]
-    pub struct LockGuard<'a, T> {
-        lock: &'a Lock<T>,
-        marker: PhantomData<&'a mut T>,
+/// A guard holding mutable access to a `Lock` which is in a locked state.
+#[must_use = "if unused the Lock will immediately unlock"]
+pub struct LockGuard<'a, T> {
+    lock: &'a Lock<T>,
+    marker: PhantomData<&'a mut T>,
 
-        /// The synchronization mode of the lock. This is explicitly passed to let LLVM relate it
-        /// to the original lock operation.
-        mode: Mode,
-    }
+    /// The synchronization mode of the lock. This is explicitly passed to let LLVM relate it
+    /// to the original lock operation.
+    mode: Mode,
+}
 
-    impl<'a, T: 'a> Deref for LockGuard<'a, T> {
-        type Target = T;
-        #[inline]
-        fn deref(&self) -> &T {
-            // SAFETY: We have shared access to the mutable access owned by this type,
-            // so we can give out a shared reference.
-            unsafe { &*self.lock.data.get() }
-        }
+impl<'a, T: 'a> Deref for LockGuard<'a, T> {
+    type Target = T;
+    #[inline]
+    fn deref(&self) -> &T {
+        // SAFETY: We have shared access to the mutable access owned by this type,
+        // so we can give out a shared reference.
+        unsafe { &*self.lock.data.get() }
     }
+}
 
-    impl<'a, T: 'a> DerefMut for LockGuard<'a, T> {
-        #[inline]
-        fn deref_mut(&mut self) -> &mut T {
-            // SAFETY: We have mutable access to the data so we can give out a mutable reference.
-            unsafe { &mut *self.lock.data.get() }
-        }
+impl<'a, T: 'a> DerefMut for LockGuard<'a, T> {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut T {
+        // SAFETY: We have mutable access to the data so we can give out a mutable reference.
+        unsafe { &mut *self.lock.data.get() }
     }
+}
 
-    impl<'a, T: 'a> Drop for LockGuard<'a, T> {
-        #[inline]
-        fn drop(&mut self) {
-            // SAFETY (union access): We get `self.mode` from the lock operation so it is consistent
-            // with the `lock.mode` state. This means we access the right union fields.
-            match self.mode {
-                Mode::NoSync => {
-                    let cell = unsafe { &self.lock.mode_union.no_sync };
-                    debug_assert!(cell.get());
-                    cell.set(false);
-                }
-                // SAFETY (unlock): We know that the lock is locked as this type is a proof of that.
-                Mode::Sync => unsafe { self.lock.mode_union.sync.unlock() },
+impl<'a, T: 'a> Drop for LockGuard<'a, T> {
+    #[inline]
+    fn drop(&mut self) {
+        // SAFETY (union access): We get `self.mode` from the lock operation so it is consistent
+        // with the `lock.mode` state. This means we access the right union fields.
+        match self.mode {
+            Mode::NoSync => {
+                let cell = unsafe { &self.lock.mode_union.no_sync };
+                debug_assert!(cell.get());
+                cell.set(false);
             }
+            // SAFETY (unlock): We know that the lock is locked as this type is a proof of that.
+            Mode::Sync => unsafe { self.lock.mode_union.sync.unlock() },
         }
     }
+}
 
-    union ModeUnion {
-        /// Indicates if the cell is locked. Only used if `Lock.mode` is `NoSync`.
-        no_sync: ManuallyDrop<Cell<bool>>,
+union ModeUnion {
+    /// Indicates if the cell is locked. Only used if `Lock.mode` is `NoSync`.
+    no_sync: ManuallyDrop<Cell<bool>>,
 
-        /// A lock implementation that's only used if `Lock.mode` is `Sync`.
-        sync: ManuallyDrop<RawMutex>,
-    }
+    /// A lock implementation that's only used if `Lock.mode` is `Sync`.
+    sync: ManuallyDrop<RawMutex>,
+}
 
-    /// The value representing a locked state for the `Cell`.
-    const LOCKED: bool = true;
+/// The value representing a locked state for the `Cell`.
+const LOCKED: bool = true;
 
-    /// A lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
-    /// It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync`.
-    pub struct Lock<T> {
-        /// Indicates if synchronization is used via `mode_union.sync` if it's `Sync`, or if a
-        /// not thread safe cell is used via `mode_union.no_sync` if it's `NoSync`.
-        /// This is set on initialization and never changed.
-        mode: Mode,
+/// A lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
+/// It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync`.
+pub struct Lock<T> {
+    /// Indicates if synchronization is used via `mode_union.sync` if it's `Sync`, or if a
+    /// not thread safe cell is used via `mode_union.no_sync` if it's `NoSync`.
+    /// This is set on initialization and never changed.
+    mode: Mode,
 
-        mode_union: ModeUnion,
-        data: UnsafeCell<T>,
-    }
+    mode_union: ModeUnion,
+    data: UnsafeCell<T>,
+}
 
-    impl<T> Lock<T> {
-        #[inline(always)]
-        pub fn new(inner: T) -> Self {
-            let (mode, mode_union) = if unlikely(mode::might_be_dyn_thread_safe()) {
-                // Create the lock with synchronization enabled using the `RawMutex` type.
-                (Mode::Sync, ModeUnion { sync: ManuallyDrop::new(RawMutex::INIT) })
-            } else {
-                // Create the lock with synchronization disabled.
-                (Mode::NoSync, ModeUnion { no_sync: ManuallyDrop::new(Cell::new(!LOCKED)) })
-            };
-            Lock { mode, mode_union, data: UnsafeCell::new(inner) }
-        }
+impl<T> Lock<T> {
+    #[inline(always)]
+    pub fn new(inner: T) -> Self {
+        let (mode, mode_union) = if unlikely(mode::might_be_dyn_thread_safe()) {
+            // Create the lock with synchronization enabled using the `RawMutex` type.
+            (Mode::Sync, ModeUnion { sync: ManuallyDrop::new(RawMutex::INIT) })
+        } else {
+            // Create the lock with synchronization disabled.
+            (Mode::NoSync, ModeUnion { no_sync: ManuallyDrop::new(Cell::new(!LOCKED)) })
+        };
+        Lock { mode, mode_union, data: UnsafeCell::new(inner) }
+    }
 
-        #[inline(always)]
-        pub fn into_inner(self) -> T {
-            self.data.into_inner()
-        }
+    #[inline(always)]
+    pub fn into_inner(self) -> T {
+        self.data.into_inner()
+    }
 
-        #[inline(always)]
-        pub fn get_mut(&mut self) -> &mut T {
-            self.data.get_mut()
-        }
+    #[inline(always)]
+    pub fn get_mut(&mut self) -> &mut T {
+        self.data.get_mut()
+    }
 
-        #[inline(always)]
-        pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
-            let mode = self.mode;
-            // SAFETY: This is safe since the union fields are used in accordance with `self.mode`.
-            match mode {
-                Mode::NoSync => {
-                    let cell = unsafe { &self.mode_union.no_sync };
-                    let was_unlocked = cell.get() != LOCKED;
-                    if was_unlocked {
-                        cell.set(LOCKED);
-                    }
-                    was_unlocked
+    #[inline(always)]
+    pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
+        let mode = self.mode;
+        // SAFETY: This is safe since the union fields are used in accordance with `self.mode`.
+        match mode {
+            Mode::NoSync => {
+                let cell = unsafe { &self.mode_union.no_sync };
+                let was_unlocked = cell.get() != LOCKED;
+                if was_unlocked {
+                    cell.set(LOCKED);
                 }
-                Mode::Sync => unsafe { self.mode_union.sync.try_lock() },
+                was_unlocked
             }
-            .then(|| LockGuard { lock: self, marker: PhantomData, mode })
+            Mode::Sync => unsafe { self.mode_union.sync.try_lock() },
         }
+        .then(|| LockGuard { lock: self, marker: PhantomData, mode })
+    }
 
-        /// This acquires the lock assuming synchronization is in a specific mode.
-        ///
-        /// Safety
-        /// This method must only be called with `Mode::Sync` if `might_be_dyn_thread_safe` was
-        /// true on lock creation.
-        #[inline(always)]
+    /// This acquires the lock assuming synchronization is in a specific mode.
+    ///
+    /// Safety
+    /// This method must only be called with `Mode::Sync` if `might_be_dyn_thread_safe` was
+    /// true on lock creation.
+    #[inline(always)]
+    #[track_caller]
+    pub unsafe fn lock_assume(&self, mode: Mode) -> LockGuard<'_, T> {
+        #[inline(never)]
         #[track_caller]
-        pub unsafe fn lock_assume(&self, mode: Mode) -> LockGuard<'_, T> {
-            #[inline(never)]
-            #[track_caller]
-            #[cold]
-            fn lock_held() -> ! {
-                panic!("lock was already held")
-            }
+        #[cold]
+        fn lock_held() -> ! {
+            panic!("lock was already held")
+        }
 
-            // SAFETY: This is safe since the union fields are used in accordance with `mode`
-            // which also must match `self.mode` due to the safety precondition.
-            unsafe {
-                match mode {
-                    Mode::NoSync => {
-                        if unlikely(self.mode_union.no_sync.replace(LOCKED) == LOCKED) {
-                            lock_held()
-                        }
+        // SAFETY: This is safe since the union fields are used in accordance with `mode`
+        // which also must match `self.mode` due to the safety precondition.
+        unsafe {
+            match mode {
+                Mode::NoSync => {
+                    if unlikely(self.mode_union.no_sync.replace(LOCKED) == LOCKED) {
+                        lock_held()
                     }
-                    Mode::Sync => self.mode_union.sync.lock(),
                 }
+                Mode::Sync => self.mode_union.sync.lock(),
             }
-            LockGuard { lock: self, marker: PhantomData, mode }
-        }
-
-        #[inline(always)]
-        #[track_caller]
-        pub fn lock(&self) -> LockGuard<'_, T> {
-            unsafe { self.lock_assume(self.mode) }
         }
+        LockGuard { lock: self, marker: PhantomData, mode }
     }
 
-    #[cfg(parallel_compiler)]
-    unsafe impl<T: DynSend> DynSend for Lock<T> {}
-    #[cfg(parallel_compiler)]
-    unsafe impl<T: DynSend> DynSync for Lock<T> {}
-}
-
-mod no_sync {
-    use std::cell::RefCell;
-    #[doc(no_inline)]
-    pub use std::cell::RefMut as LockGuard;
-
-    use super::Mode;
-
-    pub struct Lock<T>(RefCell<T>);
-
-    impl<T> Lock<T> {
-        #[inline(always)]
-        pub fn new(inner: T) -> Self {
-            Lock(RefCell::new(inner))
-        }
-
-        #[inline(always)]
-        pub fn into_inner(self) -> T {
-            self.0.into_inner()
-        }
-
-        #[inline(always)]
-        pub fn get_mut(&mut self) -> &mut T {
-            self.0.get_mut()
-        }
-
-        #[inline(always)]
-        pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
-            self.0.try_borrow_mut().ok()
-        }
-
-        #[inline(always)]
-        #[track_caller]
-        // This is unsafe to match the API for the `parallel_compiler` case.
-        pub unsafe fn lock_assume(&self, _mode: Mode) -> LockGuard<'_, T> {
-            self.0.borrow_mut()
-        }
-
-        #[inline(always)]
-        #[track_caller]
-        pub fn lock(&self) -> LockGuard<'_, T> {
-            self.0.borrow_mut()
-        }
+    #[inline(always)]
+    #[track_caller]
+    pub fn lock(&self) -> LockGuard<'_, T> {
+        unsafe { self.lock_assume(self.mode) }
     }
 }
 
+unsafe impl<T: DynSend> DynSend for Lock<T> {}
+unsafe impl<T: DynSend> DynSync for Lock<T> {}
+
 impl<T> Lock<T> {
     #[inline(always)]
     #[track_caller]
diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs
index c7df19842d6..1ba631b8623 100644
--- a/compiler/rustc_data_structures/src/sync/parallel.rs
+++ b/compiler/rustc_data_structures/src/sync/parallel.rs
@@ -6,14 +6,11 @@
 use std::any::Any;
 use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
 
-#[cfg(not(parallel_compiler))]
-pub use disabled::*;
-#[cfg(parallel_compiler)]
-pub use enabled::*;
 use parking_lot::Mutex;
+use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
 
 use crate::FatalErrorMarker;
-use crate::sync::IntoDynSyncSend;
+use crate::sync::{DynSend, DynSync, FromDyn, IntoDynSyncSend, mode};
 
 /// A guard used to hold panics that occur during a parallel section to later by unwound.
 /// This is used for the parallel compiler to prevent fatal errors from non-deterministically
@@ -49,65 +46,23 @@ pub fn parallel_guard<R>(f: impl FnOnce(&ParallelGuard) -> R) -> R {
     ret
 }
 
-mod disabled {
-    use crate::sync::parallel_guard;
-
-    #[macro_export]
-    #[cfg(not(parallel_compiler))]
-    macro_rules! parallel {
-        ($($blocks:block),*) => {{
-            $crate::sync::parallel_guard(|guard| {
-                $(guard.run(|| $blocks);)*
-            });
-        }}
-    }
-
-    pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
-    where
-        A: FnOnce() -> RA,
-        B: FnOnce() -> RB,
-    {
-        let (a, b) = parallel_guard(|guard| {
-            let a = guard.run(oper_a);
-            let b = guard.run(oper_b);
-            (a, b)
-        });
-        (a.unwrap(), b.unwrap())
-    }
-
-    pub fn par_for_each_in<T: IntoIterator>(t: T, mut for_each: impl FnMut(T::Item)) {
-        parallel_guard(|guard| {
-            t.into_iter().for_each(|i| {
-                guard.run(|| for_each(i));
-            });
-        })
-    }
-
-    pub fn try_par_for_each_in<T: IntoIterator, E>(
-        t: T,
-        mut for_each: impl FnMut(T::Item) -> Result<(), E>,
-    ) -> Result<(), E> {
-        parallel_guard(|guard| {
-            t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
-        })
-    }
-
-    pub fn par_map<T: IntoIterator, R, C: FromIterator<R>>(
-        t: T,
-        mut map: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item) -> R,
-    ) -> C {
-        parallel_guard(|guard| t.into_iter().filter_map(|i| guard.run(|| map(i))).collect())
-    }
+pub fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
+where
+    A: FnOnce() -> RA,
+    B: FnOnce() -> RB,
+{
+    let (a, b) = parallel_guard(|guard| {
+        let a = guard.run(oper_a);
+        let b = guard.run(oper_b);
+        (a, b)
+    });
+    (a.unwrap(), b.unwrap())
 }
 
-#[cfg(parallel_compiler)]
-mod enabled {
-    use crate::sync::{DynSend, DynSync, FromDyn, mode, parallel_guard};
-
-    /// Runs a list of blocks in parallel. The first block is executed immediately on
-    /// the current thread. Use that for the longest running block.
-    #[macro_export]
-    macro_rules! parallel {
+/// Runs a list of blocks in parallel. The first block is executed immediately on
+/// the current thread. Use that for the longest running block.
+#[macro_export]
+macro_rules! parallel {
         (impl $fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => {
             parallel!(impl $fblock [$block, $($c,)*] [$($rest),*])
         };
@@ -139,92 +94,89 @@ mod enabled {
         };
     }
 
-    // This function only works when `mode::is_dyn_thread_safe()`.
-    pub fn scope<'scope, OP, R>(op: OP) -> R
-    where
-        OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
-        R: DynSend,
-    {
-        let op = FromDyn::from(op);
-        rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
+// This function only works when `mode::is_dyn_thread_safe()`.
+pub fn scope<'scope, OP, R>(op: OP) -> R
+where
+    OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
+    R: DynSend,
+{
+    let op = FromDyn::from(op);
+    rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
+}
+
+#[inline]
+pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
+where
+    A: FnOnce() -> RA + DynSend,
+    B: FnOnce() -> RB + DynSend,
+{
+    if mode::is_dyn_thread_safe() {
+        let oper_a = FromDyn::from(oper_a);
+        let oper_b = FromDyn::from(oper_b);
+        let (a, b) = parallel_guard(|guard| {
+            rayon::join(
+                move || guard.run(move || FromDyn::from(oper_a.into_inner()())),
+                move || guard.run(move || FromDyn::from(oper_b.into_inner()())),
+            )
+        });
+        (a.unwrap().into_inner(), b.unwrap().into_inner())
+    } else {
+        serial_join(oper_a, oper_b)
     }
+}
 
-    #[inline]
-    pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
-    where
-        A: FnOnce() -> RA + DynSend,
-        B: FnOnce() -> RB + DynSend,
-    {
+pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>(
+    t: T,
+    for_each: impl Fn(I) + DynSync + DynSend,
+) {
+    parallel_guard(|guard| {
         if mode::is_dyn_thread_safe() {
-            let oper_a = FromDyn::from(oper_a);
-            let oper_b = FromDyn::from(oper_b);
-            let (a, b) = parallel_guard(|guard| {
-                rayon::join(
-                    move || guard.run(move || FromDyn::from(oper_a.into_inner()())),
-                    move || guard.run(move || FromDyn::from(oper_b.into_inner()())),
-                )
+            let for_each = FromDyn::from(for_each);
+            t.into_par_iter().for_each(|i| {
+                guard.run(|| for_each(i));
             });
-            (a.unwrap().into_inner(), b.unwrap().into_inner())
         } else {
-            super::disabled::join(oper_a, oper_b)
+            t.into_iter().for_each(|i| {
+                guard.run(|| for_each(i));
+            });
         }
-    }
-
-    use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
-
-    pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>(
-        t: T,
-        for_each: impl Fn(I) + DynSync + DynSend,
-    ) {
-        parallel_guard(|guard| {
-            if mode::is_dyn_thread_safe() {
-                let for_each = FromDyn::from(for_each);
-                t.into_par_iter().for_each(|i| {
-                    guard.run(|| for_each(i));
-                });
-            } else {
-                t.into_iter().for_each(|i| {
-                    guard.run(|| for_each(i));
-                });
-            }
-        });
-    }
+    });
+}
 
-    pub fn try_par_for_each_in<
-        T: IntoIterator + IntoParallelIterator<Item = <T as IntoIterator>::Item>,
-        E: Send,
-    >(
-        t: T,
-        for_each: impl Fn(<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
-    ) -> Result<(), E> {
-        parallel_guard(|guard| {
-            if mode::is_dyn_thread_safe() {
-                let for_each = FromDyn::from(for_each);
-                t.into_par_iter()
-                    .filter_map(|i| guard.run(|| for_each(i)))
-                    .reduce(|| Ok(()), Result::and)
-            } else {
-                t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
-            }
-        })
-    }
+pub fn try_par_for_each_in<
+    T: IntoIterator + IntoParallelIterator<Item = <T as IntoIterator>::Item>,
+    E: Send,
+>(
+    t: T,
+    for_each: impl Fn(<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
+) -> Result<(), E> {
+    parallel_guard(|guard| {
+        if mode::is_dyn_thread_safe() {
+            let for_each = FromDyn::from(for_each);
+            t.into_par_iter()
+                .filter_map(|i| guard.run(|| for_each(i)))
+                .reduce(|| Ok(()), Result::and)
+        } else {
+            t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
+        }
+    })
+}
 
-    pub fn par_map<
-        I,
-        T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
-        R: std::marker::Send,
-        C: FromIterator<R> + FromParallelIterator<R>,
-    >(
-        t: T,
-        map: impl Fn(I) -> R + DynSync + DynSend,
-    ) -> C {
-        parallel_guard(|guard| {
-            if mode::is_dyn_thread_safe() {
-                let map = FromDyn::from(map);
-                t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect()
-            } else {
-                t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
-            }
-        })
-    }
+pub fn par_map<
+    I,
+    T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
+    R: std::marker::Send,
+    C: FromIterator<R> + FromParallelIterator<R>,
+>(
+    t: T,
+    map: impl Fn(I) -> R + DynSync + DynSend,
+) -> C {
+    parallel_guard(|guard| {
+        if mode::is_dyn_thread_safe() {
+            let map = FromDyn::from(map);
+            t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect()
+        } else {
+            t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
+        }
+    })
 }
diff --git a/compiler/rustc_data_structures/src/sync/vec.rs b/compiler/rustc_data_structures/src/sync/vec.rs
index 314496ce9f0..21ec5cf6c13 100644
--- a/compiler/rustc_data_structures/src/sync/vec.rs
+++ b/compiler/rustc_data_structures/src/sync/vec.rs
@@ -4,40 +4,23 @@ use rustc_index::Idx;
 
 #[derive(Default)]
 pub struct AppendOnlyIndexVec<I: Idx, T: Copy> {
-    #[cfg(not(parallel_compiler))]
-    vec: elsa::vec::FrozenVec<T>,
-    #[cfg(parallel_compiler)]
     vec: elsa::sync::LockFreeFrozenVec<T>,
     _marker: PhantomData<fn(&I)>,
 }
 
 impl<I: Idx, T: Copy> AppendOnlyIndexVec<I, T> {
     pub fn new() -> Self {
-        Self {
-            #[cfg(not(parallel_compiler))]
-            vec: elsa::vec::FrozenVec::new(),
-            #[cfg(parallel_compiler)]
-            vec: elsa::sync::LockFreeFrozenVec::new(),
-            _marker: PhantomData,
-        }
+        Self { vec: elsa::sync::LockFreeFrozenVec::new(), _marker: PhantomData }
     }
 
     pub fn push(&self, val: T) -> I {
-        #[cfg(not(parallel_compiler))]
-        let i = self.vec.len();
-        #[cfg(not(parallel_compiler))]
-        self.vec.push(val);
-        #[cfg(parallel_compiler)]
         let i = self.vec.push(val);
         I::new(i)
     }
 
     pub fn get(&self, i: I) -> Option<T> {
         let i = i.index();
-        #[cfg(not(parallel_compiler))]
-        return self.vec.get_copy(i);
-        #[cfg(parallel_compiler)]
-        return self.vec.get(i);
+        self.vec.get(i)
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index b6efcada10b..d75af009850 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -5,8 +5,9 @@ use std::ptr;
 use std::sync::Arc;
 
 use parking_lot::Mutex;
-#[cfg(parallel_compiler)]
-use {crate::outline, crate::sync::CacheAligned};
+
+use crate::outline;
+use crate::sync::CacheAligned;
 
 /// A pointer to the `RegistryData` which uniquely identifies a registry.
 /// This identifier can be reused if the registry gets freed.
@@ -21,7 +22,6 @@ impl RegistryId {
     ///
     /// Note that there's a race possible where the identifier in `THREAD_DATA` could be reused
     /// so this can succeed from a different registry.
-    #[cfg(parallel_compiler)]
     fn verify(self) -> usize {
         let (id, index) = THREAD_DATA.with(|data| (data.registry_id.get(), data.index.get()));
 
@@ -102,11 +102,7 @@ impl Registry {
 /// worker local value through the `Deref` impl on the registry associated with the thread it was
 /// created on. It will panic otherwise.
 pub struct WorkerLocal<T> {
-    #[cfg(not(parallel_compiler))]
-    local: T,
-    #[cfg(parallel_compiler)]
     locals: Box<[CacheAligned<T>]>,
-    #[cfg(parallel_compiler)]
     registry: Registry,
 }
 
@@ -114,7 +110,6 @@ pub struct WorkerLocal<T> {
 // or it will panic for threads without an associated local. So there isn't a need for `T` to do
 // it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
 // can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
-#[cfg(parallel_compiler)]
 unsafe impl<T: Send> Sync for WorkerLocal<T> {}
 
 impl<T> WorkerLocal<T> {
@@ -122,33 +117,17 @@ impl<T> WorkerLocal<T> {
     /// value this worker local should take for each thread in the registry.
     #[inline]
     pub fn new<F: FnMut(usize) -> T>(mut initial: F) -> WorkerLocal<T> {
-        #[cfg(parallel_compiler)]
-        {
-            let registry = Registry::current();
-            WorkerLocal {
-                locals: (0..registry.0.thread_limit.get())
-                    .map(|i| CacheAligned(initial(i)))
-                    .collect(),
-                registry,
-            }
-        }
-        #[cfg(not(parallel_compiler))]
-        {
-            WorkerLocal { local: initial(0) }
+        let registry = Registry::current();
+        WorkerLocal {
+            locals: (0..registry.0.thread_limit.get()).map(|i| CacheAligned(initial(i))).collect(),
+            registry,
         }
     }
 
     /// Returns the worker-local values for each thread
     #[inline]
     pub fn into_inner(self) -> impl Iterator<Item = T> {
-        #[cfg(parallel_compiler)]
-        {
-            self.locals.into_vec().into_iter().map(|local| local.0)
-        }
-        #[cfg(not(parallel_compiler))]
-        {
-            std::iter::once(self.local)
-        }
+        self.locals.into_vec().into_iter().map(|local| local.0)
     }
 }
 
@@ -156,13 +135,6 @@ impl<T> Deref for WorkerLocal<T> {
     type Target = T;
 
     #[inline(always)]
-    #[cfg(not(parallel_compiler))]
-    fn deref(&self) -> &T {
-        &self.local
-    }
-
-    #[inline(always)]
-    #[cfg(parallel_compiler)]
     fn deref(&self) -> &T {
         // This is safe because `verify` will only return values less than
         // `self.registry.thread_limit` which is the size of the `self.locals` array.