@@ -588,6 +588,34 @@ impl<T: ?Sized> *mut T {
588
588
///
589
589
/// For non-`Sized` pointees this operation changes only the data pointer,
590
590
/// leaving the metadata untouched.
591
+ ///
592
+ /// ## Examples
593
+ ///
594
+ /// ```
595
+ /// #![feature(ptr_mask, strict_provenance)]
596
+ /// let mut v = 17_u32;
597
+ /// let ptr: *mut u32 = &mut v;
598
+ ///
599
+ /// // `u32` is 4 bytes aligned,
600
+ /// // which means that lower 2 bits are always 0.
601
+ /// let tag_mask = 0b11;
602
+ /// let ptr_mask = !tag_mask;
603
+ ///
604
+ /// // We can store something in these lower bits
605
+ /// let tagged_ptr = ptr.map_addr(|a| a | 0b10);
606
+ ///
607
+ /// // Get the "tag" back
608
+ /// let tag = tagged_ptr.addr() & tag_mask;
609
+ /// assert_eq!(tag, 0b10);
610
+ ///
611
+ /// // Note that `tagged_ptr` is unaligned, it's UB to read from/write to it.
612
+ /// // To get original pointer `mask` can be used:
613
+ /// let masked_ptr = tagged_ptr.mask(ptr_mask);
614
+ /// assert_eq!(unsafe { *masked_ptr }, 17);
615
+ ///
616
+ /// unsafe { *masked_ptr = 0 };
617
+ /// assert_eq!(v, 0);
618
+ /// ```
591
619
#[ unstable( feature = "ptr_mask" , issue = "98290" ) ]
592
620
#[ must_use = "returns a new pointer rather than modifying its argument" ]
593
621
#[ inline( always) ]
0 commit comments