Skip to content

Implement Arbitrary for Rc<T> and Arc<T> - #4697

Merged
feliperodri merged 1 commit into
model-checking:mainfrom
tautschnig:arbitrary-rc-arc
Jul 29, 2026
Merged

Implement Arbitrary for Rc<T> and Arc<T>#4697
feliperodri merged 1 commit into
model-checking:mainfrom
tautschnig:arbitrary-rc-arc

Conversation

@tautschnig

Copy link
Copy Markdown
Member

Description

Box<T> implements Arbitrary, but Rc<T> and Arc<T> did not, so functions taking reference-counted arguments could not be verified against nondeterministic inputs — and were skipped by kani autoharness with "Missing Arbitrary implementation" (smart-pointer receivers are among the largest skip classes in the top-100 crates.io evaluation). This PR adds the analogous implementations.

Note that unlike slice/container arguments (#4691/#4693), these need no bound and no opt-in flag: a smart pointer to T covers exactly the values of T, so the generated values retain Kani's usual full-coverage guarantee.

A follow-up will extend autoharness to smart pointers around types that only can-derive Arbitrary (compiler-synthesized implementations); that requires compiler-side models that depend on alloc and hence some optional-model plumbing for the no_core flow.

Testing

New test tests/kani/Arbitrary/rc_arc.rs with cover checks proving extreme values, specific values, and nested smart pointers (Rc<Arc<u8>>) are all generated (all SATISFIED). The Arbitrary suite and kani library unit/doc tests pass; verified via autoharness that Rc<T>/Arc<T>-taking functions are now selected and verified.

Towards #3832

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

Box<T> has an Arbitrary implementation, but Rc<T> and Arc<T> did not, so
functions taking reference-counted arguments could not be verified against
nondeterministic inputs (and were skipped by 'kani autoharness' with
'Missing Arbitrary implementation'). Add the analogous implementations.

Unlike slice or container arguments, these need no bound: a smart pointer
to T covers exactly the values of T, so the generated values retain Kani's
usual full-coverage guarantee.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig
tautschnig requested a review from a team as a code owner July 29, 2026 10:20
Copilot AI review requested due to automatic review settings July 29, 2026 10:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Jul 29, 2026

@feliperodri feliperodri left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢 it!

@feliperodri
feliperodri added this pull request to the merge queue Jul 29, 2026
Merged via the queue into model-checking:main with commit 7ab3ddf Jul 29, 2026
33 checks passed
feliperodri added a commit to tautschnig/kani that referenced this pull request Aug 24, 2026
…odel-checking#4698)

### Description

**Stacked on model-checking#4697** (only the last commit is new; review that one).

`Box<T>`/`Rc<T>`/`Arc<T>` arguments were only supported by autoharness
when `T` itself implements `Arbitrary` (resolving the blanket impls).
When `T` merely *can derive* `Arbitrary` — the common case for plain
structs without kani annotations — such arguments were skipped. This PR
adds three generation models (`any_box`/`any_rc`/`any_arc`) whose
internal `kani::any::<T>()` call gets the compiler-synthesized
`Arbitrary` implementation via `AutomaticArbitraryPass`, exactly as for
direct arguments of such types.

Two design points:
- **Optional models.** The models require `alloc`, so they exist only in
the `kani` library, not `core::kani`. This introduces
`KaniModel::is_optional()`: `validate_kani_functions` tolerates their
absence and the autoharness passes hold them as `Option<FnDef>`,
gracefully rejecting smart-pointer arguments in flows where they're
unavailable (`kani verify-std` re-validated with `--force-rerun` to make
sure the run wasn't cached).
- **Robust detection.** `Box` via `is_box()`, `Rc`/`Arc` via their rustc
diagnostic items (no name matching), plus a return-type equality check
on the resolved model instance — which also correctly rejects
non-default allocators (`Box<T, A>`); an arity-based check would have
wrongly rejected plain `Box<T>` (= `Box<T, Global>`).

Per the bounded-features policy (model-checking#4691/model-checking#4693): these values are
**unbounded** — a smart pointer to `T` covers exactly the values of `T`
— so they need no `--bounded-arguments` gating and retain the
full-coverage guarantee, demonstrated by a cover check in the test.

### Testing

New script-based test `cargo_autoharness_smart_pointers`:
`Box`/`Rc`/`Arc` of both implementing and only-derivable pointees (all
verified), a full-coverage cover check on the pointee (SATISFIED) with a
correctly failing assertion, and graceful skipping of a pointee that can
neither implement nor derive `Arbitrary`.

Full autoharness suite (14 tests), `verify_std_cmd`/`std_codegen`
(force-rerun), and `kani-compiler` unit tests pass.

Towards model-checking#3832

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.

---------

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Co-authored-by: Felipe Monteiro <felisous@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants