Re: [PATCH] rust: alloc: allow different error types in `KBox::pin_slice`
From: Danilo Krummrich
Date: Sat Feb 14 2026 - 09:17:57 EST
On Sat Feb 14, 2026 at 2:28 PM CET, Andreas Hindborg wrote:
> Previously, `KBox::pin_slice` required the initializer error type to match
> the return error type via `E: From<AllocError>`. This prevented using
> infallible initializers like `new_mutex!` inside `pin_slice`, because
> `Infallible` does not implement `From<AllocError>`.
>
> Introduce a separate type parameter `E2` for the initializer error type and
> require `AllocError: Into<E>` and `E2: Into<E>` instead. This allows the
> initializer to return a different error type that can be converted into the
> final error type, enabling use of infallible pin initializers in fallible
> allocation contexts.
>
> Signed-off-by: Andreas Hindborg <a.hindborg@xxxxxxxxxx>
I assume you have a user? I.e. do you need this patch in another tree?
> @@ -333,24 +333,31 @@ pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError>
> /// assert_eq!(s[3].d.lock().a, 20);
> /// # Ok::<(), Error>(())
> /// ```
> - pub fn pin_slice<Func, Item, E>(
> + pub fn pin_slice<Func, Item, E, E2>(
> mut init: Func,
> len: usize,
> flags: Flags,
> ) -> Result<Pin<Box<[T], A>>, E>
> where
> Func: FnMut(usize) -> Item,
> - Item: PinInit<T, E>,
> - E: From<AllocError>,
I think we should keep this bound and just add:
E: From<E2>,
> + Item: PinInit<T, E2>,
> + AllocError: Into<E>,
> + E2: Into<E>,
> {
> - let mut buffer = super::Vec::<T, A>::with_capacity(len, flags)?;
> + let mut buffer = match super::Vec::<T, A>::with_capacity(len, flags) {
> + Ok(buffer) => buffer,
> + Err(err) => return Err(err.into()),
> + };
This...
> for i in 0..len {
> let ptr = buffer.spare_capacity_mut().as_mut_ptr().cast();
> // SAFETY:
> // - `ptr` is a valid pointer to uninitialized memory.
> // - `ptr` is not used if an error is returned.
> // - `ptr` won't be moved until it is dropped, i.e. it is pinned.
> - unsafe { init(i).__pinned_init(ptr)? };
> + match unsafe { init(i).__pinned_init(ptr) } {
> + Ok(()) => (),
> + Err(err) => return Err(err.into()),
> + }
...and this match becomes unnecessary then.