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}