Record include(mapexpr) functions#62176
Conversation
Package cache headers store information needed to determine validity and a cache of source-text. The latter gets consumed by Revise, as a record of what the code was before edits were made. This allows Revise to skip defensively parsing every loaded package. However, there has long been a gap in this system: `include(mapexpr, …)` calls, which can modify the "effective" source text of the included files. Currently, Revise cannot even determine whether a package has used a non-identity `mapexpr` function without defensively parsing every included file. Add `Base.include_mapexprs(mod)`, returning the non-identity `mapexpr` functions passed to `include(mapexpr, …)` calls while loading the package rooted at `mod`, keyed by `(including_module, absolute_path)`, or `nothing` when there were none. These functions are recorded into a hidden `const` binding in the package's own root module as the includes run, so they serialize into the package image and remain available after the package is loaded from its cache. This lets revision tools (e.g. Revise) re-apply the original transform when an `include(mapexpr, …)`-ed file is edited. Recording the actual function object is necessary because a `mapexpr` that captures runtime state cannot be reconstructed by re-parsing the source; the precompile environment is closed and deterministic, so the object is serializable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
On my bike ride home I asked myself, "if I wanted to break this, how would I do it?" And unfortunately there is a clear path: piracy. Suppose This is tough because there is no monotonic world-age in which it works; you'd have to insist that |
Package cache headers store information needed to determine validity and a cache of source-text. The latter gets consumed by Revise, as a record of what the code was before edits were made. This allows Revise to skip defensively parsing every loaded package. However, there has long been a gap in this system:
include(mapexpr, …)calls, which can modify the "effective" source text of the included files. Currently, Revise cannot even determine whether a package has used a non-identitymapexprfunction without defensively parsing every included file.Add
Base.include_mapexprs(mod), returning the non-identitymapexprfunctions passed toinclude(mapexpr, …)calls while loading the package rooted atmod, keyed by(including_module, absolute_path), ornothingwhen there were none.These functions are recorded into a hidden
constbinding in the package's own root module as the includes run, so they serialize into the package image and remain available after the package is loaded from its cache.This lets revision tools (e.g. Revise) re-apply the original transform when an
include(mapexpr, …)-ed file is edited. Recording the actual function object is necessary because amapexprthat captures runtime state cannot be reconstructed by re-parsing the source; the precompile environment is closed and deterministic, so the object is serializable.