Rollup merge of #128157 - lolbinarycat:unify-ptr-ref-docs, r=cuviper
deduplicate and clarify rules for converting pointers to references part of #124669
This commit is contained in:
commit
c6ceb5be24
@ -239,24 +239,7 @@ impl<T: ?Sized> *const T {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
||||||
/// all of the following is true:
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
///
|
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -302,24 +285,8 @@ impl<T: ?Sized> *const T {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that all of the following is true:
|
/// When calling this method, you have to ensure that
|
||||||
///
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -350,20 +317,7 @@ impl<T: ?Sized> *const T {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
||||||
/// all of the following is true:
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
///
|
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -56,6 +56,52 @@
|
|||||||
//! has size 0, i.e., even if memory is not actually touched. Consider using
|
//! has size 0, i.e., even if memory is not actually touched. Consider using
|
||||||
//! [`NonNull::dangling`] in such cases.
|
//! [`NonNull::dangling`] in such cases.
|
||||||
//!
|
//!
|
||||||
|
//! ## Pointer to reference conversion
|
||||||
|
//! When converting a pointer to a reference `&T` using `&*`,
|
||||||
|
//! there are several rules that must be followed:
|
||||||
|
//!
|
||||||
|
//! * The pointer must be properly aligned.
|
||||||
|
//!
|
||||||
|
// some microprocessors may use address 0 for an interrupt vector.
|
||||||
|
// users of these microprocessors must always read/write address 0 through
|
||||||
|
// a raw pointer, not a reference.
|
||||||
|
//! * It must be non-null.
|
||||||
|
//!
|
||||||
|
//! * It must be "dereferenceable" in the sense defined above.
|
||||||
|
//!
|
||||||
|
//! * The pointer must point to a valid value of type `T`.
|
||||||
|
//! This means that the created reference can only refer to
|
||||||
|
//! uninitialized memory through careful use of `MaybeUninit`,
|
||||||
|
//! or if the uninitialized memory is entirely contained within
|
||||||
|
//! padding bytes, since
|
||||||
|
//! [padding has the same validity invariant as `MaybeUninit`][ucg-pad].
|
||||||
|
//!
|
||||||
|
//! * You must enforce Rust's aliasing rules, since the lifetime of the
|
||||||
|
//! created reference is arbitrarily chosen,
|
||||||
|
//! and does not necessarily reflect the actual lifetime of the data.
|
||||||
|
//! In particular, while this reference exists,
|
||||||
|
//! the memory the pointer points to must
|
||||||
|
//! not get accessed (read or written) through any raw pointer,
|
||||||
|
//! except for data inside an `UnsafeCell`.
|
||||||
|
//! Note that aliased writes are always UB for mutable references,
|
||||||
|
//! even if they only modify `UnsafeCell` data.
|
||||||
|
//!
|
||||||
|
//! If a pointer follows all of these rules, it is said to be
|
||||||
|
//! *convertible to a reference*.
|
||||||
|
// ^ we use this term instead of saying that the produced reference must
|
||||||
|
// be valid, as the validity of a reference is easily confused for the
|
||||||
|
// validity of the thing it refers to, and while the two concepts are
|
||||||
|
// closly related, they are not identical.
|
||||||
|
//!
|
||||||
|
//! These apply even if the result is unused!
|
||||||
|
//! (The part about being initialized is not yet fully decided, but until
|
||||||
|
//! it is, the only safe approach is to ensure that they are indeed initialized.)
|
||||||
|
//!
|
||||||
|
//! An example of the implications of the above rules is that an expression such
|
||||||
|
//! as `unsafe { &*(0 as *const u8) }` is Immediate Undefined Behavior.
|
||||||
|
//!
|
||||||
|
//! [ucgpad]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#padding
|
||||||
|
//!
|
||||||
//! ## Allocated object
|
//! ## Allocated object
|
||||||
//!
|
//!
|
||||||
//! An *allocated object* is a subset of program memory which is addressable
|
//! An *allocated object* is a subset of program memory which is addressable
|
||||||
|
@ -247,24 +247,7 @@ impl<T: ?Sized> *mut T {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
||||||
/// all of the following is true:
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
///
|
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -313,24 +296,7 @@ impl<T: ?Sized> *mut T {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that all of the following is true:
|
/// When calling this method, you have to ensure that the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
///
|
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -364,20 +330,9 @@ impl<T: ?Sized> *mut T {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
||||||
/// all of the following is true:
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
///
|
/// Note that because the created reference is to `MaybeUninit<T>`, the
|
||||||
/// * The pointer must be properly aligned.
|
/// source pointer can point to uninitialized memory.
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -609,25 +564,10 @@ impl<T: ?Sized> *mut T {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
/// When calling this method, you have to ensure that *either*
|
||||||
/// all of the following is true:
|
/// the pointer is null *or*
|
||||||
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
///
|
///
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get accessed (read or written) through any other pointer.
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -675,24 +615,8 @@ impl<T: ?Sized> *mut T {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that all of the following is true:
|
/// When calling this method, you have to ensure that
|
||||||
///
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -727,20 +651,7 @@ impl<T: ?Sized> *mut T {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
/// When calling this method, you have to ensure that *either* the pointer is null *or*
|
||||||
/// all of the following is true:
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
///
|
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get accessed (read or written) through any other pointer.
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
|
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
|
#[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
|
||||||
|
@ -126,20 +126,10 @@ impl<T: Sized> NonNull<T> {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that all of the following is true:
|
/// When calling this method, you have to ensure that
|
||||||
///
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
/// * The pointer must be properly aligned.
|
/// Note that because the created reference is to `MaybeUninit<T>`, the
|
||||||
///
|
/// source pointer can point to uninitialized memory.
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
|
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
|
||||||
@ -160,20 +150,10 @@ impl<T: Sized> NonNull<T> {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that all of the following is true:
|
/// When calling this method, you have to ensure that
|
||||||
///
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
/// * The pointer must be properly aligned.
|
/// Note that because the created reference is to `MaybeUninit<T>`, the
|
||||||
///
|
/// source pointer can point to uninitialized memory.
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get accessed (read or written) through any other pointer.
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
///
|
|
||||||
/// [the module documentation]: crate::ptr#safety
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
|
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
|
||||||
@ -359,22 +339,8 @@ impl<T: ?Sized> NonNull<T> {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that all of the following is true:
|
/// When calling this method, you have to ensure that
|
||||||
///
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get mutated (except inside `UnsafeCell`).
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -410,22 +376,8 @@ impl<T: ?Sized> NonNull<T> {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// When calling this method, you have to ensure that all of the following is true:
|
/// When calling this method, you have to ensure that
|
||||||
///
|
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
|
||||||
/// * The pointer must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * It must be "dereferenceable" in the sense defined in [the module documentation].
|
|
||||||
///
|
|
||||||
/// * The pointer must point to an initialized instance of `T`.
|
|
||||||
///
|
|
||||||
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
|
||||||
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
|
||||||
/// In particular, while this reference exists, the memory the pointer points to must
|
|
||||||
/// not get accessed (read or written) through any other pointer.
|
|
||||||
///
|
|
||||||
/// This applies even if the result of this method is unused!
|
|
||||||
/// (The part about being initialized is not yet fully decided, but until
|
|
||||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
Loading…
x
Reference in New Issue
Block a user