Skip to content

fix(jinja): exhaustively handle CallArg variants in used-variable collection - #2505

Merged
wolfv merged 1 commit into
mainfrom
fix/jinja-callarg-exhaustive
May 20, 2026
Merged

fix(jinja): exhaustively handle CallArg variants in used-variable collection#2505
wolfv merged 1 commit into
mainfrom
fix/jinja-callarg-exhaustive

Conversation

@wolfv

@wolfv wolfv commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

While fixing the minijinja 2.20 build break (PR #2427, Expr::Compare), I audited the rest of the AST walker in rattler_build_jinja/src/ast_variables.rs and found a pre-existing gap: collect_variables_from_call_arg matches only CallArg::Pos and uses _ => {} to swallow the other three variants. The same Pos-only filter is duplicated in the pin_subpackage, pin_compatible, and match special-function arms.

Result: templates using kwarg or splat call forms lose variables for variant tracking. E.g.

${{ pin_subpackage(name=somevar) }}    # somevar dropped
${{ my_fn(**kwargs) }}                 # kwargs dropped

In conda-build idioms these are always positional, so existing recipes are unlikely to hit this — but user-written macros that pass kwargs or splats would silently lose variant detection.

This PR:

  • Adds call_arg_expr — a small helper that exhaustively destructures every CallArg variant (Pos | Kwarg | PosSplat | KwargSplat) into its inner Expr. No wildcard arm, so a future minijinja release that adds a new variant will fail to compile here instead of silently losing variables — same property that just saved us for Expr::Compare.
  • Routes collect_variables_from_call_arg and the three special-function arms through the helper.
  • Adds three regression tests: chained comparison (Expr::Compare), pin_subpackage kwarg form, and a generic call covering all four CallArg variants.

This is stacked on top of #2427 so the new chained-comparison test compiles. Once #2427 merges to main, GitHub will auto-rebase this diff down to just the audit changes.

Test plan

  • cargo test -p rattler_build_jinja — 48/48 pass (up from 45)
  • cargo check --workspace clean
  • CI green

🤖 Generated with Claude Code

@wolfv
wolfv force-pushed the fix/jinja-callarg-exhaustive branch 2 times, most recently from aa9fb11 to e826be4 Compare May 20, 2026 11:54
… variables

`collect_variables_from_call_arg` previously matched only `CallArg::Pos`
with a wildcard fallback, silently dropping any variables passed via
`Kwarg`, `PosSplat`, or `KwargSplat`. The same Pos-only filter was
duplicated inside the `pin_subpackage`, `pin_compatible`, and `match`
arms of `collect_variables_from_call`, so e.g. `pin_subpackage(name=foo)`
or `my_fn(**kwargs)` would not track `foo` / `kwargs` for variant
detection.

Introduce a small `call_arg_expr` helper that exhaustively destructures
every `CallArg` variant into its inner `Expr`. No wildcard arm: a future
minijinja release that adds a new variant will fail to compile here
instead of quietly losing variables — same property we just relied on
for the `Expr::Compare` bump.

Regression tests added:
- chained-comparison form (`lo <= n < hi`) — guards Expr::Compare
- `pin_subpackage(name=somevar)` — kwarg form on a special function
- `my_fn(foo, bar=baz, *args, **kwargs)` — generic call coverage of all
  four CallArg variants

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wolfv
wolfv force-pushed the fix/jinja-callarg-exhaustive branch from e826be4 to e11ae1a Compare May 20, 2026 12:53
@wolfv
wolfv merged commit 6cab684 into main May 20, 2026
11 checks passed
@wolfv
wolfv deleted the fix/jinja-callarg-exhaustive branch May 20, 2026 13:31
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.

1 participant