[PATCH 1/4] rust: aref: document safety of ARef doctest example
Cian McGuire <[email protected]> Fri, 24 Jul 2026 22:49:37 +0100
| Newsgroups | org.kernel.vger.rust-for-linux,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> Link: https://github.com/Rust-for-Linux/linux/issues/351 Signed-off-by: Cian McGuire <[email protected]> --- 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