On 30.03.23 16:37, Alice Ryhl wrote:
On 3/30/23 00:33, y86-dev@xxxxxxxxxxxxxx wrote:
From: Benno Lossin <y86-dev@xxxxxxxxxxxxxx>
The `InPlaceInit` trait that provides two functions, for initializing
using `PinInit<T, E>` and `Init<T>`. It is implemented by `Arc<T>`,
`UniqueArc<T>` and `Box<T>`.
Signed-off-by: Benno Lossin <y86-dev@xxxxxxxxxxxxxx>
---
+/// Smart pointer that can initialize memory in-place.
+pub trait InPlaceInit<T>: Sized {
+ /// Use the given initializer to in-place initialize a `T`.
+ ///
+ /// If `T: !Unpin` it will not be able to move afterwards.
+ fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Pin<Self>>
+ where
+ Error: From<E>;
+
+ /// Use the given initializer to in-place initialize a `T`.
+ fn init<E>(init: impl Init<T, E>) -> error::Result<Self>
+ where
+ Error: From<E>;
+}
This definition is potentially rather limiting, because it can only be
used with error types that can be converted into a `kernel::Error`. What
do you think of this alternative?
pub trait InPlaceInit<T>: Sized {
fn pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
where
E: From<AllocError>;
fn init<E>(init: impl Init<T, E>) -> Result<Self, E>
where
E: From<AllocError>;
}
I initially implemented it like this, but it required almost always that
`E` is specified, I will try and see if the situation is any different now,
but I do not think so. In the user-space version of this API (see [1]) I
have four functions, normal variants that return an `AllocError` and `try`
variants that look exactly like what you suggested. In the kernel, we could
make the normal variants as they are now and add the `try` variants as you
described.
[1]: https://docs.rs/pinned-init/0.0.5/pinned_init/trait.InPlaceInit.html
--
Cheers,
Benno