Skip to content

Commit 6bc0717

Browse files
authored
Improve value and reference passing efficiency (#3406)
1 parent 420d7b6 commit 6bc0717

File tree

17 files changed

+117
-107
lines changed

17 files changed

+117
-107
lines changed

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ exit = "warn"
2929
filter_map_next = "warn"
3030
fn_params_excessive_bools = "warn"
3131
if_let_mutex = "warn"
32+
implicit_clone = "warn"
3233
imprecise_flops = "warn"
3334
inefficient_to_string = "warn"
3435
linkedlist = "warn"
@@ -41,13 +42,18 @@ mem_forget = "warn"
4142
must_use_candidate = "warn"
4243
needless_borrow = "warn"
4344
needless_continue = "warn"
45+
needless_pass_by_ref_mut = "warn"
46+
needless_pass_by_value = "warn"
4447
option_option = "warn"
48+
redundant_clone = "warn"
49+
ref_option = "warn"
4550
rest_pat_in_fully_bound_structs = "warn"
4651
return_self_not_must_use = "warn"
4752
single_match_else = "warn"
4853
str_to_string = "warn"
4954
suboptimal_flops = "warn"
5055
todo = "warn"
56+
trivially_copy_pass_by_ref = "warn"
5157
uninlined_format_args = "warn"
5258
unnested_or_patterns = "warn"
5359
unused_self = "warn"

axum-extra/src/extract/cookie/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ impl IntoResponseParts for CookieJar {
206206
type Error = Infallible;
207207

208208
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
209-
set_cookies(self.jar, res.headers_mut());
209+
set_cookies(&self.jar, res.headers_mut());
210210
Ok(res)
211211
}
212212
}
@@ -217,7 +217,7 @@ impl IntoResponse for CookieJar {
217217
}
218218
}
219219

