@@ -588,6 +588,34 @@ impl<T: ?Sized> *mut T {
588588 ///
589589 /// For non-`Sized` pointees this operation changes only the data pointer,
590590 /// 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+ /// ```
591619 #[ unstable( feature = "ptr_mask" , issue = "98290" ) ]
592620 #[ must_use = "returns a new pointer rather than modifying its argument" ]
593621 #[ inline( always) ]
0 commit comments