Commit 514e4ed2 authored by Benno Lossin's avatar Benno Lossin
Browse files

rust: pin-init: add `syn` dependency and remove `proc-macro[2]` and `quote` workarounds



`syn` makes parsing Rust from proc-macros a lot simpler. `pin-init` has
not used `syn` up until now, because the we did not support it. That
changed in commit 54e3eae8 ("Merge patch series "`syn` support""),
so we can finally utilize the added ergonomics of parsing proc-macro
input with `syn`.

Previously we only had the `proc-macro` library available, whereas the
user-space version also used `proc-macro2` and `quote`. Now both are
available, so remove the workarounds.

Due to these changes, clippy emits warnings about unnecessary
`.to_string()` as `proc-macro2` provides an additional `PartialEq` impl
on `Ident`, so the warnings are fixed.

[ Adjusted wording from upstream version and added build system changes
  for the kernel - Benno ]

Co-developed-by: default avatarGary Guo <gary@garyguo.net>
Signed-off-by: default avatarGary Guo <gary@garyguo.net>
Reviewed-by: default avatarTamir Duberstein <tamird@gmail.com>
Tested-by: default avatarAndreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: default avatarBenno Lossin <lossin@kernel.org>
parent 901f1d73
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -212,9 +212,10 @@ rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE

rustdoc-pin_init_internal: private rustdoc_host = yes
rustdoc-pin_init_internal: private rustc_target_flags = --cfg kernel \
    --extern proc_macro --crate-type proc-macro
    --extern proc_macro --extern proc_macro2 --extern quote --extern syn \
    --crate-type proc-macro
rustdoc-pin_init_internal: $(src)/pin-init/internal/src/lib.rs \
    rustdoc-clean FORCE
    rustdoc-clean rustdoc-proc_macro2 rustdoc-quote rustdoc-syn FORCE
	+$(call if_changed,rustdoc)

rustdoc-pin_init: private rustdoc_host = yes
@@ -273,9 +274,10 @@ rusttestlib-macros: $(src)/macros/lib.rs \
	+$(call if_changed,rustc_test_library)

rusttestlib-pin_init_internal: private rustc_target_flags = --cfg kernel \
    --extern proc_macro
    --extern proc_macro --extern proc_macro2 --extern quote --extern syn
rusttestlib-pin_init_internal: private rustc_test_library_proc = yes
rusttestlib-pin_init_internal: $(src)/pin-init/internal/src/lib.rs FORCE
rusttestlib-pin_init_internal: $(src)/pin-init/internal/src/lib.rs \
    rusttestlib-proc_macro2 rusttestlib-quote rusttestlib-syn FORCE
	+$(call if_changed,rustc_test_library)

rusttestlib-pin_init: private rustc_target_flags = --extern pin_init_internal \
@@ -547,8 +549,10 @@ $(obj)/$(libmacros_name): $(src)/macros/lib.rs $(obj)/libproc_macro2.rlib \
    $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE
	+$(call if_changed_dep,rustc_procmacro)

$(obj)/$(libpin_init_internal_name): private rustc_target_flags = --cfg kernel
$(obj)/$(libpin_init_internal_name): $(src)/pin-init/internal/src/lib.rs FORCE
$(obj)/$(libpin_init_internal_name): private rustc_target_flags = --cfg kernel \
    --extern proc_macro2 --extern quote --extern syn
$(obj)/$(libpin_init_internal_name): $(src)/pin-init/internal/src/lib.rs \
    $(obj)/libproc_macro2.rlib $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE
	+$(call if_changed_dep,rustc_procmacro)

quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
+2 −5
Original line number Diff line number Diff line
// SPDX-License-Identifier: Apache-2.0 OR MIT

#[cfg(not(kernel))]
use proc_macro2 as proc_macro;

use proc_macro::{TokenStream, TokenTree};
use proc_macro2::{TokenStream, TokenTree};

