Skip to contentSkip to conversation

rust: enable arbitrary_self_types and remove `Receiver`

PATCH In review Miguel Ojeda 2 participants 2 messages Dec 10, 2024

Subsystems (4)
lore
Share & tools
lore

Miguel Ojeda

author maintainer
#0 lore raw

PATCH 1/1 rust: enable arbitrary_self_types and remove `Receiver`

From: Gary Guo <[email protected]>

[ Upstream commit c95bbb59a9b22f9b838b15d28319185c1c884329 ]

The term "receiver" means that a type can be used as the type of self, and thus enables method call syntax foo.bar() instead of Foo::bar(foo). Stable Rust as of today (1.81) enables a limited selection of types (primitives and types in std, e.g. Box and Arc) to be used as receivers, while custom types cannot.

We want the kernel Arc type to have the same functionality as the Rust std Arc, so we use the Receiver trait (gated behind receiver_trait unstable feature) to gain the functionality.

The arbitrary_self_types RFC [1] (tracking issue [2]) is accepted and it will allow all types that implement a new Receiver trait (different from today's unstable trait) to be used as receivers. This trait will be automatically implemented for all Deref types, which include our Arc type, so we no longer have to opt-in to be used as receiver. To prepare us for the change, remove the Receiver implementation and the associated feature. To still allow Arc and others to be used as method receivers, turn on arbitrary_self_types feature instead.

This feature gate is introduced in 1.23.0. It used to enable both Deref types and raw pointer types to be used as receivers, but the latter is now split into a different feature gate in Rust 1.83 nightly. We do not need receivers on raw pointers so this change would not affect us and usage of arbitrary_self_types feature would work for all Rust versions that we support (>=1.78).

---
Please consider applying to 6.12.y.

It is meant to support the upcoming Rust 1.84.0 compiler (to be released in a month), since 6.12 LTS is the first stable kernel that supports a minimum Rust version, thus users may use newer compilers. Older LTSs do not need it, for that reason.

 rust/kernel/lib.rs      | 2 +-
 rust/kernel/list/arc.rs | 3 ---
 rust/kernel/sync/arc.rs | 6 ------
 scripts/Makefile.build  | 2 +-
 4 files changed, 2 insertions(+), 11 deletions(-)
rust/kernel/lib.rs +1 -1
index 032c9089e686..e936254531fd 100644
@@ -12,10 +12,10 @@
 //! do so first instead of bypassing this crate.
 
 #![no_std]
+#![feature(arbitrary_self_types)]
 #![feature(coerce_unsized)]
 #![feature(dispatch_from_dyn)]
 #![feature(new_uninit)]
-#![feature(receiver_trait)]
 #![feature(unsize)]
 
 // Ensure conditional compilation based on the kernel configuration works;
rust/kernel/list/arc.rs +0 -3
index d801b9dc6291..3483d8c232c4 100644
@@ -441,9 +441,6 @@ fn as_ref(&self) -> &Arc<T> {
     }
 }
 
-// This is to allow [`ListArc`] (and variants) to be used as the type of `self`.
-impl<T, const ID: u64> core::ops::Receiver for ListArc<T, ID> where T: ListArcSafe<ID> + ?Sized {}
-
 // This is to allow coercion from `ListArc<T>` to `ListArc<U>` if `T` can be converted to the
 // dynamically-sized type (DST) `U`.
 impl<T, U, const ID: u64> core::ops::CoerceUnsized<ListArc<U, ID>> for ListArc<T, ID>
rust/kernel/sync/arc.rs +0 -6
index 3021f30fd822..28743a7c74a8 100644
@@ -171,9 +171,6 @@ unsafe fn container_of(ptr: *const T) -> NonNull<ArcInner<T>> {
     }
 }
 
-// This is to allow [`Arc`] (and variants) to be used as the type of `self`.
-impl<T: ?Sized> core::ops::Receiver for Arc<T> {}
-
 // This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the
 // dynamically-sized type (DST) `U`.
 impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {}
@@ -480,9 +477,6 @@ pub struct ArcBorrow<'a, T: ?Sized + 'a> {
     _p: PhantomData<&'a ()>,
 }
 
-// This is to allow [`ArcBorrow`] (and variants) to be used as the type of `self`.
-impl<T: ?Sized> core::ops::Receiver for ArcBorrow<'_, T> {}
-
 // This is to allow `ArcBorrow<U>` to be dispatched on when `ArcBorrow<T>` can be coerced into
 // `ArcBorrow<U>`.
 impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<ArcBorrow<'_, U>>
scripts/Makefile.build +1 -1
index 8f423a1faf50..880785b52c04 100644
@@ -248,7 +248,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE
 # Compile Rust sources (.rs)
 # ---------------------------------------------------------------------------
 
-rust_allowed_features := new_uninit
+rust_allowed_features := arbitrary_self_types,new_uninit
 
 # `--out-dir` is required to avoid temporaries being created by `rustc` in the
 # current working directory, which may be not accessible in the out-of-tree

base-commit: 61baee2dc5341c936e7fa7b1ca33c5607868de69 --
2.47.1

maintainer
#1 lore raw

[ Sasha's backport helper bot ]

Hi,

The upstream commit SHA1 provided is correct: c95bbb59a9b22f9b838b15d28319185c1c884329

WARNING: Author mismatch between patch and upstream commit:
Backport author: Miguel Ojeda <[email protected]> Commit author: Gary Guo <[email protected]>

Status in newer kernel trees:
6.12.y | Not found

Note: The patch differs from the upstream commit:
---
1: c95bbb59a9b22 ! 1: 071e4c8427c47 rust: enable arbitrary_self_types and remove Receiver
@@ Metadata
## Commit message ##
rust: enable arbitrary_self_types and remove Receiver

+ [ Upstream commit c95bbb59a9b22f9b838b15d28319185c1c884329 ]
+
The term "receiver" means that a type can be used as the type of self, and thus enables method call syntax foo.bar() instead of Foo::bar(foo). Stable Rust as of today (1.81) enables a limited
@@ rust/kernel/lib.rs
+#![feature(arbitrary_self_types)]
#![feature(coerce_unsized)]
#![feature(dispatch_from_dyn)]
- #![feature(lint_reasons)]
#![feature(new_uninit)]
-#![feature(receiver_trait)]
#![feature(unsize)]
@@ scripts/Makefile.build: $(obj)/%.lst: $(obj)/%.c FORCE
# Compile Rust sources (.rs)
# ---------------------------------------------------------------------------

--rust_allowed_features := lint_reasons,new_uninit -+rust_allowed_features := arbitrary_self_types,lint_reasons,new_uninit +-rust_allowed_features := new_uninit ++rust_allowed_features := arbitrary_self_types,new_uninit

# --out-dir is required to avoid temporaries being created by rustc in the # current working directory, which may be not accessible in the out-of-tree
---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.12.y       |  Success    |  Success   |
| stable/linux-6.6.y        |  Failed     |  N/A       |
| stable/linux-6.1.y        |  Failed     |  N/A       |
| stable/linux-5.15.y       |  Failed     |  N/A       |
| stable/linux-5.10.y       |  Failed     |  N/A       |
| stable/linux-5.4.y        |  Failed     |  N/A       |