@@ -84,6 +84,8 @@ unsafe impl Allocator for MyAllocator {
8484 }
8585
8686 unsafe fn deallocate ( & self , ptr : NonNull < u8 > , _layout : Layout ) {
87+ // Make sure accesses via `self` don't disturb anything.
88+ let _val = self . bins [ 0 ] . top . get ( ) ;
8789 // Since manually finding the corresponding bin of `ptr` is very expensive,
8890 // doing pointer arithmetics is preferred.
8991 // But this means we access `top` via `ptr` rather than `self`!
@@ -93,22 +95,30 @@ unsafe impl Allocator for MyAllocator {
9395 if self . thread_id == thread_id {
9496 unsafe { ( * their_bin) . push ( ptr) } ;
9597 } else {
96- todo ! ( "Deallocating from another thread" )
98+ todo ! ( "Deallocating from another thread" ) ;
9799 }
100+ // Make sure we can also still access this via `self` after the rest is done.
101+ let _val = self . bins [ 0 ] . top . get ( ) ;
98102 }
99103}
100104
101105// Make sure to involve `Box` in allocating these,
102106// as that's where `noalias` may come from.
103- fn v < T , A : Allocator > ( t : T , a : A ) -> Vec < T , A > {
107+ fn v1 < T , A : Allocator > ( t : T , a : A ) -> Vec < T , A > {
104108 ( Box :: new_in ( [ t] , a) as Box < [ T ] , A > ) . into_vec ( )
105109}
110+ fn v2 < T , A : Allocator > ( t : T , a : A ) -> Vec < T , A > {
111+ let v = v1 ( t, a) ;
112+ // There was a bug in `into_boxed_slice` that caused aliasing issues,
113+ // so round-trip through that as well.
114+ v. into_boxed_slice ( ) . into_vec ( )
115+ }
106116
107117fn main ( ) {
108118 assert ! ( mem:: size_of:: <MyBin >( ) <= 128 ) ; // if it grows bigger, the trick to access the "header" no longer works
109119 let my_alloc = MyAllocator :: new ( ) ;
110- let a = v ( 1usize , & my_alloc) ;
111- let b = v ( 2usize , & my_alloc) ;
120+ let a = v1 ( 1usize , & my_alloc) ;
121+ let b = v2 ( 2usize , & my_alloc) ;
112122 assert_eq ! ( a[ 0 ] + 1 , b[ 0 ] ) ;
113123 assert_eq ! ( addr_of!( a[ 0 ] ) . wrapping_add( 1 ) , addr_of!( b[ 0 ] ) ) ;
114124 drop ( ( a, b) ) ;
0 commit comments