11use super :: key:: { Key , LazyKey , get, set} ;
22use super :: { abort_on_dtor_unwind, guard} ;
3- use crate :: alloc:: { self , Layout } ;
3+ use crate :: alloc:: { self , Layout , System } ;
44use crate :: cell:: Cell ;
55use crate :: marker:: PhantomData ;
66use crate :: mem:: ManuallyDrop ;
@@ -113,17 +113,19 @@ pub const fn value_align<T: 'static>() -> usize {
113113 crate :: mem:: align_of :: < Value < T > > ( )
114114}
115115
116- /// Equivalent to `Box<Value<T>>`, but potentially over-aligned.
117- struct AlignedBox < T : ' static , const ALIGN : usize > {
116+ /// Equivalent to `Box<Value<T>, System >`, but potentially over-aligned.
117+ struct AlignedSystemBox < T : ' static , const ALIGN : usize > {
118118 ptr : NonNull < Value < T > > ,
119119}
120120
121- impl < T : ' static , const ALIGN : usize > AlignedBox < T , ALIGN > {
121+ impl < T : ' static , const ALIGN : usize > AlignedSystemBox < T , ALIGN > {
122122 #[ inline]
123123 fn new ( v : Value < T > ) -> Self {
124124 let layout = Layout :: new :: < Value < T > > ( ) . align_to ( ALIGN ) . unwrap ( ) ;
125125
126- let ptr: * mut Value < T > = ( unsafe { alloc:: alloc ( layout) } ) . cast ( ) ;
126+ // We use the System allocator here to avoid interfering with a potential
127+ // Global allocator using thread-local storage.
128+ let ptr: * mut Value < T > = ( unsafe { System . alloc ( layout) } ) . cast ( ) ;
127129 let Some ( ptr) = NonNull :: new ( ptr) else {
128130 alloc:: handle_alloc_error ( layout) ;
129131 } ;
@@ -143,7 +145,7 @@ impl<T: 'static, const ALIGN: usize> AlignedBox<T, ALIGN> {
143145 }
144146}
145147
146- impl < T : ' static , const ALIGN : usize > Deref for AlignedBox < T , ALIGN > {
148+ impl < T : ' static , const ALIGN : usize > Deref for AlignedSystemBox < T , ALIGN > {
147149 type Target = Value < T > ;
148150
149151 #[ inline]
@@ -152,14 +154,14 @@ impl<T: 'static, const ALIGN: usize> Deref for AlignedBox<T, ALIGN> {
152154 }
153155}
154156
155- impl < T : ' static , const ALIGN : usize > Drop for AlignedBox < T , ALIGN > {
157+ impl < T : ' static , const ALIGN : usize > Drop for AlignedSystemBox < T , ALIGN > {
156158 #[ inline]
157159 fn drop ( & mut self ) {
158160 let layout = Layout :: new :: < Value < T > > ( ) . align_to ( ALIGN ) . unwrap ( ) ;
159161
160162 unsafe {
161163 let unwind_result = catch_unwind ( AssertUnwindSafe ( || self . ptr . drop_in_place ( ) ) ) ;
162- alloc :: dealloc ( self . ptr . as_ptr ( ) . cast ( ) , layout) ;
164+ System . dealloc ( self . ptr . as_ptr ( ) . cast ( ) , layout) ;
163165 if let Err ( payload) = unwind_result {
164166 resume_unwind ( payload) ;
165167 }
@@ -205,11 +207,11 @@ impl<T: 'static, const ALIGN: usize> Storage<T, ALIGN> {
205207 return ptr:: null ( ) ;
206208 }
207209
208- let value = AlignedBox :: < T , ALIGN > :: new ( Value {
210+ let value = AlignedSystemBox :: < T , ALIGN > :: new ( Value {
209211 value : i. and_then ( Option :: take) . unwrap_or_else ( f) ,
210212 key,
211213 } ) ;
212- let ptr = AlignedBox :: into_raw ( value) ;
214+ let ptr = AlignedSystemBox :: into_raw ( value) ;
213215
214216 // SAFETY:
215217 // * key came from a `LazyKey` and is thus correct.
@@ -227,7 +229,7 @@ impl<T: 'static, const ALIGN: usize> Storage<T, ALIGN> {
227229 // initializer has already returned and the next scope only starts
228230 // after we return the pointer. Therefore, there can be no references
229231 // to the old value.
230- drop ( unsafe { AlignedBox :: < T , ALIGN > :: from_raw ( old) } ) ;
232+ drop ( unsafe { AlignedSystemBox :: < T , ALIGN > :: from_raw ( old) } ) ;
231233 }
232234
233235 // SAFETY: We just created this value above.
@@ -246,7 +248,7 @@ unsafe extern "C" fn destroy_value<T: 'static, const ALIGN: usize>(ptr: *mut u8)
246248 // Note that to prevent an infinite loop we reset it back to null right
247249 // before we return from the destructor ourselves.
248250 abort_on_dtor_unwind ( || {
249- let ptr = unsafe { AlignedBox :: < T , ALIGN > :: from_raw ( ptr as * mut Value < T > ) } ;
251+ let ptr = unsafe { AlignedSystemBox :: < T , ALIGN > :: from_raw ( ptr as * mut Value < T > ) } ;
250252 let key = ptr. key ;
251253 // SAFETY: `key` is the TLS key `ptr` was stored under.
252254 unsafe { set ( key, ptr:: without_provenance_mut ( 1 ) ) } ;
0 commit comments