summaryrefslogtreecommitdiff
path: root/rust/macros/pin_data.rs
diff options
context:
space:
mode:
authorBenno Lossin <benno.lossin@proton.me>2023-04-24 11:11:38 +0300
committerMiguel Ojeda <ojeda@kernel.org>2023-05-31 19:53:09 +0300
commite957b9cda31d5114905b0485af02d332fbd079d7 (patch)
treec0e935fd52c08a44e4ae4dbbdbb3b1470fc8b69d /rust/macros/pin_data.rs
parentb8342addded0099610902775617917fdee6edde8 (diff)
downloadlinux-e957b9cda31d5114905b0485af02d332fbd079d7.tar.xz
rust: macros: refactor generics parsing of `#[pin_data]` into its own function
Other macros might also want to parse generics. Additionally this makes the code easier to read, as the next commit will introduce more code in `#[pin_data]`. Also add more comments to explain how parsing generics work. Signed-off-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com> Link: https://lore.kernel.org/r/20230424081112.99890-2-benno.lossin@proton.me Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/macros/pin_data.rs')
-rw-r--r--rust/macros/pin_data.rs70
1 files changed, 9 insertions, 61 deletions
diff --git a/rust/macros/pin_data.rs b/rust/macros/pin_data.rs
index 954149d77181..c593b05d9e8c 100644
--- a/rust/macros/pin_data.rs
+++ b/rust/macros/pin_data.rs
@@ -1,71 +1,19 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT
-use proc_macro::{Punct, Spacing, TokenStream, TokenTree};
+use crate::helpers::{parse_generics, Generics};
+use proc_macro::TokenStream;
pub(crate) fn pin_data(args: TokenStream, input: TokenStream) -> TokenStream {
// This proc-macro only does some pre-parsing and then delegates the actual parsing to
// `kernel::__pin_data!`.
- //
- // In here we only collect the generics, since parsing them in declarative macros is very
- // elaborate. We also do not need to analyse their structure, we only need to collect them.
- // `impl_generics`, the declared generics with their bounds.
- let mut impl_generics = vec![];
- // Only the names of the generics, without any bounds.
- let mut ty_generics = vec![];
- // Tokens not related to the generics e.g. the `impl` token.
- let mut rest = vec![];
- // The current level of `<`.
- let mut nesting = 0;
- let mut toks = input.into_iter();
- // If we are at the beginning of a generic parameter.
- let mut at_start = true;
- for tt in &mut toks {
- match tt.clone() {
- TokenTree::Punct(p) if p.as_char() == '<' => {
- if nesting >= 1 {
- impl_generics.push(tt);
- }
- nesting += 1;
- }
- TokenTree::Punct(p) if p.as_char() == '>' => {
- if nesting == 0 {
- break;
- } else {
- nesting -= 1;
- if nesting >= 1 {
- impl_generics.push(tt);
- }
- if nesting == 0 {
- break;
- }
- }
- }
- tt => {
- if nesting == 1 {
- match &tt {
- TokenTree::Ident(i) if i.to_string() == "const" => {}
- TokenTree::Ident(_) if at_start => {
- ty_generics.push(tt.clone());
- ty_generics.push(TokenTree::Punct(Punct::new(',', Spacing::Alone)));
- at_start = false;
- }
- TokenTree::Punct(p) if p.as_char() == ',' => at_start = true,
- TokenTree::Punct(p) if p.as_char() == '\'' && at_start => {
- ty_generics.push(tt.clone());
- }
- _ => {}
- }
- }
- if nesting >= 1 {
- impl_generics.push(tt);
- } else if nesting == 0 {
- rest.push(tt);
- }
- }
- }
- }
- rest.extend(toks);
+ 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::__pin_data! {