@@ -63,26 +63,26 @@ fn ensure_aligned<T: ?Sized + Pointable>(raw: *mut ()) {
6363/// `tag` is truncated to fit into the unused bits of the pointer to `T`.
6464#[ inline]
6565fn compose_tag < T : ?Sized + Pointable > ( ptr : * mut ( ) , tag : usize ) -> * mut ( ) {
66- int_to_ptr_with_provenance (
67- ( ptr as usize & !low_bits :: < T > ( ) ) | ( tag & low_bits :: < T > ( ) ) ,
68- ptr,
69- )
66+ map_addr ( ptr, |a| ( a & !low_bits :: < T > ( ) ) | ( tag & low_bits :: < T > ( ) ) )
7067}
7168
7269/// Decomposes a tagged pointer `data` into the pointer and the tag.
7370#[ inline]
7471fn decompose_tag < T : ?Sized + Pointable > ( ptr : * mut ( ) ) -> ( * mut ( ) , usize ) {
7572 (
76- int_to_ptr_with_provenance ( ptr as usize & !low_bits :: < T > ( ) , ptr ) ,
73+ map_addr ( ptr, |a| a & !low_bits :: < T > ( ) ) ,
7774 ptr as usize & low_bits :: < T > ( ) ,
7875 )
7976}
8077
81- // HACK: https://github.com/rust-lang/miri/issues/1866#issuecomment-985802751
78+ // FIXME: This is exactly <https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.map_addr-1>,
79+ // which we cannot use yet due to the MSRV.
8280#[ inline]
83- fn int_to_ptr_with_provenance < T > ( addr : usize , prov : * mut T ) -> * mut T {
84- let ptr = prov. cast :: < u8 > ( ) ;
85- ptr. wrapping_add ( addr. wrapping_sub ( ptr as usize ) ) . cast ( )
81+ fn map_addr < T > ( ptr : * mut T , f : impl FnOnce ( usize ) -> usize ) -> * mut T {
82+ let new_addr = f ( ptr as usize ) ;
83+ ptr. cast :: < u8 > ( )
84+ . wrapping_add ( new_addr. wrapping_sub ( ptr as usize ) )
85+ . cast :: < T > ( )
8686}
8787
8888/// Types that are pointed to by a single word.
@@ -190,7 +190,6 @@ impl<T> Pointable for T {
190190/// along with pointer as in `Box<[T]>`).
191191///
192192/// Elements are not present in the type, but they will be in the allocation.
193- /// ```
194193#[ repr( C ) ]
195194struct Array < T > {
196195 /// The number of elements (not the number of bytes).
@@ -640,9 +639,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
640639 let fetch_order = strongest_failure_ordering ( order) ;
641640 Shared :: from_ptr (
642641 self . data
643- . fetch_update ( order, fetch_order, |x| {
644- Some ( int_to_ptr_with_provenance ( x as usize & val, x) )
645- } )
642+ . fetch_update ( order, fetch_order, |x| Some ( map_addr ( x, |a| a & val) ) )
646643 . unwrap ( ) ,
647644 )
648645 }
@@ -687,9 +684,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
687684 let fetch_order = strongest_failure_ordering ( order) ;
688685 Shared :: from_ptr (
689686 self . data
690- . fetch_update ( order, fetch_order, |x| {
691- Some ( int_to_ptr_with_provenance ( x as usize | val, x) )
692- } )
687+ . fetch_update ( order, fetch_order, |x| Some ( map_addr ( x, |a| a | val) ) )
693688 . unwrap ( ) ,
694689 )
695690 }
@@ -734,9 +729,7 @@ impl<T: ?Sized + Pointable> Atomic<T> {
734729 let fetch_order = strongest_failure_ordering ( order) ;
735730 Shared :: from_ptr (
736731 self . data
737- . fetch_update ( order, fetch_order, |x| {
738- Some ( int_to_ptr_with_provenance ( x as usize ^ val, x) )
739- } )
732+ . fetch_update ( order, fetch_order, |x| Some ( map_addr ( x, |a| a ^ val) ) )
740733 . unwrap ( ) ,
741734 )
742735 }
0 commit comments