Skip to content

Expr/SyntaxTree parity: trivial conversions#60373

Merged
topolarity merged 3 commits intoJuliaLang:masterfrom
mlechu:est-2-expr-est
Dec 16, 2025
Merged

Expr/SyntaxTree parity: trivial conversions#60373
topolarity merged 3 commits intoJuliaLang:masterfrom
mlechu:est-2-expr-est

Conversation

@mlechu
Copy link
Member

@mlechu mlechu commented Dec 12, 2025

As discussed on slack with @c42f and @topolarity, I gave expansion-time conversions an honest try, but couldn't see the end of the tunnel in terms of correctness. The equivalence between SyntaxNode and Expr is only defined on surface syntax or fully-macro-expanded syntax, and not the steps in between, or if errors occur. We have a plan for syntax evolution now, too, so there compelling reasons not to lump changes to AST layout into JuliaLowering's macro expansion.

Let EST be the "new" Expr-like SyntaxTree I'm working on and CST be the current SyntaxNode-like version. PRs planned:

  1. Move SyntaxGraph/SyntaxTree from JuliaLowering to JuliaSyntax #60370
  2. (this PR) Trivial EST<->Expr conversion, tested by parsing code in bulk and round-tripping
  3. RawGreenNode->EST (identical logic to existing RawGreenNode->Expr, and testable with this PR's Expr->EST)
  4. EST->CST*: This would just be a simplification of our existing Expr->CST, and prevents us from needing to make huge changes in desugaring (which understands CST*). Macro expansion will become EST->EST rather than CST->CST*.
  5. Before one or both of the above, I may try and merge a basic SyntaxTree pattern-matching macro so operating on these things is less tedious. This is already written, but needs tests.

@topolarity
Copy link
Member

Draft due to being atop #60370.

Merged!

EST->CST: This would just be a simplification of our existing Expr->CST, and prevents us from needing to make huge changes in desugaring (which understands CST). Macro expansion will become EST->EST rather than CST->CST*.

At what point do we replace CST with EST completely, if any?

@mlechu
Copy link
Member Author

mlechu commented Dec 12, 2025

At what point do we replace CST with EST completely, if any?

PR 4 in the list replaces it completely from the perspective of macro authors. Internal to lowering, we can make individual changes to EST->CST* and desugaring at the same time at whatever pace we'd like.

@c42f
Copy link
Member

c42f commented Dec 13, 2025

At what point do we replace CST with EST completely, if any?

I'd prefer to keep CST and RawGreenNode close together, and aim for CST to eventually be the new AST once we release new-style macros. In the meantime it's an implementation detail which we can keep refining as we see fit.

My very strong preference is that we don't get stuck with the Expr AST heads and semantics in the long term (even if in SyntaxTree form) as it has plenty of deficiencies which I've discussed with @JeffBezanson and tried to fix while developing JuliaSyntax.

Copy link
Member

@topolarity topolarity left a comment

Choose a reason for hiding this comment

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

Had a good chat with @c42f and @mlechu about this change today. Sounds like we're OK with this direction for now, although the question about how to do syntax evolution (and whether that's better done in a user-facing CST that diverges from Expr, or by evolving EST / Expr in lock-step) remains somewhat open.

For now, the idea is to shoot for parity since it avoids correct-ness issues around macros consuming / generating ~invalid Julia AST. "New macro" authors will write / process EST. Those authors are just us anyway until "new" macros are polished and released to external users, at which point we can revisit this (presumably we'll have a nice, battle-tested pipeline at that point)

@topolarity topolarity merged commit 1cff130 into JuliaLang:master Dec 16, 2025
8 checks passed
mlechu added a commit that referenced this pull request Jan 30, 2026
Step 4 in the the plan at #60373.

Main changes:
- Delete old `expr_to_syntaxtree` (hooray)

- Introduce `est_to_dst`, which does a similar conversion as the above,
but can assume all macros have expanded. (I've chosen "dst" for to mean
"desugarable syntax tree" instead of the "current syntax tree" naming
I've been using thus far)

- Update macro expansion to be a function EST->EST

- Add the AST validator from
JuliaLang/JuliaLowering.jl#93, which I've
changed to work on Expr structure. It's included in this PR so that
`est_to_dst` doesn't need to do all the same checking (since nothing can
be assumed about the output of macro expansion). Most of the long
write-up there still applies, and using the same assumptions in
desugaring could make it much less messy in the future.
- This also means we're now able to return multiple AST-related syntax
errors per top-level thunk, which may be of interest to @aviatesk. I
haven't implemented pretty-printing for this beyond a `for` loop,
though.

- We now go though the `Core.@doc`system instead of the `K"doc"`system,
which should be a temporary solution before we (1) get JuliaLowering
working, then (2) handle docstrings in lowering in both implementations.

- Many tests have been updated with the changes in behaviour. I've
deleted a few where the point of the test is no longer relevant, but
otherwise tried to maintain the spirit of each test.

- Changes in syntax_macros.jl to produce the new old AST. The largest
change is to our version of `@ccall`. Desugaring has also been tweaked
so that it can tolerate `@ccall` expanded by flisp.

stdlib status: There shouldn't be any regressions, and TOML and LibGit2
now precompile.

Atop #60710

---------

Co-authored-by: Cody Tapscott <topolarity@tapscott.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants