Skip to content

Commit 827cbf2

Browse files
Merge pull request #680 from GuillaumeGomez/fix-invalid-variable-parsing
Fix invalid variable parsing
2 parents cd8fce3 + 8ca3545 commit 827cbf2

File tree

4 files changed

+67
-14
lines changed

4 files changed

+67
-14
lines changed

askama_derive/src/generator/expr.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,10 +1146,19 @@ fn starts_with_self_dot(expr_code: &TokenStream) -> bool {
11461146
}
11471147

11481148
fn write_resolved(buf: &mut Buffer, resolved: &str, span: proc_macro2::Span) {
1149-
for (idx, name) in resolved.split('.').enumerate() {
1150-
if idx > 0 {
1151-
buf.write_token(Token![.], span);
1149+
if resolved.contains('(') {
1150+
// FIXME: This is possible when we have `__askama_item.index` for example. However,
1151+
// can it happen in other cases?
1152+
//
1153+
// Also, it's super annoying in case there is a keyword...
1154+
let expr = TokenStream::from_str(resolved).unwrap();
1155+
quote_into!(buf, span, { #expr });
1156+
} else {
1157+
for (idx, name) in resolved.split('.').enumerate() {
1158+
if idx > 0 {
1159+
buf.write_token(Token![.], span);
1160+
}
1161+
buf.write_field(name, span);
11521162
}
1153-
buf.write_field(name, span);
11541163
}
11551164
}

testing/tests/macro.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,3 +646,26 @@ fn test_macro_raw_lifetime() {
646646

647647
assert_eq!(Foo.render().unwrap(), "ok");
648648
}
649+
650+
// Because of how we generated "resolved variables", we had it in two parts:
651+
// first the `(__askama_item` and then `index0)` (with the `.` generated in the
652+
// middle). Of course, doing that in two passes went horribly wrong as you cannot
653+
// generate `Ident` from that.
654+
#[test]
655+
fn test_loop_variable_in_macro_call() {
656+
#[derive(Template)]
657+
#[template(
658+
source = r#"
659+
{%- macro w(lol) -%}
660+
y: {{ lol -}}
661+
{% endmacro -%}
662+
663+
{%- for x in &[0] -%}
664+
{%- call w(loop.index) %}{% endcall -%}
665+
{% endfor %}"#,
666+
ext = "txt"
667+
)]
668+
struct Foo;
669+
670+
assert_eq!(Foo.render().unwrap(), "y: 1");
671+
}

testing/tests/ui/filter-invocation-invalid-arguments.stderr

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,16 @@ help: the trait `ValidFilterInvocation` is not implemented for `req1<'_>`
5757
|
5858
12 | #[askama::filter_fn]
5959
| ^^^^^^^^^^^^^^^^^^^^
60-
= help: the trait `ValidFilterInvocation` is implemented for `req1<'_, true>`
60+
help: the trait `ValidFilterInvocation` is implemented for `req1<'_, true>`
61+
--> tests/ui/filter-invocation-invalid-arguments.rs:13:16
62+
|
63+
13 | pub fn req1(
64+
| ________________^
65+
14 | | input: impl std::fmt::Display,
66+
15 | | _env: &dyn askama::Values,
67+
16 | | req1: usize,
68+
17 | | ) -> askama::Result<String> {
69+
| |_____^
6170
= note: this error originates in the derive macro `Template` which comes from the expansion of the attribute macro `askama::filter_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
6271

6372
error[E0599]: no method named `execute` found for struct `req1<'_>` in the current scope
@@ -90,9 +99,13 @@ error[E0277]: Argument at position 1 is invalid on filter req1<'_>. Too many arg
9099
36 | #[derive(Template)]
91100
| ^^^^^^^^ Filter function
92101
|
93-
= help: the trait `ValidArgIdx<1>` is not implemented for `req1<'_>`
94-
but trait `ValidArgIdx<0>` is implemented for it
95-
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
102+
help: the trait `ValidArgIdx<1>` is not implemented for `req1<'_>`
103+
but trait `ValidArgIdx<0>` is implemented for it
104+
--> tests/ui/filter-invocation-invalid-arguments.rs:12:5
105+
|
106+
12 | #[askama::filter_fn]
107+
| ^^^^^^^^^^^^^^^^^^^^
108+
= note: this error originates in the derive macro `Template` which comes from the expansion of the attribute macro `askama::filter_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
96109

97110
error[E0599]: no method named `with_req2` found for struct `req1<'filter, REQUIRED_ARG_FLAG_0>` in the current scope
98111
--> tests/ui/filter-invocation-invalid-arguments.rs:40:10

testing/tests/ui/truncate.stderr

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,19 @@ error[E0277]: the trait bound `usize: TryFrom<f32>` is not satisfied
2020
9 | #[derive(Template)]
2121
| ^^^^^^^^ the trait `From<f32>` is not implemented for `usize`
2222
|
23-
= help: the following other types implement trait `From<T>`:
24-
`usize` implements `From<bool>`
25-
`usize` implements `From<std::ptr::Alignment>`
26-
`usize` implements `From<u16>`
27-
`usize` implements `From<u8>`
23+
help: the following other types implement trait `From<T>`
24+
--> $RUST/core/src/convert/num.rs
25+
|
26+
= note: `usize` implements `From<bool>`
27+
::: $RUST/core/src/convert/num.rs
28+
|
29+
= note: `usize` implements `From<u8>`
30+
::: $RUST/core/src/convert/num.rs
31+
|
32+
= note: `usize` implements `From<u16>`
33+
--> $RUST/core/src/ptr/alignment.rs
34+
|
35+
= note: `usize` implements `From<std::ptr::Alignment>`
2836
= note: required for `f32` to implement `Into<usize>`
2937
= note: required for `usize` to implement `TryFrom<f32>`
30-
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
38+
= note: this error originates in the derive macro `Template` which comes from the expansion of the macro `impl_from` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)