mirror of https://github.com/rwf2/Rocket.git
Allow return type of '#[launch]' fn to be elided.
This commit is contained in:
parent
092e03f720
commit
2f330d2967
|
@ -7,7 +7,7 @@ trait EntryAttr {
|
||||||
const REQUIRES_ASYNC: bool;
|
const REQUIRES_ASYNC: bool;
|
||||||
|
|
||||||
/// Return a new or rewritten function, using block as the main execution.
|
/// Return a new or rewritten function, using block as the main execution.
|
||||||
fn function(f: &syn::ItemFn, body: &syn::Block) -> Result<TokenStream>;
|
fn function(f: &mut syn::ItemFn) -> Result<TokenStream>;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Main;
|
struct Main;
|
||||||
|
@ -15,8 +15,8 @@ struct Main;
|
||||||
impl EntryAttr for Main {
|
impl EntryAttr for Main {
|
||||||
const REQUIRES_ASYNC: bool = true;
|
const REQUIRES_ASYNC: bool = true;
|
||||||
|
|
||||||
fn function(f: &syn::ItemFn, block: &syn::Block) -> Result<TokenStream> {
|
fn function(f: &mut syn::ItemFn) -> Result<TokenStream> {
|
||||||
let (attrs, vis, mut sig) = (&f.attrs, &f.vis, f.sig.clone());
|
let (attrs, vis, block, sig) = (&f.attrs, &f.vis, &f.block, &mut f.sig);
|
||||||
if sig.ident != "main" {
|
if sig.ident != "main" {
|
||||||
// FIXME(diag): warning!
|
// FIXME(diag): warning!
|
||||||
Span::call_site()
|
Span::call_site()
|
||||||
|
@ -37,8 +37,8 @@ struct Test;
|
||||||
impl EntryAttr for Test {
|
impl EntryAttr for Test {
|
||||||
const REQUIRES_ASYNC: bool = true;
|
const REQUIRES_ASYNC: bool = true;
|
||||||
|
|
||||||
fn function(f: &syn::ItemFn, block: &syn::Block) -> Result<TokenStream> {
|
fn function(f: &mut syn::ItemFn) -> Result<TokenStream> {
|
||||||
let (attrs, vis, mut sig) = (&f.attrs, &f.vis, f.sig.clone());
|
let (attrs, vis, block, sig) = (&f.attrs, &f.vis, &f.block, &mut f.sig);
|
||||||
sig.asyncness = None;
|
sig.asyncness = None;
|
||||||
Ok(quote_spanned!(block.span().into() => #(#attrs)* #[test] #vis #sig {
|
Ok(quote_spanned!(block.span().into() => #(#attrs)* #[test] #vis #sig {
|
||||||
::rocket::async_test(async move #block)
|
::rocket::async_test(async move #block)
|
||||||
|
@ -51,7 +51,7 @@ struct Launch;
|
||||||
impl EntryAttr for Launch {
|
impl EntryAttr for Launch {
|
||||||
const REQUIRES_ASYNC: bool = false;
|
const REQUIRES_ASYNC: bool = false;
|
||||||
|
|
||||||
fn function(f: &syn::ItemFn, block: &syn::Block) -> Result<TokenStream> {
|
fn function(f: &mut syn::ItemFn) -> Result<TokenStream> {
|
||||||
if f.sig.ident == "main" {
|
if f.sig.ident == "main" {
|
||||||
return Err(Span::call_site()
|
return Err(Span::call_site()
|
||||||
.error("attribute cannot be applied to `main` function")
|
.error("attribute cannot be applied to `main` function")
|
||||||
|
@ -59,6 +59,14 @@ impl EntryAttr for Launch {
|
||||||
.span_note(f.sig.ident.span(), "this function cannot be `main`"));
|
.span_note(f.sig.ident.span(), "this function cannot be `main`"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always infer the type as `::rocket::Rocket`.
|
||||||
|
if let syn::ReturnType::Type(_, ref mut ty) = &mut f.sig.output {
|
||||||
|
if let syn::Type::Infer(_) = &mut **ty {
|
||||||
|
let new = quote_spanned!(ty.span() => ::rocket::Rocket);
|
||||||
|
*ty = syn::parse2(new).expect("path is type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ty = match &f.sig.output {
|
let ty = match &f.sig.output {
|
||||||
syn::ReturnType::Type(_, ty) => ty,
|
syn::ReturnType::Type(_, ty) => ty,
|
||||||
_ => return Err(Span::call_site()
|
_ => return Err(Span::call_site()
|
||||||
|
@ -66,13 +74,13 @@ impl EntryAttr for Launch {
|
||||||
.span_note(f.sig.span(), "this function must return a value"))
|
.span_note(f.sig.span(), "this function must return a value"))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let block = &f.block;
|
||||||
let rocket = quote_spanned!(ty.span().into() => {
|
let rocket = quote_spanned!(ty.span().into() => {
|
||||||
let ___rocket: #ty = #block;
|
let ___rocket: #ty = #block;
|
||||||
let ___rocket: ::rocket::Rocket = ___rocket;
|
let ___rocket: ::rocket::Rocket = ___rocket;
|
||||||
___rocket
|
___rocket
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: Don't duplicate the `#block` here!
|
|
||||||
let (vis, mut sig) = (&f.vis, f.sig.clone());
|
let (vis, mut sig) = (&f.vis, f.sig.clone());
|
||||||
sig.ident = syn::Ident::new("main", sig.ident.span());
|
sig.ident = syn::Ident::new("main", sig.ident.span());
|
||||||
sig.output = syn::ReturnType::Default;
|
sig.output = syn::ReturnType::Default;
|
||||||
|
@ -112,8 +120,8 @@ fn _async_entry<A: EntryAttr>(
|
||||||
_args: proc_macro::TokenStream,
|
_args: proc_macro::TokenStream,
|
||||||
input: proc_macro::TokenStream
|
input: proc_macro::TokenStream
|
||||||
) -> Result<TokenStream> {
|
) -> Result<TokenStream> {
|
||||||
let function = parse_input::<A>(input)?;
|
let mut function = parse_input::<A>(input)?;
|
||||||
A::function(&function, &function.block).map(|t| t.into())
|
A::function(&mut function).map(|t| t.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! async_entry {
|
macro_rules! async_entry {
|
||||||
|
|
|
@ -25,6 +25,15 @@ mod b {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod b_inferred {
|
||||||
|
#[rocket::launch]
|
||||||
|
async fn main2() -> _ { rocket::ignite() }
|
||||||
|
|
||||||
|
async fn use_it() {
|
||||||
|
let rocket: rocket::Rocket = main2().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod c {
|
mod c {
|
||||||
// non-async launch.
|
// non-async launch.
|
||||||
#[rocket::launch]
|
#[rocket::launch]
|
||||||
|
@ -37,6 +46,15 @@ mod c {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod c_inferred {
|
||||||
|
#[rocket::launch]
|
||||||
|
fn rocket() -> _ { rocket::ignite() }
|
||||||
|
|
||||||
|
fn use_it() {
|
||||||
|
let rocket: rocket::Rocket = rocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod d {
|
mod d {
|
||||||
// main with async, is async.
|
// main with async, is async.
|
||||||
#[rocket::main]
|
#[rocket::main]
|
||||||
|
|
Loading…
Reference in New Issue