diff --git a/core/codegen/src/attribute/route.rs b/core/codegen/src/attribute/route.rs index 7aa8d945..6b90e111 100644 --- a/core/codegen/src/attribute/route.rs +++ b/core/codegen/src/attribute/route.rs @@ -1,3 +1,6 @@ +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; + use proc_macro::{TokenStream, Span}; use crate::proc_macro2::TokenStream as TokenStream2; use devise::{syn, Spanned, SpanWrapped, Result, FromMeta, ext::TypeExt}; @@ -325,15 +328,31 @@ fn generate_internal_uri_macro(route: &Route) -> TokenStream2 { .map(|name| route.inputs.iter().find(|(ident, ..)| ident == name).unwrap()) .map(|(ident, _, ty)| quote!(#ident: #ty)); - let generated_macro_name = route.function.ident.prepend(URI_MACRO_PREFIX); + let mut hasher = DefaultHasher::new(); + let route_span = route.function.span(); + route_span.source_file().path().hash(&mut hasher); + let line_column = route_span.start(); + line_column.line.hash(&mut hasher); + line_column.column.hash(&mut hasher); + + let mut generated_macro_name = route.function.ident.prepend(URI_MACRO_PREFIX); + generated_macro_name.set_span(Span::call_site().into()); + let inner_generated_macro_name = generated_macro_name.append(&hasher.finish().to_string()); let route_uri = route.attribute.path.origin.0.to_string(); quote! { - pub macro #generated_macro_name($($token:tt)*) {{ - extern crate std; - extern crate rocket; - rocket::rocket_internal_uri!(#route_uri, (#(#dynamic_args),*), $($token)*) - }} + #[doc(hidden)] + #[macro_export] + macro_rules! #inner_generated_macro_name { + ($($token:tt)*) => {{ + extern crate std; + extern crate rocket; + rocket::rocket_internal_uri!(#route_uri, (#(#dynamic_args),*), $($token)*) + }}; + } + + #[doc(hidden)] + pub use #inner_generated_macro_name as #generated_macro_name; } } diff --git a/core/codegen/src/syn_ext.rs b/core/codegen/src/syn_ext.rs index 477fe63c..1126f8d5 100644 --- a/core/codegen/src/syn_ext.rs +++ b/core/codegen/src/syn_ext.rs @@ -9,12 +9,17 @@ pub fn syn_to_diag(error: syn::parse::Error) -> Diagnostic { pub trait IdentExt { fn prepend(&self, string: &str) -> syn::Ident; + fn append(&self, string: &str) -> syn::Ident; } impl IdentExt for syn::Ident { fn prepend(&self, string: &str) -> syn::Ident { syn::Ident::new(&format!("{}{}", string, self), self.span()) } + + fn append(&self, string: &str) -> syn::Ident { + syn::Ident::new(&format!("{}{}", self, string), self.span()) + } } pub trait ReturnTypeExt { diff --git a/core/codegen/tests/ui-fail/typed-uris-bad-params.stderr b/core/codegen/tests/ui-fail/typed-uris-bad-params.stderr index 6ca80e67..20ed1d0c 100644 --- a/core/codegen/tests/ui-fail/typed-uris-bad-params.stderr +++ b/core/codegen/tests/ui-fail/typed-uris-bad-params.stderr @@ -1,196 +1,28 @@ -error: `has_one` route uri expects 1 parameter but 0 were supplied - --> $DIR/typed-uris-bad-params.rs:22:10 +error: path parameters cannot be ignored + --> $DIR/typed-uris-bad-params.rs:79:37 | -22 | uri!(has_one); //~ ERROR expects 1 parameter but 0 - | ^^^^^^^ - | - = note: expected parameter: id: i32 +79 | uri!(optionals: id = 10, name = _); + | ^ -error: `has_one` route uri expects 1 parameter but 2 were supplied - --> $DIR/typed-uris-bad-params.rs:24:19 +error: path parameters cannot be ignored + --> $DIR/typed-uris-bad-params.rs:76:26 | -24 | uri!(has_one: 1, 23); //~ ERROR expects 1 parameter but 2 - | ^^^^^ - | - = note: expected parameter: id: i32 - -error: `has_one` route uri expects 1 parameter but 2 were supplied - --> $DIR/typed-uris-bad-params.rs:25:19 - | -25 | uri!(has_one: "Hello", 23, ); //~ ERROR expects 1 parameter but 2 - | ^^^^^^^^^^^^ - | - = note: expected parameter: id: i32 - -error: `has_one_guarded` route uri expects 1 parameter but 2 were supplied - --> $DIR/typed-uris-bad-params.rs:26:27 - | -26 | uri!(has_one_guarded: "hi", 100); //~ ERROR expects 1 parameter but 2 - | ^^^^^^^^^ - | - = note: expected parameter: id: i32 - -error: `has_two` route uri expects 2 parameters but 3 were supplied - --> $DIR/typed-uris-bad-params.rs:28:19 - | -28 | uri!(has_two: 10, "hi", "there"); //~ ERROR expects 2 parameters but 3 - | ^^^^^^^^^^^^^^^^^ - | - = note: expected parameters: id: i32, name: String - -error: `has_two` route uri expects 2 parameters but 1 was supplied - --> $DIR/typed-uris-bad-params.rs:29:19 - | -29 | uri!(has_two: 10); //~ ERROR expects 2 parameters but 1 - | ^^ - | - = note: expected parameters: id: i32, name: String - -error: invalid parameters for `has_one` route uri - --> $DIR/typed-uris-bad-params.rs:31:19 - | -31 | uri!(has_one: id = 100, name = "hi"); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: unknown parameter: `name` - --> $DIR/typed-uris-bad-params.rs:31:29 - | -31 | uri!(has_one: id = 100, name = "hi"); //~ ERROR invalid parameters - | ^^^^ - -error: invalid parameters for `has_one` route uri - --> $DIR/typed-uris-bad-params.rs:34:19 - | -34 | uri!(has_one: name = 100, id = 100); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: unknown parameter: `name` - --> $DIR/typed-uris-bad-params.rs:34:19 - | -34 | uri!(has_one: name = 100, id = 100); //~ ERROR invalid parameters - | ^^^^ - -error: invalid parameters for `has_one` route uri - --> $DIR/typed-uris-bad-params.rs:37:19 - | -37 | uri!(has_one: name = 100, age = 50, id = 100); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: unknown parameters: `name`, `age` - --> $DIR/typed-uris-bad-params.rs:37:19 - | -37 | uri!(has_one: name = 100, age = 50, id = 100); //~ ERROR invalid parameters - | ^^^^ ^^^ - -error: invalid parameters for `has_one` route uri - --> $DIR/typed-uris-bad-params.rs:40:19 - | -40 | uri!(has_one: name = 100, age = 50, id = 100, id = 50); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: unknown parameters: `name`, `age` - --> $DIR/typed-uris-bad-params.rs:40:19 - | -40 | uri!(has_one: name = 100, age = 50, id = 100, id = 50); //~ ERROR invalid parameters - | ^^^^ ^^^ -help: duplicate parameter: `id` - --> $DIR/typed-uris-bad-params.rs:40:51 - | -40 | uri!(has_one: name = 100, age = 50, id = 100, id = 50); //~ ERROR invalid parameters - | ^^ - -error: invalid parameters for `has_one` route uri - --> $DIR/typed-uris-bad-params.rs:44:19 - | -44 | uri!(has_one: id = 100, id = 100); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: duplicate parameter: `id` - --> $DIR/typed-uris-bad-params.rs:44:29 - | -44 | uri!(has_one: id = 100, id = 100); //~ ERROR invalid parameters - | ^^ - -error: invalid parameters for `has_one` route uri - --> $DIR/typed-uris-bad-params.rs:47:19 - | -47 | uri!(has_one: id = 100, id = 100, ); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: duplicate parameter: `id` - --> $DIR/typed-uris-bad-params.rs:47:29 - | -47 | uri!(has_one: id = 100, id = 100, ); //~ ERROR invalid parameters - | ^^ - -error: invalid parameters for `has_one` route uri - --> $DIR/typed-uris-bad-params.rs:50:19 - | -50 | uri!(has_one: name = "hi"); //~ ERROR invalid parameters - | ^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 - = help: missing parameter: `id` -help: unknown parameter: `name` - --> $DIR/typed-uris-bad-params.rs:50:19 - | -50 | uri!(has_one: name = "hi"); //~ ERROR invalid parameters - | ^^^^ - -error: invalid parameters for `has_one_guarded` route uri - --> $DIR/typed-uris-bad-params.rs:54:27 - | -54 | uri!(has_one_guarded: cookies = "hi", id = 100); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: unknown parameter: `cookies` - --> $DIR/typed-uris-bad-params.rs:54:27 - | -54 | uri!(has_one_guarded: cookies = "hi", id = 100); //~ ERROR invalid parameters - | ^^^^^^^ - -error: invalid parameters for `has_one_guarded` route uri - --> $DIR/typed-uris-bad-params.rs:57:27 - | -57 | uri!(has_one_guarded: id = 100, cookies = "hi"); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: uri parameters are: id: i32 -help: unknown parameter: `cookies` - --> $DIR/typed-uris-bad-params.rs:57:37 - | -57 | uri!(has_one_guarded: id = 100, cookies = "hi"); //~ ERROR invalid parameters - | ^^^^^^^ +76 | uri!(optionals: id = _, name = "bob".into()); + | ^ error: invalid parameters for `has_two` route uri - --> $DIR/typed-uris-bad-params.rs:60:19 + --> $DIR/typed-uris-bad-params.rs:72:19 | -60 | uri!(has_two: id = 100, id = 100, ); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^ +72 | uri!(has_two: id = 100, cookies = "hi"); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: uri parameters are: id: i32, name: String = help: missing parameter: `name` -help: duplicate parameter: `id` - --> $DIR/typed-uris-bad-params.rs:60:29 +help: unknown parameter: `cookies` + --> $DIR/typed-uris-bad-params.rs:72:29 | -60 | uri!(has_two: id = 100, id = 100, ); //~ ERROR invalid parameters - | ^^ - -error: invalid parameters for `has_two` route uri - --> $DIR/typed-uris-bad-params.rs:64:19 - | -64 | uri!(has_two: name = "hi"); //~ ERROR invalid parameters - | ^^^^^^^^^^^ - | - = note: uri parameters are: id: i32, name: String - = help: missing parameter: `id` +72 | uri!(has_two: id = 100, cookies = "hi"); //~ ERROR invalid parameters + | ^^^^^^^ error: invalid parameters for `has_two` route uri --> $DIR/typed-uris-bad-params.rs:67:19 @@ -212,30 +44,198 @@ help: duplicate parameter: `id` | ^^ ^^ error: invalid parameters for `has_two` route uri - --> $DIR/typed-uris-bad-params.rs:72:19 + --> $DIR/typed-uris-bad-params.rs:64:19 | -72 | uri!(has_two: id = 100, cookies = "hi"); //~ ERROR invalid parameters - | ^^^^^^^^^^^^^^^^^^^^^^^^ +64 | uri!(has_two: name = "hi"); //~ ERROR invalid parameters + | ^^^^^^^^^^^ + | + = note: uri parameters are: id: i32, name: String + = help: missing parameter: `id` + +error: invalid parameters for `has_two` route uri + --> $DIR/typed-uris-bad-params.rs:60:19 + | +60 | uri!(has_two: id = 100, id = 100, ); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^ | = note: uri parameters are: id: i32, name: String = help: missing parameter: `name` +help: duplicate parameter: `id` + --> $DIR/typed-uris-bad-params.rs:60:29 + | +60 | uri!(has_two: id = 100, id = 100, ); //~ ERROR invalid parameters + | ^^ + +error: invalid parameters for `has_one_guarded` route uri + --> $DIR/typed-uris-bad-params.rs:57:27 + | +57 | uri!(has_one_guarded: id = 100, cookies = "hi"); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 help: unknown parameter: `cookies` - --> $DIR/typed-uris-bad-params.rs:72:29 + --> $DIR/typed-uris-bad-params.rs:57:37 | -72 | uri!(has_two: id = 100, cookies = "hi"); //~ ERROR invalid parameters - | ^^^^^^^ +57 | uri!(has_one_guarded: id = 100, cookies = "hi"); //~ ERROR invalid parameters + | ^^^^^^^ -error: path parameters cannot be ignored - --> $DIR/typed-uris-bad-params.rs:76:26 +error: invalid parameters for `has_one_guarded` route uri + --> $DIR/typed-uris-bad-params.rs:54:27 | -76 | uri!(optionals: id = _, name = "bob".into()); - | ^ +54 | uri!(has_one_guarded: cookies = "hi", id = 100); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 +help: unknown parameter: `cookies` + --> $DIR/typed-uris-bad-params.rs:54:27 + | +54 | uri!(has_one_guarded: cookies = "hi", id = 100); //~ ERROR invalid parameters + | ^^^^^^^ -error: path parameters cannot be ignored - --> $DIR/typed-uris-bad-params.rs:79:37 +error: invalid parameters for `has_one` route uri + --> $DIR/typed-uris-bad-params.rs:50:19 | -79 | uri!(optionals: id = 10, name = _); - | ^ +50 | uri!(has_one: name = "hi"); //~ ERROR invalid parameters + | ^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 + = help: missing parameter: `id` +help: unknown parameter: `name` + --> $DIR/typed-uris-bad-params.rs:50:19 + | +50 | uri!(has_one: name = "hi"); //~ ERROR invalid parameters + | ^^^^ + +error: invalid parameters for `has_one` route uri + --> $DIR/typed-uris-bad-params.rs:47:19 + | +47 | uri!(has_one: id = 100, id = 100, ); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 +help: duplicate parameter: `id` + --> $DIR/typed-uris-bad-params.rs:47:29 + | +47 | uri!(has_one: id = 100, id = 100, ); //~ ERROR invalid parameters + | ^^ + +error: invalid parameters for `has_one` route uri + --> $DIR/typed-uris-bad-params.rs:44:19 + | +44 | uri!(has_one: id = 100, id = 100); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 +help: duplicate parameter: `id` + --> $DIR/typed-uris-bad-params.rs:44:29 + | +44 | uri!(has_one: id = 100, id = 100); //~ ERROR invalid parameters + | ^^ + +error: invalid parameters for `has_one` route uri + --> $DIR/typed-uris-bad-params.rs:40:19 + | +40 | uri!(has_one: name = 100, age = 50, id = 100, id = 50); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 +help: unknown parameters: `name`, `age` + --> $DIR/typed-uris-bad-params.rs:40:19 + | +40 | uri!(has_one: name = 100, age = 50, id = 100, id = 50); //~ ERROR invalid parameters + | ^^^^ ^^^ +help: duplicate parameter: `id` + --> $DIR/typed-uris-bad-params.rs:40:51 + | +40 | uri!(has_one: name = 100, age = 50, id = 100, id = 50); //~ ERROR invalid parameters + | ^^ + +error: invalid parameters for `has_one` route uri + --> $DIR/typed-uris-bad-params.rs:37:19 + | +37 | uri!(has_one: name = 100, age = 50, id = 100); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 +help: unknown parameters: `name`, `age` + --> $DIR/typed-uris-bad-params.rs:37:19 + | +37 | uri!(has_one: name = 100, age = 50, id = 100); //~ ERROR invalid parameters + | ^^^^ ^^^ + +error: invalid parameters for `has_one` route uri + --> $DIR/typed-uris-bad-params.rs:34:19 + | +34 | uri!(has_one: name = 100, id = 100); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 +help: unknown parameter: `name` + --> $DIR/typed-uris-bad-params.rs:34:19 + | +34 | uri!(has_one: name = 100, id = 100); //~ ERROR invalid parameters + | ^^^^ + +error: invalid parameters for `has_one` route uri + --> $DIR/typed-uris-bad-params.rs:31:19 + | +31 | uri!(has_one: id = 100, name = "hi"); //~ ERROR invalid parameters + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: uri parameters are: id: i32 +help: unknown parameter: `name` + --> $DIR/typed-uris-bad-params.rs:31:29 + | +31 | uri!(has_one: id = 100, name = "hi"); //~ ERROR invalid parameters + | ^^^^ + +error: `has_two` route uri expects 2 parameters but 1 was supplied + --> $DIR/typed-uris-bad-params.rs:29:19 + | +29 | uri!(has_two: 10); //~ ERROR expects 2 parameters but 1 + | ^^ + | + = note: expected parameters: id: i32, name: String + +error: `has_two` route uri expects 2 parameters but 3 were supplied + --> $DIR/typed-uris-bad-params.rs:28:19 + | +28 | uri!(has_two: 10, "hi", "there"); //~ ERROR expects 2 parameters but 3 + | ^^^^^^^^^^^^^^^^^ + | + = note: expected parameters: id: i32, name: String + +error: `has_one_guarded` route uri expects 1 parameter but 2 were supplied + --> $DIR/typed-uris-bad-params.rs:26:27 + | +26 | uri!(has_one_guarded: "hi", 100); //~ ERROR expects 1 parameter but 2 + | ^^^^^^^^^ + | + = note: expected parameter: id: i32 + +error: `has_one` route uri expects 1 parameter but 2 were supplied + --> $DIR/typed-uris-bad-params.rs:25:19 + | +25 | uri!(has_one: "Hello", 23, ); //~ ERROR expects 1 parameter but 2 + | ^^^^^^^^^^^^ + | + = note: expected parameter: id: i32 + +error: `has_one` route uri expects 1 parameter but 2 were supplied + --> $DIR/typed-uris-bad-params.rs:24:19 + | +24 | uri!(has_one: 1, 23); //~ ERROR expects 1 parameter but 2 + | ^^^^^ + | + = note: expected parameter: id: i32 + +error: `has_one` route uri expects 1 parameter but 0 were supplied + --> $DIR/typed-uris-bad-params.rs:22:10 + | +22 | uri!(has_one); //~ ERROR expects 1 parameter but 0 + | ^^^^^^^ + | + = note: expected parameter: id: i32 error: aborting due to 21 previous errors diff --git a/examples/hello_2018/src/main.rs b/examples/hello_2018/src/main.rs index 132833ff..d8d7c473 100644 --- a/examples/hello_2018/src/main.rs +++ b/examples/hello_2018/src/main.rs @@ -1,4 +1,4 @@ -#![feature(proc_macro_hygiene, decl_macro)] +#![feature(proc_macro_hygiene)] #[cfg(test)] mod tests;