From ae0a533b0b1f53a9fce48b51d2ff4cc9f3c41699 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 9 Jun 2022 10:53:45 +0200 Subject: [PATCH] Stabilize scoped threads. --- library/core/src/sync/atomic.rs | 12 ++++++------ library/std/src/thread/mod.rs | 4 ++-- library/std/src/thread/scoped.rs | 18 ++++++++++-------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 43cfb1bb640..cedeb27d6d9 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -350,7 +350,7 @@ impl AtomicBool { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, inline_const, scoped_threads)] + /// #![feature(atomic_from_mut, inline_const)] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let mut some_bools = [const { AtomicBool::new(false) }; 10]; @@ -381,7 +381,7 @@ impl AtomicBool { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, scoped_threads)] + /// #![feature(atomic_from_mut)] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let mut some_bools = [false; 10]; @@ -1015,7 +1015,7 @@ impl AtomicPtr { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, inline_const, scoped_threads)] + /// #![feature(atomic_from_mut, inline_const)] /// use std::ptr::null_mut; /// use std::sync::atomic::{AtomicPtr, Ordering}; /// @@ -1052,7 +1052,7 @@ impl AtomicPtr { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, scoped_threads)] + /// #![feature(atomic_from_mut)] /// use std::ptr::null_mut; /// use std::sync::atomic::{AtomicPtr, Ordering}; /// @@ -1607,7 +1607,7 @@ macro_rules! atomic_int { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, inline_const, scoped_threads)] + /// #![feature(atomic_from_mut, inline_const)] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")] @@ -1640,7 +1640,7 @@ macro_rules! atomic_int { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, scoped_threads)] + /// #![feature(atomic_from_mut)] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// /// let mut some_ints = [0; 10]; diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 7f9b297e9dc..f7af66ae5b5 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -183,10 +183,10 @@ use crate::time::Duration; #[macro_use] mod local; -#[unstable(feature = "scoped_threads", issue = "93203")] +#[stable(feature = "scoped_threads", since = "1.63.0")] mod scoped; -#[unstable(feature = "scoped_threads", issue = "93203")] +#[stable(feature = "scoped_threads", since = "1.63.0")] pub use scoped::{scope, Scope, ScopedJoinHandle}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs index eeccc99b3a3..4fd076e4a2d 100644 --- a/library/std/src/thread/scoped.rs +++ b/library/std/src/thread/scoped.rs @@ -9,6 +9,7 @@ use crate::sync::Arc; /// A scope to spawn scoped threads in. /// /// See [`scope`] for details. +#[stable(feature = "scoped_threads", since = "1.63.0")] pub struct Scope<'scope, 'env: 'scope> { data: ScopeData, /// Invariance over 'scope, to make sure 'scope cannot shrink, @@ -17,8 +18,6 @@ pub struct Scope<'scope, 'env: 'scope> { /// Without invariance, this would compile fine but be unsound: /// /// ```compile_fail,E0373 - /// #![feature(scoped_threads)] - /// /// std::thread::scope(|s| { /// s.spawn(|| { /// let a = String::from("abcd"); @@ -33,6 +32,7 @@ pub struct Scope<'scope, 'env: 'scope> { /// An owned permission to join on a scoped thread (block on its termination). /// /// See [`Scope::spawn`] for details. +#[stable(feature = "scoped_threads", since = "1.63.0")] pub struct ScopedJoinHandle<'scope, T>(JoinInner<'scope, T>); pub(super) struct ScopeData { @@ -82,7 +82,6 @@ impl ScopeData { /// # Example /// /// ``` -/// #![feature(scoped_threads)] /// use std::thread; /// /// let mut a = vec![1, 2, 3]; @@ -126,6 +125,7 @@ impl ScopeData { /// /// The `'env: 'scope` bound is part of the definition of the `Scope` type. #[track_caller] +#[stable(feature = "scoped_threads", since = "1.63.0")] pub fn scope<'env, F, T>(f: F) -> T where F: for<'scope> FnOnce(&'scope Scope<'scope, 'env>) -> T, @@ -183,6 +183,7 @@ impl<'scope, 'env> Scope<'scope, 'env> { /// to recover from such errors. /// /// [`join`]: ScopedJoinHandle::join + #[stable(feature = "scoped_threads", since = "1.63.0")] pub fn spawn(&'scope self, f: F) -> ScopedJoinHandle<'scope, T> where F: FnOnce() -> T + Send + 'scope, @@ -207,7 +208,6 @@ impl Builder { /// # Example /// /// ``` - /// #![feature(scoped_threads)] /// use std::thread; /// /// let mut a = vec![1, 2, 3]; @@ -240,6 +240,7 @@ impl Builder { /// a.push(4); /// assert_eq!(x, a.len()); /// ``` + #[stable(feature = "scoped_threads", since = "1.63.0")] pub fn spawn_scoped<'scope, 'env, F, T>( self, scope: &'scope Scope<'scope, 'env>, @@ -259,8 +260,6 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// # Examples /// /// ``` - /// #![feature(scoped_threads)] - /// /// use std::thread; /// /// thread::scope(|s| { @@ -271,6 +270,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// }); /// ``` #[must_use] + #[stable(feature = "scoped_threads", since = "1.63.0")] pub fn thread(&self) -> &Thread { &self.0.thread } @@ -292,8 +292,6 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// # Examples /// /// ``` - /// #![feature(scoped_threads)] - /// /// use std::thread; /// /// thread::scope(|s| { @@ -303,6 +301,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// assert!(t.join().is_err()); /// }); /// ``` + #[stable(feature = "scoped_threads", since = "1.63.0")] pub fn join(self) -> Result { self.0.join() } @@ -316,11 +315,13 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> { /// /// This function does not block. To block while waiting on the thread to finish, /// use [`join`][Self::join]. + #[stable(feature = "scoped_threads", since = "1.63.0")] pub fn is_finished(&self) -> bool { Arc::strong_count(&self.0.packet) == 1 } } +#[stable(feature = "scoped_threads", since = "1.63.0")] impl fmt::Debug for Scope<'_, '_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Scope") @@ -331,6 +332,7 @@ impl fmt::Debug for Scope<'_, '_> { } } +#[stable(feature = "scoped_threads", since = "1.63.0")] impl<'scope, T> fmt::Debug for ScopedJoinHandle<'scope, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ScopedJoinHandle").finish_non_exhaustive()