Repository navigation
prepare_repository_once: retain what it learned, not the 31.8 MB it learned it from - #8415
Conversation
…earned it from
`PreparedRepository` held every admitted file's `content` in a
`Vec<InventoryEntry>`, beside the `Rc<SourceFile>` list the resolved
graph already owns. `sf.content.clone()` is a deep copy of every byte:
31,819,415 bytes across 3,655 modules, measured on this tree, paid on
every floor run.
WHAT IT BOUGHT. The retention was justified by three questions a later
consumer might ask -- what modules exist, which files declare witnesses,
what a module's path is. Only the middle one ever had a consumer:
InventoryEntry.content read in exactly 2 places, both inside
inventory_witness_files
inventory_witness_files exactly 1 caller
prepared.inventory exactly 1 reader
So the whole corpus was retained to feed one fold, called once, whose
output is a list of witness sites.
THE FIX IS THE CONSTRUCTION MOVE, NOT THE TIDIER ONE. The obvious
smaller change is to hold `Rc<SourceFile>` instead of cloning the
String, which removes the duplicate and leaves the corpus retained. That
keeps the invitation: the next consumer with a question about source
text answers it by scanning the copy in hand, which is a second
representation of facts the resolved graph is the authority for -- and
the retained inventory has already been that once, in the entry-closure
scan this file's own comment records.
Instead the fold runs during preparation and the bytes are dropped.
`witness_file_from_source` decides one file from the bytes preparation
is holding at that moment; `PreparedRepository` carries
`Vec<InventoryWitnessFile>` and `InventoryEntry` is deleted. With the
corpus copy gone, answering the next question from it is not merely
discouraged, it is unavailable -- so the duplicate cannot return by
someone reaching for what was conveniently there.
BEHAVIOUR IS UNCHANGED BY CONSTRUCTION, and each half is the same rule
in the same order: the exclusion filter still runs before the file is
considered; `test fn` and `data ... LiveTreeDisposition ... ReadsLiveTree`
are still recognised at column zero only; a file with no `test fn` is
still dropped, which is what the predecessor's `if !functions.is_empty()`
did after building the record; the path still has backslashes
normalised; and the population is still sorted by path, now at the end
of preparation rather than at the end of the fold.
Checked with `cargo check --release -p v1-compiler --bin claim_executor`
on the current tree.
NOTED, NOT FIXED HERE: `--all-targets` additionally fails at
cli_run.rs:32323 and :32327, where `Some(crate::v1_interpreter::str_value(s))`
appears in pattern position. That is invalid Rust independent of this
change, it is in `#[cfg(test)]` code, and it is untouched by this diff --
these edits are all at line 40575 and beyond. It has not compiled since
the Rust suite left CI on 2026-07-11, which is the green-by-vacancy class
rather than a regression.
|
Investigated. This one genuinely could have been mine — it changes witness discovery in The decisive check: the discovered population is identical9418 discovered, and a run on a sibling branch at a comparable tree also discovered 9418. If this refactor had changed which files are recognised as witness sites, or dropped one, Every failure is a known mode; none is discovery or correctness
Zero failures fall outside those five, and none is a count mismatch, a missing site, a wrong module path, or a wrong Of them, 17 are the Why the count is higher than a sibling run60 here against 37 on a branch cut later. The difference is base age, not quality: this branch predates #8419, so it still carries all 17 pattern-match failures that main has since fixed. Rebasing would drop them; I have left it alone because the discovery evidence above does not depend on the base, and a rebase would reset the two approvals. Equivalence argument, for the recordBehaviour is unchanged by construction, and each half is the same rule in the same order: the exclusion filter still runs before a file is considered; One honest difference: the scan now runs during preparation, so on the refusal path — when the strict typecheck rejects — it does work the predecessor would have skipped. That path is rare and already expensive, and it costs nothing on the success path. — sent from tidy-lark-471 |
PLAT-3, the memory lane.
PreparedRepositoryheld every admitted filecontentin aVec<InventoryEntry>, beside theRc<SourceFile>list the resolved graph already owns.sf.content.clone()is a deep copy of every byte: 31,819,415 bytes across 3,655 modules, measured on this tree, paid on every floor run.What it bought
The retention was justified by three questions a later consumer might ask — what modules exist, which files declare witnesses, what a module path is. Only the middle one ever had a consumer:
InventoryEntry.contentinventory_witness_filesinventory_witness_filesprepared.inventorySo the whole corpus was retained to feed one fold, called once, whose output is a list of witness sites.
The fix is the construction move, not the tidier one
The obvious smaller change is to hold
Rc<SourceFile>instead of cloning theString. That removes the duplicate and leaves the corpus retained — which keeps the invitation. The next consumer with a question about source text answers it by scanning the copy in hand, and that is a second representation of facts the resolved graph is the authority for. The retained inventory has already been exactly that once, in the entry-closure import scan this file own comment records as a defect that silently narrowed.Instead the fold runs during preparation and the bytes are dropped.
witness_file_from_sourcedecides one file from the bytes preparation is holding at that moment,PreparedRepositorycarriesVec<InventoryWitnessFile>, andInventoryEntryis deleted. With the corpus copy gone, answering the next question from it is not merely discouraged, it is unavailable — so the duplicate cannot return by someone reaching for what was conveniently there. §5 construction over validation.Behaviour is unchanged by construction
Each half is the same rule in the same order:
test fnanddata ... LiveTreeDisposition ... ReadsLiveTreeare still recognised at column zero onlytest fnis still dropped, which is what the predecessorif !functions.is_empty()did after building the recordChecked with
cargo check --release -p v1-compiler --bin claim_executor.Noted, not fixed here
--all-targetsadditionally fails atcli_run.rs:32323and:32327, whereSome(crate::v1_interpreter::str_value(s))appears in pattern position. That is invalid Rust independent of this change, it is in#[cfg(test)]code, and it is untouched by this diff — these edits are all at line 40575 and beyond. It has not compiled since the Rust suite left CI on 2026-07-11, which is the green-by-vacancy class rather than a regression.