Skip to content

Treat caller() as variable with support for aliasing#510

Merged
GuillaumeGomez merged 5 commits intoaskama-rs:masterfrom
seijikun:mr-storable-caller
Jul 5, 2025
Merged

Treat caller() as variable with support for aliasing#510
GuillaumeGomez merged 5 commits intoaskama-rs:masterfrom
seijikun:mr-storable-caller

Conversation

@seijikun
Copy link
Copy Markdown
Contributor

@seijikun seijikun commented Jul 3, 2025

While implementing #505 over my previous version of fixing #507 (#509), I noticed that there is a much better way which actually fixes both at the same time.

The local MapChain now keeps track of:

  • variables (declaration, definition, with reference)
  • caller aliases ("variables" assigned from either caller or another alias) - this contains the call-site definition, as well as the call site's Context<'a> as metadata
  • Blockouts - This allows "hiding" a variable from a certain scope onward.

Basic design:

When a {% call ... %} block is entered, I push caller as a LocalMeta::CallerAlias into the local map, together with the call-site Context<'a> and Call<'a> definition.

When a variable is assigned from another variable (Expr::Var(dst) = Expr::Var(src)), where the src variable is a local of type LocalMeta::CallerAlias, the variable dst will also be inserted as caller alias by simply cloning src.

When a call expression like {{ abc() }} is encountered, whose variable is a LocalMeta::CallerAlias, we have found a {{ caller() }}, or any kind of: {{ caller_alias() }}. As soon as a new local scope was created for the call into caller(), a LocalMeta::Negative is inserted into the LocalMap. With this, the caller variable is blocked from access for this scope, and any number of scopes above - until a new entry for caller is inserted in one of the upper scopes. This prohibits callers from calling themselves - which is not supported. This was previously handled by tracking active_caller - but that was not prepared for multiple layers. Due to this restructuring, the error message changed a bit - but I like the new one better.


Imho, this design is rather elegant, since it also "accidentally" is the perfect preparation for supporting the short call syntax of jinja that askama is currently missing:

{% macro test() %}    cake    {% endmacro %}
{# syntax for macro calls without caller(): #}
{{ test() }}
{% call test() %}{% endcall %}

Fixes #505.
Fixes #507.

Comment thread askama_derive/src/generator.rs
Comment thread askama_derive/src/generator/node.rs Outdated
Comment thread askama_derive/src/generator/node.rs Outdated
Comment thread askama_derive/src/generator/node.rs
Comment thread testing/tests/ui/caller_arguments.stderr Outdated
@seijikun seijikun force-pushed the mr-storable-caller branch from 7dad9af to 033dfe6 Compare July 4, 2025 09:38
@seijikun
Copy link
Copy Markdown
Contributor Author

seijikun commented Jul 4, 2025

I hope I got everything. I now explicitly generate a No caller defined error when the caller keyword was used without any caller variable in scope.

Comment thread askama_derive/src/generator/node.rs Outdated
@seijikun seijikun force-pushed the mr-storable-caller branch 2 times, most recently from 8f11902 to 9acc389 Compare July 4, 2025 09:48
@seijikun
Copy link
Copy Markdown
Contributor Author

seijikun commented Jul 4, 2025

Whoops, forgot to change the stderr file back.

@seijikun
Copy link
Copy Markdown
Contributor Author

seijikun commented Jul 4, 2025

Should I bump the cargo version in github workflows as part of this PR, or separately?

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

You also need to update the version used in CI.

@seijikun seijikun force-pushed the mr-storable-caller branch from 9acc389 to a1ec7d2 Compare July 4, 2025 09:53
Comment thread askama_derive/Cargo.toml
@seijikun seijikun force-pushed the mr-storable-caller branch from a1ec7d2 to da96be4 Compare July 4, 2025 10:12
GuillaumeGomez
GuillaumeGomez previously approved these changes Jul 4, 2025
@seijikun
Copy link
Copy Markdown
Contributor Author

seijikun commented Jul 4, 2025

Is the Cluster-Fuzz error something I have to fix?

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Seems it's on the fuzzer side that something needs to be updated. Let's wait for @Kijewski to take a look at your PR first, we can check for the fuzzer afterwards.

@Kijewski
Copy link
Copy Markdown
Member

Kijewski commented Jul 4, 2025

We need to update our config like for the update to 1.83: google/oss-fuzz#13237. I can have a look at the PR later today. I'm not very well versed in that part of our codebase, though, so I'll mostly have to trust the unit tests. :)

@GuillaumeGomez, do you want to file a PR @ oss-fuzz? Otherwise I can do it this evening.

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Sure!

@seijikun
Copy link
Copy Markdown
Contributor Author

seijikun commented Jul 4, 2025

I think there already is one: google/oss-fuzz#13198

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

We override the version, that gives us more liberty. Ie: if we need to update the rust version used, we won't impact other projects. Simpler for everyone. :)

Kijewski
Kijewski previously approved these changes Jul 4, 2025
Copy link
Copy Markdown
Member

@Kijewski Kijewski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much!

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

So just waiting for the oss-fuzz to be merged then we can restart CI here and merge. :)

@GuillaumeGomez GuillaumeGomez changed the title Fix #505, #507: Treat caller() as variable with support for aliasing Treat caller() as variable with support for aliasing Jul 4, 2025
@seijikun seijikun dismissed stale reviews from Kijewski and GuillaumeGomez via d50cb4f July 5, 2025 01:22
@seijikun seijikun force-pushed the mr-storable-caller branch from da96be4 to d50cb4f Compare July 5, 2025 01:22
DavidKorczynski pushed a commit to google/oss-fuzz that referenced this pull request Jul 5, 2025
The next version of askama (v0.15) will need at least rust 1.88 to
compile. The current toolchain shipped in docker (for askama) is rust
1.83, so the project could not get fuzzed anymore.

This PR sets the used toolchain to 1.88.

Cc @Kijewski 

Related PR: askama-rs/askama#510
@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Fuzzer passed, so merging time. Thanks!

@GuillaumeGomez GuillaumeGomez enabled auto-merge July 5, 2025 21:21
@GuillaumeGomez GuillaumeGomez merged commit bbcb70e into askama-rs:master Jul 5, 2025
81 of 82 checks passed
@Kijewski Kijewski mentioned this pull request Jul 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can not use imports from within call-block of another imported macro Support storing caller within variable

3 participants