Skip to content

Conversation

@thanhnguyen-aws
Copy link
Contributor

@thanhnguyen-aws thanhnguyen-aws commented Jun 6, 2025

This PR adds loop-contracts support for for loop for 12 types: array, slice, Iter, Vec, Range, StepBy, Map, Chain, Zip, Enumerate, Take, Rev.

Main ideas:
for loop implementation:
A for loop of the form

for pat in expr {
    body
}

is transformed into a while loop:

let kani_iter = kani::KaniIntoIter::kani_into_iter(expr); \\ init_iter_stmt
let kani_iter_len = kani::KaniIter::len(&kani_iter); \\ init_len_stmt
if kaniiterlen > 0 {
    let mut kani_index = 0; \\ init_index_stmt
    kani::assume (kani::KaniIter::assumption(&kani_iter)); \\ iter_assume_stmt
    let pat = kani::KaniIter::first(&kani_iter); \\ init_pat_stmt
    while kani_index < kani_iter_len {
        kani::assume (kani::KaniIter::assumption(&kani_iter)); \\ iter_assume_stmt
        let pat = kani::KaniIter::nth(&kani_iter, kani_index); \\ pat_assign_stmt
        kani_index = kani_index + 1; \\ increase_iter_stmt
        body
    }
}

Note that

  1. expr's type is required to impl KaniIntoIter trait, which is the override impl of Rust's IntoIter (see library/kani_core/src/iter.rs).
    Reason:
    a) Reduce stack-call
    b) Avoid types that cannot be havoc effectively (user cannot state the type invariant in the loop invariant due to private fields)
    c) There is no generic way to handle Rust's into_iter().

  2. The init_index_stmt and init_pat_stmt support writing the loop-invariant properties that involve pat and kaniindex

  3. The iter_assume_stmt assumes some truths about allocation, so that the user does not need to specify them in the loop invariant

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

@thanhnguyen-aws thanhnguyen-aws requested a review from a team as a code owner June 6, 2025 20:47
@github-actions github-actions bot added the Z-EndToEndBenchCI Tag a PR to run benchmark CI label Jun 6, 2025
@carolynzech carolynzech marked this pull request as draft June 10, 2025 02:09
@thanhnguyen-aws thanhnguyen-aws marked this pull request as ready for review June 11, 2025 19:15
Copy link
Contributor

@carolynzech carolynzech left a comment

Choose a reason for hiding this comment

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

I haven't reviewed the implementation yet, these are just some nits. I have two requests to make reviewing on my end easier:

  1. This is a big PR, and it'd be much easier to review if each new piece of functionality was separated into its own commit along with its tests. I'm envisioning something like:
commit 1: code to support iter & expected tests
commit 2: code to support array & expected tests
commit 3: code to support slice & expected tests
commit 4: code to support vec & expected tests

Can you do an interactive rebase to make it look like this? It doesn't need to be exactly this--I'd just appreciate if 1) changes are committed with their tests and 2) commits irrelevant to the review (e.g., fix clippy, merges) are kept to a minimum. FWIW, I have a pre-commit hook that runs clippy, our formatting check, and copyright check so that I can't even commit unless those checks pass; I'd recommend it.

  1. Can you add more comments? I added some places that I think need some. I'd like to see each function (unless it's super simple) have a doc comment that describes 1) what it does and 2) why it exists (i.e., why we need it in the first place)

@zhassan-aws
Copy link
Contributor

Can you expand the PR description and/or the comments in library/kani_macros/src/sysroot/loop_contracts/mod.rs to explain the idea behind the implementation? It is hard to infer what this is doing just through reading the code.

Copy link

@rod-chapman rod-chapman left a comment

Choose a reason for hiding this comment

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

Please address my documentation requests.

@github-actions github-actions bot added the Z-CompilerBenchCI Tag a PR to run benchmark CI label Jun 24, 2025
Copy link
Member

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

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

Should we really make all these changes from "invariant" to "contract"? I'm making a suggestion to explain how "loop contracts" and "loop invariants" are related, but I don't know whether others share my view on this matter.

Copy link

@rod-chapman rod-chapman left a comment

Choose a reason for hiding this comment

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

In short:

  1. Can this be done without the "clone" of a? I see no need for it, and possibly huge performance impact.
  2. The "60" bounds on b is wrong surely? b should have the same size as a.len(), right?
  3. Please demonstrate how auto-harness generation works on these functions, so the harness functions are not required.

Copy link
Member

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

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

We may still need to follow up this work with some refinement, but this should be ready for broader evaluation.

@thanhnguyen-aws thanhnguyen-aws added this pull request to the merge queue Aug 20, 2025
Merged via the queue into model-checking:main with commit a7d917d Aug 20, 2025
31 of 34 checks passed
@thanhnguyen-aws thanhnguyen-aws deleted the forloopnew1 branch August 20, 2025 16:50
github-merge-queue bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Oct 9, 2025
This PR adds loop invariants and harnesses for DecimalSeq functions

Require: for-loop support for Kani:
model-checking/kani#4143

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: Michael Tautschnig <[email protected]>
Co-authored-by: Michael Tautschnig <[email protected]>
Co-authored-by: Felipe R. Monteiro <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Nov 6, 2025
Raw release notes:
```
## What's Changed
* Automatic toolchain upgrade to nightly-2025-08-07 by @github-actions[bot] in #4278
* Add loop invariant support for `while let` loop  by @thanhnguyen-aws in #4279
* Automatic toolchain upgrade to nightly-2025-08-08 by @github-actions[bot] in #4281
* Automatic toolchain upgrade to nightly-2025-08-09 by @github-actions[bot] in #4283
* Automatic cargo update to 2025-08-11 by @github-actions[bot] in #4285
* Bump tests/perf/s2n-quic from `8f510f0` to `c64faf9` by @dependabot[bot] in #4288
* Bump actions/checkout from 4 to 5 by @dependabot[bot] in #4286
* Bump actions/download-artifact from 4 to 5 by @dependabot[bot] in #4287
* Upgrade toolchain to 2025-08-10 by @carolynzech in #4289
* Automatic toolchain upgrade to nightly-2025-08-11 by @github-actions[bot] in #4290
* Automatic toolchain upgrade to nightly-2025-08-12 by @github-actions[bot] in #4292
* Update README by @carolynzech in #4291
* Automatic toolchain upgrade to nightly-2025-08-13 by @github-actions[bot] in #4297
* [Breaking Change] Fail if stub verified doesn't have a contract harness by @carolynzech in #4295
* Kani Book Documentation Improvements by @carolynzech in #4296
* Automatic toolchain upgrade to nightly-2025-08-14 by @github-actions[bot] in #4298
* Automatic toolchain upgrade to nightly-2025-08-15 by @github-actions[bot] in #4299
* Automatic toolchain upgrade to nightly-2025-08-16 by @github-actions[bot] in #4300
* Automatic cargo update to 2025-08-18 by @github-actions[bot] in #4302
* Upgrade Rust toolchain to 2025-08-18 by @tautschnig in #4304
* Automatic toolchain upgrade to nightly-2025-08-19 by @github-actions[bot] in #4307
* Bump tests/perf/s2n-quic from `c64faf9` to `ff81604` by @dependabot[bot] in #4306
* Automatic toolchain upgrade to nightly-2025-08-20 by @github-actions[bot] in #4309
* Share body cache between harnesses within a codegen unit by @AlexanderPortland in #4276
* Add loop-contracts support for `for` loop by @thanhnguyen-aws in #4143
* RFC: Partitioned proofs by @AlexanderPortland in #4228
* Update toolchain to 08-25-2025 by @thanhnguyen-aws in #4316
* Automatic cargo update to 2025-08-25 by @github-actions[bot] in #4315
* Automatic toolchain upgrade to nightly-2025-08-26 by @github-actions[bot] in #4317
* Bump tests/perf/s2n-quic from `ff81604` to `fa30e8a` by @dependabot[bot] in #4318
* Automatic toolchain upgrade to nightly-2025-08-27 by @github-actions[bot] in #4319
* Handle const generics in stubbing code by @zhassan-aws in #4323
* Automatic toolchain upgrade to nightly-2025-08-28 by @github-actions[bot] in #4324
* Automatic toolchain upgrade to nightly-2025-08-29 by @github-actions[bot] in #4325
* Add import select_autoescape by @zhassan-aws in #4327
* Bump tracing-subscriber from 0.3.19 to 0.3.20 by @dependabot[bot] in #4328
* Bump ncipollo/release-action from 1.18.0 to 1.19.1 by @dependabot[bot] in #4331
* Bump tests/perf/s2n-quic from `fa30e8a` to `d2c0794` by @dependabot[bot] in #4332
* Automatic cargo update to 2025-09-01 by @github-actions[bot] in #4330
* Upgrade toolchain to 2025-09-02 by @zhassan-aws in #4333
* Automatic toolchain upgrade to nightly-2025-09-03 by @github-actions[bot] in #4335
* Automatic toolchain upgrade to nightly-2025-09-04 by @github-actions[bot] in #4336
* Automatic toolchain upgrade to nightly-2025-09-05 by @github-actions[bot] in #4337
* Replace fxhash with rustc-hash by @zhassan-aws in #4341
* Fix LLBC regressions by @zhassan-aws in #4338
* Bump ncipollo/release-action from 1.19.1 to 1.20.0 by @dependabot[bot] in #4344
* Automatic cargo update to 2025-09-08 by @github-actions[bot] in #4342
* Bump tests/perf/s2n-quic from `d2c0794` to `26e2402` by @dependabot[bot] in #4346
* Automatic toolchain upgrade to nightly-2025-09-06 by @github-actions[bot] in #4339
* Combo of small performance changes by @AlexanderPortland in #4314
* Upgrade cargo_metadata dependency by @tautschnig in #4308
* Bump actions/github-script from 7 to 8 by @dependabot[bot] in #4343
* Bump actions/labeler from 5 to 6 by @dependabot[bot] in #4345
* Automatic toolchain upgrade to nightly-2025-09-07 by @github-actions[bot] in #4347
* Workaround sporadic git submodule failure by @tautschnig in #4349
* Implement BoundedArbitrary for boxed slices by @zhassan-aws in #4340
* Automatic toolchain upgrade to nightly-2025-09-08 by @github-actions[bot] in #4350
* Contain CI permissions to avoid global read-write by @tautschnig in #4348
* Automatic toolchain upgrade to nightly-2025-09-09 by @github-actions[bot] in #4352
* Upgrade Rust toolchain to 2025-09-10 by @tautschnig in #4354
* Automatic toolchain upgrade to nightly-2025-09-11 by @github-actions[bot] in #4355
* Automatic toolchain upgrade to nightly-2025-09-12 by @github-actions[bot] in #4356
* Do not run PR/issue-creating workflows in forks by @tautschnig in #4357
* Automatic toolchain upgrade to nightly-2025-09-13 by @github-actions[bot] in #4358
* Automatic toolchain upgrade to nightly-2025-09-14 by @github-actions[bot] in #4359
* Automatic toolchain upgrade to nightly-2025-09-15 by @github-actions[bot] in #4360
* Automatic cargo update to 2025-09-15 by @github-actions[bot] in #4361
* Bump tests/perf/s2n-quic from `26e2402` to `fc9b388` by @dependabot[bot] in #4362
* Automatic toolchain upgrade to nightly-2025-09-16 by @github-actions[bot] in #4363
* Automatic toolchain upgrade to nightly-2025-09-17 by @github-actions[bot] in #4364
* Upgrade Rust toolchain to 2025-09-18 by @tautschnig in #4366
* Autoharness: use SHA-1 to produce codegen unit file names by @tautschnig in #4370
* Upgrade Rust toolchain to 2025-09-19 by @tautschnig in #4369
* Automatic toolchain upgrade to nightly-2025-09-20 by @github-actions[bot] in #4371
* Automatic toolchain upgrade to nightly-2025-09-21 by @github-actions[bot] in #4372
* Update attributes.md by @0xsecaas in #4376
* Bump tests/perf/s2n-quic from `fc9b388` to `b131854` by @dependabot[bot] in #4377
* Automatic toolchain upgrade to nightly-2025-09-22 by @github-actions[bot] in #4373
* Automatic cargo update to 2025-09-22 by @github-actions[bot] in #4374
* Revert "Cache dependencies for CI jobs (#4181)" by @tautschnig in #4375
* Automatic toolchain upgrade to nightly-2025-09-23 by @github-actions[bot] in #4378
* Automatic toolchain upgrade to nightly-2025-09-24 by @github-actions[bot] in #4379
* Automatic toolchain upgrade to nightly-2025-09-25 by @github-actions[bot] in #4380
* Automatic toolchain upgrade to nightly-2025-09-26 by @github-actions[bot] in #4381
* Automatic toolchain upgrade to nightly-2025-09-27 by @github-actions[bot] in #4382
* Automatic toolchain upgrade to nightly-2025-09-28 by @github-actions[bot] in #4383
* Automatic toolchain upgrade to nightly-2025-09-29 by @github-actions[bot] in #4384
* Automatic cargo update to 2025-09-29 by @github-actions[bot] in #4385
* Bump tests/perf/s2n-quic from `b131854` to `1cca93b` by @dependabot[bot] in #4386
* Upgrade Rust toolchain to 2025-09-30 by @tautschnig in #4388
* Automatic toolchain upgrade to nightly-2025-10-01 by @github-actions[bot] in #4389
* Automatic toolchain upgrade to nightly-2025-10-02 by @github-actions[bot] in #4391
* Upgrade Rust toolchain to 2025-10-03 by @tautschnig in #4393
* Complete CI permissions limiting by @tautschnig in #4394
* Automatic toolchain upgrade to nightly-2025-10-04 by @github-actions[bot] in #4395
* Automatic toolchain upgrade to nightly-2025-10-05 by @github-actions[bot] in #4396
* Automatic cargo update to 2025-10-06 by @github-actions[bot] in #4398
* Automatic toolchain upgrade to nightly-2025-10-06 by @github-actions[bot] in #4397
* Automatic toolchain upgrade to nightly-2025-10-07 by @github-actions[bot] in #4401
* Automatic toolchain upgrade to nightly-2025-10-08 by @github-actions[bot] in #4402
* Automatic toolchain upgrade to nightly-2025-10-09 by @github-actions[bot] in #4403
* Automatic toolchain upgrade to nightly-2025-10-10 by @github-actions[bot] in #4404
* Automatic toolchain upgrade to nightly-2025-10-11 by @github-actions[bot] in #4405
* Bump tests/perf/s2n-quic from `1cca93b` to `995f37b` by @dependabot[bot] in #4400
* Automatic cargo update to 2025-10-13 by @github-actions[bot] in #4409
* Upgrade Rust toolchain to 2025-10-12 by @tautschnig in #4407
* Bump tests/perf/s2n-quic from `995f37b` to `5240fd6` by @dependabot[bot] in #4410
* Automatic toolchain upgrade to nightly-2025-10-13 by @github-actions[bot] in #4411
* Automatic toolchain upgrade to nightly-2025-10-14 by @github-actions[bot] in #4412
* Automatic toolchain upgrade to nightly-2025-10-15 by @github-actions[bot] in #4414
* Automatic toolchain upgrade to nightly-2025-10-16 by @github-actions[bot] in #4415
* Automatic toolchain upgrade to nightly-2025-10-17 by @github-actions[bot] in #4416
* Automatic cargo update to 2025-10-20 by @github-actions[bot] in #4417
* Automatic toolchain upgrade to nightly-2025-10-18 by @github-actions[bot] in #4418
* Bump tests/perf/s2n-quic from `5240fd6` to `73c9278` by @dependabot[bot] in #4419
* Automatic toolchain upgrade to nightly-2025-10-19 by @github-actions[bot] in #4420
* Automatic toolchain upgrade to nightly-2025-10-20 by @github-actions[bot] in #4421
* Automatic toolchain upgrade to nightly-2025-10-21 by @github-actions[bot] in #4422
* Automatic toolchain upgrade to nightly-2025-10-22 by @github-actions[bot] in #4423
* Automatic toolchain upgrade to nightly-2025-10-23 by @github-actions[bot] in #4424
* Automatic cargo update to 2025-10-27 by @github-actions[bot] in #4428
* Bump tests/perf/s2n-quic from `73c9278` to `42fe409` by @dependabot[bot] in #4429
* Bump actions/download-artifact from 5 to 6 by @dependabot[bot] in #4430
* Upgrade Rust toolchain to 2025-10-24 by @tautschnig in #4426
* Automatic toolchain upgrade to nightly-2025-10-25 by @github-actions[bot] in #4431
* Automatic toolchain upgrade to nightly-2025-10-26 by @github-actions[bot] in #4432
* Automatic toolchain upgrade to nightly-2025-10-27 by @github-actions[bot] in #4433
* Automatic toolchain upgrade to nightly-2025-10-28 by @github-actions[bot] in #4434
* Automatic toolchain upgrade to nightly-2025-10-29 by @github-actions[bot] in #4435
* Automatic toolchain upgrade to nightly-2025-10-30 by @github-actions[bot] in #4436
* Automatic toolchain upgrade to nightly-2025-10-31 by @github-actions[bot] in #4437
* Automatic cargo update to 2025-11-03 by @github-actions[bot] in #4441
* Upgrade Rust toolchain to 2025-11-03 by @tautschnig in #4440
* Bump tests/perf/s2n-quic from `42fe409` to `e726f08` by @dependabot[bot] in #4443
* Switch macos-13 CI jobs to macos-15-intel by @tautschnig in #4442
* Automatic toolchain upgrade to nightly-2025-11-04 by @github-actions[bot] in #4444
* Incrementally update charon submodule with LLBC backend adaptations by @tautschnig in #4445
* Automatic toolchain upgrade to nightly-2025-11-05 by @github-actions[bot] in #4446
* Major-version update cargo dependencies by @tautschnig in #4447

## New Contributors
* @0xsecaas made their first contribution in #4376

**Full Changelog**: kani-0.65.0...kani-0.66.0
```


By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
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.

5 participants