Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions askama_derive/src/filter_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ impl FilterSignature {
/// fields into the local context by consuming them. Required arguments are unwrapped from
/// their `Option<>` container, and optional arguments are moved as is.
/// Then, the actual filter code is inserted after.
fn gen_exec_impl(&self, filter_impl: &Block) -> TokenStream {
fn gen_exec_impl(&self, sig: &Signature, filter_impl: &Block) -> TokenStream {
let ident = &self.ident;
// input variable
// method generics (only the parameters not already present on struct)
Expand All @@ -643,9 +643,11 @@ impl FilterSignature {
});
let (all_lifetimes, _) = self.lifetimes_bounds(|_| true);
let (_, type_lifetimes) = self.lifetimes_bounds(|l| l.used_by_extra_args);

// env variable
let env_ident = &self.arg_env.ident;
let env_ty = &self.arg_env.ty;

// struct generics
let required_generics: Vec<_> = self
.args_required_generics
Expand All @@ -657,6 +659,7 @@ impl FilterSignature {

// filter result
let result_ty = &self.result_ty;

// variables
let required_args = self.args_required.iter().map(|a| {
let mutability = a.mutability;
Expand All @@ -673,15 +676,21 @@ impl FilterSignature {
}
});

let fn_token = &sig.fn_token;
let impl_generics = quote! { #(#required_generics: #required_generic_bounds,)* };
let impl_struct_generics = quote! { #(#required_generics,)* #(#required_flags,)* };
let lifetimes_fillers = self.lifetimes_fillers(|l| l.used_by_extra_args);
quote! {
quote_spanned! {
sig.paren_token.span =>
// if all required arguments have been supplied (P0 == true, P1 == true)
// ... the execute() method is "unlocked":
impl<#(#all_lifetimes,)* #impl_generics> #ident<'_, #(#type_lifetimes,)* #impl_struct_generics> {
#[inline(always)]
pub fn execute< #(#input_bounds,)*>(self, #input_mutability #input_ident: #input_ty, #env_ident: #env_ty) #result_ty {
pub #fn_token execute< #(#input_bounds,)* >(
self,
#input_mutability #input_ident: #input_ty,
#env_ident: #env_ty
) #result_ty {
// map filter variables with original name into scope
#( #required_args )*
#( #optional_args )*
Expand Down Expand Up @@ -717,7 +726,7 @@ fn filter_fn_impl(attr: TokenStream, ffn: &ItemFn) -> Result<TokenStream, Compil
let struct_def = fsig.gen_struct_definition(&ffn.vis);
let default_impl = fsig.gen_default_impl();
let setter_impl = fsig.gen_setters();
let exec_impl = fsig.gen_exec_impl(&ffn.block);
let exec_impl = fsig.gen_exec_impl(&ffn.sig, &ffn.block);

Ok(quote!(
#struct_def
Expand Down
67 changes: 42 additions & 25 deletions testing/tests/clippy_lints/lib.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,50 @@
#![deny(clippy::elidable_lifetime_names)]
#![deny(clippy::all)]
#![deny(clippy::unnecessary_wraps)]

// FIXME: This is expected, however the span is wrong.
// #![deny(clippy::unnecessary_wraps)]

// https://github.com/askama-rs/askama/issues/651
// // Checks that `clippy:unnecessary_wraps` is not triggered.
// pub mod unnecessary_wraps {
// mod filters {
// use std::fmt::Display;

// #[askama::filter_fn]
// pub fn simple(value: impl Display, _env: &dyn askama::Values) -> askama::Result<String> {
// Ok(value.to_string())
// }
// }

// #[derive(askama::Template)]
// #[template(source = r#"{{ "foo" | simple }}"#, ext = "txt")]
// struct Foo<'a> {
// _bar: &'a (),
// }
// }

// Checks that `clippy::elidable_lifetime_names` is not triggered.
/// Checks that `clippy::unnecessary_wraps` is not triggered.
#[cfg(any())] // FIXME: <https://github.com/askama-rs/askama/issues/651>

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note test

Suspicious comment
pub mod unnecessary_wraps {
use askama::Template;

mod filters {
use std::fmt::Display;

#[askama::filter_fn]
pub(super) fn simple(
value: impl Display,
_env: &dyn askama::Values,
) -> askama::Result<String> {
Ok(value.to_string())
}
}

#[derive(Template)]
#[template(source = r#"{{ "Hello" | simple }}"#, ext = "txt")]
struct Test<'a> {
_data: &'a (),
}

#[test]
fn test_output() {
let test = Test { _data: &() };
assert_eq!(test.render().unwrap(), "Hello");
}
}

/// Checks that `clippy::elidable_lifetime_names` is not triggered.
pub mod elidable_lifetime_names {
#[derive(Debug, askama::Template)]
#[template(source = "", ext = "txt")]
use askama::Template;

#[derive(Debug, Template)]
#[template(source = "Hello", ext = "txt")]
struct Test<'a> {
_data: &'a (),
}

#[test]
fn test_output() {
let test = Test { _data: &() };
assert_eq!(test.render().unwrap(), "Hello");
}
}
Loading