Skip to content

Commit e9c0f21

Browse files
committed
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`.
1 parent 9b4d7c6 commit e9c0f21

File tree

3 files changed

+34
-22
lines changed

3 files changed

+34
-22
lines changed

library/core/src/ptr/const_ptr.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,11 @@ impl<T: ?Sized> *const T {
444444
///
445445
/// `count` is in units of **bytes**.
446446
///
447-
/// This is purely a convenience for casting to a `u8` pointer and
448-
/// using [offset][pointer::offset] on it. See that method for documentation
449-
/// and safety requirements.
447+
/// This is purely a convenience for casting to a `u8` pointer and using
448+
/// [offset][pointer::offset] on it. See that method for documentation and
449+
/// safety requirements. Note that the usual guidance on operations on
450+
/// zero-sized referents does not apply here — the only valid `count` for
451+
/// zero-sized referents is `0`.
450452
///
451453
/// For non-`Sized` pointees this operation changes only the data pointer,
452454
/// leaving the metadata untouched.
@@ -526,9 +528,9 @@ impl<T: ?Sized> *const T {
526528
///
527529
/// `count` is in units of **bytes**.
528530
///
529-
/// This is purely a convenience for casting to a `u8` pointer and
530-
/// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
531-
/// for documentation.
531+
/// This is purely a convenience for casting to a `u8` pointer and using
532+
/// [wrapping_offset][pointer::wrapping_offset] on it. See that method for
533+
/// documentation.
532534
///
533535
/// For non-`Sized` pointees this operation changes only the data pointer,
534536
/// leaving the metadata untouched.
@@ -955,9 +957,11 @@ impl<T: ?Sized> *const T {
955957
///
956958
/// `count` is in units of bytes.
957959
///
958-
/// This is purely a convenience for casting to a `u8` pointer and
959-
/// using [add][pointer::add] on it. See that method for documentation
960-
/// and safety requirements.
960+
/// This is purely a convenience for casting to a `u8` pointer and using
961+
/// [add][pointer::add] on it. See that method for documentation and safety
962+
/// requirements. Note that the usual guidance on operations on zero-sized
963+
/// referents does not apply here — the only valid `count`s for zero-sized
964+
/// referents is `0`.
961965
///
962966
/// For non-`Sized` pointees this operation changes only the data pointer,
963967
/// leaving the metadata untouched.
@@ -1068,9 +1072,11 @@ impl<T: ?Sized> *const T {
10681072
///
10691073
/// `count` is in units of bytes.
10701074
///
1071-
/// This is purely a convenience for casting to a `u8` pointer and
1072-
/// using [sub][pointer::sub] on it. See that method for documentation
1073-
/// and safety requirements.
1075+
/// This is purely a convenience for casting to a `u8` pointer and using
1076+
/// [sub][pointer::sub] on it. See that method for documentation and safety
1077+
/// requirements. Note that the usual guidance on operations on zero-sized
1078+
/// referents does not apply here — the only valid `count`s for zero-sized
1079+
/// referents is `0`.
10741080
///
10751081
/// For non-`Sized` pointees this operation changes only the data pointer,
10761082
/// leaving the metadata untouched.

library/core/src/ptr/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//! The precise rules for validity are not determined yet. The guarantees that are
1616
//! provided at this point are very minimal:
1717
//!
18-
//! * For operations of [size zero][zst], *every* pointer is valid, including the [null] pointer.
18+
//! * For operations of size zero, *every* pointer is valid, including the [null] pointer.
1919
//! The following points are only concerned with non-zero-sized accesses.
2020
//! * A [null] pointer is *never* valid.
2121
//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer be

library/core/src/ptr/mut_ptr.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,11 @@ impl<T: ?Sized> *mut T {
442442
///
443443
/// `count` is in units of **bytes**.
444444
///
445-
/// This is purely a convenience for casting to a `u8` pointer and
446-
/// using [offset][pointer::offset] on it. See that method for documentation
447-
/// and safety requirements.
445+
/// This is purely a convenience for casting to a `u8` pointer and using
446+
/// [offset][pointer::offset] on it. See that method for documentation and
447+
/// safety requirements. Note that the usual guidance on operations on
448+
/// zero-sized referents does not apply here — the only valid `count`s for
449+
/// zero-sized referents is `0`.
448450
///
449451
/// For non-`Sized` pointees this operation changes only the data pointer,
450452
/// leaving the metadata untouched.
@@ -1034,9 +1036,11 @@ impl<T: ?Sized> *mut T {
10341036
///
10351037
/// `count` is in units of bytes.
10361038
///
1037-
/// This is purely a convenience for casting to a `u8` pointer and
1038-
/// using [add][pointer::add] on it. See that method for documentation
1039-
/// and safety requirements.
1039+
/// This is purely a convenience for casting to a `u8` pointer and using
1040+
/// [add][pointer::add] on it. See that method for documentation and safety
1041+
/// requirements. Note that the usual guidance on operations on zero-sized
1042+
/// referents does not apply here — the only valid `count`s for zero-sized
1043+
/// referents is `0`.
10401044
///
10411045
/// For non-`Sized` pointees this operation changes only the data pointer,
10421046
/// leaving the metadata untouched.
@@ -1147,9 +1151,11 @@ impl<T: ?Sized> *mut T {
11471151
///
11481152
/// `count` is in units of bytes.
11491153
///
1150-
/// This is purely a convenience for casting to a `u8` pointer and
1151-
/// using [sub][pointer::sub] on it. See that method for documentation
1152-
/// and safety requirements.
1154+
/// This is purely a convenience for casting to a `u8` pointer and using
1155+
/// [sub][pointer::sub] on it. See that method for documentation and safety
1156+
/// requirements. Note that the usual guidance on operations on zero-sized
1157+
/// referents does not apply here — the only valid `count`s for zero-sized
1158+
/// referents is `0`.
11531159
///
11541160
/// For non-`Sized` pointees this operation changes only the data pointer,
11551161
/// leaving the metadata untouched.

0 commit comments

Comments
 (0)