From nobody Mon Feb 9 07:22:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B0731EEE6; Sun, 11 Jan 2026 12:26:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768134409; cv=none; b=as02iqOQVUQQqFaTZBNqZOs0lsvxaqdj2yYfR/Z66uDUBnREIK5JZn/BbTjKAEixO2BonKKX/OsmK9zny1tXV5Mc/WhDcmiJWVtOI3T1vjM3f99C48ilmQOObNA3I0cfV1j+VZWwQ6C5lq77tIMp2K9g+3wyo/d6tBncW2j+KUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768134409; c=relaxed/simple; bh=pKB/7QQqseTCuEGoUrahYAjQ0lE+uRk5IYoEj++VtC8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U7iWIULP4iiYx65eXmP+XW+PxmQofzTAypDgLjXQqlr2/v8w+IEx4rqSxKEaImH8Xhi95dwmjpHhbOh/EjEl49uzvhdiccmv52Dc3lqgRBaFgMucTcJAqfl99TLQirqEigj/0eebR9DQWDBiPAXH/dazcEO4icCDIvpoZydYghY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fezW/XMC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fezW/XMC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8F5DDC4CEF7; Sun, 11 Jan 2026 12:26:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1768134408; bh=pKB/7QQqseTCuEGoUrahYAjQ0lE+uRk5IYoEj++VtC8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fezW/XMCASgxfuhgJJbQMo92yJMKIw0T83UT9gcxl82XOf9KdJq7KrOF8EjpayS57 i9rn/THTgw3cgU3Xe+QiIAjOpF7dsQ+lmBGn5iqsfR32JyGQraVYYWCRhEO1/PXW0D ngSqDBalu4H9Zb7hAkj1uAj2Cu3m8cjRAaczRjfQ8+0RACFAU0iKVDCjKxKxyychbR e8XJRjjH7Rs2XBHgztHXSAWxcLEHO/i9qKH4Mixh0Dr5tReHir6+xauX7MM8teGjAM mlb4lnc6YUID/HZW9T8cHjVf3IoRO7/nYU2eIgBMMPOCVR9oDmvunpMcrTMCM/TyYn A33WIzgXaeqZA== From: Benno Lossin To: Miguel Ojeda , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Fiona Behrens , Tamir Duberstein , Christian Schrefl Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 03/15] rust: pin-init: add `syn` dependency and remove `proc-macro[2]` and `quote` workarounds Date: Sun, 11 Jan 2026 13:25:01 +0100 Message-ID: <20260111122554.2662175-4-lossin@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260111122554.2662175-1-lossin@kernel.org> References: <20260111122554.2662175-1-lossin@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" `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 54e3eae85562 ("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: Gary Guo Signed-off-by: Gary Guo Reviewed-by: Tamir Duberstein Signed-off-by: Benno Lossin --- This commit is also used in Gary's series to rewrite the `macros` crate using syn:=20 https://lore.kernel.org/all/20260107161729.3855851-1-gary@kernel.org Changes in v2: none --- rust/Makefile | 16 ++++++++++------ rust/pin-init/internal/src/helpers.rs | 7 ++----- rust/pin-init/internal/src/lib.rs | 16 ---------------- rust/pin-init/internal/src/pin_data.rs | 18 ++++++------------ rust/pin-init/internal/src/pinned_drop.rs | 10 ++++------ rust/pin-init/internal/src/zeroable.rs | 6 ++---- scripts/generate_rust_analyzer.py | 2 +- 7 files changed, 25 insertions(+), 50 deletions(-) diff --git a/rust/Makefile b/rust/Makefile index 5d357dce1704..82bda6ccfe39 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -212,9 +212,10 @@ rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE =20 rustdoc-pin_init_internal: private rustdoc_host =3D yes rustdoc-pin_init_internal: private rustc_target_flags =3D --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) =20 rustdoc-pin_init: private rustdoc_host =3D yes @@ -273,9 +274,10 @@ rusttestlib-macros: $(src)/macros/lib.rs \ +$(call if_changed,rustc_test_library) =20 rusttestlib-pin_init_internal: private rustc_target_flags =3D --cfg kernel= \ - --extern proc_macro + --extern proc_macro --extern proc_macro2 --extern quote --extern syn rusttestlib-pin_init_internal: private rustc_test_library_proc =3D 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) =20 rusttestlib-pin_init: private rustc_target_flags =3D --extern pin_init_int= ernal \ @@ -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) =20 -$(obj)/$(libpin_init_internal_name): private rustc_target_flags =3D --cfg = kernel -$(obj)/$(libpin_init_internal_name): $(src)/pin-init/internal/src/lib.rs F= ORCE +$(obj)/$(libpin_init_internal_name): private rustc_target_flags =3D --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 FOR= CE +$(call if_changed_dep,rustc_procmacro) =20 quiet_cmd_rustc_library =3D $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QU= IET)) L $@ diff --git a/rust/pin-init/internal/src/helpers.rs b/rust/pin-init/internal= /src/helpers.rs index 236f989a50f2..90f85eaa4123 100644 --- a/rust/pin-init/internal/src/helpers.rs +++ b/rust/pin-init/internal/src/helpers.rs @@ -1,9 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT =20 -#[cfg(not(kernel))] -use proc_macro2 as proc_macro; - -use proc_macro::{TokenStream, TokenTree}; +use proc_macro2::{TokenStream, TokenTree}; =20 /// Parsed generics. /// @@ -101,7 +98,7 @@ pub(crate) fn parse_generics(input: TokenStream) -> (Gen= erics, Vec) { 1 =3D> { // Here depending on the token, it might be a gene= ric variable name. match tt.clone() { - TokenTree::Ident(i) if at_start && i.to_string= () =3D=3D "const" =3D> { + TokenTree::Ident(i) if at_start && i =3D=3D "c= onst" =3D> { let Some(name) =3D toks.next() else { // Parsing error. break; diff --git a/rust/pin-init/internal/src/lib.rs b/rust/pin-init/internal/src= /lib.rs index 297b0129a5bf..4c4dc639ce82 100644 --- a/rust/pin-init/internal/src/lib.rs +++ b/rust/pin-init/internal/src/lib.rs @@ -7,27 +7,11 @@ //! `pin-init` proc macros. =20 #![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 kerne= l 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)] =20 use proc_macro::TokenStream; =20 -#[cfg(kernel)] -#[path =3D "../../../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; diff --git a/rust/pin-init/internal/src/pin_data.rs b/rust/pin-init/interna= l/src/pin_data.rs index 87d4a7eb1d35..86a53b37cc66 100644 --- a/rust/pin-init/internal/src/pin_data.rs +++ b/rust/pin-init/internal/src/pin_data.rs @@ -1,10 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT =20 -#[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; =20 pub(crate) fn pin_data(args: TokenStream, input: TokenStream) -> TokenStre= am { // This proc-macro only does some pre-parsing and then delegates the a= ctual parsing to @@ -28,7 +26,7 @@ pub(crate) fn pin_data(args: TokenStream, input: TokenStr= eam) -> TokenStream { // The name of the struct with ty_generics. let struct_name =3D rest .iter() - .skip_while(|tt| !matches!(tt, TokenTree::Ident(i) if i.to_string(= ) =3D=3D "struct")) + .skip_while(|tt| !matches!(tt, TokenTree::Ident(i) if i =3D=3D "st= ruct")) .nth(1) .and_then(|tt| match tt { TokenTree::Ident(_) =3D> { @@ -65,7 +63,7 @@ pub(crate) fn pin_data(args: TokenStream, input: TokenStr= eam) -> 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() =3D=3D "= struct") { + if matches!(&tt, TokenTree::Ident(i) if i =3D=3D "struct") { vec![tt] } else { replace_self_and_deny_type_defs(&struct_name, tt, &mut err= s) @@ -98,11 +96,7 @@ fn replace_self_and_deny_type_defs( ) -> Vec { match tt { TokenTree::Ident(ref i) - if i.to_string() =3D=3D "enum" - || i.to_string() =3D=3D "trait" - || i.to_string() =3D=3D "struct" - || i.to_string() =3D=3D "union" - || i.to_string() =3D=3D "impl" =3D> + if i =3D=3D "enum" || i =3D=3D "trait" || i =3D=3D "struct" ||= i =3D=3D "union" || i =3D=3D "impl" =3D> { errs.extend( format!( @@ -119,7 +113,7 @@ fn replace_self_and_deny_type_defs( ); vec![tt] } - TokenTree::Ident(i) if i.to_string() =3D=3D "Self" =3D> struct_nam= e.clone(), + TokenTree::Ident(i) if i =3D=3D "Self" =3D> struct_name.clone(), TokenTree::Literal(_) | TokenTree::Punct(_) | TokenTree::Ident(_) = =3D> vec![tt], TokenTree::Group(g) =3D> vec![TokenTree::Group(Group::new( g.delimiter(), diff --git a/rust/pin-init/internal/src/pinned_drop.rs b/rust/pin-init/inte= rnal/src/pinned_drop.rs index c4ca7a70b726..cf8cd1c42984 100644 --- a/rust/pin-init/internal/src/pinned_drop.rs +++ b/rust/pin-init/internal/src/pinned_drop.rs @@ -1,15 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT =20 -#[cfg(not(kernel))] -use proc_macro2 as proc_macro; - -use proc_macro::{TokenStream, TokenTree}; +use proc_macro2::{TokenStream, TokenTree}; +use quote::quote; =20 pub(crate) fn pinned_drop(_args: TokenStream, input: TokenStream) -> Token= Stream { let mut toks =3D input.into_iter().collect::>(); assert!(!toks.is_empty()); // Ensure that we have an `impl` item. - assert!(matches!(&toks[0], TokenTree::Ident(i) if i.to_string() =3D=3D= "impl")); + assert!(matches!(&toks[0], TokenTree::Ident(i) if i =3D=3D "impl")); // Ensure that we are implementing `PinnedDrop`. let mut nesting: usize =3D 0; let mut pinned_drop_idx =3D None; @@ -27,7 +25,7 @@ pub(crate) fn pinned_drop(_args: TokenStream, input: Toke= nStream) -> TokenStream if i >=3D 1 && nesting =3D=3D 0 { // Found the end of the generics, this should be `PinnedDrop`. assert!( - matches!(tt, TokenTree::Ident(i) if i.to_string() =3D=3D "= PinnedDrop"), + matches!(tt, TokenTree::Ident(i) if i =3D=3D "PinnedDrop"), "expected 'PinnedDrop', found: '{tt:?}'" ); pinned_drop_idx =3D Some(i); diff --git a/rust/pin-init/internal/src/zeroable.rs b/rust/pin-init/interna= l/src/zeroable.rs index e0ed3998445c..d8a5ef3883f4 100644 --- a/rust/pin-init/internal/src/zeroable.rs +++ b/rust/pin-init/internal/src/zeroable.rs @@ -1,10 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 =20 -#[cfg(not(kernel))] -use proc_macro2 as proc_macro; - use crate::helpers::{parse_generics, Generics}; -use proc_macro::{TokenStream, TokenTree}; +use proc_macro2::{TokenStream, TokenTree}; +use quote::quote; =20 pub(crate) fn parse_zeroable_derive_input( input: TokenStream, diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_anal= yzer.py index 147d0cc94068..d31d93888658 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -123,7 +123,7 @@ def generate_crates(srctree, objtree, sysroot_src, exte= rnal_src, cfgs, core_edit append_crate( "pin_init_internal", srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs", - [], + ["std", "proc_macro", "proc_macro2", "quote", "syn"], cfg=3D["kernel"], is_proc_macro=3DTrue, ) --=20 2.52.0