Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions crates/unsafe-review-core/src/analysis/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,9 @@ fn is_public_api_surface(kind: &UnsafeSiteKind, snippet: &str) -> bool {
fn find_owner(lines: &[&str], idx: usize) -> Option<String> {
for raw in lines[..=idx].iter().rev().take(80) {
let line = raw.trim();
if is_comment_line(line) {
continue;
}
if let Some(name) = parse_impl_owner(line) {
return Some(name);
}
Expand Down Expand Up @@ -765,6 +768,9 @@ fn find_owner_declaration_index(lines: &[&str], idx: usize) -> Option<usize> {
let limit = idx.min(lines.len().saturating_sub(1));
for (line_idx, raw) in lines[..=limit].iter().enumerate().rev().take(120) {
let line = raw.trim();
if is_comment_line(line) {
continue;
}
if parse_impl_owner(line).is_some()
|| parse_trait_name(line).is_some()
|| parse_fn_name(line).is_some()
Expand All @@ -775,6 +781,10 @@ fn find_owner_declaration_index(lines: &[&str], idx: usize) -> Option<usize> {
None
}

fn is_comment_line(line: &str) -> bool {
line.starts_with("//") || line.starts_with("/*") || line.starts_with('*')
}

fn owner_doc_start(lines: &[&str], decl_idx: usize) -> usize {
let mut start = decl_idx;
let mut idx = decl_idx;
Expand Down Expand Up @@ -918,6 +928,20 @@ mod tests {
);
}

#[test]
fn owner_inference_ignores_comment_text_when_scanning_backwards() {
let lines = [
"fn keep_rest(&mut self) {",
" unsafe {",
" // Normally `Drop` impl would drop [tail].",
" let src = ptr.add(this.idx);",
" }",
"}",
];

assert_eq!(find_owner(&lines, 3), Some("keep_rest".to_string()));
}

#[test]
fn text_detection_does_not_classify_deref_assignments_as_writes() {
assert_eq!(detect_site("*ptr = value;"), None);
Expand Down
59 changes: 56 additions & 3 deletions docs/handoffs/2026-05-18-real-crate-dogfood-v0.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ evidence-quality gap:
Regression proof was added with a repo-mode analyzer test for pointer
arithmetic inside a documented unsafe function.

A real PR-diff dogfood pass on `servo/rust-smallvec#407` exposed and fixed an
owner-inference gap:

- owner inference now ignores comment lines while scanning backward
- comment prose such as `` `Drop` impl would drop `` is no longer parsed as an
`impl would` owner
- witness commands now use the real owner when one is available

Regression proof was added with a scanner unit test for comment text during
owner inference.

## Dogfood observations

The before/after numbers below are top-50 capped repo inventory snapshots, not
Expand Down Expand Up @@ -208,6 +219,45 @@ The pointer arithmetic card now recognizes the enclosing `# Safety` contract and
local guard evidence, then routes the remaining gap to Miri/cargo-careful as a
witness need.

### `rust-smallvec#407`

PR: `https://github.com/servo/rust-smallvec/pull/407`

The PR fixes a use-after-free in `DrainFilter::keep_rest` for zero-capacity
`SmallVec`s by changing the ZST guard and adding a Miri-targeted regression
test.

Before comment-aware owner inference:

```text
elapsed_seconds: 33.48
changed_rust_files: 2
cards: 1
contract_missing: 1
owner: would
verify: cargo +nightly miri test would
```

The owner was inferred from comment prose:

```text
// Normally `Drop` impl would drop [tail] ...
```

After comment-aware owner inference:

```text
elapsed_seconds: 34.8
changed_rust_files: 2
cards: 1
contract_missing: 1
owner: keep_rest
verify: cargo +nightly miri test keep_rest
```

The card class did not change. The improvement is that the card now points the
reviewer and witness route at the real owner instead of prose.

## Proof

Targeted local validation:
Expand All @@ -229,6 +279,7 @@ rtk cargo run --locked -p unsafe-review -- repo --root target/dogfood-work/small
rtk cargo run --locked -p unsafe-review -- repo --root target/dogfood-work/arrayvec --format json --max-cards 50 --out target/dogfood-work/arrayvec.unsafe-review.after.json
rtk cargo run --locked -p unsafe-review -- repo --root target/dogfood-work/memchr --format json --max-cards 50 --out target/dogfood-work/memchr.unsafe-review.after-cap-targetfeature.json
rtk cargo run --locked -p unsafe-review -- check --root target/dogfood-work/memchr --diff target/dogfood-work/memchr-pr215.raw.diff --format json --max-cards 20 --out target/dogfood-work/memchr-pr215.owner-contract.json
rtk cargo run --locked -p unsafe-review -- check --root target/dogfood-work/smallvec --diff target/dogfood-work/smallvec-pr407.raw.diff --format json --max-cards 20 --out target/dogfood-work/smallvec-pr407.owner-fix.json
```

The dogfood reruns used a temporary `CARGO_TARGET_DIR` to avoid a Windows file
Expand All @@ -242,11 +293,13 @@ The repo may claim:

- the first real-crate dogfood slice was run on `rust-smallvec` and `arrayvec`
- a capped `memchr` dogfood snapshot now completes
- a real PR-diff dogfood run on `memchr#215` produces card output
- real PR-diff dogfood runs on `memchr#215` and `rust-smallvec#407` produce card
output
- dogfood found and fixed import/declaration and `cfg(target_feature)`
false positives
- capped repo scans stop after the requested card cap
- operation cards can inherit enclosing unsafe function `# Safety` docs
- owner inference ignores comments while scanning backward
- false-positive regression coverage exists in fixtures and calibration
- dogfood output remains advisory static review evidence

Expand All @@ -256,7 +309,7 @@ The repo must not claim:
- usable-alpha support-tier promotion
- full-repository coverage from top-50 capped snapshots
- uncapped repo-scan performance
- general PR-diff usefulness from one PR
- general PR-diff usefulness from two PRs
- memory-safety proof
- UB-free status
- witness execution
Expand All @@ -266,7 +319,7 @@ The repo must not claim:

- Only three real crates completed in this slice.
- The successful dogfood snapshots were capped at 50 cards.
- Only one real PR diff was measured.
- Only two real PR diffs were measured.
- `memchr` completion depends on capped-scan behavior; uncapped performance is
still unmeasured.
- No human audit was performed for every emitted card.
Expand Down
2 changes: 1 addition & 1 deletion docs/status/OBJECTIVE_AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ witnesses by default.
| Explicit receipts can be authored and validated safely | `receipt template` and `receipt validate` are covered by CLI e2e tests and support tiers | Experimental | Template output does not verify that the recorded command ran |
| Public claims map to proof | `SUPPORT_TIERS.md` maps every current surface to proof and limits | In place | Keep updating for every new lane |
| No soundness, UB-free, Miri-clean, site-execution, or default-blocking claim | Trust-boundary text is enforced across artifacts; support tiers and handoffs repeat limits | In place | Must remain part of all new projections |
| First real-crate dogfood measurement | Handoff `2026-05-18-real-crate-dogfood-v0.6.md` records top-50 capped `rust-smallvec`, `arrayvec`, and `memchr` runs plus a `memchr#215` PR-diff run; dogfood found and fixed import/declaration false positives, `cfg(target_feature)` false positives, capped repo scan timeout behavior, and missing owner-contract inheritance for operation cards | Experimental | More crates, more real PR diffs, uncapped/sampled runs, and human review are still needed before calibration claims |
| First real-crate dogfood measurement | Handoff `2026-05-18-real-crate-dogfood-v0.6.md` records top-50 capped `rust-smallvec`, `arrayvec`, and `memchr` runs plus `memchr#215` and `rust-smallvec#407` PR-diff runs; dogfood found and fixed import/declaration false positives, `cfg(target_feature)` false positives, capped repo scan timeout behavior, missing owner-contract inheritance for operation cards, and comment-derived owner false positives | Experimental | More crates, more real PR diffs, uncapped/sampled runs, and human review are still needed before calibration claims |

## Current Gaps

Expand Down
2 changes: 1 addition & 1 deletion docs/status/SUPPORT_TIERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ All tiers describe static review evidence. None means memory-safety proof.
| Raw pointer card slice | experimental | cards | `raw_pointer_alignment`, `raw_pointer_deref`, `raw_pointer_read_unaligned`, `raw_pointer_write_assignment`, `split_raw_pointer_read_call`, `split_unsafe_block`, and safe-reference negative fixtures | source-level review evidence only |
| Core operation smoke slice | experimental | cards | `maybeuninit_assume_init`, `vec_set_len`, `transmute_invalid_value`, `get_unchecked_mut_bounds`, and `pin_new_unchecked` fixture goldens | curated fixtures, not broad semantic proof |
| Fixture calibration manifest | experimental | `fixtures/calibration.toml` / `cargo xtask check-calibration` | manifest covers positive, negative, and false-positive-control core fixture claims, including import/declaration and `cfg(target_feature)` false-positive controls, and validates expected card counts, classes, operation families, and hazards against goldens | proof index only; not real-world calibration or support-tier promotion evidence by itself |
| Real-crate dogfood measurement | experimental | dogfood handoff | `2026-05-18-real-crate-dogfood-v0.6.md` records top-50 capped `rust-smallvec`, `arrayvec`, and `memchr` repo runs plus a `memchr#215` PR-diff run; it also records the import/declaration, `cfg(target_feature)`, capped-scan, and owner-contract inheritance fixes those runs exposed | three capped snapshots and one PR diff only; no calibrated rates, no full audit, no uncapped performance claim, and no support-tier promotion |
| Real-crate dogfood measurement | experimental | dogfood handoff | `2026-05-18-real-crate-dogfood-v0.6.md` records top-50 capped `rust-smallvec`, `arrayvec`, and `memchr` repo runs plus `memchr#215` and `rust-smallvec#407` PR-diff runs; it also records the import/declaration, `cfg(target_feature)`, capped-scan, owner-contract inheritance, and comment-aware owner inference fixes those runs exposed | three capped snapshots and two PR diffs only; no calibrated rates, no full audit, no uncapped performance claim, and no support-tier promotion |
| Contract evidence mining | experimental | cards | public unsafe fn/trait fixtures and private helper `SAFETY:` fixture | comment quality is heuristic |
| Guard evidence mining | experimental | cards | raw-pointer alignment and comment-not-guard fixtures prove bounds evidence does not discharge alignment | obligation-specific patterns are still sparse |
| Witness routing | experimental | cards | route-table tests plus raw pointer, FFI, unsafe impl Send, Pin, and invalid-value fixture routes | route recommendation only; receipt import is a separate surface and does not execute witnesses |
Expand Down
Loading