diff --git a/core/codegen/src/attribute/route.rs b/core/codegen/src/attribute/route.rs index 6a4abebc..23bf7c0f 100644 --- a/core/codegen/src/attribute/route.rs +++ b/core/codegen/src/attribute/route.rs @@ -339,6 +339,24 @@ fn generate_internal_uri_macro(route: &Route) -> TokenStream2 { } } +fn generate_respond_expr(route: &Route) -> TokenStream2 { + let ret_span = match route.function.decl.output { + syn::ReturnType::Default => route.function.ident.span(), + syn::ReturnType::Type(_, ref ty) => ty.span().into() + }; + + define_vars_and_mods!(req); + define_vars_and_mods!(ret_span => handler); + let user_handler_fn_name = &route.function.ident; + let parameter_names = route.inputs.iter() + .map(|(_, rocket_ident, _)| rocket_ident); + + quote_spanned! { ret_span => + let ___responder = #user_handler_fn_name(#(#parameter_names),*); + #handler::Outcome::from(#req, ___responder) + } +} + fn codegen_route(route: Route) -> Result { // Generate the declarations for path, data, and request guard parameters. let mut data_stmt = None; @@ -372,8 +390,9 @@ fn codegen_route(route: Route) -> Result { let user_handler_fn_name = &user_handler_fn.ident; let generated_fn_name = user_handler_fn_name.prepend(ROUTE_FN_PREFIX); let generated_struct_name = user_handler_fn_name.prepend(ROUTE_STRUCT_PREFIX); - let parameter_names = route.inputs.iter().map(|(_, rocket_ident, _)| rocket_ident); let generated_internal_uri_macro = generate_internal_uri_macro(&route); + let generated_respond_expr = generate_respond_expr(&route); + let method = route.attribute.method; let path = route.attribute.path.origin.0.to_string(); let rank = Optional(route.attribute.rank); @@ -391,8 +410,7 @@ fn codegen_route(route: Route) -> Result { #(#parameter_definitions)* #data_stmt - let ___responder = #user_handler_fn_name(#(#parameter_names),*); - #handler::Outcome::from(#req, ___responder) + #generated_respond_expr } /// Rocket code generated wrapping URI macro. diff --git a/core/codegen/tests/ui-fail/catch_type_errors.rs b/core/codegen/tests/ui-fail/catch_type_errors.rs index 1399b56c..328c0019 100644 --- a/core/codegen/tests/ui-fail/catch_type_errors.rs +++ b/core/codegen/tests/ui-fail/catch_type_errors.rs @@ -4,13 +4,13 @@ use rocket::Request; #[catch(404)] fn f1(_request: &Request) -> usize { - //~^^ ERROR usize: rocket::response::Responder + //~^ ERROR usize: rocket::response::Responder 10 } #[catch(404)] fn f2(_request: &Request) -> bool { - //~^^ ERROR bool: rocket::response::Responder + //~^ ERROR bool: rocket::response::Responder false } @@ -22,7 +22,7 @@ fn f3(_request: bool) -> usize { #[catch(404)] fn f4() -> usize { - //~^^ ERROR usize: rocket::response::Responder + //~^ ERROR usize: rocket::response::Responder 10 } diff --git a/core/codegen/tests/ui-fail/catch_type_errors.stderr b/core/codegen/tests/ui-fail/catch_type_errors.stderr index 237b864d..d2d2da7e 100644 --- a/core/codegen/tests/ui-fail/catch_type_errors.stderr +++ b/core/codegen/tests/ui-fail/catch_type_errors.stderr @@ -1,20 +1,18 @@ error[E0277]: the trait bound `usize: rocket::response::Responder<'_>` is not satisfied - --> $DIR/catch_type_errors.rs:5:1 + --> $DIR/catch_type_errors.rs:6:30 | -5 | #[catch(404)] - | ^^^^^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `usize` +6 | fn f1(_request: &Request) -> usize { + | ^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `usize` | = note: required by `rocket::response::Responder::respond_to` - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `bool: rocket::response::Responder<'_>` is not satisfied - --> $DIR/catch_type_errors.rs:11:1 + --> $DIR/catch_type_errors.rs:12:30 | -11 | #[catch(404)] - | ^^^^^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `bool` +12 | fn f2(_request: &Request) -> bool { + | ^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `bool` | = note: required by `rocket::response::Responder::respond_to` - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/catch_type_errors.rs:18:7 @@ -28,13 +26,12 @@ error[E0308]: mismatched types found fn item `fn(bool) -> usize {f3}` error[E0277]: the trait bound `usize: rocket::response::Responder<'_>` is not satisfied - --> $DIR/catch_type_errors.rs:23:1 + --> $DIR/catch_type_errors.rs:24:12 | -23 | #[catch(404)] - | ^^^^^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `usize` +24 | fn f4() -> usize { + | ^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `usize` | = note: required by `rocket::response::Responder::respond_to` - = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/core/codegen/tests/ui-fail/responder-types.rs b/core/codegen/tests/ui-fail/responder-types.rs index c6eb14dd..99da355e 100644 --- a/core/codegen/tests/ui-fail/responder-types.rs +++ b/core/codegen/tests/ui-fail/responder-types.rs @@ -1,5 +1,8 @@ // normalize-stderr-test: "<(.*) as (.*)>" -> "$1 as $$TRAIT" // normalize-stderr-test: "and \d+ others" -> "and $$N others" +// normalize-stderr-test: "::: [^\.]*" -> "::: $$FILE" + +#![feature(proc_macro_hygiene, decl_macro)] #[macro_use] extern crate rocket; @@ -32,4 +35,8 @@ struct Thing4 { //~^ ERROR Header } +#[get("/")] +fn foo() -> usize { 0 } +//~^ ERROR Responder + fn main() { } diff --git a/core/codegen/tests/ui-fail/responder-types.stderr b/core/codegen/tests/ui-fail/responder-types.stderr index 884153e5..3cb57ad3 100644 --- a/core/codegen/tests/ui-fail/responder-types.stderr +++ b/core/codegen/tests/ui-fail/responder-types.stderr @@ -1,15 +1,15 @@ error[E0277]: the trait bound `u8: rocket::response::Responder<'_>` is not satisfied - --> $DIR/responder-types.rs:8:5 - | -8 | thing: u8, - | ^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `u8` - | - = note: required by `rocket::response::Responder::respond_to` + --> $DIR/responder-types.rs:11:5 + | +11 | thing: u8, + | ^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `u8` + | + = note: required by `rocket::response::Responder::respond_to` error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From` is not satisfied - --> $DIR/responder-types.rs:15:5 + --> $DIR/responder-types.rs:18:5 | -15 | other: u8, +18 | other: u8, | ^^^^^^^^^ the trait `std::convert::From` is not implemented for `rocket::http::Header<'_>` | = help: the following implementations were found: @@ -21,17 +21,17 @@ error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From` = note: required because of the requirements on the impl of `std::convert::Into>` for `u8` error[E0277]: the trait bound `u8: rocket::response::Responder<'_>` is not satisfied - --> $DIR/responder-types.rs:21:5 + --> $DIR/responder-types.rs:24:5 | -21 | thing: u8, +24 | thing: u8, | ^^^^^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `u8` | = note: required by `rocket::response::Responder::respond_to` error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From` is not satisfied - --> $DIR/responder-types.rs:23:5 + --> $DIR/responder-types.rs:26:5 | -23 | other: u8, +26 | other: u8, | ^^^^^^^^^ the trait `std::convert::From` is not implemented for `rocket::http::Header<'_>` | = help: the following implementations were found: @@ -43,9 +43,9 @@ error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From` = note: required because of the requirements on the impl of `std::convert::Into>` for `u8` error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From` is not satisfied - --> $DIR/responder-types.rs:31:5 + --> $DIR/responder-types.rs:34:5 | -31 | then: String, +34 | then: String, | ^^^^^^^^^^^^ the trait `std::convert::From` is not implemented for `rocket::http::Header<'_>` | = help: the following implementations were found: @@ -56,6 +56,17 @@ error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From>` for `std::string::String` -error: aborting due to 5 previous errors +error[E0277]: the trait bound `usize: rocket::response::Responder<'_>` is not satisfied + --> $DIR/responder-types.rs:39:13 + | +39 | fn foo() -> usize { 0 } + | ^^^^^ the trait `rocket::response::Responder<'_>` is not implemented for `usize` + | + ::: $FILE.rs:202:20 + | +202 | pub fn from>(req: &Request, responder: T) -> Outcome<'r> { + | ------------- required by this bound in `rocket::handler::, rocket::http::Status, rocket::Data>>::from` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`.