Skip to content

Autoharness: support smart pointers of compiler-derivable pointees - #4698

Merged
feliperodri merged 6 commits into
model-checking:mainfrom
tautschnig:autoharness-smart-pointers
Aug 24, 2026
Merged

Autoharness: support smart pointers of compiler-derivable pointees#4698
feliperodri merged 6 commits into
model-checking:mainfrom
tautschnig:autoharness-smart-pointers

Conversation

@tautschnig

Copy link
Copy Markdown
Member

Description

Stacked on #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 (#4691/#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 #3832

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

tautschnig and others added 2 commits July 29, 2026 10:20
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>
Box<T>, Rc<T>, and Arc<T> arguments were only supported when T itself
implements Arbitrary (resolving the smart pointer's blanket Arbitrary
implementation). When T merely *can derive* Arbitrary -- the common case for
plain structs without kani annotations -- such arguments were skipped.

Add three generation models (any_box/any_rc/any_arc) whose internal
kani::any::<T>() call is replaced with the compiler-synthesized Arbitrary
implementation by AutomaticArbitraryPass, exactly as for direct arguments of
such types. The models live in the kani library only: they require alloc and
thus have no core::kani counterpart, so this introduces the notion of
*optional* models (KaniModel::is_optional): validate_kani_functions tolerates
their absence, and the autoharness passes hold them as Option<FnDef>,
rejecting smart-pointer arguments in flows where the models are unavailable
(e.g. kani verify-std).

Smart-pointer detection uses is_box() and the Rc/Arc diagnostic items, plus
a return-type equality check on the resolved model, which also correctly
rejects non-default allocators (Box<T, A>).

These values are unbounded -- a smart pointer to T covers exactly the values
of T -- so they need no --bounded-arguments gating and retain Kani's usual
full-coverage guarantee (demonstrated by a cover check in the test).

Towards model-checking#3832

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

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 added the Z-Autoharness Issue related to autoharness subcommand label Jul 29, 2026
Resolving the generation models with an unsized pointee (e.g. Box<[u8]>)
can crash constant evaluation during body retrieval, and such pointees
cannot be generated anyway. Found by re-running the top-100 crates.io
evaluation (bytes, memchr); regression-tested with a Box<[u8]> argument
that is now skipped gracefully.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@feliperodri feliperodri added this to the Autoharness milestone Aug 18, 2026
# Conflicts:
#	kani-compiler/src/kani_middle/codegen_units.rs
#	kani-compiler/src/kani_middle/kani_functions.rs
#	kani-compiler/src/kani_middle/mod.rs
#	kani-compiler/src/kani_middle/transform/automatic.rs
#	library/kani/src/arbitrary.rs

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.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment thread tests/script-based-pre/cargo_autoharness_smart_pointers/smart-pointers.expected Outdated
Comment thread tests/script-based-pre/cargo_autoharness_smart_pointers/src/lib.rs Outdated
Comment thread kani-compiler/src/kani_middle/mod.rs
Address review feedback on the cargo_autoharness_smart_pointers test:

- box_unsized: use Box<str> instead of Box<[u8]>. Box<[u8]> implements
  BoundedArbitrary, so without --bounded-arguments it is skipped with
  "Requires --bounded-arguments" rather than "Missing Arbitrary
  implementation"; Box<str> has no bounded impl and genuinely exercises
  the unsupported (unsized-pointee) path.
- arc_assert: use Arc<OnlyDerivable> instead of Arc<Derived>. Derived
  implements Arbitrary, so Arc<Derived> resolves the blanket impl and
  never exercises the new AnyArc model path; OnlyDerivable forces the
  compiler-derived pointee path that the cover check is meant to cover.
@feliperodri
feliperodri added this pull request to the merge queue Aug 24, 2026
Merged via the queue into model-checking:main with commit 58da8c0 Aug 24, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-Autoharness Issue related to autoharness subcommand 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