Currently, Revocable::new() only supports infallible PinInit
implementations, i.e. impl PinInit<T, Infallible>.
This has been sufficient so far, since users such as Devres do not
support fallibility.
Since this is about to change, make Revocable::new() generic over the
error type E.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/devres.rs | 2 +-
rust/kernel/revocable.rs | 7 +++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
index d8bdf2bdb879..a7df9fbd724f 100644
--- a/rust/kernel/devres.rs
+++ b/rust/kernel/devres.rs
@@ -98,7 +98,7 @@ struct DevresInner<T> {
impl<T> DevresInner<T> {
fn new(dev: &Device<Bound>, data: T, flags: Flags) -> Result<Arc<DevresInner<T>>> {
let inner = Arc::pin_init(
- pin_init!( DevresInner {
+ try_pin_init!( DevresInner {
dev: dev.into(),
callback: Self::devres_callback,
data <- Revocable::new(data),
diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs
index fa1fd70efa27..41b8fe374af6 100644
--- a/rust/kernel/revocable.rs
+++ b/rust/kernel/revocable.rs
@@ -82,8 +82,11 @@ unsafe impl<T: Sync + Send> Sync for Revocable<T> {}
impl<T> Revocable<T> {
/// Creates a new revocable instance of the given data.
- pub fn new(data: impl PinInit<T>) -> impl PinInit<Self> {
- pin_init!(Self {
+ pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, Error>
+ where
+ Error: From<E>,
+ {
+ try_pin_init!(Self {
is_available: AtomicBool::new(true),
data <- Opaque::pin_init(data),
})
--
2.49.0
On Thu Jun 12, 2025 at 4:51 PM CEST, Danilo Krummrich wrote: > Currently, Revocable::new() only supports infallible PinInit > implementations, i.e. impl PinInit<T, Infallible>. > > This has been sufficient so far, since users such as Devres do not > support fallibility. > > Since this is about to change, make Revocable::new() generic over the > error type E. > > Signed-off-by: Danilo Krummrich <dakr@kernel.org> > --- > rust/kernel/devres.rs | 2 +- > rust/kernel/revocable.rs | 7 +++++-- > 2 files changed, 6 insertions(+), 3 deletions(-) > > diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs > index d8bdf2bdb879..a7df9fbd724f 100644 > --- a/rust/kernel/devres.rs > +++ b/rust/kernel/devres.rs > @@ -98,7 +98,7 @@ struct DevresInner<T> { > impl<T> DevresInner<T> { > fn new(dev: &Device<Bound>, data: T, flags: Flags) -> Result<Arc<DevresInner<T>>> { > let inner = Arc::pin_init( > - pin_init!( DevresInner { > + try_pin_init!( DevresInner { > dev: dev.into(), > callback: Self::devres_callback, > data <- Revocable::new(data), > diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs > index fa1fd70efa27..41b8fe374af6 100644 > --- a/rust/kernel/revocable.rs > +++ b/rust/kernel/revocable.rs > @@ -82,8 +82,11 @@ unsafe impl<T: Sync + Send> Sync for Revocable<T> {} > > impl<T> Revocable<T> { > /// Creates a new revocable instance of the given data. > - pub fn new(data: impl PinInit<T>) -> impl PinInit<Self> { > - pin_init!(Self { > + pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, Error> > + where > + Error: From<E>, I don't think we need this bound as you don't use it in the function body. --- Cheers, Benno > + { > + try_pin_init!(Self { > is_available: AtomicBool::new(true), > data <- Opaque::pin_init(data), > })
On Thu, Jun 12, 2025 at 05:48:36PM +0200, Benno Lossin wrote: > On Thu Jun 12, 2025 at 4:51 PM CEST, Danilo Krummrich wrote: > > diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs > > index fa1fd70efa27..41b8fe374af6 100644 > > --- a/rust/kernel/revocable.rs > > +++ b/rust/kernel/revocable.rs > > @@ -82,8 +82,11 @@ unsafe impl<T: Sync + Send> Sync for Revocable<T> {} > > > > impl<T> Revocable<T> { > > /// Creates a new revocable instance of the given data. > > - pub fn new(data: impl PinInit<T>) -> impl PinInit<Self> { > > - pin_init!(Self { > > + pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, Error> > > + where > > + Error: From<E>, > > I don't think we need this bound as you don't use it in the function > body. I think it's needed by try_pin_init!() below, no? Without it I get the compilation error in [1]. > > + { > > + try_pin_init!(Self { > > is_available: AtomicBool::new(true), > > data <- Opaque::pin_init(data), > > }) > [1] error[E0277]: `?` couldn't convert the error to `error::Error` --> rust/kernel/revocable.rs:87:9 | 87 | / try_pin_init!(Self { 88 | | is_available: AtomicBool::new(true), 89 | | data <- Opaque::pin_init(data), 90 | | }) | | ^ | | | | |__________this can't be annotated with `?` because it has type `Result<_, E>` | the trait `core::convert::From<E>` is not implemented for `error::Error` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: required for `core::result::Result<revocable::Revocable<T>::new::__InitOk, error::Error>` to implement `core::ops::FromResidual<core::result::Result<core::convert::Infallible, E>>` = note: this error originates in the macro `$crate::__init_internal` which comes from the expansion of the macro `try_pin_init` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | 83 | impl<T> Revocable<T> where error::Error: core::convert::From<E> { | ++++++++++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `impl PinInit<Revocable<T>, Error>: PinInit<Revocable<T>, E>` is not satisfied --> rust/kernel/revocable.rs:85:48 | 85 | pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, E> | ^^^^^^^^^^^^^^^^^^^^^ the trait `pin_init::PinInit<revocable::Revocable<T>, E>` is not implemented for `impl pin_init::PinInit<revocable::Revocable<T>, error::Error>` | = help: the following other types implement trait `pin_init::PinInit<T, E>`: `core::result::Result<T, E>` implements `pin_init::PinInit<T, E>` `pin_init::ChainInit<I, F, T, E>` implements `pin_init::PinInit<T, E>` `pin_init::ChainPinInit<I, F, T, E>` implements `pin_init::PinInit<T, E>` `pin_init::__internal::AlwaysFail<T>` implements `pin_init::PinInit<T, ()>` = note: the full name for the type has been written to 'kernel.long-type-441004638990533407.txt' = note: consider using `--verbose` to print the full type name to the console
On Thu Jun 12, 2025 at 5:58 PM CEST, Danilo Krummrich wrote: > On Thu, Jun 12, 2025 at 05:48:36PM +0200, Benno Lossin wrote: >> On Thu Jun 12, 2025 at 4:51 PM CEST, Danilo Krummrich wrote: >> > diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs >> > index fa1fd70efa27..41b8fe374af6 100644 >> > --- a/rust/kernel/revocable.rs >> > +++ b/rust/kernel/revocable.rs >> > @@ -82,8 +82,11 @@ unsafe impl<T: Sync + Send> Sync for Revocable<T> {} >> > >> > impl<T> Revocable<T> { >> > /// Creates a new revocable instance of the given data. >> > - pub fn new(data: impl PinInit<T>) -> impl PinInit<Self> { >> > - pin_init!(Self { >> > + pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, Error> >> > + where >> > + Error: From<E>, >> >> I don't think we need this bound as you don't use it in the function >> body. > > I think it's needed by try_pin_init!() below, no? > > Without it I get the compilation error in [1]. > >> > + { >> > + try_pin_init!(Self { >> > is_available: AtomicBool::new(true), >> > data <- Opaque::pin_init(data), >> > }) Does it work with this? try_pin_init!(Self { is_available: AtomicBool::new(true), data <- Opaque::pin_init(data), }? E) --- Cheers, Benno >> > > [1] > > error[E0277]: `?` couldn't convert the error to `error::Error` > --> rust/kernel/revocable.rs:87:9 > | > 87 | / try_pin_init!(Self { > 88 | | is_available: AtomicBool::new(true), > 89 | | data <- Opaque::pin_init(data), > 90 | | }) > | | ^ > | | | > | |__________this can't be annotated with `?` because it has type `Result<_, E>` > | the trait `core::convert::From<E>` is not implemented for `error::Error` > | > = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait > = note: required for `core::result::Result<revocable::Revocable<T>::new::__InitOk, error::Error>` to implement `core::ops::FromResidual<core::result::Result<core::convert::Infallible, E>>` > = note: this error originates in the macro `$crate::__init_internal` which comes from the expansion of the macro `try_pin_init` (in Nightly builds, run with -Z macro-backtrace for more info) > help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement > | > 83 | impl<T> Revocable<T> where error::Error: core::convert::From<E> { > | ++++++++++++++++++++++++++++++++++++++++++ > > error[E0277]: the trait bound `impl PinInit<Revocable<T>, Error>: PinInit<Revocable<T>, E>` is not satisfied > --> rust/kernel/revocable.rs:85:48 > | > 85 | pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, E> > | ^^^^^^^^^^^^^^^^^^^^^ the trait `pin_init::PinInit<revocable::Revocable<T>, E>` is not implemented for `impl pin_init::PinInit<revocable::Revocable<T>, error::Error>` > | > = help: the following other types implement trait `pin_init::PinInit<T, E>`: > `core::result::Result<T, E>` implements `pin_init::PinInit<T, E>` > `pin_init::ChainInit<I, F, T, E>` implements `pin_init::PinInit<T, E>` > `pin_init::ChainPinInit<I, F, T, E>` implements `pin_init::PinInit<T, E>` > `pin_init::__internal::AlwaysFail<T>` implements `pin_init::PinInit<T, ()>` > = note: the full name for the type has been written to 'kernel.long-type-441004638990533407.txt' > = note: consider using `--verbose` to print the full type name to the console
On Thu, Jun 12, 2025 at 06:17:40PM +0200, Benno Lossin wrote: > On Thu Jun 12, 2025 at 5:58 PM CEST, Danilo Krummrich wrote: > > On Thu, Jun 12, 2025 at 05:48:36PM +0200, Benno Lossin wrote: > >> On Thu Jun 12, 2025 at 4:51 PM CEST, Danilo Krummrich wrote: > >> > diff --git a/rust/kernel/revocable.rs b/rust/kernel/revocable.rs > >> > index fa1fd70efa27..41b8fe374af6 100644 > >> > --- a/rust/kernel/revocable.rs > >> > +++ b/rust/kernel/revocable.rs > >> > @@ -82,8 +82,11 @@ unsafe impl<T: Sync + Send> Sync for Revocable<T> {} > >> > > >> > impl<T> Revocable<T> { > >> > /// Creates a new revocable instance of the given data. > >> > - pub fn new(data: impl PinInit<T>) -> impl PinInit<Self> { > >> > - pin_init!(Self { > >> > + pub fn new<E>(data: impl PinInit<T, E>) -> impl PinInit<Self, Error> > >> > + where > >> > + Error: From<E>, > >> > >> I don't think we need this bound as you don't use it in the function > >> body. > > > > I think it's needed by try_pin_init!() below, no? > > > > Without it I get the compilation error in [1]. > > > >> > + { > >> > + try_pin_init!(Self { > >> > is_available: AtomicBool::new(true), > >> > data <- Opaque::pin_init(data), > >> > }) > > Does it work with this? > > try_pin_init!(Self { > is_available: AtomicBool::new(true), > data <- Opaque::pin_init(data), > }? E) Yes, it does -- thanks!
© 2016 - 2025 Red Hat, Inc.