Skip to content

Commit 1a8076a

Browse files
y86-devojeda
authored andcommitted
rust: init: make PinInit<T, E> a supertrait of Init<T, E>
Remove the blanket implementation of `PinInit<T, E> for I where I: Init<T, E>`. This blanket implementation prevented custom types that implement `PinInit`. Reviewed-by: Martin Rodriguez Reboredo <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Gary Guo <[email protected]> Signed-off-by: Benno Lossin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 2e704f1 commit 1a8076a

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed

rust/kernel/init.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
799799
///
800800
/// [`Arc<T>`]: crate::sync::Arc
801801
#[must_use = "An initializer must be used in order to create its value."]
802-
pub unsafe trait Init<T: ?Sized, E = Infallible>: Sized {
802+
pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
803803
/// Initializes `slot`.
804804
///
805805
/// # Safety
@@ -810,18 +810,6 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: Sized {
810810
unsafe fn __init(self, slot: *mut T) -> Result<(), E>;
811811
}
812812

813-
// SAFETY: Every in-place initializer can also be used as a pin-initializer.
814-
unsafe impl<T: ?Sized, E, I> PinInit<T, E> for I
815-
where
816-
I: Init<T, E>,
817-
{
818-
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
819-
// SAFETY: `__init` meets the same requirements as `__pinned_init`, except that it does not
820-
// require `slot` to not move after init.
821-
unsafe { self.__init(slot) }
822-
}
823-
}
824-
825813
/// Creates a new [`PinInit<T, E>`] from the given closure.
826814
///
827815
/// # Safety
@@ -964,6 +952,13 @@ unsafe impl<T, E> Init<T, E> for T {
964952
}
965953
}
966954

955+
// SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
956+
unsafe impl<T, E> PinInit<T, E> for T {
957+
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
958+
unsafe { self.__init(slot) }
959+
}
960+
}
961+
967962
/// Smart pointer that can initialize memory in-place.
968963
pub trait InPlaceInit<T>: Sized {
969964
/// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this

rust/kernel/init/__internal.rs

+12
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ where
3232
}
3333
}
3434

35+
// SAFETY: While constructing the `InitClosure`, the user promised that it upholds the
36+
// `__pinned_init` invariants.
37+
unsafe impl<T: ?Sized, F, E> PinInit<T, E> for InitClosure<F, T, E>
38+
where
39+
F: FnOnce(*mut T) -> Result<(), E>,
40+
{
41+
#[inline]
42+
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
43+
(self.0)(slot)
44+
}
45+
}
46+
3547
/// This trait is only implemented via the `#[pin_data]` proc-macro. It is used to facilitate
3648
/// the pin projections within the initializers.
3749
///

0 commit comments

Comments
 (0)