@@ -92,6 +92,8 @@ unsafe impl Allocator for MyAllocator {
9292 }
9393
9494 unsafe fn deallocate ( & self , ptr : NonNull < u8 > , _layout : Layout ) {
95+ // Make sure accesses via `self` don't disturb anything.
96+ let _val = self . bins [ 0 ] . top . get ( ) ;
9597 // Since manually finding the corresponding bin of `ptr` is very expensive,
9698 // doing pointer arithmetics is preferred.
9799 // But this means we access `top` via `ptr` rather than `self`!
@@ -101,22 +103,30 @@ unsafe impl Allocator for MyAllocator {
101103 if self . thread_id == thread_id {
102104 unsafe { ( * their_bin) . push ( ptr) } ;
103105 } else {
104- todo ! ( "Deallocating from another thread" )
106+ todo ! ( "Deallocating from another thread" ) ;
105107 }
108+ // Make sure we can also still access this via `self` after the rest is done.
109+ let _val = self . bins [ 0 ] . top . get ( ) ;
106110 }
107111}
108112
109113// Make sure to involve `Box` in allocating these,
110114// as that's where `noalias` may come from.
111- fn v < T , A : Allocator > ( t : T , a : A ) -> Vec < T , A > {
115+ fn v1 < T , A : Allocator > ( t : T , a : A ) -> Vec < T , A > {
112116 ( Box :: new_in ( [ t] , a) as Box < [ T ] , A > ) . into_vec ( )
113117}
118+ fn v2 < T , A : Allocator > ( t : T , a : A ) -> Vec < T , A > {
119+ let v = v1 ( t, a) ;
120+ // There was a bug in `into_boxed_slice` that caused aliasing issues,
121+ // so round-trip through that as well.
122+ v. into_boxed_slice ( ) . into_vec ( )
123+ }
114124
115125fn main ( ) {
116126 assert ! ( mem:: size_of:: <MyBin >( ) <= 128 ) ; // if it grows bigger, the trick to access the "header" no longer works
117127 let my_alloc = MyAllocator :: new ( ) ;
118- let a = v ( 1usize , & my_alloc) ;
119- let b = v ( 2usize , & my_alloc) ;
128+ let a = v1 ( 1usize , & my_alloc) ;
129+ let b = v2 ( 2usize , & my_alloc) ;
120130 assert_eq ! ( a[ 0 ] + 1 , b[ 0 ] ) ;
121131 assert_eq ! ( addr_of!( a[ 0 ] ) . wrapping_add( 1 ) , addr_of!( b[ 0 ] ) ) ;
122132 drop ( ( a, b) ) ;
0 commit comments