@@ -9,23 +9,24 @@ use crate::sync::Arc;
9
9
/// A scope to spawn scoped threads in.
10
10
///
11
11
/// See [`scope`] for details.
12
- pub struct Scope < ' env > {
12
+ pub struct Scope < ' scope , ' env : ' scope > {
13
13
data : ScopeData ,
14
- /// Invariance over 'env , to make sure 'env cannot shrink,
14
+ /// Invariance over 'scope , to make sure 'scope cannot shrink,
15
15
/// which is necessary for soundness.
16
16
///
17
17
/// Without invariance, this would compile fine but be unsound:
18
18
///
19
- /// ```compile_fail
19
+ /// ```compile_fail,E0373
20
20
/// #![feature(scoped_threads)]
21
21
///
22
22
/// std::thread::scope(|s| {
23
- /// s.spawn(|s | {
23
+ /// s.spawn(|| {
24
24
/// let a = String::from("abcd");
25
- /// s.spawn(|_ | println!("{:?}", a)); // might run after `a` is dropped
25
+ /// s.spawn(|| println!("{:?}", a)); // might run after `a` is dropped
26
26
/// });
27
27
/// });
28
28
/// ```
29
+ scope : PhantomData < & ' scope mut & ' scope ( ) > ,
29
30
env : PhantomData < & ' env mut & ' env ( ) > ,
30
31
}
31
32
@@ -88,12 +89,12 @@ impl ScopeData {
88
89
/// let mut x = 0;
89
90
///
90
91
/// thread::scope(|s| {
91
- /// s.spawn(|_ | {
92
+ /// s.spawn(|| {
92
93
/// println!("hello from the first scoped thread");
93
94
/// // We can borrow `a` here.
94
95
/// dbg!(&a);
95
96
/// });
96
- /// s.spawn(|_ | {
97
+ /// s.spawn(|| {
97
98
/// println!("hello from the second scoped thread");
98
99
/// // We can even mutably borrow `x` here,
99
100
/// // because no other threads are using it.
@@ -109,7 +110,7 @@ impl ScopeData {
109
110
#[ track_caller]
110
111
pub fn scope < ' env , F , T > ( f : F ) -> T
111
112
where
112
- F : FnOnce ( & Scope < ' env > ) -> T ,
113
+ F : for < ' scope > FnOnce ( & ' scope Scope < ' scope , ' env > ) -> T ,
113
114
{
114
115
let scope = Scope {
115
116
data : ScopeData {
@@ -118,6 +119,7 @@ where
118
119
a_thread_panicked : AtomicBool :: new ( false ) ,
119
120
} ,
120
121
env : PhantomData ,
122
+ scope : PhantomData ,
121
123
} ;
122
124
123
125
// Run `f`, but catch panics so we can make sure to wait for all the threads to join.
@@ -138,7 +140,7 @@ where
138
140
}
139
141
}
140
142
141
- impl < ' env > Scope < ' env > {
143
+ impl < ' scope , ' env > Scope < ' scope , ' env > {
142
144
/// Spawns a new thread within a scope, returning a [`ScopedJoinHandle`] for it.
143
145
///
144
146
/// Unlike non-scoped threads, threads spawned with this function may
@@ -163,10 +165,10 @@ impl<'env> Scope<'env> {
163
165
/// to recover from such errors.
164
166
///
165
167
/// [`join`]: ScopedJoinHandle::join
166
- pub fn spawn < ' scope , F , T > ( & ' scope self , f : F ) -> ScopedJoinHandle < ' scope , T >
168
+ pub fn spawn < F , T > ( & ' scope self , f : F ) -> ScopedJoinHandle < ' scope , T >
167
169
where
168
- F : FnOnce ( & Scope < ' env > ) -> T + Send + ' env ,
169
- T : Send + ' env ,
170
+ F : FnOnce ( ) -> T + Send + ' scope ,
171
+ T : Send + ' scope ,
170
172
{
171
173
Builder :: new ( ) . spawn_scoped ( self , f) . expect ( "failed to spawn thread" )
172
174
}
@@ -196,7 +198,7 @@ impl Builder {
196
198
/// thread::scope(|s| {
197
199
/// thread::Builder::new()
198
200
/// .name("first".to_string())
199
- /// .spawn_scoped(s, |_ |
201
+ /// .spawn_scoped(s, ||
200
202
/// {
201
203
/// println!("hello from the {:?} scoped thread", thread::current().name());
202
204
/// // We can borrow `a` here.
@@ -205,7 +207,7 @@ impl Builder {
205
207
/// .unwrap();
206
208
/// thread::Builder::new()
207
209
/// .name("second".to_string())
208
- /// .spawn_scoped(s, |_ |
210
+ /// .spawn_scoped(s, ||
209
211
/// {
210
212
/// println!("hello from the {:?} scoped thread", thread::current().name());
211
213
/// // We can even mutably borrow `x` here,
@@ -222,14 +224,14 @@ impl Builder {
222
224
/// ```
223
225
pub fn spawn_scoped < ' scope , ' env , F , T > (
224
226
self ,
225
- scope : & ' scope Scope < ' env > ,
227
+ scope : & ' scope Scope < ' scope , ' env > ,
226
228
f : F ,
227
229
) -> io:: Result < ScopedJoinHandle < ' scope , T > >
228
230
where
229
- F : FnOnce ( & Scope < ' env > ) -> T + Send + ' env ,
230
- T : Send + ' env ,
231
+ F : FnOnce ( ) -> T + Send + ' scope ,
232
+ T : Send + ' scope ,
231
233
{
232
- Ok ( ScopedJoinHandle ( unsafe { self . spawn_unchecked_ ( || f ( scope ) , Some ( & scope. data ) ) } ?) )
234
+ Ok ( ScopedJoinHandle ( unsafe { self . spawn_unchecked_ ( || f ( ) , Some ( & scope. data ) ) } ?) )
233
235
}
234
236
}
235
237
@@ -245,7 +247,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> {
245
247
/// use std::thread;
246
248
///
247
249
/// thread::scope(|s| {
248
- /// let t = s.spawn(|_ | {
250
+ /// let t = s.spawn(|| {
249
251
/// println!("hello");
250
252
/// });
251
253
/// println!("thread id: {:?}", t.thread().id());
@@ -279,7 +281,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> {
279
281
/// use std::thread;
280
282
///
281
283
/// thread::scope(|s| {
282
- /// let t = s.spawn(|_ | {
284
+ /// let t = s.spawn(|| {
283
285
/// panic!("oh no");
284
286
/// });
285
287
/// assert!(t.join().is_err());
@@ -299,7 +301,7 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> {
299
301
}
300
302
}
301
303
302
- impl < ' env > fmt:: Debug for Scope < ' env > {
304
+ impl < ' scope , ' env > fmt:: Debug for Scope < ' scope , ' env > {
303
305
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
304
306
f. debug_struct ( "Scope" )
305
307
. field ( "num_running_threads" , & self . data . num_running_threads . load ( Ordering :: Relaxed ) )
0 commit comments