All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Gary Guo <gary@garyguo.net>
Cc: "Asahi Lina" <lina@asahilina.net>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Sven Van Asbroeck" <thesven73@gmail.com>,
	"Fox Chen" <foxhlchen@gmail.com>,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	asahi@lists.linux.dev
Subject: Re: [PATCH 5/5] rust: error: Add from_kernel_result!() macro
Date: Sat, 25 Feb 2023 18:22:11 -0800	[thread overview]
Message-ID: <Y/rCU1S+GDgIojNf@boqun-archlinux> (raw)
In-Reply-To: <20230225222340.34d749ee.gary@garyguo.net>

On Sat, Feb 25, 2023 at 10:23:40PM +0000, Gary Guo wrote:
> On Fri, 24 Feb 2023 15:56:05 -0800
> Boqun Feng <boqun.feng@gmail.com> wrote:
> 
> > On Fri, Feb 24, 2023 at 05:50:23PM +0900, Asahi Lina wrote:
> > > From: Wedson Almeida Filho <wedsonaf@gmail.com>
> > > 
> > > Add a helper macro to easily return C result codes from a Rust function
> > > that calls functions which return a Result<T>.
> > > 
> > > Lina: Imported from rust-for-linux/rust, originally developed by Wedson
> > > as part of file_operations.rs. Added the allow() flags since there is no
> > > user in the kernel crate yet and fixed a typo in a comment.
> > > 
> > > Co-developed-by: Fox Chen <foxhlchen@gmail.com>
> > > Signed-off-by: Fox Chen <foxhlchen@gmail.com>
> > > Co-developed-by: Miguel Ojeda <ojeda@kernel.org>
> > > Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
> > > Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
> > > Signed-off-by: Asahi Lina <lina@asahilina.net>
> > > ---
> > >  rust/kernel/error.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 52 insertions(+)
> > > 
> > > diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
> > > index cf3d089477d2..8a9222595cd1 100644
> > > --- a/rust/kernel/error.rs
> > > +++ b/rust/kernel/error.rs
> > > @@ -226,3 +226,55 @@ pub(crate) fn from_kernel_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
> > >      }
> > >      Ok(ptr)
> > >  }
> > > +
> > > +// TODO: Remove `dead_code` marker once an in-kernel client is available.
> > > +#[allow(dead_code)]
> > > +pub(crate) fn from_kernel_result_helper<T>(r: Result<T>) -> T
> > > +where
> > > +    T: From<i16>,
> > > +{
> > > +    match r {
> > > +        Ok(v) => v,
> > > +        // NO-OVERFLOW: negative `errno`s are no smaller than `-bindings::MAX_ERRNO`,
> > > +        // `-bindings::MAX_ERRNO` fits in an `i16` as per invariant above,
> > > +        // therefore a negative `errno` always fits in an `i16` and will not overflow.
> > > +        Err(e) => T::from(e.to_kernel_errno() as i16),
> > > +    }
> > > +}
> > > +
> > > +/// Transforms a [`crate::error::Result<T>`] to a kernel C integer result.
> > > +///
> > > +/// This is useful when calling Rust functions that return [`crate::error::Result<T>`]
> > > +/// from inside `extern "C"` functions that need to return an integer
> > > +/// error result.
> > > +///
> > > +/// `T` should be convertible from an `i16` via `From<i16>`.
> > > +///
> > > +/// # Examples
> > > +///
> > > +/// ```ignore
> > > +/// # use kernel::from_kernel_result;
> > > +/// # use kernel::bindings;
> > > +/// unsafe extern "C" fn probe_callback(
> > > +///     pdev: *mut bindings::platform_device,
> > > +/// ) -> core::ffi::c_int {
> > > +///     from_kernel_result! {
> > > +///         let ptr = devm_alloc(pdev)?;
> > > +///         bindings::platform_set_drvdata(pdev, ptr);
> > > +///         Ok(0)
> > > +///     }
> > > +/// }
> > > +/// ```
> > > +// TODO: Remove `unused_macros` marker once an in-kernel client is available.
> > > +#[allow(unused_macros)]
> > > +macro_rules! from_kernel_result {  
> > 
> > This actually doesn't need to be a macro, right? The following function
> > version:
> > 
> > 	pub fn from_kernel_result<T, F>(f: F) -> T
> > 	where
> > 	    T: From<i16>,
> > 	    F: FnOnce() -> Result<T>;
> > 
> > is not bad, the above case then can be written as:
> > 
> > 	unsafe extern "C" fn probe_callback(
> > 	    pdev: *mut bindings::platform_device,
> > 	) -> core::ffi::c_int {
> > 	    from_kernel_result(|| {
> > 		let ptr = devm_alloc(pdev)?;
> > 		bindings::platform_set_drvdata(pdev, ptr);
> > 		Ok(0)
> > 	    })
> > 	}
> > 
> > less magical, but the control flow is more clear.
> > 
> > Thoughts?
> 
> I don't think even the closure is necessary? Why not just
> 
>  	pub fn from_kernel_result<T: From<i16>>(r: Result<T>) -> T
> 
> and
> 
>  	unsafe extern "C" fn probe_callback(
>  	    pdev: *mut bindings::platform_device,
>  	) -> core::ffi::c_int {
>  	    from_kernel_result({
>  		let ptr = devm_alloc(pdev)?;

Hmm.. looks like the `?` only "propagating them (the errors) to the
calling *function*":

	https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator

, so this doesn't work as we expect:

	https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=64c9039e1da2c436f9f4f5ea46e97e90

Hope I didn't miss something subtle here..

Regards,
Boqun

>  		bindings::platform_set_drvdata(pdev, ptr);
>  		Ok(0)
>  	    })
>  	}
> 
> ?
> 
> Best,
> Gary

  reply	other threads:[~2023-02-26  2:22 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-24  8:50 [PATCH 0/5] rust: error: Add missing wrappers to convert to/from kernel error codes Asahi Lina
2023-02-24  8:50 ` [PATCH 1/5] rust: error: Add Error::to_ptr() Asahi Lina
2023-02-25 22:14   ` Gary Guo
2023-02-26 14:26     ` Miguel Ojeda
2023-03-07 20:21       ` Miguel Ojeda
2023-02-24  8:50 ` [PATCH 2/5] rust: error: Add Error::from_kernel_errno() Asahi Lina
2023-02-25 22:19   ` Gary Guo
2023-02-26 13:56     ` Miguel Ojeda
2023-02-27 13:27   ` Andreas Hindborg
2023-02-24  8:50 ` [PATCH 3/5] rust: error: Add to_result() helper Asahi Lina
2023-02-27 13:26   ` Andreas Hindborg
2023-02-24  8:50 ` [PATCH 4/5] rust: error: Add a helper to convert a C ERR_PTR to a `Result` Asahi Lina
2023-02-27 13:41   ` Andreas Hindborg
2023-02-27 13:52     ` Miguel Ojeda
2023-02-24  8:50 ` [PATCH 5/5] rust: error: Add from_kernel_result!() macro Asahi Lina
2023-02-24 23:56   ` Boqun Feng
2023-02-25  2:31     ` Asahi Lina
2023-02-25 22:23     ` Gary Guo
2023-02-26  2:22       ` Boqun Feng [this message]
2023-02-26 13:36         ` Gary Guo
2023-02-26 18:16           ` Boqun Feng
2023-02-26 20:59             ` Miguel Ojeda
2023-02-26 22:13               ` Boqun Feng
2023-02-27 12:10                 ` Miguel Ojeda
2023-02-27 16:11                   ` Boqun Feng
2023-02-27 13:59               ` Martin Rodriguez Reboredo
2023-02-26 13:40         ` Miguel Ojeda

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=Y/rCU1S+GDgIojNf@boqun-archlinux \
    --to=boqun.feng@gmail.com \
    --cc=alex.gaynor@gmail.com \
    --cc=asahi@lists.linux.dev \
    --cc=bjorn3_gh@protonmail.com \
    --cc=foxhlchen@gmail.com \
    --cc=gary@garyguo.net \
    --cc=lina@asahilina.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=thesven73@gmail.com \
    --cc=wedsonaf@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.