lucchetto_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemFn};
4
5
6#[proc_macro_attribute]
7pub fn without_gvl(_attr: TokenStream, item: TokenStream) -> TokenStream {
8    let input = parse_macro_input!(item as ItemFn);
9    let attrs = &input.attrs;
10    let vis = &input.vis;
11    let sig = &input.sig;
12    let mut anon_sig = sig.clone();
13    anon_sig.ident = syn::Ident::new("__anon_wrapper", sig.ident.span());
14
15    let params = sig.inputs.iter().map(|arg| {
16        if let syn::FnArg::Typed(pat) = arg {
17            let arg = &pat.pat;
18            let ty = &pat.ty;
19            quote!(#arg, #ty)
20        } else {
21            panic!("expected typed argument")
22        }
23    });
24
25    let return_ty = match &sig.output {
26        syn::ReturnType::Default => quote!(()),
27        syn::ReturnType::Type(_, ty) => quote!(#ty),
28    };
29
30    let block = &input.block;
31
32    quote!(
33        #(#attrs)*
34        #vis #sig {
35            #anon_sig {
36                #block
37            }
38            lucchetto::call_without_gvl!(__anon_wrapper, args: (#(#params),*), return_type: #return_ty)
39        }
40    ).into()
41}