[PATCH v4 10/14] rust: alloc: add `Box::into_pin`

Andreas Hindborg posted 14 patches 1 year ago
There is a newer version of this series
[PATCH v4 10/14] rust: alloc: add `Box::into_pin`
Posted by Andreas Hindborg 1 year ago
Add an associated function to convert a `Box<T>` into a `Pin<Box<T>>`.

Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
 rust/kernel/alloc/kbox.rs | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 9ce414361c2c6dd8eea09b11041f6c307cbc7864..1a993ec8602b37041c192458d8b6acff30769a04 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -245,6 +245,16 @@ pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError>
         Ok(Self::new(x, flags)?.into())
     }
 
+    /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement
+    /// [`Unpin`], then `x` will be pinned in memory and can't be moved.
+    pub fn into_pin(boxed: Self) -> Pin<Self> {
+        // SAFETY: `Self` is guaranteed to be the only pointer to the boxed
+        // value. Thus, if `T: !Unpin`, `T` is guaranteed to stay pinned; there
+        // is no way to get rid of the `Pin` and move out of the returned
+        // `Pin<Box<T>>`.
+        unsafe { Pin::new_unchecked(boxed) }
+    }
+
     /// Forgets the contents (does not run the destructor), but keeps the allocation.
     fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> {
         let ptr = Self::into_raw(this);

-- 
2.46.0
Re: [PATCH v4 10/14] rust: alloc: add `Box::into_pin`
Posted by Danilo Krummrich 1 year ago
On Fri, Dec 06, 2024 at 08:33:02PM +0100, Andreas Hindborg wrote:
> Add an associated function to convert a `Box<T>` into a `Pin<Box<T>>`.

What do you need this function for?

There is an `impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>` already.

> 
> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
> ---
>  rust/kernel/alloc/kbox.rs | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
> index 9ce414361c2c6dd8eea09b11041f6c307cbc7864..1a993ec8602b37041c192458d8b6acff30769a04 100644
> --- a/rust/kernel/alloc/kbox.rs
> +++ b/rust/kernel/alloc/kbox.rs
> @@ -245,6 +245,16 @@ pub fn pin(x: T, flags: Flags) -> Result<Pin<Box<T, A>>, AllocError>
>          Ok(Self::new(x, flags)?.into())
>      }
>  
> +    /// Convert a [`Box<T,A>`] to a [`Pin<Box<T,A>>`]. If `T` does not implement
> +    /// [`Unpin`], then `x` will be pinned in memory and can't be moved.
> +    pub fn into_pin(boxed: Self) -> Pin<Self> {
> +        // SAFETY: `Self` is guaranteed to be the only pointer to the boxed
> +        // value. Thus, if `T: !Unpin`, `T` is guaranteed to stay pinned; there
> +        // is no way to get rid of the `Pin` and move out of the returned
> +        // `Pin<Box<T>>`.
> +        unsafe { Pin::new_unchecked(boxed) }
> +    }
> +
>      /// Forgets the contents (does not run the destructor), but keeps the allocation.
>      fn forget_contents(this: Self) -> Box<MaybeUninit<T>, A> {
>          let ptr = Self::into_raw(this);
> 
> -- 
> 2.46.0
> 
>
Re: [PATCH v4 10/14] rust: alloc: add `Box::into_pin`
Posted by Andreas Hindborg 1 year ago
"Danilo Krummrich" <dakr@kernel.org> writes:

> On Fri, Dec 06, 2024 at 08:33:02PM +0100, Andreas Hindborg wrote:
>> Add an associated function to convert a `Box<T>` into a `Pin<Box<T>>`.
>
> What do you need this function for?
>
> There is an `impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>` already.
>

I didn't realize, but that could work as well. I was rebasing this
series from before we did our own `Box`, and rust `Box` has this method,
which I was using.

At any rate, I think it would make sense to have `into_pin` as well as
the `From` impl, to match the standard library. We could always
implement one in terms of the other.


Best regards,
Andreas Hindborg
Re: [PATCH v4 10/14] rust: alloc: add `Box::into_pin`
Posted by Danilo Krummrich 1 year ago
On Fri, Dec 06, 2024 at 10:25:02PM +0100, Andreas Hindborg wrote:
> "Danilo Krummrich" <dakr@kernel.org> writes:
> 
> > On Fri, Dec 06, 2024 at 08:33:02PM +0100, Andreas Hindborg wrote:
> >> Add an associated function to convert a `Box<T>` into a `Pin<Box<T>>`.
> >
> > What do you need this function for?
> >
> > There is an `impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>` already.
> >
> 
> I didn't realize, but that could work as well. I was rebasing this
> series from before we did our own `Box`, and rust `Box` has this method,
> which I was using.
> 
> At any rate, I think it would make sense to have `into_pin` as well as
> the `From` impl, to match the standard library. We could always
> implement one in terms of the other.

I'm not against that -- one of my earlier allocator series actually even had
this function. However, the feedback was to rather not have it at the time.

As mentioned, I'm still fine with including this function though.

Please implement `ìnto_pin` using the existing `From` trait for the next
iteration.

- Danilo

> 
> 
> Best regards,
> Andreas Hindborg
> 
>