From: Danilo Krummrich <dakr@kernel.org>
To: lossin@kernel.org, gary@garyguo.net, ojeda@kernel.org,
boqun@kernel.org, bjorn3_gh@protonmail.com,
a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu,
daniel.almeida@collabora.com, tamird@kernel.org,
acourbot@nvidia.com, work@onurozkan.dev, lyude@redhat.com,
deborah.brouwer@collabora.com
Cc: rust-for-linux@vger.kernel.org, driver-core@lists.linux.dev,
Danilo Krummrich <dakr@kernel.org>
Subject: [PATCH 1/2] pin-init: add PinInit::map_err() for error type conversion
Date: Thu, 18 Jun 2026 21:32:58 +0200 [thread overview]
Message-ID: <20260618193951.601239-2-dakr@kernel.org> (raw)
In-Reply-To: <20260618193951.601239-1-dakr@kernel.org>
Add a map_err() method to PinInit that converts the error type of an
initializer. This is useful when combining initializers with different
error types, for example when an infallible initializer (error type
Infallible) needs to be used in a context that expects a different error
type.
The MapErr wrapper stores the original initializer and mapping function,
implementing PinInit and Init with the appropriate trait bounds on the
original initializer.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/pin-init/src/lib.rs | 44 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs
index fd40c8f244a1..deaf65147e99 100644
--- a/rust/pin-init/src/lib.rs
+++ b/rust/pin-init/src/lib.rs
@@ -949,6 +949,18 @@ fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
{
ChainPinInit(self, f, __internal::PhantomInvariant::new())
}
+
+ /// Convert the error type of this pin-initializer.
+ ///
+ /// This is useful when combining initializers with different error types, for example
+ /// when an infallible initializer (error type [`Infallible`]) needs to be used in a context
+ /// that expects a different error type.
+ fn map_err<E2, F>(self, f: F) -> MapErr<Self, F, T, E>
+ where
+ F: FnOnce(E) -> E2,
+ {
+ MapErr(self, f, __internal::PhantomInvariant::new())
+ }
}
/// An initializer returned by [`PinInit::pin_chain`].
@@ -975,6 +987,38 @@ unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
}
}
+/// An initializer returned by [`PinInit::map_err`].
+pub struct MapErr<I, F, T: ?Sized, E>(I, F, __internal::PhantomInvariant<(E, T)>);
+
+// SAFETY: The `__pinned_init` function is implemented such that it
+// - returns `Ok(())` on successful initialization,
+// - returns `Err(err)` on error and in this case `slot` will be dropped.
+// - considers `slot` pinned.
+unsafe impl<T: ?Sized, E, E2, I, F> PinInit<T, E2> for MapErr<I, F, T, E>
+where
+ I: PinInit<T, E>,
+ F: FnOnce(E) -> E2,
+{
+ unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E2> {
+ // SAFETY: All requirements fulfilled since this function is `__pinned_init`.
+ unsafe { self.0.__pinned_init(slot).map_err(self.1) }
+ }
+}
+
+// SAFETY: The `__init` function is implemented such that it
+// - returns `Ok(())` on successful initialization,
+// - returns `Err(err)` on error and in this case `slot` will be dropped.
+unsafe impl<T: ?Sized, E, E2, I, F> Init<T, E2> for MapErr<I, F, T, E>
+where
+ I: Init<T, E>,
+ F: FnOnce(E) -> E2,
+{
+ unsafe fn __init(self, slot: *mut T) -> Result<(), E2> {
+ // SAFETY: All requirements fulfilled since this function is `__init`.
+ unsafe { self.0.__init(slot).map_err(self.1) }
+ }
+}
+
/// An initializer for `T`.
///
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
--
2.54.0
next prev parent reply other threads:[~2026-06-18 19:40 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-18 19:32 [PATCH 0/2] rust: revocable: fix potential race between concurrent revokers Danilo Krummrich
2026-06-18 19:32 ` Danilo Krummrich [this message]
2026-06-18 19:32 ` [PATCH 2/2] rust: revocable: fix " Danilo Krummrich
2026-06-18 21:35 ` Boqun Feng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260618193951.601239-2-dakr@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=deborah.brouwer@collabora.com \
--cc=driver-core@lists.linux.dev \
--cc=gary@garyguo.net \
--cc=lossin@kernel.org \
--cc=lyude@redhat.com \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox