@@ -91,13 +91,13 @@ pub struct LocalKey<T: 'static> {
91
91
//
92
92
// Note that the thunk is itself unsafe because the returned lifetime of the
93
93
// slot where data lives, `'static`, is not actually valid. The lifetime
94
- // here is actually `' thread` !
94
+ // here is actually slightly shorter than the currently running thread!
95
95
//
96
96
// Although this is an extra layer of indirection, it should in theory be
97
97
// trivially devirtualizable by LLVM because the value of `inner` never
98
98
// changes and the constant should be readonly within a crate. This mainly
99
99
// only runs into problems when TLS statics are exported across crates.
100
- inner : fn ( ) -> Option < & ' static UnsafeCell < Option < T > > > ,
100
+ inner : unsafe fn ( ) -> Option < & ' static UnsafeCell < Option < T > > > ,
101
101
102
102
// initialization routine to invoke to create a value
103
103
init : fn ( ) -> T ,
@@ -157,12 +157,13 @@ macro_rules! thread_local {
157
157
issue = "0" ) ]
158
158
#[ macro_export]
159
159
#[ allow_internal_unstable]
160
+ #[ cfg_attr( not( stage0) , allow_internal_unsafe) ]
160
161
macro_rules! __thread_local_inner {
161
162
( $( #[ $attr: meta] ) * $vis: vis $name: ident, $t: ty, $init: expr) => {
162
163
$( #[ $attr] ) * $vis static $name: $crate:: thread:: LocalKey <$t> = {
163
164
fn __init( ) -> $t { $init }
164
165
165
- fn __getit( ) -> $crate:: option:: Option <
166
+ unsafe fn __getit( ) -> $crate:: option:: Option <
166
167
& ' static $crate:: cell:: UnsafeCell <
167
168
$crate:: option:: Option <$t>>>
168
169
{
@@ -178,7 +179,9 @@ macro_rules! __thread_local_inner {
178
179
__KEY. get( )
179
180
}
180
181
181
- $crate:: thread:: LocalKey :: new( __getit, __init)
182
+ unsafe {
183
+ $crate:: thread:: LocalKey :: new( __getit, __init)
184
+ }
182
185
} ;
183
186
}
184
187
}
@@ -252,8 +255,8 @@ impl<T: 'static> LocalKey<T> {
252
255
#[ unstable( feature = "thread_local_internals" ,
253
256
reason = "recently added to create a key" ,
254
257
issue = "0" ) ]
255
- pub const fn new ( inner : fn ( ) -> Option < & ' static UnsafeCell < Option < T > > > ,
256
- init : fn ( ) -> T ) -> LocalKey < T > {
258
+ pub const unsafe fn new ( inner : unsafe fn ( ) -> Option < & ' static UnsafeCell < Option < T > > > ,
259
+ init : fn ( ) -> T ) -> LocalKey < T > {
257
260
LocalKey {
258
261
inner : inner,
259
262
init : init,
@@ -391,6 +394,7 @@ pub mod fast {
391
394
}
392
395
}
393
396
397
+ #[ cfg( stage0) ]
394
398
unsafe impl < T > :: marker:: Sync for Key < T > { }
395
399
396
400
impl < T > Key < T > {
@@ -402,14 +406,12 @@ pub mod fast {
402
406
}
403
407
}
404
408
405
- pub fn get ( & ' static self ) -> Option < & ' static UnsafeCell < Option < T > > > {
406
- unsafe {
407
- if mem:: needs_drop :: < T > ( ) && self . dtor_running . get ( ) {
408
- return None
409
- }
410
- self . register_dtor ( ) ;
409
+ pub unsafe fn get ( & self ) -> Option < & ' static UnsafeCell < Option < T > > > {
410
+ if mem:: needs_drop :: < T > ( ) && self . dtor_running . get ( ) {
411
+ return None
411
412
}
412
- Some ( & self . inner )
413
+ self . register_dtor ( ) ;
414
+ Some ( & * ( & self . inner as * const _ ) )
413
415
}
414
416
415
417
unsafe fn register_dtor ( & self ) {
@@ -478,26 +480,24 @@ pub mod os {
478
480
}
479
481
}
480
482
481
- pub fn get ( & ' static self ) -> Option < & ' static UnsafeCell < Option < T > > > {
482
- unsafe {
483
- let ptr = self . os . get ( ) as * mut Value < T > ;
484
- if !ptr. is_null ( ) {
485
- if ptr as usize == 1 {
486
- return None
487
- }
488
- return Some ( & ( * ptr) . value ) ;
483
+ pub unsafe fn get ( & ' static self ) -> Option < & ' static UnsafeCell < Option < T > > > {
484
+ let ptr = self . os . get ( ) as * mut Value < T > ;
485
+ if !ptr. is_null ( ) {
486
+ if ptr as usize == 1 {
487
+ return None
489
488
}
490
-
491
- // If the lookup returned null, we haven't initialized our own
492
- // local copy, so do that now.
493
- let ptr: Box < Value < T > > = box Value {
494
- key : self ,
495
- value : UnsafeCell :: new ( None ) ,
496
- } ;
497
- let ptr = Box :: into_raw ( ptr) ;
498
- self . os . set ( ptr as * mut u8 ) ;
499
- Some ( & ( * ptr) . value )
489
+ return Some ( & ( * ptr) . value ) ;
500
490
}
491
+
492
+ // If the lookup returned null, we haven't initialized our own
493
+ // local copy, so do that now.
494
+ let ptr: Box < Value < T > > = box Value {
495
+ key : self ,
496
+ value : UnsafeCell :: new ( None ) ,
497
+ } ;
498
+ let ptr = Box :: into_raw ( ptr) ;
499
+ self . os . set ( ptr as * mut u8 ) ;
500
+ Some ( & ( * ptr) . value )
501
501
}
502
502
}
503
503
0 commit comments