askama icon indicating copy to clipboard operation
askama copied to clipboard

Macro doesn't resolve argument

Open DaniPopes opened this issue 1 year ago • 1 comments

Only happens when shadowing the argument in a block and a for loop is present. More details in the repro comments.

This can be easily avoided by renaming either the parameter or the assigned variable, but this error was very confusing when I first encountered it.

Repro:

#[derive(askama::Template)]
//~^ error[E0425]: cannot find value `string` in this scope
#[template(
    source = r#"
{% macro one(string) %}
    {# a block #}
    {% if false %}
        {# assignment with same name as param #}
        {% let string = string.trim_start() %}

        {# any `for` statement #}
        {% for _ in std::iter::once(()) %} {% endfor %}
    {% endif %}

    {# `string` doesn't correctly expand to `self.field` making compilation fail with E0425 #}
    {{ string.trim() }}
{% endmacro %}

{% call one(field) %}
"#,
    ext = "txt",
    whitespace = "suppress",
    print = "code"
)]
struct S {
    field: &'static str,
}

DaniPopes avatar Apr 05 '23 21:04 DaniPopes

Ah, thank you for finding the issued and adding an example to reproduce it!

The generator for for-loops only calls self.locals.push() if it is used with for … in … if …, but the method should always be called, because the loop body is a new scope. I haven't looked into it, but I wager that if-else-blocks and match-with-blocks have the same problem.

Kijewski avatar Apr 05 '23 22:04 Kijewski