[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20251104-b4-as-flattened-v3-1-6cb9c26b45cd@nvidia.com>
Date: Tue, 04 Nov 2025 19:59:16 +0900
From: Alexandre Courbot <acourbot@...dia.com>
To: Miguel Ojeda <ojeda@...nel.org>, Boqun Feng <boqun.feng@...il.com>,
Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>, Andreas Hindborg <a.hindborg@...nel.org>,
Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>,
Danilo Krummrich <dakr@...nel.org>, Nathan Chancellor <nathan@...nel.org>,
Nicolas Schier <nicolas.schier@...ux.dev>
Cc: linux-kernel@...r.kernel.org, rust-for-linux@...r.kernel.org,
linux-kbuild@...r.kernel.org, Alexandre Courbot <acourbot@...dia.com>
Subject: [PATCH v3] rust: enable slice_flatten feature and provide it
through an extension trait
In Rust 1.80, the previously unstable `slice::flatten` family of methods
have been stabilized and renamed to `slice::as_flattened`.
This creates an issue as we want to use `as_flattened`, but need to
support the MSRV (which at the moment is Rust 1.78) where it is named
`flatten`.
Solve this by enabling the `slice_flatten` feature, and providing an
`as_flattened` implementation through an extension trait for compiler
versions where it is not available.
The trait is then exported from the prelude, making the `as_flattened`
family of methods transparently available for all supported compiler
versions.
This extension trait can be removed once the MSRV passes 1.80.
Suggested-by: Miguel Ojeda <ojeda@...nel.org>
Link: https://lore.kernel.org/all/CANiq72kK4pG=O35NwxPNoTO17oRcg1yfGcvr3==Fi4edr+sfmw@mail.gmail.com/
Acked-by: Danilo Krummrich <dakr@...nel.org>
Acked-by: Miguel Ojeda <ojeda@...nel.org>
Signed-off-by: Alexandre Courbot <acourbot@...dia.com>
---
This patch was part of the Nova GSP boot series [1], but since it
requires attention from the core Rust team (and possibly the build
maintainers?) and is otherwise buried under Nova patches, I am taking
the freedom to send it separately for visibility.
With v3 the extension trait is now imported if needed in the kernel
prelude, making its use transparent from user and not requiring any
user code update when it will be removed.
[1] https://lore.kernel.org/all/20251029-gsp_boot-v7-0-34227afad347@nvidia.com/
[2] https://lore.kernel.org/all/CANiq72kK4pG=O35NwxPNoTO17oRcg1yfGcvr3==Fi4edr+sfmw@mail.gmail.com/
---
Changes in v3:
- Include the extension trait in the kernel prelude so users don't need
to conditionally import it. (thanks Alice!)
- Link to v2: https://lore.kernel.org/r/20251104-b4-as-flattened-v2-1-b042d8715a8d@nvidia.com
Changes in v2:
- Rename methods to `as_flattened` and `as_flattened_mut` to match
standard library (thanks Alice!).
- Only expose the `AsFlattened` trait if using Rust < 1.80.
- Fixed a couple of typos (thanks Miguel!)
- Link to v1: https://lore.kernel.org/r/20251101-b4-as-flattened-v1-1-860f2ebeedfd@nvidia.com
---
init/Kconfig | 3 +++
rust/kernel/lib.rs | 4 ++++
rust/kernel/prelude.rs | 3 +++
rust/kernel/slice.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
scripts/Makefile.build | 3 ++-
5 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/init/Kconfig b/init/Kconfig
index cab3ad28ca49..7da93c9cccc3 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -147,6 +147,9 @@ config LD_CAN_USE_KEEP_IN_OVERLAY
# https://github.com/llvm/llvm-project/pull/130661
def_bool LD_IS_BFD || LLD_VERSION >= 210000
+config RUSTC_HAS_SLICE_AS_FLATTENED
+ def_bool RUSTC_VERSION >= 108000
+
config RUSTC_HAS_COERCE_POINTEE
def_bool RUSTC_VERSION >= 108400
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 3dd7bebe7888..2581a356d114 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -21,6 +21,9 @@
#![feature(inline_const)]
#![feature(pointer_is_aligned)]
//
+// Stable since Rust 1.80.0.
+#![feature(slice_flatten)]
+//
// Stable since Rust 1.81.0.
#![feature(lint_reasons)]
//
@@ -128,6 +131,7 @@
pub mod security;
pub mod seq_file;
pub mod sizes;
+pub mod slice;
mod static_assert;
#[doc(hidden)]
pub mod std_vendor;
diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
index 198d09a31449..9ee8acc563de 100644
--- a/rust/kernel/prelude.rs
+++ b/rust/kernel/prelude.rs
@@ -51,3 +51,6 @@
pub use super::current;
pub use super::uaccess::UserPtr;
+
+#[cfg(not(CONFIG_RUSTC_HAS_SLICE_AS_FLATTENED))]
+pub use super::slice::AsFlattened;
diff --git a/rust/kernel/slice.rs b/rust/kernel/slice.rs
new file mode 100644
index 000000000000..6ca91a4fd1f2
--- /dev/null
+++ b/rust/kernel/slice.rs
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Additional (and temporary) slice helpers.
+
+/// Extension trait providing a portable version of [`as_flattened`] and
+/// [`as_flattened_mut`].
+///
+/// In Rust 1.80, the previously unstable `slice::flatten` family of methods
+/// have been stabilized and renamed from `flatten` to `as_flattened`.
+///
+/// This creates an issue for as long as the MSRV is < 1.80, as the same functionality is provided
+/// by different methods depending on the compiler version.
+///
+/// This extension trait solves this by abstracting `as_flatten` and calling the correct method
+/// depending on the Rust version.
+///
+/// This trait can be removed once the MSRV passes 1.80.
+///
+/// [`as_flattened`]: slice::as_flattened
+/// [`as_flattened_mut`]: slice::as_flattened_mut
+#[cfg(not(CONFIG_RUSTC_HAS_SLICE_AS_FLATTENED))]
+pub trait AsFlattened<T> {
+ /// Takes a `&[[T; N]]` and flattens it to a `&[T]`.
+ ///
+ /// This is an portable layer on top of [`as_flattened`]; see its documentation for details.
+ ///
+ /// [`as_flattened`]: slice::as_flattened
+ fn as_flattened(&self) -> &[T];
+
+ /// Takes a `&mut [[T; N]]` and flattens it to a `&mut [T]`.
+ ///
+ /// This is an portable layer on top of [`as_flattened_mut`]; see its documentation for details.
+ ///
+ /// [`as_flattened_mut`]: slice::as_flattened_mut
+ fn as_flattened_mut(&mut self) -> &mut [T];
+}
+
+#[cfg(not(CONFIG_RUSTC_HAS_SLICE_AS_FLATTENED))]
+impl<T, const N: usize> AsFlattened<T> for [[T; N]] {
+ #[allow(clippy::incompatible_msrv)]
+ fn as_flattened(&self) -> &[T] {
+ self.flatten()
+ }
+
+ #[allow(clippy::incompatible_msrv)]
+ fn as_flattened_mut(&mut self) -> &mut [T] {
+ self.flatten_mut()
+ }
+}
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index d0ee33a487be..a84b9e3171a3 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -308,6 +308,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE
# The features in this list are the ones allowed for non-`rust/` code.
#
+# - Stable since Rust 1.80.0: `feature(slice_flatten)`.
# - Stable since Rust 1.81.0: `feature(lint_reasons)`.
# - Stable since Rust 1.82.0: `feature(asm_const)`,
# `feature(offset_of_nested)`, `feature(raw_ref_op)`.
@@ -317,7 +318,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE
#
# Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on
# the unstable features in use.
-rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,used_with_arg
+rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,slice_flatten,used_with_arg
# `--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: 6553a8f168fb7941ae73d39eccac64f3a2b9b399
change-id: 20251101-b4-as-flattened-0b3e0f566836
Best regards,
--
Alexandre Courbot <acourbot@...dia.com>
Powered by blists - more mailing lists