@@ -91,13 +91,13 @@ pub struct LocalKey<T: 'static> {
9191 //
9292 // Note that the thunk is itself unsafe because the returned lifetime of the
9393 // 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!
9595 //
9696 // Although this is an extra layer of indirection, it should in theory be
9797 // trivially devirtualizable by LLVM because the value of `inner` never
9898 // changes and the constant should be readonly within a crate. This mainly
9999 // 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 > > > ,
101101
102102 // initialization routine to invoke to create a value
103103 init : fn ( ) -> T ,
@@ -157,12 +157,13 @@ macro_rules! thread_local {
157157 issue = "0" ) ]
158158#[ macro_export]
159159#[ allow_internal_unstable]
160+ #[ cfg_attr( not( stage0) , allow_internal_unsafe) ]
160161macro_rules! __thread_local_inner {
161162 ( $( #[ $attr: meta] ) * $vis: vis $name: ident, $t: ty, $init: expr) => {
162163 $( #[ $attr] ) * $vis static $name: $crate:: thread:: LocalKey <$t> = {
163164 fn __init( ) -> $t { $init }
164165
165- fn __getit( ) -> $crate:: option:: Option <
166+ unsafe fn __getit( ) -> $crate:: option:: Option <
166167 & ' static $crate:: cell:: UnsafeCell <
167168 $crate:: option:: Option <$t>>>
168169 {
@@ -178,7 +179,9 @@ macro_rules! __thread_local_inner {
178179 __KEY. get( )
179180 }
180181
181- $crate:: thread:: LocalKey :: new( __getit, __init)
182+ unsafe {
183+ $crate:: thread:: LocalKey :: new( __getit, __init)
184+ }
182185 } ;
183186 }
184187}
@@ -252,8 +255,8 @@ impl<T: 'static> LocalKey<T> {
252255 #[ unstable( feature = "thread_local_internals" ,
253256 reason = "recently added to create a key" ,
254257 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 > {
257260 LocalKey {
258261 inner : inner,
259262 init : init,
@@ -391,6 +394,7 @@ pub mod fast {
391394 }
392395 }
393396
397+ #[ cfg( stage0) ]
394398 unsafe impl < T > :: marker:: Sync for Key < T > { }
395399
396400 impl < T > Key < T > {
@@ -402,14 +406,12 @@ pub mod fast {
402406 }
403407 }
404408
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
411412 }
412- Some ( & self . inner )
413+ self . register_dtor ( ) ;
414+ Some ( & * ( & self . inner as * const _ ) )
413415 }
414416
415417 unsafe fn register_dtor ( & self ) {
@@ -478,26 +480,24 @@ pub mod os {
478480 }
479481 }
480482
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
489488 }
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 ) ;
500490 }
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 )
501501 }
502502 }
503503
0 commit comments