/// Parsed generics.
///
@@ -101,7 +98,7 @@ pub(crate) fn parse_generics(input: TokenStream) -> (Generics, Vec<TokenTree>) {
                    1 => {
                        // Here depending on the token, it might be a generic variable name.
                        match tt.clone() {
                            TokenTree::Ident(i) if at_start && i.to_string() == "const" => {
                            TokenTree::Ident(i) if at_start && i == "const" => {
                                let Some(name) = toks.next() else {
                                    // Parsing error.
                                    break;
+0 −16
Original line number Diff line number Diff line
@@ -7,27 +7,11 @@
//! `pin-init` proc macros.

#![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))]
// Allow `.into()` to convert
// - `proc_macro2::TokenStream` into `proc_macro::TokenStream` in the user-space version.
// - `proc_macro::TokenStream` into `proc_macro::TokenStream` in the kernel version.
//   Clippy warns on this conversion, but it's required by the user-space version.
//
// Remove once we have `proc_macro2` in the kernel.
#![allow(clippy::useless_conversion)]
// Documentation is done in the pin-init crate instead.
#![allow(missing_docs)]

use proc_macro::TokenStream;

#[cfg(kernel)]
#[path = "../../../macros/quote.rs"]
#[macro_use]
#[cfg_attr(not(kernel), rustfmt::skip)]
mod quote;
#[cfg(not(kernel))]
#[macro_use]
extern crate quote;

mod helpers;
mod pin_data;
mod pinned_drop;
+6 −12
Original line number Diff line number Diff line
// SPDX-License-Identifier: Apache-2.0 OR MIT

#[cfg(not(kernel))]
use proc_macro2 as proc_macro;

use crate::helpers::{parse_generics, Generics};
use proc_macro::{Group, Punct, Spacing, TokenStream, TokenTree};
use proc_macro2::{Group, Punct, Spacing, TokenStream, TokenTree};
use quote::quote;

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
@@ -28,7 +26,7 @@ pub(crate) fn pin_data(args: TokenStream, input: TokenStream) -> TokenStream {
    // The name of the struct with ty_generics.
    let struct_name = rest
        .iter()
        .skip_while(|tt| !matches!(tt, TokenTree::Ident(i) if i.to_string() == "struct"))
        .skip_while(|tt| !matches!(tt, TokenTree::Ident(i) if i == "struct"))
        .nth(1)
        .and_then(|tt| match tt {
            TokenTree::Ident(_) => {
@@ -65,7 +63,7 @@ pub(crate) fn pin_data(args: TokenStream, input: TokenStream) -> TokenStream {
        .into_iter()
        .flat_map(|tt| {
            // We ignore top level `struct` tokens, since they would emit a compile error.
            if matches!(&tt, TokenTree::Ident(i) if i.to_string() == "struct") {
            if matches!(&tt, TokenTree::Ident(i) if i == "struct") {
                vec![tt]
            } else {
                replace_self_and_deny_type_defs(&struct_name, tt, &mut errs)
@@ -98,11 +96,7 @@ fn replace_self_and_deny_type_defs(
) -> Vec<TokenTree> {
    match tt {
        TokenTree::Ident(ref i)
            if i.to_string() == "enum"
                || i.to_string() == "trait"
                || i.to_string() == "struct"
                || i.to_string() == "union"
                || i.to_string() == "impl" =>
            if i == "enum" || i == "trait" || i == "struct" || i == "union" || i == "impl" =>
        {
            errs.extend(
                format!(
@@ -119,7 +113,7 @@ fn replace_self_and_deny_type_defs(
            );
            vec![tt]
        }
        TokenTree::Ident(i) if i.to_string() == "Self" => struct_name.clone(),
        TokenTree::Ident(i) if i == "Self" => struct_name.clone(),
        TokenTree::Literal(_) | TokenTree::Punct(_) | TokenTree::Ident(_) => vec![tt],
        TokenTree::Group(g) => vec![TokenTree::Group(Group::new(
            g.delimiter(),
+4 −6
Original line number Diff line number Diff line
// SPDX-License-Identifier: Apache-2.0 OR MIT

#[cfg(not(kernel))]
use proc_macro2 as proc_macro;

use proc_macro::{TokenStream, TokenTree};
use proc_macro2::{TokenStream, TokenTree};
use quote::quote;

pub(crate) fn pinned_drop(_args: TokenStream, input: TokenStream) -> TokenStream {
    let mut toks = input.into_iter().collect::<Vec<_>>();
    assert!(!toks.is_empty());
    // Ensure that we have an `impl` item.
    assert!(matches!(&toks[0], TokenTree::Ident(i) if i.to_string() == "impl"));
    assert!(matches!(&toks[0], TokenTree::Ident(i) if i == "impl"));
    // Ensure that we are implementing `PinnedDrop`.
    let mut nesting: usize = 0;
    let mut pinned_drop_idx = None;
@@ -27,7 +25,7 @@ pub(crate) fn pinned_drop(_args: TokenStream, input: TokenStream) -> TokenStream
        if i >= 1 && nesting == 0 {
            // Found the end of the generics, this should be `PinnedDrop`.
            assert!(
                matches!(tt, TokenTree::Ident(i) if i.to_string() == "PinnedDrop"),
                matches!(tt, TokenTree::Ident(i) if i == "PinnedDrop"),
                "expected 'PinnedDrop', found: '{tt:?}'"
            );
            pinned_drop_idx = Some(i);
Loading