mirror of https://github.com/rwf2/Rocket.git
Make references to core types absolute in codegen.
Prior to this commit, codegen emitted tokens containing bare types like 'Result' and 'Box' as well as presumed imported variants such as 'None' and 'Ok'. However, users are free to shadow these, and if they do, the generated code will fail to compile, or worse, be incorrect. To avoid this, this commit makes all references to these core types and imports absolute.
This commit is contained in:
parent
cb5c02064b
commit
3a8e23f7f2
|
@ -124,7 +124,7 @@ fn parse_route(attr: RouteAttribute, function: syn::ItemFn) -> Result<Route> {
|
|||
}
|
||||
|
||||
fn param_expr(seg: &Segment, ident: &syn::Ident, ty: &syn::Type) -> TokenStream2 {
|
||||
define_vars_and_mods!(req, data, error, log, request, Outcome);
|
||||
define_vars_and_mods!(req, data, error, log, request, _None, _Some, _Ok, _Err, Outcome);
|
||||
let i = seg.index.expect("dynamic parameters must be indexed");
|
||||
let span = ident.span().unstable().join(ty.span()).unwrap().into();
|
||||
let name = ident.to_string();
|
||||
|
@ -146,20 +146,20 @@ fn param_expr(seg: &Segment, ident: &syn::Ident, ty: &syn::Type) -> TokenStream2
|
|||
let expr = match seg.kind {
|
||||
Kind::Single => quote_spanned! { span =>
|
||||
match #req.raw_segment_str(#i) {
|
||||
Some(__s) => match <#ty as #request::FromParam>::from_param(__s) {
|
||||
Ok(__v) => __v,
|
||||
Err(#error) => return #parse_error,
|
||||
#_Some(__s) => match <#ty as #request::FromParam>::from_param(__s) {
|
||||
#_Ok(__v) => __v,
|
||||
#_Err(#error) => return #parse_error,
|
||||
},
|
||||
None => return #internal_error
|
||||
#_None => return #internal_error
|
||||
}
|
||||
},
|
||||
Kind::Multi => quote_spanned! { span =>
|
||||
match #req.raw_segments(#i) {
|
||||
Some(__s) => match <#ty as #request::FromSegments>::from_segments(__s) {
|
||||
Ok(__v) => __v,
|
||||
Err(#error) => return #parse_error,
|
||||
#_Some(__s) => match <#ty as #request::FromSegments>::from_segments(__s) {
|
||||
#_Ok(__v) => __v,
|
||||
#_Err(#error) => return #parse_error,
|
||||
},
|
||||
None => return #internal_error
|
||||
#_None => return #internal_error
|
||||
}
|
||||
},
|
||||
Kind::Static => return quote!()
|
||||
|
@ -201,6 +201,7 @@ fn data_expr(ident: &syn::Ident, ty: &syn::Type) -> TokenStream2 {
|
|||
}
|
||||
|
||||
fn query_exprs(route: &Route) -> Option<TokenStream2> {
|
||||
define_vars_and_mods!(_None, _Some, _Ok, _Err, _Option);
|
||||
define_vars_and_mods!(data, trail, log, request, req, Outcome, SmallVec, Query);
|
||||
let query_segments = route.attribute.path.query.as_ref()?;
|
||||
let (mut decls, mut matchers, mut builders) = (vec![], vec![], vec![]);
|
||||
|
@ -221,7 +222,7 @@ fn query_exprs(route: &Route) -> Option<TokenStream2> {
|
|||
let decl = match segment.kind {
|
||||
Kind::Single => quote_spanned! { span =>
|
||||
#[allow(non_snake_case)]
|
||||
let mut #ident: Option<#ty> = None;
|
||||
let mut #ident: #_Option<#ty> = #_None;
|
||||
},
|
||||
Kind::Multi => quote_spanned! { span =>
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -235,14 +236,14 @@ fn query_exprs(route: &Route) -> Option<TokenStream2> {
|
|||
(_, #name, __v) => {
|
||||
#[allow(unreachable_patterns, unreachable_code)]
|
||||
let __v = match <#ty as #request::FromFormValue>::from_form_value(__v) {
|
||||
Ok(__v) => __v,
|
||||
Err(__e) => {
|
||||
#_Ok(__v) => __v,
|
||||
#_Err(__e) => {
|
||||
#log::warn_(&format!("Failed to parse '{}': {:?}", #name, __e));
|
||||
return #Outcome::Forward(#data);
|
||||
}
|
||||
};
|
||||
|
||||
#ident = Some(__v);
|
||||
#ident = #_Some(__v);
|
||||
}
|
||||
},
|
||||
Kind::Static => quote! {
|
||||
|
@ -257,8 +258,8 @@ fn query_exprs(route: &Route) -> Option<TokenStream2> {
|
|||
Kind::Single => quote_spanned! { span =>
|
||||
#[allow(non_snake_case)]
|
||||
let #ident = match #ident.or_else(<#ty as #request::FromFormValue>::default) {
|
||||
Some(__v) => __v,
|
||||
None => {
|
||||
#_Some(__v) => __v,
|
||||
#_None => {
|
||||
#log::warn_(&format!("Missing required query parameter '{}'.", #name));
|
||||
return #Outcome::Forward(#data);
|
||||
}
|
||||
|
@ -267,8 +268,8 @@ fn query_exprs(route: &Route) -> Option<TokenStream2> {
|
|||
Kind::Multi => quote_spanned! { span =>
|
||||
#[allow(non_snake_case)]
|
||||
let #ident = match <#ty as #request::FromQuery>::from_query(#Query(&#trail)) {
|
||||
Ok(__v) => __v,
|
||||
Err(__e) => {
|
||||
#_Ok(__v) => __v,
|
||||
#_Err(__e) => {
|
||||
#log::warn_(&format!("Failed to parse '{}': {:?}", #name, __e));
|
||||
return #Outcome::Forward(#data);
|
||||
}
|
||||
|
@ -286,7 +287,7 @@ fn query_exprs(route: &Route) -> Option<TokenStream2> {
|
|||
Some(quote! {
|
||||
#(#decls)*
|
||||
|
||||
if let Some(__items) = #req.raw_query_items() {
|
||||
if let #_Some(__items) = #req.raw_query_items() {
|
||||
for __i in __items {
|
||||
match (__i.raw.as_str(), __i.key.as_str(), __i.value) {
|
||||
#(
|
||||
|
|
|
@ -82,6 +82,7 @@ pub fn derive_from_form(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
})
|
||||
.try_map_fields(move |_, fields| {
|
||||
define_vars_and_mods!(_None, _Some, _Ok, _Err);
|
||||
let (constructors, matchers, builders) = fields.iter().map(|field| {
|
||||
let (ident, span) = (&field.ident, field.span().into());
|
||||
let default_name = ident.as_ref().expect("named").to_string();
|
||||
|
@ -94,10 +95,10 @@ pub fn derive_from_form(input: TokenStream) -> TokenStream {
|
|||
span => <#ty as ::rocket::request::FromFormValue>
|
||||
};
|
||||
|
||||
let constructor = quote_spanned!(span => let mut #ident = None;);
|
||||
let constructor = quote_spanned!(span => let mut #ident = #_None;);
|
||||
|
||||
let matcher = quote_spanned! { span =>
|
||||
#name => { #ident = Some(#ty::from_form_value(__v)
|
||||
#name => { #ident = #_Some(#ty::from_form_value(__v)
|
||||
.map_err(|_| #form_error::BadValue(__k, __v))?); },
|
||||
};
|
||||
|
||||
|
@ -116,13 +117,13 @@ pub fn derive_from_form(input: TokenStream) -> TokenStream {
|
|||
match __k.as_str() {
|
||||
#(#matchers)*
|
||||
_ if __strict && __k != "_method" => {
|
||||
return Err(#form_error::Unknown(__k, __v));
|
||||
return #_Err(#form_error::Unknown(__k, __v));
|
||||
}
|
||||
_ => { /* lenient or "method"; let it pass */ }
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self { #(#builders)* })
|
||||
#_Ok(Self { #(#builders)* })
|
||||
})
|
||||
})
|
||||
.to_tokens()
|
||||
|
|
|
@ -7,6 +7,7 @@ struct Form {
|
|||
}
|
||||
|
||||
pub fn derive_from_form_value(input: TokenStream) -> TokenStream {
|
||||
define_vars_and_mods!(_Ok, _Err, _Result);
|
||||
DeriveGenerator::build_for(input, quote!(impl<'__v> ::rocket::request::FromFormValue<'__v>))
|
||||
.generic_support(GenericSupport::None)
|
||||
.data_support(DataSupport::Enum)
|
||||
|
@ -25,19 +26,19 @@ pub fn derive_from_form_value(input: TokenStream) -> TokenStream {
|
|||
|
||||
Ok(())
|
||||
})
|
||||
.function(|_, inner| quote! {
|
||||
.function(move |_, inner| quote! {
|
||||
type Error = &'__v ::rocket::http::RawStr;
|
||||
|
||||
fn from_form_value(
|
||||
value: &'__v ::rocket::http::RawStr
|
||||
) -> ::std::result::Result<Self, Self::Error> {
|
||||
) -> #_Result<Self, Self::Error> {
|
||||
let uncased = value.as_uncased_str();
|
||||
#inner
|
||||
::std::result::Result::Err(value)
|
||||
#_Err(value)
|
||||
}
|
||||
})
|
||||
.try_map_enum(null_enum_mapper)
|
||||
.try_map_variant(|_, variant| {
|
||||
.try_map_variant(move |_, variant| {
|
||||
let variant_str = Form::from_attrs("form", &variant.attrs)
|
||||
.unwrap_or_else(|| Ok(Form { value: variant.ident.to_string() }))?
|
||||
.value;
|
||||
|
@ -45,7 +46,7 @@ pub fn derive_from_form_value(input: TokenStream) -> TokenStream {
|
|||
let builder = variant.builder(|_| unreachable!());
|
||||
Ok(quote! {
|
||||
if uncased == #variant_str {
|
||||
return ::std::result::Result::Ok(#builder);
|
||||
return #_Ok(#builder);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -38,6 +38,7 @@ pub fn derive_responder(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
})
|
||||
.try_map_fields(|_, fields| {
|
||||
define_vars_and_mods!(_Ok);
|
||||
fn set_header_tokens<T: ToTokens + Spanned>(item: T) -> TokenStream2 {
|
||||
quote_spanned!(item.span().into() => __res.set_header(#item);)
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ pub fn derive_responder(input: TokenStream) -> TokenStream {
|
|||
#(#headers)*
|
||||
#content_type
|
||||
#status
|
||||
Ok(__res)
|
||||
#_Ok(__res)
|
||||
})
|
||||
})
|
||||
.to_tokens()
|
||||
|
|
|
@ -233,9 +233,10 @@ impl FromMeta for RoutePath {
|
|||
|
||||
impl<T: ToTokens> ToTokens for Optional<T> {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||
define_vars_and_mods!(_Some, _None);
|
||||
let opt_tokens = match self.0 {
|
||||
Some(ref val) => quote!(Some(#val)),
|
||||
None => quote!(None)
|
||||
Some(ref val) => quote!(#_Some(#val)),
|
||||
None => quote!(#_None)
|
||||
};
|
||||
|
||||
tokens.extend(opt_tokens);
|
||||
|
|
|
@ -63,30 +63,50 @@ extern crate proc_macro;
|
|||
extern crate rocket_http as http;
|
||||
extern crate indexmap;
|
||||
|
||||
macro_rules! define {
|
||||
($val:path as $v:ident) => (#[allow(non_snake_case)] let $v = quote!($val););
|
||||
macro_rules! vars_and_mods {
|
||||
($($name:ident => $path:path,)*) => {
|
||||
macro_rules! define {
|
||||
// Note: the `o` is to capture the input's span
|
||||
$(($i:ident $name) => {
|
||||
#[allow(non_snake_case)] let $i = quote!($path);
|
||||
};)*
|
||||
$(($span:expr => $i:ident $name) => {
|
||||
#[allow(non_snake_case)] let $i = quote_spanned!($span => $path);
|
||||
};)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vars_and_mods! {
|
||||
req => __req,
|
||||
catcher => __catcher,
|
||||
data => __data,
|
||||
error => __error,
|
||||
trail => __trail,
|
||||
request => rocket::request,
|
||||
response => rocket::response,
|
||||
handler => rocket::handler,
|
||||
log => rocket::logger,
|
||||
Outcome => rocket::Outcome,
|
||||
FromData => rocket::data::FromData,
|
||||
Transform => rocket::data::Transform,
|
||||
Query => rocket::request::Query,
|
||||
Request => rocket::Request,
|
||||
Response => rocket::response::Response,
|
||||
Data => rocket::Data,
|
||||
StaticRouteInfo => rocket::StaticRouteInfo,
|
||||
SmallVec => rocket::http::private::SmallVec,
|
||||
_Option => ::std::option::Option,
|
||||
_Result => ::std::result::Result,
|
||||
_Some => ::std::option::Option::Some,
|
||||
_None => ::std::option::Option::None,
|
||||
_Ok => ::std::result::Result::Ok,
|
||||
_Err => ::std::result::Result::Err,
|
||||
}
|
||||
|
||||
macro_rules! define_vars_and_mods {
|
||||
(@req as $v:ident) => (define!(__req as $v));
|
||||
(@catcher as $v:ident) => (define!(__catcher as $v));
|
||||
(@data as $v:ident) => (define!(__data as $v));
|
||||
(@error as $v:ident) => (define!(__error as $v));
|
||||
(@trail as $v:ident) => (define!(__trail as $v));
|
||||
(@request as $v:ident) => (define!(::rocket::request as $v));
|
||||
(@response as $v:ident) => (define!(::rocket::response as $v));
|
||||
(@handler as $v:ident) => (define!(::rocket::handler as $v));
|
||||
(@log as $v:ident) => (define!(::rocket::logger as $v));
|
||||
(@Outcome as $v:ident) => (define!(::rocket::Outcome as $v));
|
||||
(@FromData as $v:ident) => (define!(::rocket::data::FromData as $v));
|
||||
(@Transform as $v:ident) => (define!(::rocket::data::Transform as $v));
|
||||
(@Query as $v:ident) => (define!(::rocket::request::Query as $v));
|
||||
(@Request as $v:ident) => (define!(::rocket::Request as $v));
|
||||
(@Response as $v:ident) => (define!(::rocket::response::Response as $v));
|
||||
(@Data as $v:ident) => (define!(::rocket::Data as $v));
|
||||
(@StaticRouteInfo as $v:ident) => (define!(::rocket::StaticRouteInfo as $v));
|
||||
(@SmallVec as $v:ident) => (define!(::rocket::http::private::SmallVec as $v));
|
||||
($($name:ident),*) => ($(define_vars_and_mods!(@$name as $name);)*)
|
||||
($($name:ident),*) => ($(define!($name $name);)*);
|
||||
($span:expr => $($name:ident),*) => ($(define!($span => $name $name);)*)
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
|
|
Loading…
Reference in New Issue