220-
fn set_cookies(jar: cookie::CookieJar, headers: &mut HeaderMap) {
220+
fn set_cookies(jar: &cookie::CookieJar, headers: &mut HeaderMap) {
221221
for cookie in jar.delta() {
222222
if let Ok(header_value) = cookie.encoded().to_string().parse() {
223223
headers.append(SET_COOKIE, header_value);

axum-extra/src/extract/cookie/private.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<K> IntoResponseParts for PrivateCookieJar<K> {
274274
type Error = Infallible;
275275

276276
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
277-
set_cookies(self.jar, res.headers_mut());
277+
set_cookies(&self.jar, res.headers_mut());
278278
Ok(res)
279279
}
280280
}

axum-extra/src/extract/cookie/signed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ impl<K> IntoResponseParts for SignedCookieJar<K> {
292292
type Error = Infallible;
293293

294294
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
295-
set_cookies(self.jar, res.headers_mut());
295+
set_cookies(&self.jar, res.headers_mut());
296296
Ok(res)
297297
}
298298
}

axum-extra/src/protobuf.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ mod tests {
172172

173173
let app = Router::new().route(
174174
"/",
175-
post(|input: Protobuf<Input>| async move { input.foo.to_owned() }),
175+
post(|Protobuf(input): Protobuf<Input>| async move { input.foo }),
176176
);
177177

178178
let input = Input {
@@ -228,10 +228,8 @@ mod tests {
228228
}
229229

230230
#[axum::debug_handler]
231-
async fn handler(input: Protobuf<Input>) -> Protobuf<Output> {
232-
let output = Output {
233-
result: input.foo.to_owned(),
234-
};
231+
async fn handler(Protobuf(input): Protobuf<Input>) -> Protobuf<Output> {
232+
let output = Output { result: input.foo };
235233

236234
Protobuf(output)
237235
}

axum-macros/src/debug_handler.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ use proc_macro2::{Ident, Span, TokenStream};
88
use quote::{format_ident, quote, quote_spanned};
99
use syn::{parse::Parse, spanned::Spanned, FnArg, ItemFn, ReturnType, Token, Type};
1010

11-
pub(crate) fn expand(attr: Attrs, item_fn: ItemFn, kind: FunctionKind) -> TokenStream {
11+
pub(crate) fn expand(attr: Attrs, item_fn: &ItemFn, kind: FunctionKind) -> TokenStream {
1212
let Attrs { state_ty } = attr;
1313

1414
let mut state_ty = state_ty.map(second);
1515

16-
let check_extractor_count = check_extractor_count(&item_fn, kind);
17-
let check_path_extractor = check_path_extractor(&item_fn, kind);
18-
let check_output_tuples = check_output_tuples(&item_fn);
16+
let check_extractor_count = check_extractor_count(item_fn, kind);
17+
let check_path_extractor = check_path_extractor(item_fn, kind);
18+
let check_output_tuples = check_output_tuples(item_fn);
1919
let check_output_impls_into_response = if check_output_tuples.is_empty() {
20-
check_output_impls_into_response(&item_fn)
20+
check_output_impls_into_response(item_fn)
2121
} else {
2222
check_output_tuples
2323
};
@@ -28,7 +28,7 @@ pub(crate) fn expand(attr: Attrs, item_fn: ItemFn, kind: FunctionKind) -> TokenS
2828
let mut err = None;
2929

3030
if state_ty.is_none() {
31-
let state_types_from_args = state_types_from_args(&item_fn);
31+
let state_types_from_args = state_types_from_args(item_fn);
3232

3333
#[allow(clippy::comparison_chain)]
3434
if state_types_from_args.len() == 1 {
@@ -50,16 +50,16 @@ pub(crate) fn expand(attr: Attrs, item_fn: ItemFn, kind: FunctionKind) -> TokenS
5050
err.unwrap_or_else(|| {
5151
let state_ty = state_ty.unwrap_or_else(|| syn::parse_quote!(()));
5252

53-
let check_future_send = check_future_send(&item_fn, kind);
53+
let check_future_send = check_future_send(item_fn, kind);
5454

55-
if let Some(check_input_order) = check_input_order(&item_fn, kind) {
55+
if let Some(check_input_order) = check_input_order(item_fn, kind) {
5656
quote! {
5757
#check_input_order
5858
#check_future_send
5959
}
6060
} else {
6161
let check_inputs_impls_from_request =
62-
check_inputs_impls_from_request(&item_fn, state_ty, kind);
62+
check_inputs_impls_from_request(item_fn, &state_ty, kind);
6363

6464
quote! {
6565
#check_inputs_impls_from_request
@@ -76,7 +76,7 @@ pub(crate) fn expand(attr: Attrs, item_fn: ItemFn, kind: FunctionKind) -> TokenS
7676
};
7777

7878
let middleware_takes_next_as_last_arg =
79-
matches!(kind, FunctionKind::Middleware).then(|| next_is_last_input(&item_fn));
79+
matches!(kind, FunctionKind::Middleware).then(|| next_is_last_input(item_fn));
8080

8181
quote! {
8282
#item_fn
@@ -104,7 +104,7 @@ impl fmt::Display for FunctionKind {
104104
}
105105

106106
impl FunctionKind {
107-
fn name_uppercase_plural(&self) -> &'static str {
107+
fn name_uppercase_plural(self) -> &'static str {
108108
match self {
109109
Self::Handler => "Handlers",
110110
Self::Middleware => "Middleware",
@@ -222,7 +222,7 @@ fn is_self_pat_type(typed: &syn::PatType) -> bool {
222222

223223
fn check_inputs_impls_from_request(
224224
item_fn: &ItemFn,
225-
state_ty: Type,
225+
state_ty: &Type,
226226
kind: FunctionKind,
227227
) -> TokenStream {
228228
let takes_self = item_fn.sig.inputs.first().is_some_and(|arg| match arg {

axum-macros/src/from_request/mod.rs

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(crate) enum Trait {
1919
}
2020

2121
impl Trait {
22-
fn via_marker_type(&self) -> Option<Type> {
22+
fn via_marker_type(self) -> Option<Type> {
2323
match self {
2424
Self::FromRequest => Some(parse_quote!(M)),
2525
Self::FromRequestParts => None,
@@ -132,17 +132,17 @@ pub(crate) fn expand(item: syn::Item, tr: Trait) -> syn::Result<TokenStream> {
132132

133133
let trait_impl = match (via.map(second), rejection.map(second)) {
134134
(Some(via), rejection) => impl_struct_by_extracting_all_at_once(
135-
ident,
135+
&ident,
136136
fields,
137-
via,
138-
rejection,
139-
generic_ident,
137+
&via,
138+
rejection.as_ref(),
139+
generic_ident.as_ref(),
140140
&state,
141141
tr,
142142
)?,
143143
(None, rejection) => {
144144
error_on_generic_ident(generic_ident, tr)?;
145-
impl_struct_by_extracting_each_field(ident, fields, rejection, &state, tr)?
145+
impl_struct_by_extracting_each_field(&ident, &fields, rejection, &state, tr)?
146146
}
147147
};
148148

@@ -206,11 +206,11 @@ pub(crate) fn expand(item: syn::Item, tr: Trait) -> syn::Result<TokenStream> {
206206

207207
match (via.map(second), rejection) {
208208
(Some(via), rejection) => impl_enum_by_extracting_all_at_once(
209-
ident,
209+
&ident,
210210
variants,
211-
via,
212-
rejection.map(second),
213-
state,
211+
&via,
212+
rejection.map(second).as_ref(),
213+
&state,
214214
tr,
215215
),
216216
(None, Some((rejection_kw, _))) => Err(syn::Error::new_spanned(
@@ -328,8 +328,8 @@ fn error_on_generic_ident(generic_ident: Option<Ident>, tr: Trait) -> syn::Resul
328328
}
329329

330330
fn impl_struct_by_extracting_each_field(
331-
ident: syn::Ident,
332-
fields: syn::Fields,
331+
ident: &syn::Ident,
332+
fields: &syn::Fields,
333333
rejection: Option<syn::Path>,
334334
state: &State,
335335
tr: Trait,
@@ -339,7 +339,7 @@ fn impl_struct_by_extracting_each_field(
339339
::std::unimplemented!()
340340
}
341341
} else {
342-
let extract_fields = extract_fields(&fields, &rejection, tr)?;
342+
let extract_fields = extract_fields(fields, rejection.as_ref(), tr)?;
343343
quote! {
344344
::std::result::Result::Ok(Self {
345345
#(#extract_fields)*
@@ -349,7 +349,7 @@ fn impl_struct_by_extracting_each_field(
349349

350350
let rejection_ident = if let Some(rejection) = rejection {
351351
quote!(#rejection)
352-
} else if has_no_fields(&fields) {
352+
} else if has_no_fields(fields) {
353353
quote!(::std::convert::Infallible)
354354
} else {
355355
quote!(::axum::response::Response)
@@ -411,7 +411,7 @@ fn has_no_fields(fields: &syn::Fields) -> bool {
411411

412412
fn extract_fields(
413413
fields: &syn::Fields,
414-
rejection: &Option<syn::Path>,
414+
rejection: Option<&syn::Path>,
415415
tr: Trait,
416416
) -> syn::Result<Vec<TokenStream>> {
417417
fn member(field: &syn::Field, index: usize) -> TokenStream {
@@ -426,7 +426,7 @@ fn extract_fields(
426426
}
427427
}
428428

429-
fn into_inner(via: &Option<(attr::kw::via, syn::Path)>, ty_span: Span) -> TokenStream {
429+
fn into_inner(via: Option<&(attr::kw::via, syn::Path)>, ty_span: Span) -> TokenStream {
430430
if let Some((_, path)) = via {
431431
let span = path.span();
432432
quote_spanned! {span=>
@@ -440,7 +440,7 @@ fn extract_fields(
440440
}
441441

442442
fn into_outer(
443-
via: &Option<(attr::kw::via, syn::Path)>,
443+
via: Option<&(attr::kw::via, syn::Path)>,
444444
ty_span: Span,
445445
field_ty: &Type,
446446
) -> TokenStream {
@@ -472,10 +472,10 @@ fn extract_fields(
472472

473473
let member = member(field, index);
474474
let ty_span = field.ty.span();
475-
let into_inner = into_inner(&via, ty_span);
475+
let into_inner = into_inner(via.as_ref(), ty_span);
476476

477477
if peel_option(&field.ty).is_some() {
478-
let field_ty = into_outer(&via, ty_span, peel_option(&field.ty).unwrap());
478+
let field_ty = into_outer(via.as_ref(), ty_span, peel_option(&field.ty).unwrap());
479479
let tokens = match tr {
480480
Trait::FromRequest => {
481481
quote_spanned! {ty_span=>
@@ -510,7 +510,7 @@ fn extract_fields(
510510
};
511511
Ok(tokens)
512512
} else if peel_result_ok(&field.ty).is_some() {
513-
let field_ty = into_outer(&via,ty_span, peel_result_ok(&field.ty).unwrap());
513+
let field_ty = into_outer(via.as_ref(), ty_span, peel_result_ok(&field.ty).unwrap());
514514
let tokens = match tr {
515515
Trait::FromRequest => {
516516
quote_spanned! {ty_span=>
@@ -543,7 +543,7 @@ fn extract_fields(
543543
};
544544
Ok(tokens)
545545
} else {
546-
let field_ty = into_outer(&via,ty_span,&field.ty);
546+
let field_ty = into_outer(via.as_ref(), ty_span, &field.ty);
547547
let map_err = if let Some(rejection) = rejection {
548548
quote! { <#rejection as ::std::convert::From<_>>::from }
549549
} else {
@@ -593,10 +593,10 @@ fn extract_fields(
593593

594594
let member = member(field, fields.len() - 1);
595595
let ty_span = field.ty.span();
596-
let into_inner = into_inner(&via, ty_span);
596+
let into_inner = into_inner(via.as_ref(), ty_span);
597597

598598
let item = if peel_option(&field.ty).is_some() {
599-
let field_ty = into_outer(&via, ty_span, peel_option(&field.ty).unwrap());
599+
let field_ty = into_outer(via.as_ref(), ty_span, peel_option(&field.ty).unwrap());
600600
quote_spanned! {ty_span=>
601601
#member: {
602602
<#field_ty as ::axum::extract::FromRequest<_, _>>::from_request(req, state)
@@ -606,7 +606,7 @@ fn extract_fields(
606606
},
607607
}
608608
} else if peel_result_ok(&field.ty).is_some() {
609-
let field_ty = into_outer(&via, ty_span, peel_result_ok(&field.ty).unwrap());
609+
let field_ty = into_outer(via.as_ref(), ty_span, peel_result_ok(&field.ty).unwrap());
610610
quote_spanned! {ty_span=>
611611
#member: {
612612
<#field_ty as ::axum::extract::FromRequest<_, _>>::from_request(req, state)
@@ -615,7 +615,7 @@ fn extract_fields(
615615
},
616616
}
617617
} else {
618-
let field_ty = into_outer(&via, ty_span, &field.ty);
618+
let field_ty = into_outer(via.as_ref(), ty_span, &field.ty);
619619
let map_err = if let Some(rejection) = rejection {
620620
quote! { <#rejection as ::std::convert::From<_>>::from }
621621
} else {
@@ -697,11 +697,11 @@ fn peel_result_ok(ty: &syn::Type) -> Option<&syn::Type> {
697697
}
698698

699699
fn impl_struct_by_extracting_all_at_once(
700-
ident: syn::Ident,
700+
ident: &syn::Ident,
701701
fields: syn::Fields,
702-
via_path: syn::Path,
703-
rejection: Option<syn::Path>,
704-
generic_ident: Option<Ident>,
702+
via_path: &syn::Path,
703+
rejection: Option<&syn::Path>,
704+
generic_ident: Option<&Ident>,
705705
state: &State,
706706
tr: Trait,
707707
) -> syn::Result<TokenStream> {
@@ -750,7 +750,7 @@ fn impl_struct_by_extracting_all_at_once(
750750
// - `State`, not other extractors
751751
//
752752
// honestly not sure why but the tests all pass
753-
let via_marker_type = if path_ident_is_state(&via_path) {
753+
let via_marker_type = if path_ident_is_state(via_path) {
754754
tr.via_marker_type()
755755
} else {
756756
None
@@ -868,11 +868,11 @@ fn impl_struct_by_extracting_all_at_once(
868868
}
869869

870870
fn impl_enum_by_extracting_all_at_once(
871-
ident: syn::Ident,
871+
ident: &syn::Ident,
872872
variants: Punctuated<syn::Variant, Token![,]>,
873-
path: syn::Path,
874-
rejection: Option<syn::Path>,
875-
state: State,
873+
path: &syn::Path,
874+
rejection: Option<&syn::Path>,
875+
state: &State,
876876
tr: Trait,
877877
) -> syn::Result<TokenStream> {
878878
for variant in variants {

axum-macros/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ pub fn debug_handler(_attr: TokenStream, input: TokenStream) -> TokenStream {
579579

580580
#[cfg(debug_assertions)]
581581
return expand_attr_with(_attr, input, |attrs, item_fn| {
582-
debug_handler::expand(attrs, item_fn, FunctionKind::Handler)
582+
debug_handler::expand(attrs, &item_fn, FunctionKind::Handler)
583583
});
584584
}
585585

@@ -635,7 +635,7 @@ pub fn debug_middleware(_attr: TokenStream, input: TokenStream) -> TokenStream {
635635

636636
#[cfg(debug_assertions)]
637637
return expand_attr_with(_attr, input, |attrs, item_fn| {
638-
debug_handler::expand(attrs, item_fn, FunctionKind::Middleware)
638+
debug_handler::expand(attrs, &item_fn, FunctionKind::Middleware)
639639
});
640640
}
641641

@@ -662,7 +662,7 @@ pub fn __private_axum_test(_attr: TokenStream, input: TokenStream) -> TokenStrea
662662
/// [`axum_extra::routing::TypedPath`]: https://docs.rs/axum-extra/latest/axum_extra/routing/trait.TypedPath.html
663663
#[proc_macro_derive(TypedPath, attributes(typed_path))]
664664
pub fn derive_typed_path(input: TokenStream) -> TokenStream {
665-
expand_with(input, typed_path::expand)
665+
expand_with(input, |item_struct| typed_path::expand(&item_struct))
666666
}
667667

668668
/// Derive an implementation of [`FromRef`] for each field in a struct.

0 commit comments

Comments
 (0)