From eebcdf6b163174ec1629d121264c0477652e3323 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 10 Aug 2026 16:04:57 +0800 Subject: refactor(macros): clean up clippy lints and simplify code --- mingling_macros/src/attr/chain.rs | 44 ++++++++++----------------- mingling_macros/src/attr/completion.rs | 33 +++++--------------- mingling_macros/src/attr/help.rs | 3 +- mingling_macros/src/attr/renderer.rs | 28 +++++++++-------- mingling_macros/src/derive/enum_tag.rs | 14 +++------ mingling_macros/src/extensions.rs | 4 +-- mingling_macros/src/func/dispatcher.rs | 2 +- mingling_macros/src/func/node.rs | 4 +-- mingling_macros/src/func/pack.rs | 2 +- mingling_macros/src/func/pack_structural.rs | 3 +- mingling_macros/src/func/program_final_gen.rs | 1 + mingling_macros/src/func/r_append.rs | 16 +++++----- mingling_macros/src/func/r_print.rs | 8 ++--- mingling_macros/src/func/register_help.rs | 19 ++++++++---- mingling_macros/src/func/suggest.rs | 9 +++--- mingling_macros/src/lib.rs | 13 +++++--- mingling_macros/src/systems/res_injection.rs | 2 +- 17 files changed, 92 insertions(+), 113 deletions(-) diff --git a/mingling_macros/src/attr/chain.rs b/mingling_macros/src/attr/chain.rs index dc28a39..a597a39 100644 --- a/mingling_macros/src/attr/chain.rs +++ b/mingling_macros/src/attr/chain.rs @@ -20,22 +20,11 @@ fn is_unit_return_type(sig: &Signature) -> bool { } } -/// Validates that the return type is acceptable. -/// Accepts `()`, `Next`, `ChainProcess<...>`, or any type that can -/// be converted to `ChainProcess` via `.into()` (i.e. any pack type). -fn validate_return_type(sig: &Signature) -> Result<(), proc_macro2::TokenStream> { - // `()` or omitted is always valid - if is_unit_return_type(sig) { - return Ok(()); - } - - Ok(()) -} - /// Builds the `proc` function implementation inside the generated `Chain` impl. /// /// Instead of inlining the user's body, the trait method calls the original /// function by name, with resources injected from the application context. +#[allow(clippy::needless_pass_by_value)] fn generate_proc_fn( fn_name: &Ident, has_resources: bool, @@ -214,6 +203,9 @@ pub(crate) fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream { #[cfg(feature = "async")] let is_async_fn = input_fn.sig.asyncness.is_some(); + #[cfg(not(feature = "async"))] + let is_async_fn = false; + #[cfg(not(feature = "async"))] { if let Err(err) = reject_async(&input_fn.sig) { @@ -224,11 +216,6 @@ pub(crate) fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream { // Check if return type is unit let is_unit_return = is_unit_return_type(&input_fn.sig); - // Validate return type - if let Err(err) = validate_return_type(&input_fn.sig) { - return err.into(); - } - // Extract the previous type, parameter name, and resource injection params let (_, previous_type, resources) = match extract_args_info(&input_fn.sig) { Ok(info) => info, @@ -259,10 +246,7 @@ pub(crate) fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream { &resources, &program_type, &previous_type, - #[cfg(feature = "async")] is_async_fn, - #[cfg(not(feature = "async"))] - false, is_unit_return, ); @@ -343,9 +327,6 @@ pub(crate) fn register_chain(input: TokenStream) -> TokenStream { // Record the chain existence check let chain_exist_entry = build_chain_exist_arm(&previous_type); - let mut chains = crate::get_global_set(&crate::CHAINS).lock().unwrap(); - let mut chain_exist = crate::get_global_set(&crate::CHAINS_EXIST).lock().unwrap(); - let chain_entry_str = chain_entry.to_string(); let chain_exist_entry_str = chain_exist_entry.to_string(); @@ -357,18 +338,25 @@ pub(crate) fn register_chain(input: TokenStream) -> TokenStream { .unwrap() .ident .to_string(); - if let Err(err) = crate::check_duplicate_variant( - &chains, + let value = crate::check_duplicate_variant( + &crate::get_global_set(&crate::CHAINS).lock().unwrap(), &chain_entry_str, &variant_name, "chain", previous_type.span(), - ) { + ); + if let Err(err) = value { return err.into(); } - chains.insert(chain_entry_str); - chain_exist.insert(chain_exist_entry_str); + crate::get_global_set(&crate::CHAINS) + .lock() + .unwrap() + .insert(chain_entry_str); + crate::get_global_set(&crate::CHAINS_EXIST) + .lock() + .unwrap() + .insert(chain_exist_entry_str); quote! {}.into() } diff --git a/mingling_macros/src/attr/completion.rs b/mingling_macros/src/attr/completion.rs index 3ced091..f1635a8 100644 --- a/mingling_macros/src/attr/completion.rs +++ b/mingling_macros/src/attr/completion.rs @@ -5,9 +5,10 @@ use syn::spanned::Spanned; use syn::{FnArg, Ident, ItemFn, Pat, PatType, Type, TypePath, parse_macro_input}; #[cfg(feature = "comp")] +#[allow(clippy::too_many_lines)] pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStream { - // Parse the attribute arguments such as HelloEntry or crate::EntryFine from #[completion(crate::EntryFine)] use crate::get_global_set; + let previous_type_path: TypePath = if attr.is_empty() { return syn::Error::new( proc_macro2::Span::call_site(), @@ -20,22 +21,18 @@ pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStre }; let previous_type_ident = &previous_type_path.path.segments.last().unwrap().ident; - // Parse the function item let input_fn = parse_macro_input!(item as ItemFn); - // Validate the function is not async if input_fn.sig.asyncness.is_some() { return syn::Error::new(input_fn.sig.span(), "Completion function cannot be async") .to_compile_error() .into(); } - // Get the function signature parts let sig = &input_fn.sig; let inputs = &sig.inputs; let output = &sig.output; - // Must have at least one parameter ctx if inputs.is_empty() { return syn::Error::new( inputs.span(), @@ -45,7 +42,6 @@ pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStre .into(); } - // Extract the first param pattern and type for the ctx parameter let first_arg = &inputs[0]; let _ctx_type = match first_arg { FnArg::Typed(PatType { ty, .. }) => (**ty).clone(), @@ -60,26 +56,19 @@ pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStre }; let fixed_ctx: Pat = syn::parse_quote!(ctx); - // Extract resources from params 2 through N, skipping ctx let resources = match extract_resources_from_args(sig, 1) { Ok(r) => r, Err(e) => return e.to_compile_error().into(), }; - // Get the function body let fn_body = &input_fn.block; - // Get function attributes excluding the completion attribute let mut fn_attrs = input_fn.attrs.clone(); fn_attrs.retain(|attr| !attr.path().is_ident("completion")); - // Get function visibility let vis = &input_fn.vis; - - // Get function name let fn_name = &sig.ident; - // Generate internal name from function name using snake_case let internal_name = format!( "__internal_completion_{}", just_fmt::snake_case!(fn_name.to_string()) @@ -90,10 +79,8 @@ pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStre let has_resources = !resources.is_empty(); let mut_resources: Vec<_> = resources.iter().filter(|r| r.is_mut).collect(); - // Generate immutable resource bindings let immut_resource_stmts = generate_immut_resource_bindings(resources.iter(), &program_type); - // Build the call to the original function with resource arguments injected let resource_args: Vec<_> = resources .iter() .map(|res| { @@ -108,7 +95,6 @@ pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStre quote! { #fn_name(#fixed_ctx) } }; - // Wrap the function call with modify_res for mutable resources let inner_call = if mut_resources.is_empty() { fn_call } else { @@ -134,10 +120,7 @@ pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStre quote! { #inner_call } }; - // Generate the struct and implementation - // The `comp` trait method only takes `ctx` as the first parameter; resources are injected internally - - let expanded = quote! { + let expanded: proc_macro2::TokenStream = quote! { #(#fn_attrs)* #[doc(hidden)] #[allow(non_camel_case_types)] @@ -162,22 +145,22 @@ pub(crate) fn completion_attr(attr: TokenStream, item: TokenStream) -> TokenStre Self::#previous_type_ident => <#struct_name as ::mingling::Completion>::comp(ctx), }; - let mut completions = get_global_set(&crate::COMPLETIONS).lock().unwrap(); let completion_str = completion_entry.to_string(); - - // Check for duplicate variant before inserting let variant_name = previous_type_ident.to_string(); + let span = previous_type_path.span(); + + let mut completions = get_global_set(&crate::COMPLETIONS).lock().unwrap(); if let Err(err) = crate::check_duplicate_variant( &completions, &completion_str, &variant_name, "completion", - previous_type_path.span(), + span, ) { return err.into(); } - completions.insert(completion_str); + drop(completions); expanded.into() } diff --git a/mingling_macros/src/attr/help.rs b/mingling_macros/src/attr/help.rs index b4ad989..42d81cf 100644 --- a/mingling_macros/src/attr/help.rs +++ b/mingling_macros/src/attr/help.rs @@ -14,6 +14,7 @@ fn extract_user_return_type(sig: &Signature) -> Option } } +#[allow(clippy::too_many_lines)] pub(crate) fn help_attr(item: TokenStream) -> TokenStream { // Parse the function item let input_fn = parse_macro_input!(item as ItemFn); @@ -50,7 +51,7 @@ pub(crate) fn help_attr(item: TokenStream) -> TokenStream { // Get original inputs to keep the original function let original_inputs = input_fn.sig.inputs.clone(); - let original_return_type = user_return_type.clone().unwrap_or(quote! { () }); + let original_return_type = user_return_type.unwrap_or_else(|| quote! { () }); // Generate internal name using snake_case let internal_name = format!( diff --git a/mingling_macros/src/attr/renderer.rs b/mingling_macros/src/attr/renderer.rs index 828dc00..038edd8 100644 --- a/mingling_macros/src/attr/renderer.rs +++ b/mingling_macros/src/attr/renderer.rs @@ -15,9 +15,7 @@ fn extract_user_return_type(sig: &Signature) -> Option } #[allow(clippy::too_many_lines)] -pub(crate) fn renderer_attr(attr: TokenStream, item: TokenStream) -> TokenStream { - // #[renderer] takes no arguments; always use the default program path - let _ = attr; +pub(crate) fn renderer_attr(item: TokenStream) -> TokenStream { let program_path = crate::default_program_path(); let program_type = &program_path; @@ -121,7 +119,7 @@ pub(crate) fn renderer_attr(attr: TokenStream, item: TokenStream) -> TokenStream // The original function preserves the user's exact signature and body. // Resource parameters are passed directly by the caller, NOT injected from context. let original_inputs = input_fn.sig.inputs.clone(); - let original_return_type = user_return_type.clone().unwrap_or(quote! { () }); + let original_return_type = user_return_type.unwrap_or_else(|| quote! { () }); let expanded = quote! { #(#fn_attrs)* @@ -249,14 +247,15 @@ pub(crate) fn register_renderer(input: TokenStream) -> TokenStream { } } // renderers lock released here - let mut renderers = get_global_set(&crate::RENDERERS).lock().unwrap(); - let mut renderer_exist = get_global_set(&crate::RENDERERS_EXIST).lock().unwrap(); - - #[cfg(feature = "structural_renderer")] - let mut structural_renderers = get_global_set(&crate::STRUCTURAL_RENDERERS).lock().unwrap(); - - renderers.insert(renderer_entry_str); - renderer_exist.insert(renderer_exist_entry_str); + // Insert renderer registration directly without holding a lock variable + get_global_set(&crate::RENDERERS) + .lock() + .unwrap() + .insert(renderer_entry_str); + get_global_set(&crate::RENDERERS_EXIST) + .lock() + .unwrap() + .insert(renderer_exist_entry_str); // Only register structural renderer if the type is in STRUCTURED_TYPES #[cfg(feature = "structural_renderer")] @@ -266,7 +265,10 @@ pub(crate) fn register_renderer(input: TokenStream) -> TokenStream { .unwrap() .contains(&variant_name); if is_structured { - structural_renderers.insert(structural_renderer_entry_str); + get_global_set(&crate::STRUCTURAL_RENDERERS) + .lock() + .unwrap() + .insert(structural_renderer_entry_str); } } diff --git a/mingling_macros/src/derive/enum_tag.rs b/mingling_macros/src/derive/enum_tag.rs index a7f71f0..fb1710f 100644 --- a/mingling_macros/src/derive/enum_tag.rs +++ b/mingling_macros/src/derive/enum_tag.rs @@ -135,13 +135,10 @@ fn process_variant( fn extract_description(attrs: &[Attribute]) -> Result> { for attr in attrs { if attr.path().is_ident("enum_desc") { - return match attr.parse_args::() { - Ok(lit_str) => Ok(Some(lit_str.value())), - Err(_) => Err(Error::new_spanned( + return attr.parse_args::().map_or_else(|_| Err(Error::new_spanned( attr, "#[enum_desc] attribute must be in the form `#[enum_desc(\"description\")]`", - )), - }; + )), |lit_str| Ok(Some(lit_str.value()))); } } @@ -153,13 +150,10 @@ fn extract_description(attrs: &[Attribute]) -> Result> { fn extract_rename(attrs: &[Attribute]) -> Result> { for attr in attrs { if attr.path().is_ident("enum_rename") { - return match attr.parse_args::() { - Ok(lit_str) => Ok(Some(lit_str.value())), - Err(_) => Err(Error::new_spanned( + return attr.parse_args::().map_or_else(|_| Err(Error::new_spanned( attr, "#[enum_rename] attribute must be in the form `#[enum_rename(\"new_name\")]`", - )), - }; + )), |lit_str| Ok(Some(lit_str.value()))); } } diff --git a/mingling_macros/src/extensions.rs b/mingling_macros/src/extensions.rs index f4a6fde..13b231c 100644 --- a/mingling_macros/src/extensions.rs +++ b/mingling_macros/src/extensions.rs @@ -35,7 +35,7 @@ impl Parse for Extensions { let _ = input.parse::(); } } - Ok(Extensions { exts }) + Ok(Self { exts }) } } @@ -59,7 +59,7 @@ impl Parse for CompletionExt { let ident: Ident = input.parse()?; exts.push(ident); } - Ok(CompletionExt { entry_type, exts }) + Ok(Self { entry_type, exts }) } } diff --git a/mingling_macros/src/func/dispatcher.rs b/mingling_macros/src/func/dispatcher.rs index a9e2464..d834c95 100644 --- a/mingling_macros/src/func/dispatcher.rs +++ b/mingling_macros/src/func/dispatcher.rs @@ -53,7 +53,7 @@ impl Parse for DispatcherChainInput { let entry_attrs = input.call(Attribute::parse_outer)?; let pack = input.parse()?; - Ok(DispatcherChainInput::Default { + Ok(Self::Default { cmd_attrs, entry_attrs, command_name, diff --git a/mingling_macros/src/func/node.rs b/mingling_macros/src/func/node.rs index 1b944a1..0b0de58 100644 --- a/mingling_macros/src/func/node.rs +++ b/mingling_macros/src/func/node.rs @@ -12,7 +12,7 @@ struct NodeInput { impl Parse for NodeInput { fn parse(input: ParseStream) -> SynResult { - Ok(NodeInput { + Ok(Self { path: input.parse()?, }) } @@ -38,7 +38,7 @@ pub(crate) fn node(input: TokenStream) -> TokenStream { if s.starts_with('_') { s.to_string() } else { - kebab_case!(s).to_string() + kebab_case!(s) } }) .collect(); diff --git a/mingling_macros/src/func/pack.rs b/mingling_macros/src/func/pack.rs index 7206b8e..d85f59e 100644 --- a/mingling_macros/src/func/pack.rs +++ b/mingling_macros/src/func/pack.rs @@ -16,7 +16,7 @@ impl Parse for PackInput { input.parse::()?; let inner_type: Type = input.parse()?; - Ok(PackInput { + Ok(Self { attrs, type_name, inner_type, diff --git a/mingling_macros/src/func/pack_structural.rs b/mingling_macros/src/func/pack_structural.rs index 9399959..e5b2362 100644 --- a/mingling_macros/src/func/pack_structural.rs +++ b/mingling_macros/src/func/pack_structural.rs @@ -6,6 +6,7 @@ use crate::get_global_set; /// `pack_structural!` — like `pack!` but also marks the type as supporting /// structured output via `StructuralData`. +#[allow(clippy::too_many_lines)] pub(crate) fn pack_structural(input: TokenStream) -> TokenStream { // Parse same input format as `pack!` let input_parsed = syn::parse_macro_input!(input as PackStructuralInput); @@ -159,7 +160,7 @@ impl syn::parse::Parse for PackStructuralInput { let type_name: Ident = input.parse()?; input.parse::()?; let inner_type: syn::Type = input.parse()?; - Ok(PackStructuralInput { + Ok(Self { attrs, type_name, inner_type, diff --git a/mingling_macros/src/func/program_final_gen.rs b/mingling_macros/src/func/program_final_gen.rs index 429e60c..f43f37a 100644 --- a/mingling_macros/src/func/program_final_gen.rs +++ b/mingling_macros/src/func/program_final_gen.rs @@ -45,6 +45,7 @@ fn ident_tokens(name: &str) -> proc_macro2::TokenStream { } #[allow(clippy::too_many_lines)] +#[allow(clippy::similar_names)] // You're being quite picky. pub(crate) fn program_final_gen_impl(_input: TokenStream) -> TokenStream { let name = syn::Ident::new("ThisProgram", proc_macro2::Span::call_site()); diff --git a/mingling_macros/src/func/r_append.rs b/mingling_macros/src/func/r_append.rs index 247da27..ffdc9ba 100644 --- a/mingling_macros/src/func/r_append.rs +++ b/mingling_macros/src/func/r_append.rs @@ -12,18 +12,18 @@ pub(crate) fn r_append(input: TokenStream) -> TokenStream { let dst_ident = parsed.dst.clone(); let src_tokens = parsed.src; - let expanded = match dst_ident { - Some(dst) => { + let expanded = dst_ident.map_or_else( + || { quote! { - #dst.append_other(#src_tokens); + __render_result_buffer.append_other(#src_tokens); } - } - None => { + }, + |dst| { quote! { - __render_result_buffer.append_other(#src_tokens); + #dst.append_other(#src_tokens); } - } - }; + }, + ); expanded.into() } diff --git a/mingling_macros/src/func/r_print.rs b/mingling_macros/src/func/r_print.rs index 20f15b8..06d8a45 100644 --- a/mingling_macros/src/func/r_print.rs +++ b/mingling_macros/src/func/r_print.rs @@ -21,10 +21,10 @@ impl Parse for PrintInput { let dst: Ident = input.parse()?; let _comma: Token![,] = input.parse()?; let args: TokenStream2 = input.parse()?; - Ok(PrintInput::Explicit { dst, args }) + Ok(Self::Explicit { dst, args }) } else { let args: TokenStream2 = input.parse()?; - Ok(PrintInput::Implicit { args }) + Ok(Self::Implicit { args }) } } } @@ -73,13 +73,13 @@ impl Parse for AppendInput { let dst: Ident = input.parse()?; let _comma: Token![,] = input.parse()?; let src: TokenStream2 = input.parse()?; - Ok(AppendInput { + Ok(Self { dst: Some(dst), src, }) } else { let src: TokenStream2 = input.parse()?; - Ok(AppendInput { dst: None, src }) + Ok(Self { dst: None, src }) } } } diff --git a/mingling_macros/src/func/register_help.rs b/mingling_macros/src/func/register_help.rs index e715244..d1957a5 100644 --- a/mingling_macros/src/func/register_help.rs +++ b/mingling_macros/src/func/register_help.rs @@ -39,21 +39,28 @@ pub(crate) fn register_help(input: TokenStream) -> TokenStream { let entry_str = help_entry.to_string(); // Check if entry was already pre-inserted by `#[help]` attribute - let mut helps = get_global_set(&crate::HELP_REQUESTS).lock().unwrap(); - if helps.contains(&entry_str) { + let helps = get_global_set(&crate::HELP_REQUESTS); + let help_set = helps.lock().unwrap(); + if help_set.contains(&entry_str) { // Already registered by `#[help]`, no duplicate check needed return quote::quote! {}.into(); } // Check for duplicate variant (different struct, same type) let variant_name = entry_type.path.segments.last().unwrap().ident.to_string(); - if let Err(err) = - crate::check_duplicate_variant(&helps, &entry_str, &variant_name, "help", entry_type.span()) - { + let dup_check = crate::check_duplicate_variant( + &help_set, + &entry_str, + &variant_name, + "help", + entry_type.span(), + ); + if let Err(err) = dup_check { return err.into(); } - helps.insert(entry_str); + drop(help_set); + helps.lock().unwrap().insert(entry_str); quote::quote! {}.into() } diff --git a/mingling_macros/src/func/suggest.rs b/mingling_macros/src/func/suggest.rs index 6613a98..c2841d5 100644 --- a/mingling_macros/src/func/suggest.rs +++ b/mingling_macros/src/func/suggest.rs @@ -16,7 +16,7 @@ enum SuggestItem { impl Parse for SuggestInput { fn parse(input: ParseStream) -> syn::Result { let items = Punctuated::parse_terminated(input)?; - Ok(SuggestInput { items }) + Ok(Self { items }) } } @@ -27,15 +27,14 @@ impl Parse for SuggestItem { if input.peek(Token![:]) { let _colon: Token![:] = input.parse()?; let value: Expr = input.parse()?; - Ok(SuggestItem::WithDesc(Box::new((key, value)))) + Ok(Self::WithDesc(Box::new((key, value)))) } else { - Ok(SuggestItem::Simple(key)) + Ok(Self::Simple(key)) } } } -/// 判断表达式是否是一个纯字符串字面量(仅由一对引号包裹) -fn is_pure_lit_str(expr: &Expr) -> bool { +const fn is_pure_lit_str(expr: &Expr) -> bool { matches!(expr, Expr::Lit(lit) if matches!(lit.lit, syn::Lit::Str(_))) } diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs index ce3455e..c87584d 100644 --- a/mingling_macros/src/lib.rs +++ b/mingling_macros/src/lib.rs @@ -142,6 +142,9 @@ //! ``` #![deny(missing_docs)] +#![deny(clippy::pedantic)] +#![deny(clippy::nursery)] +#![allow(clippy::redundant_pub_crate)] use proc_macro::TokenStream; use std::collections::BTreeSet; @@ -220,7 +223,7 @@ pub(crate) fn check_duplicate_variant( kind: &str, error_span: proc_macro2::Span, ) -> Result<(), proc_macro2::TokenStream> { - for existing in set.iter() { + for existing in set { if existing == entry_str { // Exact same entry - re-registration from RA re-analysis, skip continue; @@ -239,7 +242,7 @@ pub(crate) fn check_duplicate_variant( } /// Checks if a stored entry string contains the given variant name. -/// Handles both "StructName => Variant," and "Self::Variant => ..." formats. +/// Handles both "[`StructName`] => Variant," and "[`Self::Variant`] => ..." formats. fn entry_has_variant(entry: &str, variant_name: &str) -> bool { let variant_match = format!("=> {variant_name}"); @@ -998,10 +1001,10 @@ pub fn chain(attr: TokenStream, item: TokenStream) -> TokenStream { /// ``` #[proc_macro_attribute] pub fn renderer(attr: TokenStream, item: TokenStream) -> TokenStream { - if let Some(redispatch) = extensions::try_redispatch_simple(attr.clone(), &item, "renderer") { + if let Some(redispatch) = extensions::try_redispatch_simple(attr, &item, "renderer") { return redispatch; } - renderer::renderer_attr(attr, item) + renderer::renderer_attr(item) } /// Declares a completion suggestion provider for a command entry type. @@ -1419,7 +1422,7 @@ pub fn register_dispatcher(input: TokenStream) -> TokenStream { /// [`BasicProgramSetup`]: https://docs.rs/mingling/latest/mingling/setup/struct.BasicProgramSetup.html #[proc_macro_attribute] pub fn help(attr: TokenStream, item: TokenStream) -> TokenStream { - if let Some(redispatch) = extensions::try_redispatch_simple(attr.clone(), &item, "help") { + if let Some(redispatch) = extensions::try_redispatch_simple(attr, &item, "help") { return redispatch; } help::help_attr(item) diff --git a/mingling_macros/src/systems/res_injection.rs b/mingling_macros/src/systems/res_injection.rs index 606b9a6..ea16474 100644 --- a/mingling_macros/src/systems/res_injection.rs +++ b/mingling_macros/src/systems/res_injection.rs @@ -160,7 +160,7 @@ pub(crate) fn generate_immut_resource_bindings<'a>( /// Generates a unique binding name for a mutable resource variable. fn mut_res_binding_name(var_name: &Ident) -> Ident { - syn::Ident::new(&format!("__{}_binding", var_name), var_name.span()) + syn::Ident::new(&format!("__{var_name}_binding"), var_name.span()) } /// Wraps the function body in mutable resource closures (sync version). -- cgit