[PATCH] rust/alloc: add Vec::into_boxed_slice()
From: David Rheinsberg
Date: Thu Mar 26 2026 - 06:09:12 EST
Add `Vec::into_boxed_slice()` similar to
`std::vec::Vec::into_boxed_slice()` [1].
There is currently no way to easily consume the allocation of a vector.
However, it is very convenient to use `Vec` to initialize a dynamically
sized array and then "seal" it, so it can be passed along as a Box:
fn create_from(src: &[T]) -> Result<KBox<[U]>, AllocError> {
let v = Vec::with_capacity(n, GFP_KERNEL)?;
for i in src {
v.push(foo(i)?, GFP_KERNEL)?;
}
Ok(v.into_boxed_slice())
}
A valid alternative is to use `Box::new_uninit()` rather than
`Vec::with_capacity()`, and eventually convert the box via
`Box::assume_init()`. This works but needlessly requires unsafe code,
awkward drop handling, etc. Using `Vec` is the much simpler solution.
[1] https://doc.rust-lang.org/std/vec/struct.Vec.html#method.into_boxed_slice
Signed-off-by: David Rheinsberg <david@xxxxxxxxxxxx>
---
rust/kernel/alloc/kvec.rs | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index ac8d6f763ae8..537818bb66d0 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -826,6 +826,23 @@ pub fn resize(&mut self, new_len: usize, value: T, flags: Flags) -> Result<(), A
}
}
}
+
+ /// Converts the vector into [`Box<[T], A>`].
+ ///
+ /// Excess capacity is retained in the allocation, but lost until the box
+ /// is dropped.
+ pub fn into_boxed_slice(self) -> Box<[T], A> {
+ let (buf, len, _cap) = self.into_raw_parts();
+ let slice = ptr::slice_from_raw_parts_mut(buf, len);
+
+ // SAFETY:
+ // - `slice` has been allocated with `A`
+ // - `slice` is suitably aligned
+ // - `slice` has at least a length of `len`
+ // - all elements within `slice` are initialized values of `T`
+ // - `len` does not exceed `isize::MAX`
+ unsafe { Box::from_raw(slice) }
+ }
}
impl<T, A> Drop for Vec<T, A>
--
2.53.0