[PATCH 1/4] rust: aref: document safety of ARef doctest example

From: Cian McGuire

Date: Fri Jul 24 2026 - 17:56:29 EST


The `into_raw` doctest contains two `unsafe` items whose SAFETY comments
were left as "TODO.": the `AlwaysRefCounted` impl for the example's
`Empty` type, and the subsequent `ARef::from_raw` call.

Both are sound for the same reason: `Empty`'s `inc_ref`/`dec_ref` are
no-ops. `AlwaysRefCounted`'s safety contract only constrains `dec_ref`,
requiring that it not free the object while a live increment remains;
since this `dec_ref` never frees anything, that requirement holds
vacuously.

The same fact justifies the `from_raw` call. Elsewhere in this file,
`Clone` and `From<&T>` justify their own calls to `from_raw` by pointing
at a preceding `inc_ref()` call, but no such call happens in this
example. That is fine here specifically because `Empty` does not track a
real reference count at all, so there is no accounting for `from_raw` to
violate, regardless of whether an increment "really" occurred.

Suggested-by: Miguel Ojeda <ojeda@xxxxxxxxxx>
Link: https://github.com/Rust-for-Linux/linux/issues/351
Signed-off-by: Cian McGuire <cianmcguire167@xxxxxxxxx>
---
rust/kernel/sync/aref.rs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/rust/kernel/sync/aref.rs b/rust/kernel/sync/aref.rs
index b721b2e00b98..a27b9b8f2eda 100644
--- a/rust/kernel/sync/aref.rs
+++ b/rust/kernel/sync/aref.rs
@@ -124,7 +124,8 @@ pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
///
/// struct Empty {}
///
- /// # // SAFETY: TODO.
+ /// # // SAFETY: `inc_ref` and `dec_ref` are no-ops, so the requirement that `dec_ref`
+ /// # // must not free the object while a live increment remains is trivially satisfied.
/// unsafe impl AlwaysRefCounted for Empty {
/// fn inc_ref(&self) {}
/// unsafe fn dec_ref(_obj: NonNull<Self>) {}
@@ -132,7 +133,8 @@ pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
///
/// let mut data = Empty {};
/// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
- /// # // SAFETY: TODO.
+ /// # // SAFETY: `Empty`'s `inc_ref`/`dec_ref` do not track a real count, so `dec_ref` can
+ /// # // never free `data`; the safety contract of `from_raw` is vacuously satisfied here.
/// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
/// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
///
--
2.55.0