@@ -13,22 +13,21 @@ pub macro thread_local_inner {
1313 ( @key $t: ty, const $init: expr) => { {
1414 #[ inline]
1515 #[ deny( unsafe_op_in_unsafe_fn) ]
16- // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_refs` lint
17- #[ cfg_attr( bootstrap, allow( static_mut_ref) ) ]
18- #[ cfg_attr( not( bootstrap) , allow( static_mut_refs) ) ]
1916 unsafe fn __getit (
2017 _init : $crate:: option:: Option < & mut $crate:: option:: Option < $t> > ,
2118 ) -> $crate:: option:: Option < & ' static $t> {
2219 const INIT_EXPR : $t = $init;
2320 // If the platform has support for `#[thread_local]`, use it.
2421 #[ thread_local]
25- static mut VAL : $t = INIT_EXPR ;
22+ // We use `UnsafeCell` here instead of `static mut` to ensure any generated TLS shims
23+ // have a nonnull attribute on their return value.
24+ static VAL : $crate:: cell:: UnsafeCell < $t> = $crate:: cell:: UnsafeCell :: new ( INIT_EXPR ) ;
2625
2726 // If a dtor isn't needed we can do something "very raw" and
2827 // just get going.
2928 if !$crate:: mem:: needs_drop :: < $t> ( ) {
3029 unsafe {
31- return $crate:: option:: Option :: Some ( & VAL )
30+ return $crate:: option:: Option :: Some ( & * VAL . get ( ) )
3231 }
3332 }
3433
@@ -55,15 +54,15 @@ pub macro thread_local_inner {
5554 // so now.
5655 0 => {
5756 $crate:: thread:: local_impl:: Key :: < $t> :: register_dtor (
58- $crate :: ptr :: addr_of_mut! ( VAL ) as * mut $crate:: primitive:: u8 ,
57+ VAL . get ( ) as * mut $crate:: primitive:: u8 ,
5958 destroy,
6059 ) ;
6160 STATE . set ( 1 ) ;
62- $crate:: option:: Option :: Some ( & VAL )
61+ $crate:: option:: Option :: Some ( & * VAL . get ( ) )
6362 }
6463 // 1 == the destructor is registered and the value
6564 // is valid, so return the pointer.
66- 1 => $crate:: option:: Option :: Some ( & VAL ) ,
65+ 1 => $crate:: option:: Option :: Some ( & * VAL . get ( ) ) ,
6766 // otherwise the destructor has already run, so we
6867 // can't give access.
6968 _ => $crate:: option:: Option :: None ,
0 commit comments