Skip to content

Commit 9173212

Browse files
committed
Auto merge of rust-lang#79273 - Dylan-DPC:rollup-zd10xlt, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - rust-lang#77844 (clarify rules for ZST Boxes) - rust-lang#79067 (Refactor the abi handling code a bit) - rust-lang#79182 (Fix links to extern types in rustdoc (fixes rust-lang#78777)) - rust-lang#79231 (Exhaustively match in variant count instrinsic) - rust-lang#79238 (Direct RUSTC_LOG (tracing/log) output to stderr instead of stdout.) - rust-lang#79256 (Fix typos) - rust-lang#79264 (Get rid of some doctree items) - rust-lang#79272 (Support building clone shims for arrays with generic size) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 201384e + 4d06975 commit 9173212

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

alloc/src/boxed.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@
6262
//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the
6363
//! [`Global`] allocator with [`Layout::for_value(&*value)`].
6464
//!
65+
//! For zero-sized values, the `Box` pointer still has to be [valid] for reads
66+
//! and writes and sufficiently aligned. In particular, casting any aligned
67+
//! non-zero integer literal to a raw pointer produces a valid pointer, but a
68+
//! pointer pointing into previously allocated memory that since got freed is
69+
//! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot
70+
//! be used is to use [`ptr::NonNull::dangling`].
71+
//!
6572
//! So long as `T: Sized`, a `Box<T>` is guaranteed to be represented
6673
//! as a single pointer and is also ABI-compatible with C pointers
6774
//! (i.e. the C type `T*`). This means that if you have extern "C"
@@ -125,6 +132,7 @@
125132
//! [`Global`]: crate::alloc::Global
126133
//! [`Layout`]: crate::alloc::Layout
127134
//! [`Layout::for_value(&*value)`]: crate::alloc::Layout::for_value
135+
//! [valid]: ptr#safety
128136
129137
#![stable(feature = "rust1", since = "1.0.0")]
130138

@@ -530,7 +538,10 @@ impl<T: ?Sized> Box<T> {
530538
/// memory problems. For example, a double-free may occur if the
531539
/// function is called twice on the same raw pointer.
532540
///
541+
/// The safety conditions are described in the [memory layout] section.
542+
///
533543
/// # Examples
544+
///
534545
/// Recreate a `Box` which was previously converted to a raw pointer
535546
/// using [`Box::into_raw`]:
536547
/// ```

core/src/ptr/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
//! provided at this point are very minimal:
1717
//!
1818
//! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst].
19-
//! * All pointers (except for the null pointer) are valid for all operations of
20-
//! [size zero][zst].
2119
//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer
2220
//! be *dereferenceable*: the memory range of the given size starting at the pointer must all be
2321
//! within the bounds of a single allocated object. Note that in Rust,
2422
//! every (stack-allocated) variable is considered a separate allocated object.
23+
//! * Even for operations of [size zero][zst], the pointer must not be pointing to deallocated
24+
//! memory, i.e., deallocation makes pointers invalid even for zero-sized operations. However,
25+
//! casting any non-zero integer *literal* to a pointer is valid for zero-sized accesses, even if
26+
//! some memory happens to exist at that address and gets deallocated. This corresponds to writing
27+
//! your own allocator: allocating zero-sized objects is not very hard. The canonical way to
28+
//! obtain a pointer that is valid for zero-sized accesses is [`NonNull::dangling`].
2529
//! * All accesses performed by functions in this module are *non-atomic* in the sense
2630
//! of [atomic operations] used to synchronize between threads. This means it is
2731
//! undefined behavior to perform two concurrent accesses to the same location from different

0 commit comments

Comments
 (0)