add `macroexpand!` function and add `legacyscope` kwarg (#59276)
Setting `legacyscope=false` is intended to make it much easier to debug
and test macro expansion, since it no longer runs a buggy symbol
mangling pass automatically. Adding the mutating version
(`macroexpand!`) is mainly a handy way to opt in to the new
legacyscope=true, without needing to spell that out.
More background: the macroexpand.scm pass design is buggy, so we'd like
to stop using in the future. Currently changing the default causes
visible breakage to a lot of buggy packages tests, so for now just
provide the option to skip the legacy scope resolution. This is a
continuation of https://github.com/JuliaLang/julia/pull/49793 and a
prerequisite for eventually replacing the flisp code with JuliaLowering
(once we can deprecate this parameter).
Implement in-place macro expansion with `macroexpand!` (no corresponding
`@macroexpand!`) that avoids copying AST nodes when the original
expression is no longer needed anyways. But more importantly, add a
`legacyscope::Bool` keyword argument to the functions that allows opting
out of the legacy scope mangling.
Changes:
- Consolidate `jl_macroexpand` C functions with added parameters for
`recursive`, `inplace`, and the (legacy) `expand_scope` control.
- Add `macroexpand!` Julia function with `legacyscope=false` default.
- Update `macroexpand` to have `legacyscope` (default `true`) for
backward compatibility, until v2 or earlier.
Added to backporting so that new code can start to be written with
`legacyscope=false`. Not entirely a new feature, since this is just
adding the ability to disable an old (long deprecated) feature.
🤖 Generated with Claude