module: programmatically retract export/public (#62131)
Add `jl_module_set_visibility` and the Base wrapper~s~
`set_binding_visibility!` ~/ `binding_visibility`~, which select a
name's declared visibility (`:none`, `:public`, or `:export`) in a
module. Unlike the `export` and `public` keywords, the selector can
lower the state, retracting a declaration. Setting `:none` on an
exported name clears the world-versioned `PARTITION_FLAG_EXPORTED`, so
modules that did `using M` stop resolving the name once their world age
advances past the call; the public flag is cleared on the binding.
This gives tooling a way to honor an `export` removed from source
(timholy/Revise.jl#633).
A couple of comments about the larger picture: the design enforces a
3-state model, meaning it's not possible to be both public and exported.
It's worth noting that
[`jl_module_public_`](https://github.com/JuliaLang/julia/blob/528757702d170f4a6d56192412d7e4a0d042c2b1/src/module.c#L1501-L1507)
(still) looks like a "don't change" check, but after discussion with
@Keno at https://github.com/timholy/Revise.jl/pull/1089 I now think this
should be interpreted as a slightly-confusing mechanism to enforce the
3-state model. (I can add a comment clarifying that if true and
desired.) ~~`binding_visibility` isn't strictly needed, but it felt
right to add it. I'd argue that Julia's current `isexported` and
`ispublic` functions are, in a sense, less honest about this. But I'm
happy to delete `binding_visibility` if it's deemed unnecessary.~~
(deleted)
---------
Co-authored-by: Keno Fischer <keno@juliacomputing.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>