Skip to content

Commit b0c5dc2

Browse files
committed
edit docs a little
1 parent c8da321 commit b0c5dc2

File tree

2 files changed

+49
-27
lines changed

2 files changed

+49
-27
lines changed

src/libcore/intrinsics.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -986,11 +986,14 @@ extern "rust-intrinsic" {
986986
/// size_of::<T>()` bytes must *not* overlap with the region of memory
987987
/// beginning at `dst` with the same size.
988988
///
989-
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
990-
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
989+
/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
990+
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
991991
/// in the region beginning at `*src` and the region beginning at `*dst` can
992992
/// [violate memory safety][read-ownership].
993993
///
994+
/// These restrictions apply even if the effectively copied size (`count *
995+
/// size_of::<T>()`) is `0`.
996+
///
994997
/// [`Copy`]: ../marker/trait.Copy.html
995998
/// [`read`]: ../ptr/fn.read.html
996999
/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
@@ -1071,6 +1074,9 @@ extern "rust-intrinsic" {
10711074
/// in the region beginning at `*src` and the region beginning at `*dst` can
10721075
/// [violate memory safety][read-ownership].
10731076
///
1077+
/// These restrictions apply even if the effectively copied size (`count *
1078+
/// size_of::<T>()`) is `0`.
1079+
///
10741080
/// [`Copy`]: ../marker/trait.Copy.html
10751081
/// [`read`]: ../ptr/fn.read.html
10761082
/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
@@ -1115,6 +1121,9 @@ extern "rust-intrinsic" {
11151121
/// value of `T`. Creating an invalid value of `T` can result in undefined
11161122
/// behavior.
11171123
///
1124+
/// These restrictions apply even if the effectively written size (`count *
1125+
/// size_of::<T>()`) is `0`.
1126+
///
11181127
/// [valid]: ../ptr/index.html#safety
11191128
///
11201129
/// # Examples
@@ -1164,7 +1173,7 @@ extern "rust-intrinsic" {
11641173
/// `min_align_of::<T>()`
11651174
///
11661175
/// The volatile parameter is set to `true`, so it will not be optimized out
1167-
/// unless size is equal to zero..
1176+
/// unless size is equal to zero.
11681177
pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
11691178
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
11701179
/// size of `count` * `size_of::<T>()` and an alignment of

src/libcore/ptr.rs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,23 @@
1616
//!
1717
//! # Safety
1818
//!
19-
//! Many functions in this module take raw pointers as arguments and dereference
20-
//! them. For this to be safe, these pointers must be valid. However, because
21-
//! rust does not yet have a formal memory model, determining whether an
22-
//! arbitrary pointer is valid for a given operation can be tricky.
19+
//! Many functions in this module take raw pointers as arguments and read from
20+
//! or write to them. For this to be safe, these pointers must be *valid*.
21+
//! Whether a pointer is valid depends on the operation it is used for
22+
//! (read or write), and the extent of the memory that is accessed (i.e.,
23+
//! how many bytes are read/written). Most functions use `*mut T` and `*const T`
24+
//! to access only a single value, in which case the documentation omits the size
25+
//! and implicitly assumes it to be `size_of::<T>()` bytes.
2326
//!
24-
//! There are two types of operations on memory, reads and writes. A single
25-
//! pointer can be valid for any combination of these operations. For example, a
26-
//! pointer is not valid for writes if a `&mut` exists which [refers to the same
27-
//! memory][aliasing]. The set of operations for which a pointer argument must
28-
//! be valid is explicitly documented for each function. This is not strictly
29-
//! necessary for `*const` arguments, as they can only be used for reads and
30-
//! never for writes.
31-
//!
32-
//! Some functions (e.g. [`copy`]) take a single pointer but
33-
//! operate on many values. In this case, the function will state the size of
34-
//! the operation for which the pointer must be valid. For example,
35-
//! `copy::<T>(&src, &mut dst, 3)` requires `dst` to be valid for writes of
36-
//! `size_of::<T>() * 3` bytes. When the documentation requires that a pointer
37-
//! be valid for an operation but omits the size of that operation, the size is
38-
//! implied to be `size_of::<T>()` bytes.
39-
//!
40-
//! While we can't yet define whether an arbitrary pointer is a valid one, there
27+
//! While we can't yet define whether an arbitrary pointer is valid, there
4128
//! are a few rules regarding validity:
4229
//!
43-
//! * The result of casting a reference to a pointer is valid for as long as the
44-
//! underlying object is live.
45-
//! * A [null] pointer is *never* valid.
30+
//! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst].
4631
//! * All pointers (except for the null pointer) are valid for all operations of
4732
//! [size zero][zst].
33+
//! * The result of casting a reference to a pointer is valid for as long as the
34+
//! underlying object is live and no reference (just raw pointers) is used to
35+
//! access the same memory.
4836
//!
4937
//! These axioms, along with careful use of [`offset`] for pointer arithmentic,
5038
//! are enough to correctly implement many useful things in unsafe code. Still,
@@ -60,6 +48,10 @@
6048
//! this requirement in their documentation. Notable exceptions to this are
6149
//! [`read_unaligned`] and [`write_unaligned`].
6250
//!
51+
//! When a function requires proper alignment, it does so even if the access
52+
//! has size 0, i.e., even if memory is not actually touched. Consider using
53+
//! [`NonNull::dangling`] in such cases.
54+
//!
6355
//! [aliasing]: ../../nomicon/aliasing.html
6456
//! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
6557
//! [ub]: ../../reference/behavior-considered-undefined.html
@@ -69,6 +61,7 @@
6961
//! [`offset`]: ../../std/primitive.pointer.html#method.offset
7062
//! [`read_unaligned`]: ./fn.read_unaligned.html
7163
//! [`write_unaligned`]: ./fn.write_unaligned.html
64+
//! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
7265
7366
#![stable(feature = "rust1", since = "1.0.0")]
7467

@@ -122,6 +115,8 @@ pub use intrinsics::write_bytes;
122115
/// again. [`write`] can be used to overwrite data without causing it to be
123116
/// dropped.
124117
///
118+
/// These restrictions apply even if `T` has size `0`.
119+
///
125120
/// [valid]: ../ptr/index.html#safety
126121
/// [`Copy`]: ../marker/trait.Copy.html
127122
/// [`write`]: ../ptr/fn.write.html
@@ -211,6 +206,8 @@ pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
211206
///
212207
/// * Both `x` and `y` must be properly aligned.
213208
///
209+
/// These restrictions apply even if `T` has size `0`.
210+
///
214211
/// [valid]: ../ptr/index.html#safety
215212
///
216213
/// # Examples
@@ -278,6 +275,8 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
278275
/// size_of::<T>()` bytes must *not* overlap with the region of memory
279276
/// beginning at `y` with the same size.
280277
///
278+
/// These restrictions apply even if `T` has size `0`.
279+
///
281280
/// [valid]: ../ptr/index.html#safety
282281
///
283282
/// # Examples
@@ -389,6 +388,8 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
389388
///
390389
/// * `dest` must be properly aligned.
391390
///
391+
/// These restrictions apply even if `T` has size `0`.
392+
///
392393
/// [valid]: ../ptr/index.html#safety
393394
///
394395
/// # Examples
@@ -426,6 +427,8 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
426427
/// * `src` must be properly aligned. Use [`read_unaligned`] if this is not the
427428
/// case.
428429
///
430+
/// These restrictions apply even if `T` has size `0`.
431+
///
429432
/// ## Ownership of the Returned Value
430433
///
431434
/// `read` creates a bitwise copy of `T`, regardless of whether `T` is [`Copy`].
@@ -540,6 +543,8 @@ pub unsafe fn read<T>(src: *const T) -> T {
540543
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
541544
/// value and the value at `*src` can [violate memory safety][read-ownership].
542545
///
546+
/// These restrictions apply even if `T` has size `0`.
547+
///
543548
/// [`Copy`]: ../marker/trait.Copy.html
544549
/// [`read`]: ./fn.read.html
545550
/// [`write_unaligned`]: ./fn.write_unaligned.html
@@ -616,6 +621,8 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
616621
/// * `dst` must be properly aligned. Use [`write_unaligned`] if this is not the
617622
/// case.
618623
///
624+
/// These restrictions apply even if `T` has size `0`.
625+
///
619626
/// [valid]: ../ptr/index.html#safety
620627
/// [`write_unaligned`]: ./fn.write_unaligned.html
621628
///
@@ -687,6 +694,8 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
687694
///
688695
/// * `dst` must be [valid] for writes.
689696
///
697+
/// These restrictions apply even if `T` has size `0`.
698+
///
690699
/// [valid]: ../ptr/index.html#safety
691700
///
692701
/// # Examples
@@ -770,6 +779,8 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
770779
/// However, storing non-[`Copy`] types in volatile memory is almost certainly
771780
/// incorrect.
772781
///
782+
/// These restrictions apply even if `T` has size `0`.
783+
///
773784
/// [valid]: ../ptr/index.html#safety
774785
/// [`Copy`]: ../marker/trait.Copy.html
775786
/// [`read`]: ./fn.read.html
@@ -839,6 +850,8 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
839850
///
840851
/// * `dst` must be properly aligned.
841852
///
853+
/// These restrictions apply even if `T` has size `0`.
854+
///
842855
/// [valid]: ../ptr/index.html#safety
843856
///
844857
/// Just like in C, whether an operation is volatile has no bearing whatsoever

0 commit comments

Comments
 (0)