Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macros: fix skipping generics on #[tokio::main] #2177

Merged
merged 1 commit into from
Jan 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions tests-integration/tests/macros_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ async fn basic_main() -> usize {
1
}

#[tokio::main]
async fn generic_fun<T: Default>() -> T {
T::default()
}

#[cfg(feature = "rt-core")]
mod spawn {
#[tokio::main]
Expand All @@ -22,4 +27,5 @@ mod spawn {
#[test]
fn shell() {
assert_eq!(1, basic_main());
assert_eq!(bool::default(), generic_fun::<bool>())
}
34 changes: 18 additions & 16 deletions tokio-macros/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ enum Runtime {
}

fn parse_knobs(
input: syn::ItemFn,
mut input: syn::ItemFn,
args: syn::AttributeArgs,
is_test: bool,
rt_threaded: bool,
) -> Result<TokenStream, syn::Error> {
let ret = &input.sig.output;
let name = &input.sig.ident;
let inputs = &input.sig.inputs;
let sig = &mut input.sig;
let body = &input.block;
let attrs = &input.attrs;
let vis = input.vis;

if input.sig.asyncness.is_none() {
if sig.asyncness.is_none() {
let msg = "the async keyword is missing from the function declaration";
return Err(syn::Error::new_spanned(input.sig.fn_token, msg));
return Err(syn::Error::new_spanned(sig.fn_token, msg));
}

sig.asyncness = None;

let mut runtime = None;
let mut core_threads = None;
let mut max_threads = None;
Expand Down Expand Up @@ -152,7 +152,7 @@ fn parse_knobs(
let result = quote! {
#header
#(#attrs)*
#vis fn #name(#inputs) #ret {
#vis #sig {
#rt
.enable_all()
.build()
Expand Down Expand Up @@ -214,28 +214,30 @@ pub(crate) mod old {

#[cfg(not(test))] // Work around for rust-lang/rust#62127
pub(crate) fn main(args: TokenStream, item: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(item as syn::ItemFn);
let mut input = syn::parse_macro_input!(item as syn::ItemFn);
let args = syn::parse_macro_input!(args as syn::AttributeArgs);

let ret = &input.sig.output;
let name = &input.sig.ident;
let inputs = &input.sig.inputs;
let sig = &mut input.sig;
let name = &sig.ident;
let inputs = &sig.inputs;
let body = &input.block;
let attrs = &input.attrs;
let vis = input.vis;

if input.sig.asyncness.is_none() {
if sig.asyncness.is_none() {
let msg = "the async keyword is missing from the function declaration";
return syn::Error::new_spanned(input.sig.fn_token, msg)
return syn::Error::new_spanned(sig.fn_token, msg)
.to_compile_error()
.into();
} else if name == "main" && !inputs.is_empty() {
let msg = "the main function cannot accept arguments";
return syn::Error::new_spanned(&input.sig.inputs, msg)
return syn::Error::new_spanned(&sig.inputs, msg)
.to_compile_error()
.into();
}

sig.asyncness = None;

let mut runtime = Runtime::Auto;

for arg in args {
Expand All @@ -259,13 +261,13 @@ pub(crate) mod old {
let result = match runtime {
Runtime::Threaded | Runtime::Auto => quote! {
#(#attrs)*
#vis fn #name(#inputs) #ret {
#vis #sig {
tokio::runtime::Runtime::new().unwrap().block_on(async { #body })
}
},
Runtime::Basic => quote! {
#(#attrs)*
#vis fn #name(#inputs) #ret {
#vis #sig {
tokio::runtime::Builder::new()
.basic_scheduler()
.enable_all()
Expand Down