fix(gc): root every argument of a cross-module direct call (#7240, by @jdalton) - #7252
Merged
Merged
Conversation
An argument list is evaluated left to right and each finished value sits in
a bare SSA register while the later ones are lowered.
`lower_call/extern_func.rs`'s generic `perry_fn_<src>__<name>` path lowered
the whole list in a plain `for a in args` loop with no protection at all, so
`f(A, B, {…}, Schema.array(), body => …)` leaves A and B naming
pre-collection addresses the moment an evacuating minor lands in argument 3,
4 or 5 — and it does: argument 3 allocates an object, argument 4 runs user
code with its own back-edge polls, argument 5 allocates a closure.
This is #7227's residual. In the registry it is `src/lib/api/alerts.ts`'s
module init calling `defineApiCall(url, method, …)` across the module
boundary; the fault surfaces one frame down inside `js_regexp_test`, because
the stale `url` is what `/\[[a-zA-Z]+\]/.test(url)` hands it. Measured at the
fault rather than read off the disassembly: the string literal's
`__perry_init_strings_*` handle global held the post-move address evacuation
wrote back, while the register held the retired from-space one.
A string-literal argument therefore takes `OperandProtection::Reload` — its
handle global is a registered root, so the string is never swept, and
re-emitting the load below the collection point costs no runtime call. Other
arguments take a real temp root. Both come from `lower_exprs_rooted`, which
already does this for the `new C(…)` list, and each argument is gated on
`any_later_ref_may_trigger_gc` so lists with nothing allocating after them
emit the IR they emitted before.
The static checker missed it because it classifies a heap-value source as an
`ALLOC_RE` call or a shadow-slot load; a load of a string-literal handle
global is neither. Over the new gap test's IR it reports 24 `--moving-only`
stale uses at the call and names none of them `%r9`/`%r10`, the two literals
that actually faulted.
Refs #7154, #7226, #7227, #7161
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughChangesCross-module argument rooting
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Aug 2, 2026
Closed
proggeramlug
added a commit
that referenced
this pull request
Aug 2, 2026
jdalton
added a commit
to jdalton/perry
that referenced
this pull request
Aug 2, 2026
Four PRs in a row shipped a test file that ran nowhere. PerryTS#7192 and PerryTS#7216 each added a `test_gap_gc_*` stale-root witness and no corpus line; PerryTS#7252 added a third; PerryTS#7270/PerryTS#7271 added two more, caught by the maintainer at merge. Four occurrences of one mistake is a missing gate, not carelessness. An unregistered file is not a failing test, it is no test at all. The PR is green, the reviewer sees a witness in the diff next to a passing run and reads the two together as "covered", and nothing says otherwise because nothing ran. This is CLAUDE.md's fourth hazard in its purest form: the gate runs, its subject never does. Registration checks already existed for two of the three prefixes (`gc_repsel_matrix.sh` auto-detects `test_gap_repsel_*`/`test_gap_specabi_*`, `gc-moving-witnesses.yml` adds `test_gap_gc_*`) and neither could catch the pull request that needed it: both sit behind a 90-minute release build of the compiler, behind a changed-paths relevance filter, and in workflows that are not in branch protection's required contexts. `scripts/check_test_registration.py` is the cheap half of those checks, pulled out to where it can block, and generalised past that one corpus. Pure filesystem and text — no compiler, no Node, ~0.2s — over four mechanisms: gc-repsel-corpus test-files/test_gap_{gc,repsel,specabi}_*.ts -> test-parity/gc_repsel_corpus.txt feature-matrix-probes test-features/probes/**/*.ts -> test-features/feature_matrix.toml compiler-output-workloads benchmarks/compiler_output/fixtures/**/*.ts -> benchmarks/compiler_output/workloads.toml rust-test-modules crates/*/**/tests/**/*.rs below a suite root -> the `mod` declaration in the parent module The last is the Rust analogue and is worth naming: cargo auto-discovers `crates/<c>/tests/<suite>.rs`, but a file one level deeper only compiles if a `mod` names it. Without one rustc never parses it — not dead code, not code, no warning. Built to be able to fail, against all four hazards: 1. no `continue-on-error`, no `|| true`; the step's exit status is the gate. 2. it is a step in `lint`, which is ALREADY a required context. That placement is the point: forgetting to add a new job to branch protection is hazard 2, and it is what left `gc-root-dominance` red and blocking nothing for days. No admin action is needed here because the step that gets forgotten does not exist. 3. `lint`'s concurrency already cancels pull-request runs only. 4. the subject is asserted live. Each mechanism floors its candidate set and FAILS if the glob stops matching, so "0 dark over 0 candidates" cannot print the same verdict as "0 dark over 157". Every run states `checked N files against M registries`. Exclusions are named with reasons rather than counted, because a threshold cannot tell a new dark file from an old one — fix one, add one, tally unchanged. A stale exclusion, one matching no file on disk, is itself a failure, so an excuse cannot outlive the file it excuses. Same for the mirror image: a registry entry whose file is gone fails as a rotted entry. `--self-test` (32 cases, also run in `lint`) plants an unregistered file into each of the four mechanisms over the REAL registries via an in-memory overlay, asserts the gate names it, then removes it and asserts green. It also pins the one false positive found while writing this: `resolve/tests/ declaration_sidecar_tests/compile_package.rs` IS declared, by a `mod` inside an inline `mod … { }` block two levels up, and the first draft condemned it. A gate that cries wolf gets deleted. Verified end to end on disk, not just through the overlay: planted a real unregistered file in each of the four mechanisms, watched the gate go red and name it; registered one and watched it go green; deleted the file leaving the line and watched the rotted-entry arm go red; restored and watched it go green. Today's dark set is empty for all four, so this is green on `main` from the first run and safe in a required context. Three feature probes and two compiler-output fixtures are excluded, each with its reason: four are helper modules imported by a registered test, and `benchmarks/compiler_output/fixtures/raw_numeric_layout_smoke.ts` is registered in a different registry (the `raw_numeric_layouts` target-collector workload in `scripts/run_memory_stability_tests.sh`). Deliberately out of scope: `tests/*.sh|py|ts`, where 143 of 171 files are referenced by nothing in the tree. There is no registry there to diff against, so "unregistered" is not even well defined; that is an archaeology problem (triage each, wire it up or delete it) and inventing a registry for it retroactively would make this gate red on day one for reasons unrelated to the four dark witnesses. `--list` says so out loud rather than leaving the silence. Docs where an author will actually meet the rule: a new `docs/src/testing/test-registration.md`, a bullet in CONTRIBUTING.md's "what goes in a PR", and a rewritten header on each of the three registry files. Refs PerryTS#7192, PerryTS#7216, PerryTS#7252, PerryTS#7270, PerryTS#7271.
jdalton
added a commit
to jdalton/perry
that referenced
this pull request
Aug 2, 2026
Four PRs in a row shipped a test file that ran nowhere. PerryTS#7192 and PerryTS#7216 each added a `test_gap_gc_*` stale-root witness and no corpus line; PerryTS#7252 added a third; PerryTS#7270/PerryTS#7271 added two more, caught by the maintainer at merge. Four occurrences of one mistake is a missing gate, not carelessness. An unregistered file is not a failing test, it is no test at all. The PR is green, the reviewer sees a witness in the diff next to a passing run and reads the two together as "covered", and nothing says otherwise because nothing ran. This is CLAUDE.md's fourth hazard in its purest form: the gate runs, its subject never does. Registration checks already existed for two of the three prefixes (`gc_repsel_matrix.sh` auto-detects `test_gap_repsel_*`/`test_gap_specabi_*`, `gc-moving-witnesses.yml` adds `test_gap_gc_*`) and neither could catch the pull request that needed it: both sit behind a 90-minute release build of the compiler, behind a changed-paths relevance filter, and in workflows that are not in branch protection's required contexts. `scripts/check_test_registration.py` is the cheap half of those checks, pulled out to where it can block, and generalised past that one corpus. Pure filesystem and text — no compiler, no Node, ~0.2s — over four mechanisms: gc-repsel-corpus test-files/test_gap_{gc,repsel,specabi}_*.ts -> test-parity/gc_repsel_corpus.txt feature-matrix-probes test-features/probes/**/*.ts -> test-features/feature_matrix.toml compiler-output-workloads benchmarks/compiler_output/fixtures/**/*.ts -> benchmarks/compiler_output/workloads.toml rust-test-modules crates/*/**/tests/**/*.rs below a suite root -> the `mod` declaration in the parent module The last is the Rust analogue and is worth naming: cargo auto-discovers `crates/<c>/tests/<suite>.rs`, but a file one level deeper only compiles if a `mod` names it. Without one rustc never parses it — not dead code, not code, no warning. Built to be able to fail, against all four hazards: 1. no `continue-on-error`, no `|| true`; the step's exit status is the gate. 2. it is a step in `lint`, which is ALREADY a required context. That placement is the point: forgetting to add a new job to branch protection is hazard 2, and it is what left `gc-root-dominance` red and blocking nothing for days. No admin action is needed here because the step that gets forgotten does not exist. 3. `lint`'s concurrency already cancels pull-request runs only. 4. the subject is asserted live. Each mechanism floors its candidate set and FAILS if the glob stops matching, so "0 dark over 0 candidates" cannot print the same verdict as "0 dark over 157". Every run states `checked N files against M registries`. Exclusions are named with reasons rather than counted, because a threshold cannot tell a new dark file from an old one — fix one, add one, tally unchanged. A stale exclusion, one matching no file on disk, is itself a failure, so an excuse cannot outlive the file it excuses. Same for the mirror image: a registry entry whose file is gone fails as a rotted entry. `--self-test` (32 cases, also run in `lint`) plants an unregistered file into each of the four mechanisms over the REAL registries via an in-memory overlay, asserts the gate names it, then removes it and asserts green. It also pins the one false positive found while writing this: `resolve/tests/ declaration_sidecar_tests/compile_package.rs` IS declared, by a `mod` inside an inline `mod … { }` block two levels up, and the first draft condemned it. A gate that cries wolf gets deleted. Verified end to end on disk, not just through the overlay: planted a real unregistered file in each of the four mechanisms, watched the gate go red and name it; registered one and watched it go green; deleted the file leaving the line and watched the rotted-entry arm go red; restored and watched it go green. Today's dark set is empty for all four, so this is green on `main` from the first run and safe in a required context. Three feature probes and two compiler-output fixtures are excluded, each with its reason: four are helper modules imported by a registered test, and `benchmarks/compiler_output/fixtures/raw_numeric_layout_smoke.ts` is registered in a different registry (the `raw_numeric_layouts` target-collector workload in `scripts/run_memory_stability_tests.sh`). Deliberately out of scope: `tests/*.sh|py|ts`, where 143 of 171 files are referenced by nothing in the tree. There is no registry there to diff against, so "unregistered" is not even well defined; that is an archaeology problem (triage each, wire it up or delete it) and inventing a registry for it retroactively would make this gate red on day one for reasons unrelated to the four dark witnesses. `--list` says so out loud rather than leaving the silence. Docs where an author will actually meet the rule: a new `docs/src/testing/test-registration.md`, a bullet in CONTRIBUTING.md's "what goes in a PR", and a rewritten header on each of the three registry files. Refs PerryTS#7192, PerryTS#7216, PerryTS#7252, PerryTS#7270, PerryTS#7271.
jdalton
added a commit
to jdalton/perry
that referenced
this pull request
Aug 2, 2026
Four PRs in a row shipped a test file that ran nowhere. PerryTS#7192 and PerryTS#7216 each added a `test_gap_gc_*` stale-root witness and no corpus line; PerryTS#7252 added a third; PerryTS#7270/PerryTS#7271 added two more, caught by the maintainer at merge. Four occurrences of one mistake is a missing gate, not carelessness. An unregistered file is not a failing test, it is no test at all. The PR is green, the reviewer sees a witness in the diff next to a passing run and reads the two together as "covered", and nothing says otherwise because nothing ran. This is CLAUDE.md's fourth hazard in its purest form: the gate runs, its subject never does. Registration checks already existed for two of the three prefixes (`gc_repsel_matrix.sh` auto-detects `test_gap_repsel_*`/`test_gap_specabi_*`, `gc-moving-witnesses.yml` adds `test_gap_gc_*`) and neither could catch the pull request that needed it: both sit behind a 90-minute release build of the compiler, behind a changed-paths relevance filter, and in workflows that are not in branch protection's required contexts. `scripts/check_test_registration.py` is the cheap half of those checks, pulled out to where it can block, and generalised past that one corpus. Pure filesystem and text — no compiler, no Node, ~0.2s — over four mechanisms: gc-repsel-corpus test-files/test_gap_{gc,repsel,specabi}_*.ts -> test-parity/gc_repsel_corpus.txt feature-matrix-probes test-features/probes/**/*.ts -> test-features/feature_matrix.toml compiler-output-workloads benchmarks/compiler_output/fixtures/**/*.ts -> benchmarks/compiler_output/workloads.toml rust-test-modules crates/*/**/tests/**/*.rs below a suite root -> the `mod` declaration in the parent module The last is the Rust analogue and is worth naming: cargo auto-discovers `crates/<c>/tests/<suite>.rs`, but a file one level deeper only compiles if a `mod` names it. Without one rustc never parses it — not dead code, not code, no warning. Built to be able to fail, against all four hazards: 1. no `continue-on-error`, no `|| true`; the step's exit status is the gate. 2. it is a step in `lint`, which is ALREADY a required context. That placement is the point: forgetting to add a new job to branch protection is hazard 2, and it is what left `gc-root-dominance` red and blocking nothing for days. No admin action is needed here because the step that gets forgotten does not exist. 3. `lint`'s concurrency already cancels pull-request runs only. 4. the subject is asserted live. Each mechanism floors its candidate set and FAILS if the glob stops matching, so "0 dark over 0 candidates" cannot print the same verdict as "0 dark over 157". Every run states `checked N files against M registries`. Exclusions are named with reasons rather than counted, because a threshold cannot tell a new dark file from an old one — fix one, add one, tally unchanged. A stale exclusion, one matching no file on disk, is itself a failure, so an excuse cannot outlive the file it excuses. Same for the mirror image: a registry entry whose file is gone fails as a rotted entry. `--self-test` (32 cases, also run in `lint`) plants an unregistered file into each of the four mechanisms over the REAL registries via an in-memory overlay, asserts the gate names it, then removes it and asserts green. It also pins the one false positive found while writing this: `resolve/tests/ declaration_sidecar_tests/compile_package.rs` IS declared, by a `mod` inside an inline `mod … { }` block two levels up, and the first draft condemned it. A gate that cries wolf gets deleted. Verified end to end on disk, not just through the overlay: planted a real unregistered file in each of the four mechanisms, watched the gate go red and name it; registered one and watched it go green; deleted the file leaving the line and watched the rotted-entry arm go red; restored and watched it go green. Today's dark set is empty for all four, so this is green on `main` from the first run and safe in a required context. Three feature probes and two compiler-output fixtures are excluded, each with its reason: four are helper modules imported by a registered test, and `benchmarks/compiler_output/fixtures/raw_numeric_layout_smoke.ts` is registered in a different registry (the `raw_numeric_layouts` target-collector workload in `scripts/run_memory_stability_tests.sh`). Deliberately out of scope: `tests/*.sh|py|ts`, where 143 of 171 files are referenced by nothing in the tree. There is no registry there to diff against, so "unregistered" is not even well defined; that is an archaeology problem (triage each, wire it up or delete it) and inventing a registry for it retroactively would make this gate red on day one for reasons unrelated to the four dark witnesses. `--list` says so out loud rather than leaving the silence. Docs where an author will actually meet the rule: a new `docs/src/testing/test-registration.md`, a bullet in CONTRIBUTING.md's "what goes in a PR", and a rewritten header on each of the three registry files. Refs PerryTS#7192, PerryTS#7216, PerryTS#7252, PerryTS#7270, PerryTS#7271.
jdalton
added a commit
to jdalton/perry
that referenced
this pull request
Aug 3, 2026
Four PRs in a row shipped a test file that ran nowhere. PerryTS#7192 and PerryTS#7216 each added a `test_gap_gc_*` stale-root witness and no corpus line; PerryTS#7252 added a third; PerryTS#7270/PerryTS#7271 added two more, caught by the maintainer at merge. Four occurrences of one mistake is a missing gate, not carelessness. An unregistered file is not a failing test, it is no test at all. The PR is green, the reviewer sees a witness in the diff next to a passing run and reads the two together as "covered", and nothing says otherwise because nothing ran. This is CLAUDE.md's fourth hazard in its purest form: the gate runs, its subject never does. Registration checks already existed for two of the three prefixes (`gc_repsel_matrix.sh` auto-detects `test_gap_repsel_*`/`test_gap_specabi_*`, `gc-moving-witnesses.yml` adds `test_gap_gc_*`) and neither could catch the pull request that needed it: both sit behind a 90-minute release build of the compiler, behind a changed-paths relevance filter, and in workflows that are not in branch protection's required contexts. `scripts/check_test_registration.py` is the cheap half of those checks, pulled out to where it can block, and generalised past that one corpus. Pure filesystem and text — no compiler, no Node, ~0.2s — over four mechanisms: gc-repsel-corpus test-files/test_gap_{gc,repsel,specabi}_*.ts -> test-parity/gc_repsel_corpus.txt feature-matrix-probes test-features/probes/**/*.ts -> test-features/feature_matrix.toml compiler-output-workloads benchmarks/compiler_output/fixtures/**/*.ts -> benchmarks/compiler_output/workloads.toml rust-test-modules crates/*/**/tests/**/*.rs below a suite root -> the `mod` declaration in the parent module The last is the Rust analogue and is worth naming: cargo auto-discovers `crates/<c>/tests/<suite>.rs`, but a file one level deeper only compiles if a `mod` names it. Without one rustc never parses it — not dead code, not code, no warning. Built to be able to fail, against all four hazards: 1. no `continue-on-error`, no `|| true`; the step's exit status is the gate. 2. it is a step in `lint`, which is ALREADY a required context. That placement is the point: forgetting to add a new job to branch protection is hazard 2, and it is what left `gc-root-dominance` red and blocking nothing for days. No admin action is needed here because the step that gets forgotten does not exist. 3. `lint`'s concurrency already cancels pull-request runs only. 4. the subject is asserted live. Each mechanism floors its candidate set and FAILS if the glob stops matching, so "0 dark over 0 candidates" cannot print the same verdict as "0 dark over 157". Every run states `checked N files against M registries`. Exclusions are named with reasons rather than counted, because a threshold cannot tell a new dark file from an old one — fix one, add one, tally unchanged. A stale exclusion, one matching no file on disk, is itself a failure, so an excuse cannot outlive the file it excuses. Same for the mirror image: a registry entry whose file is gone fails as a rotted entry. `--self-test` (32 cases, also run in `lint`) plants an unregistered file into each of the four mechanisms over the REAL registries via an in-memory overlay, asserts the gate names it, then removes it and asserts green. It also pins the one false positive found while writing this: `resolve/tests/ declaration_sidecar_tests/compile_package.rs` IS declared, by a `mod` inside an inline `mod … { }` block two levels up, and the first draft condemned it. A gate that cries wolf gets deleted. Verified end to end on disk, not just through the overlay: planted a real unregistered file in each of the four mechanisms, watched the gate go red and name it; registered one and watched it go green; deleted the file leaving the line and watched the rotted-entry arm go red; restored and watched it go green. Today's dark set is empty for all four, so this is green on `main` from the first run and safe in a required context. Three feature probes and two compiler-output fixtures are excluded, each with its reason: four are helper modules imported by a registered test, and `benchmarks/compiler_output/fixtures/raw_numeric_layout_smoke.ts` is registered in a different registry (the `raw_numeric_layouts` target-collector workload in `scripts/run_memory_stability_tests.sh`). Deliberately out of scope: `tests/*.sh|py|ts`, where 143 of 171 files are referenced by nothing in the tree. There is no registry there to diff against, so "unregistered" is not even well defined; that is an archaeology problem (triage each, wire it up or delete it) and inventing a registry for it retroactively would make this gate red on day one for reasons unrelated to the four dark witnesses. `--list` says so out loud rather than leaving the silence. Docs where an author will actually meet the rule: a new `docs/src/testing/test-registration.md`, a bullet in CONTRIBUTING.md's "what goes in a PR", and a rewritten header on each of the three registry files. Refs PerryTS#7192, PerryTS#7216, PerryTS#7252, PerryTS#7270, PerryTS#7271.
proggeramlug
pushed a commit
that referenced
this pull request
Aug 3, 2026
Four PRs in a row shipped a test file that ran nowhere. #7192 and #7216 each added a `test_gap_gc_*` stale-root witness and no corpus line; #7252 added a third; #7270/#7271 added two more, caught by the maintainer at merge. Four occurrences of one mistake is a missing gate, not carelessness. An unregistered file is not a failing test, it is no test at all. The PR is green, the reviewer sees a witness in the diff next to a passing run and reads the two together as "covered", and nothing says otherwise because nothing ran. This is CLAUDE.md's fourth hazard in its purest form: the gate runs, its subject never does. Registration checks already existed for two of the three prefixes (`gc_repsel_matrix.sh` auto-detects `test_gap_repsel_*`/`test_gap_specabi_*`, `gc-moving-witnesses.yml` adds `test_gap_gc_*`) and neither could catch the pull request that needed it: both sit behind a 90-minute release build of the compiler, behind a changed-paths relevance filter, and in workflows that are not in branch protection's required contexts. `scripts/check_test_registration.py` is the cheap half of those checks, pulled out to where it can block, and generalised past that one corpus. Pure filesystem and text — no compiler, no Node, ~0.2s — over four mechanisms: gc-repsel-corpus test-files/test_gap_{gc,repsel,specabi}_*.ts -> test-parity/gc_repsel_corpus.txt feature-matrix-probes test-features/probes/**/*.ts -> test-features/feature_matrix.toml compiler-output-workloads benchmarks/compiler_output/fixtures/**/*.ts -> benchmarks/compiler_output/workloads.toml rust-test-modules crates/*/**/tests/**/*.rs below a suite root -> the `mod` declaration in the parent module The last is the Rust analogue and is worth naming: cargo auto-discovers `crates/<c>/tests/<suite>.rs`, but a file one level deeper only compiles if a `mod` names it. Without one rustc never parses it — not dead code, not code, no warning. Built to be able to fail, against all four hazards: 1. no `continue-on-error`, no `|| true`; the step's exit status is the gate. 2. it is a step in `lint`, which is ALREADY a required context. That placement is the point: forgetting to add a new job to branch protection is hazard 2, and it is what left `gc-root-dominance` red and blocking nothing for days. No admin action is needed here because the step that gets forgotten does not exist. 3. `lint`'s concurrency already cancels pull-request runs only. 4. the subject is asserted live. Each mechanism floors its candidate set and FAILS if the glob stops matching, so "0 dark over 0 candidates" cannot print the same verdict as "0 dark over 157". Every run states `checked N files against M registries`. Exclusions are named with reasons rather than counted, because a threshold cannot tell a new dark file from an old one — fix one, add one, tally unchanged. A stale exclusion, one matching no file on disk, is itself a failure, so an excuse cannot outlive the file it excuses. Same for the mirror image: a registry entry whose file is gone fails as a rotted entry. `--self-test` (32 cases, also run in `lint`) plants an unregistered file into each of the four mechanisms over the REAL registries via an in-memory overlay, asserts the gate names it, then removes it and asserts green. It also pins the one false positive found while writing this: `resolve/tests/ declaration_sidecar_tests/compile_package.rs` IS declared, by a `mod` inside an inline `mod … { }` block two levels up, and the first draft condemned it. A gate that cries wolf gets deleted. Verified end to end on disk, not just through the overlay: planted a real unregistered file in each of the four mechanisms, watched the gate go red and name it; registered one and watched it go green; deleted the file leaving the line and watched the rotted-entry arm go red; restored and watched it go green. Today's dark set is empty for all four, so this is green on `main` from the first run and safe in a required context. Three feature probes and two compiler-output fixtures are excluded, each with its reason: four are helper modules imported by a registered test, and `benchmarks/compiler_output/fixtures/raw_numeric_layout_smoke.ts` is registered in a different registry (the `raw_numeric_layouts` target-collector workload in `scripts/run_memory_stability_tests.sh`). Deliberately out of scope: `tests/*.sh|py|ts`, where 143 of 171 files are referenced by nothing in the tree. There is no registry there to diff against, so "unregistered" is not even well defined; that is an archaeology problem (triage each, wire it up or delete it) and inventing a registry for it retroactively would make this gate red on day one for reasons unrelated to the four dark witnesses. `--list` says so out loud rather than leaving the silence. Docs where an author will actually meet the rule: a new `docs/src/testing/test-registration.md`, a bullet in CONTRIBUTING.md's "what goes in a PR", and a rewritten header on each of the three registry files. Refs #7192, #7216, #7252, #7270, #7271.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Authored by @jdalton. This is #7240's own commit, restacked onto
mainwith authorship preserved (git logshowsauthor=jdalton). Opened as a separate branch only because #7240 could not be updated in place — see below. #7240 is the PR of record for review discussion; this exists to land it.Why a new branch
#7240 stacked on #7227, which stacked #7226. Both landed as squash merges, which rewrote their commits — so #7240's branch still carried the pre-squash
28dc70d27and4e99c1bad, and GitHub reportedCONFLICTING/DIRTY. The content of those two is already onmain.git rebase --onto origin/main 28dc70d27replays only #7240's own commit and applies cleanly, no conflicts. The result is 1 commit / 5 files, exactly the diff #7240 describes:Force-pushing the restack to the fork branch would have been the tidier route and was deliberately not taken.
What I verified
cargo fmt --all -- --checkclean.cargo check -p perry-codegenclean.What I did NOT verify
sfw-registry --help30/30 result is @jdalton's measurement, reproduced here by nobody. It is not a blocker for this merge — rooting cross-module call arguments is strictly more correct regardless — but it must be independently reproduced before it is used as evidence to re-enable evacuating-minor-by-default (the fix(gc): disable evacuating minor by default pending #7154 (use-after-free on dynamically-added fields) #7161 revert). Do not let the number carry into that decision unconfirmed.Closes #7240.
Summary by CodeRabbit
Bug Fixes
Tests