Skip to content

Commit b457d70

Browse files
authored
Rollup merge of #103694 - WaffleLapkin:mask_doc_example, r=scottmcm
Add documentation examples for `pointer::mask` The examples are somewhat convoluted, but I don't know how to make this better :(
2 parents 1db7f69 + 8498e3a commit b457d70

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

library/core/src/ptr/const_ptr.rs

+25
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,31 @@ impl<T: ?Sized> *const T {
568568
///
569569
/// For non-`Sized` pointees this operation changes only the data pointer,
570570
/// leaving the metadata untouched.
571+
///
572+
/// ## Examples
573+
///
574+
/// ```
575+
/// #![feature(ptr_mask, strict_provenance)]
576+
/// let v = 17_u32;
577+
/// let ptr: *const u32 = &v;
578+
///
579+
/// // `u32` is 4 bytes aligned,
580+
/// // which means that lower 2 bits are always 0.
581+
/// let tag_mask = 0b11;
582+
/// let ptr_mask = !tag_mask;
583+
///
584+
/// // We can store something in these lower bits
585+
/// let tagged_ptr = ptr.map_addr(|a| a | 0b10);
586+
///
587+
/// // Get the "tag" back
588+
/// let tag = tagged_ptr.addr() & tag_mask;
589+
/// assert_eq!(tag, 0b10);
590+
///
591+
/// // Note that `tagged_ptr` is unaligned, it's UB to read from it.
592+
/// // To get original pointer `mask` can be used:
593+
/// let masked_ptr = tagged_ptr.mask(ptr_mask);
594+
/// assert_eq!(unsafe { *masked_ptr }, 17);
595+
/// ```
571596
#[unstable(feature = "ptr_mask", issue = "98290")]
572597
#[must_use = "returns a new pointer rather than modifying its argument"]
573598
#[inline(always)]

library/core/src/ptr/mut_ptr.rs

+28
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)