All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gary Guo <gary@garyguo.net>
To: Benno Lossin <benno.lossin@proton.me>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Andreas Hindborg" <nmi@metaspace.dk>,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	patches@lists.linux.dev, "Asahi Lina" <lina@asahilina.net>
Subject: Re: [PATCH 2/7] rust: add derive macro for `Zeroable`
Date: Sun, 25 Jun 2023 21:46:28 +0100	[thread overview]
Message-ID: <20230625214628.32d55a54.gary@garyguo.net> (raw)
In-Reply-To: <20230624092330.157338-2-benno.lossin@proton.me>

On Sat, 24 Jun 2023 09:25:03 +0000
Benno Lossin <benno.lossin@proton.me> wrote:

> Add a derive proc-macro for the `Zeroable` trait. The macro supports
> structs where every field implements the `Zeroable` trait. This way
> `unsafe` implementations can be avoided.
> 
> The macro is split into two parts:
> - a proc-macro to parse generics into impl and ty generics,
> - a declarative macro that expands to the impl block.
> 
> Suggested-by: Asahi Lina <lina@asahilina.net>
> Signed-off-by: Benno Lossin <benno.lossin@proton.me>

Reviewed-by: Gary Guo <gary@garyguo.net>

> ---
>  rust/kernel/init/macros.rs | 28 ++++++++++++++++++++++++++++
>  rust/kernel/prelude.rs     |  2 +-
>  rust/macros/lib.rs         | 20 ++++++++++++++++++++
>  rust/macros/quote.rs       |  6 ++++++
>  rust/macros/zeroable.rs    | 25 +++++++++++++++++++++++++
>  5 files changed, 80 insertions(+), 1 deletion(-)
>  create mode 100644 rust/macros/zeroable.rs
> 
> diff --git a/rust/kernel/init/macros.rs b/rust/kernel/init/macros.rs
> index fbaebd34f218..e8165ff53a94 100644
> --- a/rust/kernel/init/macros.rs
> +++ b/rust/kernel/init/macros.rs
> @@ -1213,3 +1213,31 @@ macro_rules! __init_internal {
>          );
>      };
>  }
> +
> +#[doc(hidden)]
> +#[macro_export]
> +macro_rules! __derive_zeroable {
> +    (parse_input:
> +        @sig(
> +            $(#[$($struct_attr:tt)*])*
> +            $vis:vis struct $name:ident
> +            $(where $($whr:tt)*)?
> +        ),
> +        @impl_generics($($impl_generics:tt)*),
> +        @ty_generics($($ty_generics:tt)*),
> +        @body({
> +            $(
> +                $(#[$($field_attr:tt)*])*
> +                $field:ident : $field_ty:ty
> +            ),* $(,)?
> +        }),
> +    ) => {
> +        // SAFETY: every field type implements `Zeroable` and padding bytes may be zero.
> +        #[automatically_derived]
> +        unsafe impl<$($impl_generics)*> $crate::Zeroable for $name<$($ty_generics)*>
> +        where
> +            $($field_ty: $crate::Zeroable,)*
> +            $($($whr)*)?
> +        {}
> +    };
> +}
> diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
> index c28587d68ebc..ae21600970b3 100644
> --- a/rust/kernel/prelude.rs
> +++ b/rust/kernel/prelude.rs
> @@ -18,7 +18,7 @@
>  pub use alloc::{boxed::Box, vec::Vec};
> 
>  #[doc(no_inline)]
> -pub use macros::{module, pin_data, pinned_drop, vtable};
> +pub use macros::{module, pin_data, pinned_drop, vtable, Zeroable};
> 
>  pub use super::build_assert;
> 
> diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
> index 3fc74cb4ea19..9f056a5c780a 100644
> --- a/rust/macros/lib.rs
> +++ b/rust/macros/lib.rs
> @@ -10,6 +10,7 @@
>  mod pin_data;
>  mod pinned_drop;
>  mod vtable;
> +mod zeroable;
> 
>  use proc_macro::TokenStream;
> 
> @@ -246,3 +247,22 @@ pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream {
>  pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
>      pinned_drop::pinned_drop(args, input)
>  }
> +
> +/// Derives the [`Zeroable`] trait for the given struct.
> +///
> +/// This can only be used for structs where every field implements the [`Zeroable`] trait.
> +///
> +/// # Examples
> +///
> +/// ```rust
> +/// #[derive(Zeroable)]
> +/// pub struct DriverData {
> +///     id: i64,
> +///     buf_ptr: *mut u8,
> +///     len: usize,
> +/// }
> +/// ```
> +#[proc_macro_derive(Zeroable)]
> +pub fn derive_zeroable(input: TokenStream) -> TokenStream {
> +    zeroable::derive(input)
> +}
> diff --git a/rust/macros/quote.rs b/rust/macros/quote.rs
> index dddbb4e6f4cb..b76c198a4ed5 100644
> --- a/rust/macros/quote.rs
> +++ b/rust/macros/quote.rs
> @@ -124,6 +124,12 @@ macro_rules! quote_spanned {
>          ));
>          quote_spanned!(@proc $v $span $($tt)*);
>      };
> +    (@proc $v:ident $span:ident ; $($tt:tt)*) => {
> +        $v.push(::proc_macro::TokenTree::Punct(
> +                ::proc_macro::Punct::new(';', ::proc_macro::Spacing::Alone)
> +        ));
> +        quote_spanned!(@proc $v $span $($tt)*);
> +    };
>      (@proc $v:ident $span:ident $id:ident $($tt:tt)*) => {
>          $v.push(::proc_macro::TokenTree::Ident(::proc_macro::Ident::new(stringify!($id), $span)));
>          quote_spanned!(@proc $v $span $($tt)*);
> diff --git a/rust/macros/zeroable.rs b/rust/macros/zeroable.rs
> new file mode 100644
> index 000000000000..cddb866c44ef
> --- /dev/null
> +++ b/rust/macros/zeroable.rs
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +use crate::helpers::{parse_generics, Generics};
> +use proc_macro::TokenStream;
> +
> +pub(crate) fn derive(input: TokenStream) -> TokenStream {
> +    let (
> +        Generics {
> +            impl_generics,
> +            ty_generics,
> +        },
> +        mut rest,
> +    ) = parse_generics(input);
> +    // This should be the body of the struct `{...}`.
> +    let last = rest.pop();
> +    quote! {
> +        ::kernel::__derive_zeroable!(
> +            parse_input:
> +                @sig(#(#rest)*),
> +                @impl_generics(#(#impl_generics)*),
> +                @ty_generics(#(#ty_generics)*),
> +                @body(#last),
> +        );
> +    }
> +}
> --
> 2.41.0
> 
> 


  parent reply	other threads:[~2023-06-25 20:46 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-24  9:24 [PATCH 1/7] rust: init: consolidate init macros Benno Lossin
2023-06-24  9:25 ` [PATCH 2/7] rust: add derive macro for `Zeroable` Benno Lossin
2023-06-24 14:55   ` Björn Roy Baron
2023-06-25 20:46   ` Gary Guo [this message]
2023-07-03 11:50   ` Alice Ryhl
2023-06-24  9:25 ` [PATCH 3/7] rust: init: make guards in the init macros hygienic Benno Lossin
2023-06-24 14:58   ` Björn Roy Baron
2023-06-25 20:54   ` Gary Guo
2023-06-28 11:41     ` Benno Lossin
2023-06-28 16:48       ` Gary Guo
2023-06-24  9:25 ` [PATCH 4/7] rust: init: wrap type checking struct initializers in a closure Benno Lossin
2023-06-24 15:03   ` Björn Roy Baron
2023-06-24 21:05     ` Benno Lossin
2023-06-24  9:25 ` [PATCH 5/7] rust: init: add `..Zeroable::zeroed()` syntax for zeroing all missing fields Benno Lossin
2023-06-24 15:11   ` Björn Roy Baron
2023-06-24 21:14     ` Benno Lossin
2023-06-25 12:56       ` Björn Roy Baron
2023-06-25 13:07         ` Benno Lossin
2023-06-25 14:17           ` Björn Roy Baron
2023-06-25 16:46             ` Benno Lossin
2023-07-03 11:58   ` Alice Ryhl
2023-07-03 18:15   ` Boqun Feng
2023-07-05 17:48     ` Gary Guo
2023-07-05 21:44       ` Benno Lossin
2023-06-24  9:25 ` [PATCH 6/7] rust: init: Add functions to create array initializers Benno Lossin
2023-06-24 15:17   ` Björn Roy Baron
2023-07-03 12:03   ` Alice Ryhl
2023-06-24  9:25 ` [PATCH 7/7] rust: init: add support for arbitrary paths in init macros Benno Lossin
2023-06-24 15:20   ` Björn Roy Baron
2023-06-25 21:01   ` Gary Guo
2023-06-28 11:26     ` Benno Lossin
2023-06-28 17:13       ` Gary Guo
2023-06-24 14:49 ` [PATCH 1/7] rust: init: consolidate " Björn Roy Baron

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=20230625214628.32d55a54.gary@garyguo.net \
    --to=gary@garyguo.net \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=lina@asahilina.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nmi@metaspace.dk \
    --cc=ojeda@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=rust-for-linux@vger.kernel.org \
    --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.