Skip to content

gate(#10944): the asserted-global rule could not see static mut - #11004

Closed
proggeramlug wants to merge 1 commit into
mainfrom
fix/10947-static-mut-gate
Closed

proggeramlug wants to merge 1 commit into
mainfrom
fix/10947-static-mut-gate

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Review finding on PR #10947, which closed unmerged after its work landed on main as fc7108496b. The finding was never applied, so the gap is live on main today at scripts/global_sink_isolation.py:594. This is that fix, rebased onto main.

The gap

_STATIC required the identifier immediately after static, so a static mut declaration never matched at all. And had it matched, _SHARED_TY would have excluded it anyway — a static mut is typically a plain integer or array, not an Atomic* or a lock.

Two independent reasons the rule could not see it, in the one place it most needed to. A contended AtomicU64 read gives a wrong count; racing on a static mut is undefined behaviour. The gate's hole sat exactly where the hazard is worst.

The fix

Capture an optional mut and treat its presence as sufficient on its own. A static mut is shared mutable state by definition — it does not have to argue its way past a type filter.

Stated as latent, not claimed as a catch

The tree's only two static mut declarations (ohos_napi.rs:804, :876) are asserted by no test. The baseline stays at 62 entries and this changes no current verdict. It closes the gap before one arrives.

Checks

  • The line anchor keeps &'static mut references out — the three in test helpers (sweep_page_tally.rs:61, concat_site.rs:14, full_rebuild_skip.rs:42) begin with let or fn, not static. Verified against all five real occurrences in the tree plus four constructed near-misses; 8/8 discriminate correctly.
  • --self-test: 20 checks, 0 failures. Gate: 0 hazards, 6 allowlisted, 120 statics classified, 62 asserted (baseline 62).
  • The new case can fail. Restoring main's narrow regex reddens it by name (an asserted static mut was NOT reported); restoring the fix returns it to green.

Summary by CodeRabbit

  • Bug Fixes
    • Improved detection of unsafe global mutable state referenced by test assertions, including plain scalar declarations.
  • Tests
    • Expanded scanner self-tests to cover this case.
    • Updated the self-test success message.

Review finding on #10947. `_STATIC` required the identifier immediately
after `static`, so a `static mut` declaration never matched at all; and
had it matched, `_SHARED_TY` would have excluded it anyway, because a
`static mut` is usually a plain integer or array rather than an Atomic
or a lock.

That is a hole exactly where the hazard is worst. An `AtomicU64` read
under contention gives a wrong count; racing on a `static mut` is
undefined behaviour. The one shape the rule most needed to catch was
the one shape it structurally could not.

Fixed by capturing an optional `mut` and treating its presence as
sufficient on its own -- a `static mut` is shared mutable state by
definition, so it does not have to argue its way past a type filter.

Latent today, and stated as such rather than claimed as a catch: the
tree's only two `static mut` declarations (ohos_napi.rs) are asserted
by no test, so the baseline stays at 62 entries and this commit
changes no current verdict. It closes the gap before one arrives.

The line anchor keeps `&'static mut` references out: the three in test
helpers begin with `let` or `fn`, not `static`. Checked against all
five real occurrences in the tree plus four constructed near-misses.

Self-test gains a `static mut` case that fails without the fix.
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 36e16a76-47d1-493d-9012-d70b56c2ed2b

📥 Commits

Reviewing files that changed from the base of the PR and between c7cbc3c and 7ca4956.

📒 Files selected for processing (1)
  • scripts/global_sink_isolation.py

Included review availability: Your plan provides up to 8 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The asserted-global scanner now captures static mut declarations and reports referenced mutable statics even when their types are not in the shared-type filter. The self-test covers a mutable scalar static and updates its success message.

Changes

Mutable Static Detection

Layer / File(s) Summary
Mutable static scanning
scripts/global_sink_isolation.py
The static declaration pattern captures optional mut declarations. Global detection reports declarations that are mutable or use a recognized shared-state type.
Detection self-test
scripts/global_sink_isolation.py
The self-test verifies detection of an asserted static mut HITS: u64 declaration. Its success message states that mutable static hazards are covered.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 7ca49

The scanner now detects asserted static mut declarations, with self-test coverage added. No merge-blocking production impact is identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: updating the gate to detect static mut declarations.
Description check ✅ Passed The description explains the problem, fix, scope, related review finding, and validation results. It does not use the template headings or include the checklist, but it provides the required technical…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed on main in merge train 257 (#11039, v0.5.1640), main 990b3eeada.

Carried at head 7ca495691f. CI on the train head passed every job except the known public-baseline lint step: all 6 gap shards, cargo-test, e2e-scoped, gc-stress, check, warnings and security-audit green.

This train was split by blast radius after an earlier 35-PR assembly hit five gap regressions: it carries only PRs touching no lowering path. Trains rebase-merge, so commits get new SHAs and GitHub cannot mark this merged. Closed as landed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant