Skip to content

repsel: --opt-report panics on real dependency JS — RULE2 carries two tiers and render.rs asserts one #7234

Description

@proggeramlug

--opt-report panics on real dependency JS in any debug-assertions build,
because RULE2 ("rule 2 (containment)") carries two tiers in
collectors/ptr_shape_report.rs — 10 records with Tier::Fixable and 3 with
Tier::CompilerLimitation — and opt_report/render.rs:418 asserts that a rule
carries exactly one.

thread 'perry-main' panicked at crates/perry-codegen/src/opt_report/render.rs:418:9:
assertion `left == right` failed: rule rule 2 (containment) carries two tiers; the bucket would report only one
  left: Some(CompilerLimitation)
 right: Some(Fixable)
Error: perry compiler panicked: …

The assertion is #7176's own S20 guard (one_rule_carrying_two_tiers_is_a_hard_error),
added because a debug_assert nothing exercised was a green hole. It is
correct; the table it guards is not.

Reproduction

cargo build -p perry                       # debug — assertions ON
mkdir /tmp/r && cp <module> /tmp/r/mod.js && cd /tmp/r
PERRY_NO_AUTO_OPTIMIZE=1 <perry> compile mod.js --opt-report=json --no-link

Module: @typescript-eslint/eslint-plugin/dist/rules/naming-convention-utils/schema.js
(from real-apps/scriptc/node_modules). It emits both a Fixable rule-2
denial and a CompilerLimitation one, so the renderer's per-rule tier fold
sees two.

Why nobody has hit it

  • --profile perry-dev inherits release, so debug_asserts are off —
    every local repsel measurement in this campaign has been perry-dev and never
    saw it.
  • The repsel-census CI job DOES build cargo build -p perry (debug), but its
    corpus is benchmarks/repsel_census + benchmarks/suite, and no fixture
    there lands both tiers under rule 2. Real dependency JS does, routinely.

Scope

Found while measuring #7170 R1 (PR #7233), and exonerated by in-place A/B:
with all five of that PR's production files reverted to origin/main in the
same target dir and the same package set, the panic is identical. It is
pre-existing at 46e5e377b, and it is not introduced by the three GC commits
between 65a64f428 and there — reverting to origin/main sources is what
reproduces it.

Fix shape (two options, not equivalent)

  1. Split the rule string. If a reassigned binding and a delete really are
    different tiers, they should be different rule strings, and
    ALLOC_BUCKET_FLOORS / by_rule would then tell them apart — which is the
    whole point of perf(repsel): make the Ptr<Shape> alloc-site buckets mean what schedulers read them as (#7170 R0) #7176 §5's composite key.
  2. Pick one tier for rule 2. Cheaper, and loses the distinction the records
    were written to carry.

Either way the fix needs a test that puts both tiers in one report, because
that is the case no existing fixture reaches — the same gap that let this ship.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions