From e9c0f21f6397cba33667a656227bcb9bd364233c Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Thu, 28 Nov 2024 15:05:14 +0000 Subject: [PATCH] clarify requirements of `byte_{offset,add,sub}` for zero-sized referents The safety documentation on `core::ptr` presents this rule: > For operations of size zero, every pointer is valid, including the null pointer. However, due to the implementation details of `byte_{offset,add,sub}`, which involve operations on non-zero-sized referents, this rule does not apply to these methods. This commit clarifies extends the over-arching rule with an "unless otherwise noted" caveat, and clarifies the documentation of `byte_{offset,add,sub}` to note that the only valid `count` for zero-sized referents is presently `0`. --- library/core/src/ptr/const_ptr.rs | 30 ++++++++++++++++++------------ library/core/src/ptr/mod.rs | 2 +- library/core/src/ptr/mut_ptr.rs | 24 +++++++++++++++--------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 27516789f867c..bc49bf99e35c1 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -444,9 +444,11 @@ impl *const T { /// /// `count` is in units of **bytes**. /// - /// This is purely a convenience for casting to a `u8` pointer and - /// using [offset][pointer::offset] on it. See that method for documentation - /// and safety requirements. + /// This is purely a convenience for casting to a `u8` pointer and using + /// [offset][pointer::offset] on it. See that method for documentation and + /// safety requirements. Note that the usual guidance on operations on + /// zero-sized referents does not apply here — the only valid `count` for + /// zero-sized referents is `0`. /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. @@ -526,9 +528,9 @@ impl *const T { /// /// `count` is in units of **bytes**. /// - /// This is purely a convenience for casting to a `u8` pointer and - /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method - /// for documentation. + /// This is purely a convenience for casting to a `u8` pointer and using + /// [wrapping_offset][pointer::wrapping_offset] on it. See that method for + /// documentation. /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. @@ -955,9 +957,11 @@ impl *const T { /// /// `count` is in units of bytes. /// - /// This is purely a convenience for casting to a `u8` pointer and - /// using [add][pointer::add] on it. See that method for documentation - /// and safety requirements. + /// This is purely a convenience for casting to a `u8` pointer and using + /// [add][pointer::add] on it. See that method for documentation and safety + /// requirements. Note that the usual guidance on operations on zero-sized + /// referents does not apply here — the only valid `count`s for zero-sized + /// referents is `0`. /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. @@ -1068,9 +1072,11 @@ impl *const T { /// /// `count` is in units of bytes. /// - /// This is purely a convenience for casting to a `u8` pointer and - /// using [sub][pointer::sub] on it. See that method for documentation - /// and safety requirements. + /// This is purely a convenience for casting to a `u8` pointer and using + /// [sub][pointer::sub] on it. See that method for documentation and safety + /// requirements. Note that the usual guidance on operations on zero-sized + /// referents does not apply here — the only valid `count`s for zero-sized + /// referents is `0`. /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 805edddfe6312..4506a7468dd88 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -15,7 +15,7 @@ //! The precise rules for validity are not determined yet. The guarantees that are //! provided at this point are very minimal: //! -//! * For operations of [size zero][zst], *every* pointer is valid, including the [null] pointer. +//! * For operations of size zero, *every* pointer is valid, including the [null] pointer. //! The following points are only concerned with non-zero-sized accesses. //! * A [null] pointer is *never* valid. //! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer be diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e637edd745918..2d7aee7377381 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -442,9 +442,11 @@ impl *mut T { /// /// `count` is in units of **bytes**. /// - /// This is purely a convenience for casting to a `u8` pointer and - /// using [offset][pointer::offset] on it. See that method for documentation - /// and safety requirements. + /// This is purely a convenience for casting to a `u8` pointer and using + /// [offset][pointer::offset] on it. See that method for documentation and + /// safety requirements. Note that the usual guidance on operations on + /// zero-sized referents does not apply here — the only valid `count`s for + /// zero-sized referents is `0`. /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. @@ -1034,9 +1036,11 @@ impl *mut T { /// /// `count` is in units of bytes. /// - /// This is purely a convenience for casting to a `u8` pointer and - /// using [add][pointer::add] on it. See that method for documentation - /// and safety requirements. + /// This is purely a convenience for casting to a `u8` pointer and using + /// [add][pointer::add] on it. See that method for documentation and safety + /// requirements. Note that the usual guidance on operations on zero-sized + /// referents does not apply here — the only valid `count`s for zero-sized + /// referents is `0`. /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched. @@ -1147,9 +1151,11 @@ impl *mut T { /// /// `count` is in units of bytes. /// - /// This is purely a convenience for casting to a `u8` pointer and - /// using [sub][pointer::sub] on it. See that method for documentation - /// and safety requirements. + /// This is purely a convenience for casting to a `u8` pointer and using + /// [sub][pointer::sub] on it. See that method for documentation and safety + /// requirements. Note that the usual guidance on operations on zero-sized + /// referents does not apply here — the only valid `count`s for zero-sized + /// referents is `0`. /// /// For non-`Sized` pointees this operation changes only the data pointer, /// leaving the metadata untouched.