docs(repsel): pin why the delete barrier's per-module scope is sound for proven-this (#7143) - #7722
Conversation
…for proven-this (#7143) Investigated #7143: `has_shape_barrier_sites()` is computed per module, and a proven-`this` receiver is aliased across modules by construction, so a `delete` performed in a module that never declares the class sets no flag the declaring module's Phase 5a admission can see. Confirmed no miscompile exists — every routing site that can call a `$pshape` clone independently re-derives soundness at the point it matters (a runtime keys-token pointer check, or genuine Phase 3b containment), never by trusting the per-module admission fact. Verified with a two-module reproducer compiled end to end (output matches node exactly) and a new IR-level ratchet test mirroring the existing #7142 tower guard test.
📝 WalkthroughWalkthroughThe changes document cross-module ChangesCross-module delete barrier validation
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related issues
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test-files/test_issue_7143_delete_barrier_cross_module.ts`:
- Around line 3-5: Correct the fixture comment to state that module A
(fixtures/issue_7143_pkg/shared.ts) never mentions delete, while preserving the
existing explanation of module B and the readC$pshape aliasing.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 6ccbd1ff-c5f2-4e3d-a15b-7c4674a72921
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (8)
CLAUDE.mdCargo.tomlchangelog.d/7722-delete-barrier-scope.mdcrates/perry-codegen/src/collectors/proven_this.rscrates/perry-codegen/src/collectors/proven_this_routing_tests.rscrates/perry-codegen/src/collectors/ptr_shape.rstest-files/fixtures/issue_7143_pkg/shared.tstest-files/test_issue_7143_delete_barrier_cross_module.ts
| // aliased across modules by construction. This module (B) never mentions | ||
| // `delete`, so module A (fixtures/issue_7143_pkg/shared.ts) is free to admit | ||
| // a `readC$pshape` clone for `C.readC` and route `readViaA`'s call to it. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the module reference in the fixture comment.
Line 3 says module B never mentions delete. Line 18 deletes inst.b in module B. State that module A never mentions delete.
Proposed fix
-// aliased across modules by construction. This module (B) never mentions
-// `delete`, so module A (fixtures/issue_7143_pkg/shared.ts) is free to admit
+// aliased across modules by construction. Module A
+// (fixtures/issue_7143_pkg/shared.ts) never mentions `delete`, so it is free to admit📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // aliased across modules by construction. This module (B) never mentions | |
| // `delete`, so module A (fixtures/issue_7143_pkg/shared.ts) is free to admit | |
| // a `readC$pshape` clone for `C.readC` and route `readViaA`'s call to it. | |
| // aliased across modules by construction. Module A | |
| // (fixtures/issue_7143_pkg/shared.ts) never mentions `delete`, so it is free to admit | |
| // a `readC$pshape` clone for `C.readC` and route `readViaA`'s call to it. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test-files/test_issue_7143_delete_barrier_cross_module.ts` around lines 3 -
5, Correct the fixture comment to state that module A
(fixtures/issue_7143_pkg/shared.ts) never mentions delete, while preserving the
existing explanation of module B and the readC$pshape aliasing.
Merging as v0.5.1417 — the answer is "no miscompile", and that is the findingThe asymmetry #7143 describes is real: It is not a miscompile, because in Phase 5a that fact is a cost heuristic only. Correctness comes from elsewhere: every routing site that can call a Why spend a test on a non-bug. The distinction is invisible in the source: nothing at the Phase 5a call site says "this use is advisory". Someone tidying the two uses into a shared helper would silently make the advisory one load-bearing, or the load-bearing one advisory — and that edit would look like a cleanup.
I sabotage-verified it rather than trusting it: pointing the guard predicate at a non-existent symbol fails with
One incidental: the added module note pushed |
repsel: document and pin why the
deleteshape barrier's per-module scope is sound for proven-this(#7143)Investigated #7143 ("the Phase 5a
deleteshape barrier is module-scoped,but a proven-
thisreceiver is aliased across modules by construction").Confirmed the asymmetry the issue describes:
ModuleDispatchFacts::has_shape_barrier_sites()is computed per module (
collect_module_dispatch_facts), and Phase 5a'sproven-
thisadmission (collectors/proven_this.rs::method_proven_this)consults only its OWN module's copy — a
delete/Reflect.deletePropertyona class instance in a module that imports the class, rather than declaring
it, sets no flag the declaring module's admission decision can see.
No miscompile exists. Built a two-module reproducer
(
test-files/test_issue_7143_delete_barrier_cross_module.ts+test-files/fixtures/issue_7143_pkg/shared.ts) matching the issue's ownsuggested shape — module A declares
class C { a; b; c }plus a methodreading
this.c, admits a$pshapeclone since it contains nodeleteitself; module B holds an instance A handed it, deletes
boff it (whichrelocates
c's packed slot viaperry-runtime's keys-array compaction),then calls back into module A, which dispatches
inst.readC()on thenow-mutated object. The compiled binary's output matches
node --experimental-strip-typesexactly (3,3,3), and the--trace llvmIR shows why: EVERY routing site that can call a$pshapeclone independently re-derives soundness at the point it matters, rather
than trusting the per-module admission fact —
method_direct.fast(lower_call/method_override.rs) sits behindjs_typed_feedback_method_direct_call_guard/js_method_direct_shape_guard,whose contract includes a raw pointer compare of the receiver's live
keys_arrayagainst the class's canonical keys token.delete's onlycode path for a class instance with a keys array
(
perry-runtime/src/object/delete_rest.rs::js_object_delete_field, sharedby
Reflect.deleteProperty) always clones a FRESH keys array, so thiscompare can never pass on a post-delete receiver, from any module.
Ptr<Shape>receiver arm needs no runtime check:its containment proof (
collectors/ptr_shape.rsrule 2) already rules outany alias to the object existing anywhere, so there is nothing for a
cross-module
deleteto reach through.(
dynamic_dispatch.rs::emit_tower_pshape_call) already carries its ownexplicit keys-token re-check, added specifically for this reason — its doc
comment already cited repsel Phase 5a: the
deleteshape barrier is module-scoped, but a proven-thisreceiver is aliased across modules by construction #7143 by number.Landed as a documentation + regression-test PR, not a bug fix: added a
"
deleteis aliased across modules by construction" section tocollectors/proven_this.rsstating this invariant explicitly (module-widebarrier facts are a cost heuristic for Phase 5a, never the correctness
mechanism — a future 4th routing site must independently re-derive a
dominating runtime check or genuine containment), a cross-reference from
collectors/ptr_shape.rs's module-wide barrier rule, a newguarded_pshape_call_site_is_preceded_by_a_keys_token_guardIR ratchet inproven_this_routing_tests.rspinning themethod_direct.fastguarddominance (mirroring the existing tower ratchet), and the two-file
reproducer above as a permanent parity-suite fixture.
Summary by CodeRabbit
Documentation
Tests
Chores
0.5.1417.