Skip to content

yeast: Isolate interpolation contexts from each other - #22964

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

tausbn wants to merge 2 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, 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.

This prevents mutations in one output template interpolation from
affecting sibling output.
With the new context isolation, we don't need to explicitly introduce a
new scope. We could probably get rid of `ctx.scoped` now, but there's no
harm in leaving it around.
@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

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

The context-isolation change introduces borrowing conflicts and alters dereference behavior, breaking previously valid interpolation expressions and borrowed inputs.

2 open issues
What changed in this PR

This PR extends Yeast’s context isolation from rules to individual output-template interpolations, preventing mutations in one interpolation from affecting its siblings.

Changes:

  • Add a guard that clones and restores the user context around each interpolation.
  • Add a regression test covering isolation across several interpolation forms.
  • Simplify Swift translation rules by replacing explicit context scopes with isolated interpolations.
File Description
unified/​extractor/​src/​languages/​swift/​swift.rs Simplifies initializer and callee translation and updates context-reset documentation.
shared/​yeast/​tests/​test.rs Tests that interpolation mutations do not leak into sibling interpolations or the surrounding context.
shared/​yeast/​src/​build.rs Adds a context guard that restores the original user context when dropped.
shared/​yeast-macros/​src/​lower.rs Wraps generated interpolation code in the isolation guard.

Review effort: Max


fn isolated_interpolation(body: TokenStream) -> TokenStream {
quote! {{
let mut ctx = ctx.cloned_user_ctx();

fn isolated_interpolation(body: TokenStream) -> TokenStream {
quote! {{
let mut ctx = ctx.cloned_user_ctx();

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