Skip to content

yeast: Isolate interpolation contexts from each other - #22964

Draft
tausbn wants to merge 8 commits into
mainfrom
tausbn/yeast-isolate-interpolation-contexts
Draft

tausbn wants to merge 8 commits into
mainfrom
tausbn/yeast-isolate-interpolation-contexts

Conversation

@tausbn

@tausbn tausbn commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Currently we have context isolation between rules: a change to ctx is visible when we translate child nodes (if the translation happens after the change, of course), but these changes cannot leak to different rules.

However, the same isolation does not apply to context modifications made inside of the interpolations of an output template. That is, in the following template

(foo 
    bar: {ctx.reset(); bar}
    baz: {baz}
)

both bar and baz will be evaluated in a reset context. If we swap the two field assignments, then only bar gets a reset context.

This behaviour is very surprising, and likely to cause hard-to-spot bugs.

To fix this, we now clone the user context for each interpolation individually (but only if they refer to the ctx variable), which means they cannot interfere with each other. This is slightly less efficient, but much safer.

This also enables us to get rid of the two uses of ctx.scoped that we currently have, and clean up the code a bit.

@tausbn tausbn added the no-change-note-required This PR does not need a change note label Oct 30, 2026
@tausbn
tausbn requested a max review from Copilot October 30, 2026 17:06

This comment was marked as outdated.

We catch any panics in `Runner::run_once`, and turn them into `Err`
results. This prevents them from affecting the extraction of other
files.
Also updates the remaining tests to use the new infallible interface.
When `panic!` gets called, the default Rust panic handler prints out the
error (and possibly a backtrace) to stderr. This means even if we handle
the panics in `run_once`, we still get the printed output.

To avoid this, we use `resume_unwind` (which foregoes the default
behaviour) instead, and add a helper function called
`translation_failure` that takes care of the places where translation
could previously panic.
@tausbn
tausbn force-pushed the tausbn/yeast-isolate-interpolation-contexts branch 2 times, most recently from fdd6839 to 027df4b Compare November 6, 2026 15:12
Wraps each interpolation is a small bit of code that clones the user
context before running the block of code, and restores it afterwards.

We only do this for blocks that actually mention the `ctx` variable.
Other cases (the vast majority) just inline the block directly, so that
there's no unnecessary overhead in the most common case.

The `ctx` check is not perfect -- it won't notice cases where you
(outside the interpolation) rebind it to a different variable, say, but
it should be a good enough test for the way we currently write rules.
This allows us to get rid of two uses of `ctx.scoped`, cleaning up the
code a bit in the process.
@tausbn
tausbn force-pushed the tausbn/yeast-isolate-interpolation-contexts branch from 027df4b to 81057bd Compare November 6, 2026 15:19
@tausbn
tausbn requested a max review from Copilot November 6, 2026 15:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Interpolation handling can fail to compile with borrowed builders and leak context mutations across translations, while public query failures can lose readable diagnostics.

6 open issues

Review effort: Max

Comment thread shared/yeast-macros/src/lower.rs Resolved
Comment thread shared/yeast-macros/src/lower.rs Resolved
Comment thread shared/yeast-macros/src/lower.rs Resolved
Comment thread shared/yeast/src/query.rs Resolved

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note Unified

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants