Skip to content

core::ptr: deduplicate docs for as_ref, addr, and as_uninit_ref #142315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 13 additions & 65 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,28 +146,7 @@ impl<T: ?Sized> *const T {
self as _
}

/// Gets the "address" portion of the pointer.
///
/// This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
/// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
/// casting the returned address back to a pointer yields a [pointer without
/// provenance][without_provenance], which is undefined behavior to dereference. To properly
/// restore the lost information and obtain a dereferenceable pointer, use
/// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
///
/// If using those APIs is not possible because there is no way to preserve a pointer with the
/// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
/// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
/// instead. However, note that this makes your code less portable and less amenable to tools
/// that check for compliance with the Rust memory model.
///
/// On most platforms this will produce a value with the same bytes as the original
/// pointer, because all the bytes are dedicated to describing the address.
/// Platforms which need to store additional information in the pointer may
/// perform a change of representation to produce a value containing only the address
/// portion of the pointer. What that means is up to the platform to define.
///
/// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
#[doc = include_str!("./docs/addr.md")]
#[must_use]
#[inline(always)]
#[stable(feature = "strict_provenance", since = "1.84.0")]
Expand Down Expand Up @@ -254,23 +233,16 @@ impl<T: ?Sized> *const T {
(self.cast(), metadata(self))
}

/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
/// must be used instead.
///
/// [`as_uninit_ref`]: #method.as_uninit_ref
///
/// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is null *or*
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
#[doc = include_str!("./docs/as_ref.md")]
///
/// # Panics during const evaluation
///
/// This method will panic during const evaluation if the pointer cannot be
/// determined to be null or not. See [`is_null`] for more information.
/// ```
/// let ptr: *const u8 = &10u8 as *const u8;
///
/// [`is_null`]: #method.is_null
/// unsafe {
/// let val_back = &*ptr;
/// assert_eq!(val_back, &10);
/// }
/// ```
///
/// # Examples
///
Expand All @@ -284,20 +256,9 @@ impl<T: ?Sized> *const T {
/// }
/// ```
///
/// # Null-unchecked version
///
/// If you are sure the pointer can never be null and are looking for some kind of
/// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
/// dereference the pointer directly.
///
/// ```
/// let ptr: *const u8 = &10u8 as *const u8;
///
/// unsafe {
/// let val_back = &*ptr;
/// assert_eq!(val_back, &10);
/// }
/// ```
/// [`is_null`]: #method.is_null
/// [`as_uninit_ref`]: #method.as_uninit_ref
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")]
#[inline]
Expand Down Expand Up @@ -338,23 +299,10 @@ impl<T: ?Sized> *const T {
unsafe { &*self }
}

/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
/// that the value has to be initialized.
///
/// [`as_ref`]: #method.as_ref
///
/// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is null *or*
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
///
/// # Panics during const evaluation
///
/// This method will panic during const evaluation if the pointer cannot be
/// determined to be null or not. See [`is_null`] for more information.
#[doc = include_str!("./docs/as_uninit_ref.md")]
///
/// [`is_null`]: #method.is_null
/// [`as_ref`]: #method.as_ref
///
/// # Examples
///
Expand Down
21 changes: 21 additions & 0 deletions library/core/src/ptr/docs/INFO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
This directory holds method documentation that otherwise
would be duplicated across mutable and immutable pointers.

Note that most of the docs here are not the complete docs
for their corrosponding method. This is for a few reasons:

1. Examples need to be different for mutable/immutable
pointers, in order to actually call the correct method.
2. Link reference definitions are frequently different
between mutable/immutable pointers, in order to link to
the correct method.
For example, `<*const T>::as_ref` links to
`<*const T>::is_null`, while `<*mut T>::as_ref` links to
`<*mut T>::is_null`.
3. Many methods on mutable pointers link to an alternate
version that returns a mutable reference instead of
a shared reference.

Always review the rendered docs manually when making
changes to these files to make sure you're not accidentally
splitting up a section.
22 changes: 22 additions & 0 deletions library/core/src/ptr/docs/addr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Gets the "address" portion of the pointer.

This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
casting the returned address back to a pointer yields a [pointer without
provenance][without_provenance], which is undefined behavior to dereference. To properly
restore the lost information and obtain a dereferenceable pointer, use
[`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].

If using those APIs is not possible because there is no way to preserve a pointer with the
required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
instead. However, note that this makes your code less portable and less amenable to tools
that check for compliance with the Rust memory model.

On most platforms this will produce a value with the same bytes as the original
pointer, because all the bytes are dedicated to describing the address.
Platforms which need to store additional information in the pointer may
perform a change of representation to produce a value containing only the address
portion of the pointer. What that means is up to the platform to define.

This is a [Strict Provenance][crate::ptr#strict-provenance] API.
19 changes: 19 additions & 0 deletions library/core/src/ptr/docs/as_ref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Returns `None` if the pointer is null, or else returns a shared reference to
the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
must be used instead.

# Safety

When calling this method, you have to ensure that *either* the pointer is null *or*
the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).

# Panics during const evaluation

This method will panic during const evaluation if the pointer cannot be
determined to be null or not. See [`is_null`] for more information.

# Null-unchecked version

If you are sure the pointer can never be null and are looking for some kind of
`as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
dereference the pointer directly.
15 changes: 15 additions & 0 deletions library/core/src/ptr/docs/as_uninit_ref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Returns `None` if the pointer is null, or else returns a shared reference to
the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
that the value has to be initialized.

# Safety

When calling this method, you have to ensure that *either* the pointer is null *or*
the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
Note that because the created reference is to `MaybeUninit<T>`, the
source pointer can point to uninitialized memory.

# Panics during const evaluation

This method will panic during const evaluation if the pointer cannot be
determined to be null or not. See [`is_null`] for more information.
90 changes: 21 additions & 69 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,28 +133,9 @@ impl<T: ?Sized> *mut T {
self as _
}

/// Gets the "address" portion of the pointer.
///
/// This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
/// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
/// casting the returned address back to a pointer yields a [pointer without
/// provenance][without_provenance_mut], which is undefined behavior to dereference. To properly
/// restore the lost information and obtain a dereferenceable pointer, use
/// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
///
/// If using those APIs is not possible because there is no way to preserve a pointer with the
/// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
/// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
/// instead. However, note that this makes your code less portable and less amenable to tools
/// that check for compliance with the Rust memory model.
///
/// On most platforms this will produce a value with the same bytes as the original
/// pointer, because all the bytes are dedicated to describing the address.
/// Platforms which need to store additional information in the pointer may
/// perform a change of representation to produce a value containing only the address
/// portion of the pointer. What that means is up to the platform to define.
#[doc = include_str!("./docs/addr.md")]
///
/// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
/// [without_provenance]: without_provenance_mut
#[must_use]
#[inline(always)]
#[stable(feature = "strict_provenance", since = "1.84.0")]
Expand Down Expand Up @@ -241,26 +222,16 @@ impl<T: ?Sized> *mut T {
(self.cast(), super::metadata(self))
}

/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
/// must be used instead.
///
/// For the mutable counterpart see [`as_mut`].
#[doc = include_str!("./docs/as_ref.md")]
///
/// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
/// [`as_mut`]: #method.as_mut
///
/// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is null *or*
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
///
/// # Panics during const evaluation
///
/// This method will panic during const evaluation if the pointer cannot be
/// determined to be null or not. See [`is_null`] for more information.
/// ```
/// let ptr: *mut u8 = &mut 10u8 as *mut u8;
///
/// [`is_null`]: #method.is_null-1
/// unsafe {
/// let val_back = &*ptr;
/// println!("We got back the value: {val_back}!");
/// }
/// ```
///
/// # Examples
///
Expand All @@ -274,20 +245,14 @@ impl<T: ?Sized> *mut T {
/// }
/// ```
///
/// # Null-unchecked version
///
/// If you are sure the pointer can never be null and are looking for some kind of
/// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
/// dereference the pointer directly.
/// # See Also
///
/// ```
/// let ptr: *mut u8 = &mut 10u8 as *mut u8;
/// For the mutable counterpart see [`as_mut`].
///
/// unsafe {
/// let val_back = &*ptr;
/// println!("We got back the value: {val_back}!");
/// }
/// ```
/// [`is_null`]: #method.is_null-1
/// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
/// [`as_mut`]: #method.as_mut

#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")]
#[inline]
Expand Down Expand Up @@ -330,28 +295,15 @@ impl<T: ?Sized> *mut T {
unsafe { &*self }
}

/// Returns `None` if the pointer is null, or else returns a shared reference to
/// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
/// that the value has to be initialized.
///
/// For the mutable counterpart see [`as_uninit_mut`].
#[doc = include_str!("./docs/as_uninit_ref.md")]
///
/// [`is_null`]: #method.is_null-1
/// [`as_ref`]: pointer#method.as_ref-1
/// [`as_uninit_mut`]: #method.as_uninit_mut
///
/// # Safety
///
/// When calling this method, you have to ensure that *either* the pointer is null *or*
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
/// Note that because the created reference is to `MaybeUninit<T>`, the
/// source pointer can point to uninitialized memory.
///
/// # Panics during const evaluation
///
/// This method will panic during const evaluation if the pointer cannot be
/// determined to be null or not. See [`is_null`] for more information.
/// # See Also
/// For the mutable counterpart see [`as_uninit_mut`].
///
/// [`is_null`]: #method.is_null-1
/// [`as_uninit_mut`]: #method.as_uninit_mut
///
/// # Examples
///
Expand Down
Loading