From 81af5b5031e346c5e2bdb8d0a88bf2904308a731 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 Nov 2023 10:55:18 +0100 Subject: [PATCH 1/2] update and clarify addr_of docs --- library/core/src/ptr/mod.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 84b179df8c192..12c6922eec0ce 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1989,9 +1989,18 @@ impl fmt::Debug for F { /// as all other references. This macro can create a raw pointer *without* creating /// a reference first. /// -/// Note, however, that the `expr` in `addr_of!(expr)` is still subject to all -/// the usual rules. In particular, `addr_of!(*ptr::null())` is Undefined -/// Behavior because it dereferences a null pointer. +/// The `expr` in `addr_of!(expr)` is evaluated as a place expression, but never loads +/// from the place or requires the place to be dereferenceable. This means that +/// `addr_of!(*ptr)` is defined behavior even if `ptr` is dangling or misaligned. +/// Note however that `addr_of!((*ptr).field)` still requires the projection to +/// `field` to be in-bounds, using the same rules as [`offset`]. +/// +/// Note that `Deref`/`Index` coercions (and their mutable counterparts) are applied inside +/// `addr_of!` like everywhere else, in which case a reference is created to call `Deref::deref` or +/// `Index::index`, respectively. The statements above only apply when no such coercions are +/// applied. +/// +/// [`offset`]: pointer::offset /// /// # Example /// @@ -2029,9 +2038,18 @@ pub macro addr_of($place:expr) { /// as all other references. This macro can create a raw pointer *without* creating /// a reference first. /// -/// Note, however, that the `expr` in `addr_of_mut!(expr)` is still subject to all -/// the usual rules. In particular, `addr_of_mut!(*ptr::null_mut())` is Undefined -/// Behavior because it dereferences a null pointer. +/// The `expr` in `addr_of_mut!(expr)` is evaluated as a place expression, but never loads +/// from the place or requires the place to be dereferenceable. This means that +/// `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is dangling or misaligned. +/// Note however that `addr_of_mut!((*ptr).field)` still requires the projection to +/// `field` to be in-bounds, using the same rules as [`offset`]. +/// +/// Note that `Deref`/`Index` coercions (and their mutable counterparts) are applied inside +/// `addr_of_mut!` like everywhere else, in which case a reference is created to call `Deref::deref` +/// or `Index::index`, respectively. The statements above only apply when no such coercions are +/// applied. +/// +/// [`offset`]: pointer::offset /// /// # Examples /// From e30f8ae8672c89ba473aea8662fd5f22992810fb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 10 Nov 2023 07:34:28 +0100 Subject: [PATCH 2/2] mention null explicitly Co-authored-by: Josh Stone --- library/core/src/ptr/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 12c6922eec0ce..289e234b669aa 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1991,7 +1991,7 @@ impl fmt::Debug for F { /// /// The `expr` in `addr_of!(expr)` is evaluated as a place expression, but never loads /// from the place or requires the place to be dereferenceable. This means that -/// `addr_of!(*ptr)` is defined behavior even if `ptr` is dangling or misaligned. +/// `addr_of!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned. /// Note however that `addr_of!((*ptr).field)` still requires the projection to /// `field` to be in-bounds, using the same rules as [`offset`]. /// @@ -2040,7 +2040,7 @@ pub macro addr_of($place:expr) { /// /// The `expr` in `addr_of_mut!(expr)` is evaluated as a place expression, but never loads /// from the place or requires the place to be dereferenceable. This means that -/// `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is dangling or misaligned. +/// `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned. /// Note however that `addr_of_mut!((*ptr).field)` still requires the projection to /// `field` to be in-bounds, using the same rules as [`offset`]. ///