{{ message }}
yeast: Extend rule! macro with support for raw captures#22070
Open
tausbn wants to merge 4 commits into
Open
Conversation
The `@@name` capture marker in `rule!` queries skips the auto-translate prefix for that specific capture, letting the body see the original capture (and thus delay its translation using `ctx.translate` until it becomes convenient). Regular `@name` captures continue to be auto-translated as before. Specifically these are translated _eagerly_, before the main body of the rewrite rule is run. I settled on `@@` as the syntax because it did not add new symbols that the user has to keep track of (it's still a kind of capture), but it's still visually distinct enough that the user should be able to tell that there's something special going on. In principle one could accidentally write one form of capture where the other was intended, but in practice this would result in code that did not compile (because the types would not match).
With `@@name` available, there's no longer a need to use `manual_rule!`. Every place where it is used, we can instead just mark the relevant raw captures as such. This results in quite a lot of cleanup! (Also, to me at least, it makes these rules a lot easier to reason about.) A first iteration of this approach resulted in a lot of `.map(Into::into)` being needed, because `SwiftContext` stores `Id`s, but captures produce `NodeRef`s. To avoid this, I swapped it around so that the context stores `NodeRef`s. This does require adding `.into()` in a few places, but it makes the rest of the code a lot more ergonomic.
The `manual_rule!` macro is now fully subsumed by `rule!` + `@@name`, so this commit simply gets rid of the now no longer needed code.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the Yeast rule! macro to support raw captures via an @@name marker, allowing rules to opt out of the macro’s OneShot auto-translation prefix for specific captures (so the rule body can manually call ctx.translate(...) at the right time). It also removes the superseded manual_rule! macro and restores the ergonomics of not having to explicitly return Ok(...) from rule bodies.
Changes:
- Add
@@namecapture markers in the macro parser and plumb a per-rule “skip list” intoauto_translate_captures. - Implement capture-mapping support to skip auto-translation for selected capture names; remove
manual_rule!exports/implementation. - Update Swift desugaring rules to use
rule!+@@...instead ofmanual_rule!, and add tests/docs for raw capture behavior.
Show a summary per file
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 3
- Review effort level: Low
- unified/swift: Mark `binding_kind` as a raw `@@` capture in the property_declaration rule. It is only used to read its source text (`ctx.ast.source_text`), never as a translated node. With `@` the auto-translate prefix would route the unnamed `let`/`var` token through the catch-all `_ @node => {node}` fallback for a no-op roundtrip; `@@` makes the intent explicit and removes that reliance. - shared/yeast/tests: Reword a stale comment in test_raw_capture_marker. The text claimed a "second assertion" exists in this test, but the explicit-translation check actually lives in the companion test_raw_capture_marker_explicit_translate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

This entirely supersedes the previous
manual_rule!macro, which effectively marked all captures as raw.With the changes in this PR, writing a capture as
@@fooinstead of@foomakes it a raw capture. These captures must be translated manually by callingctx.translate(foo)at the appropriate time.I opted for the
@@prefix as raw capture marker, as it still signals "capture", but doesn't introduce a new symbol. Normal captures get the shorter syntax, as they are the more common case.Also, in terms of evaluation, normal captures are translated eagerly, before the body of the macro is run.
There are a few remaining annoyances that I want to address (but not in this PR). The fact that we have two types (
NodeRefandId) that are essentially justusize, and that we need to explicitly.into()to convert between is annoying. I think these types can be unified relatively easily.