Skip to content

Commit

Permalink
Rollup merge of rust-lang#103694 - WaffleLapkin:mask_doc_example, r=s…
Browse files Browse the repository at this point in the history
…cottmcm

Add documentation examples for `pointer::mask`

The examples are somewhat convoluted, but I don't know how to make this better :(
  • Loading branch information
Dylan-DPC authored Nov 9, 2022
2 parents 1c23d6a + 8498e3a commit b587010
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
25 changes: 25 additions & 0 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,31 @@ impl<T: ?Sized> *const T {
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
///
/// ## Examples
///
/// ```
/// #![feature(ptr_mask, strict_provenance)]
/// let v = 17_u32;
/// let ptr: *const u32 = &v;
///
/// // `u32` is 4 bytes aligned,
/// // which means that lower 2 bits are always 0.
/// let tag_mask = 0b11;
/// let ptr_mask = !tag_mask;
///
/// // We can store something in these lower bits
/// let tagged_ptr = ptr.map_addr(|a| a | 0b10);
///
/// // Get the "tag" back
/// let tag = tagged_ptr.addr() & tag_mask;
/// assert_eq!(tag, 0b10);
///
/// // Note that `tagged_ptr` is unaligned, it's UB to read from it.
/// // To get original pointer `mask` can be used:
/// let masked_ptr = tagged_ptr.mask(ptr_mask);
/// assert_eq!(unsafe { *masked_ptr }, 17);
/// ```
#[unstable(feature = "ptr_mask", issue = "98290")]
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline(always)]
Expand Down
28 changes: 28 additions & 0 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,34 @@ impl<T: ?Sized> *mut T {
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
///
/// ## Examples
///
/// ```
/// #![feature(ptr_mask, strict_provenance)]
/// let mut v = 17_u32;
/// let ptr: *mut u32 = &mut v;
///
/// // `u32` is 4 bytes aligned,
/// // which means that lower 2 bits are always 0.
/// let tag_mask = 0b11;
/// let ptr_mask = !tag_mask;
///
/// // We can store something in these lower bits
/// let tagged_ptr = ptr.map_addr(|a| a | 0b10);
///
/// // Get the "tag" back
/// let tag = tagged_ptr.addr() & tag_mask;
/// assert_eq!(tag, 0b10);
///
/// // Note that `tagged_ptr` is unaligned, it's UB to read from/write to it.
/// // To get original pointer `mask` can be used:
/// let masked_ptr = tagged_ptr.mask(ptr_mask);
/// assert_eq!(unsafe { *masked_ptr }, 17);
///
/// unsafe { *masked_ptr = 0 };
/// assert_eq!(v, 0);
/// ```
#[unstable(feature = "ptr_mask", issue = "98290")]
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline(always)]
Expand Down

0 comments on commit b587010

Please sign in to comment.