Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function Contracts: Interior Mutability Tests #3351

Merged
merged 38 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ed8fee1
add tests
Jul 17, 2024
0bbd78b
fix tests
Jul 17, 2024
35a9320
preserves memory
Jul 17, 2024
76a9c54
fmt
Jul 17, 2024
7ca72aa
OnceCell
Jul 17, 2024
4ce98ad
documentation
Jul 18, 2024
f97140e
stub
Jul 18, 2024
7b96733
more comments
Jul 18, 2024
fae9ff2
fix test
Jul 19, 2024
e2df787
Merge branch 'main' into int-mut-tests
pi314mm Jul 19, 2024
600a0f1
rfc update
Jul 19, 2024
7a0a554
unsafecell and cell can be reached through public api
Jul 22, 2024
759b6dc
Merge branch 'main' into int-mut-tests
pi314mm Jul 22, 2024
e704958
triple slash for comments
Jul 22, 2024
382e8fe
more tests
Jul 23, 2024
39cdc44
fmt
Jul 23, 2024
03f3d6d
fix tests
Jul 24, 2024
8925ffb
comments
Jul 24, 2024
519fe5c
comments
Jul 24, 2024
8cf4f6c
Merge branch 'main' into int-mut-tests
pi314mm Jul 24, 2024
2126d79
add explanation in docs
Jul 25, 2024
3fb40fc
delete
Jul 26, 2024
5201fc1
Merge branch 'main' into int-mut-tests
pi314mm Jul 26, 2024
0c7bda5
Merge branch 'main' into int-mut-tests
pi314mm Jul 26, 2024
13baa5b
Update tests/expected/function-contract/interior-mutability/api/unsaf…
feliperodri Jul 30, 2024
5feba8c
Update tests/expected/function-contract/interior-mutability/api/unsaf…
feliperodri Jul 30, 2024
7f84e89
Update tests/expected/function-contract/interior-mutability/api/cell_…
feliperodri Jul 30, 2024
882477c
Update tests/expected/function-contract/interior-mutability/api/cell_…
feliperodri Jul 30, 2024
82c3e6f
Update tests/expected/function-contract/interior-mutability/api/cell.rs
feliperodri Jul 30, 2024
1e12172
Update tests/expected/function-contract/interior-mutability/api/cell.rs
feliperodri Jul 30, 2024
42fd597
Update tests/expected/function-contract/interior-mutability/whole-str…
feliperodri Jul 30, 2024
60b0d8a
Update tests/expected/function-contract/interior-mutability/whole-str…
feliperodri Jul 30, 2024
dbf938f
Update tests/expected/function-contract/interior-mutability/whole-str…
feliperodri Jul 30, 2024
065b554
Update tests/expected/function-contract/interior-mutability/whole-str…
feliperodri Jul 30, 2024
19b4cbf
Update tests/expected/function-contract/interior-mutability/whole-str…
feliperodri Jul 30, 2024
aaf64ed
Update tests/expected/function-contract/interior-mutability/whole-str…
feliperodri Jul 30, 2024
172839f
Update tests/expected/function-contract/interior-mutability/whole-str…
feliperodri Jul 30, 2024
ba95719
Merge branch 'main' into int-mut-tests
feliperodri Jul 30, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
assertion\
- Status: SUCCESS\
- Description: "|_| im.x.get() < 101"\
in function modify

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

/// Mutating Cell via `as_ptr` in contracts
use std::cell::Cell;

/// This struct contains Cell which can be mutated
struct InteriorMutability {
x: Cell<u32>,
}

#[kani::requires(im.x.get() < 100)]
#[kani::modifies(im.x.as_ptr())]
#[kani::ensures(|_| im.x.get() < 101)]
///im is an immutable reference with interior mutability
fn modify(im: &InteriorMutability) {
im.x.set(im.x.get() + 1)
}

#[kani::proof_for_contract(modify)]
fn harness_for_modify() {
let im: InteriorMutability = InteriorMutability { x: Cell::new(kani::any()) };
modify(&im)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
assertion\
- Status: SUCCESS\
- Description: "|_| old(im.x.get() + im.x.get()) == im.x.get()"\

assertion\
- Status: SUCCESS\
- Description: "|_| old(im.x.get() + im.x.get() + im.x.get() + im.x.get()) == im.x.get()"\

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

/// The objective of this test is to show that the contracts for double can be replaced as a stub within the contracts for quadruple.
/// This shows that we can generate `kani::any()` for Cell.
use std::cell::Cell;

/// This struct contains Cell which can be mutated
struct InteriorMutability {
x: Cell<u32>,
}

#[kani::ensures(|_| old(im.x.get() + im.x.get()) == im.x.get())]
#[kani::requires(im.x.get() < 100)]
#[kani::modifies(im.x.as_ptr())]
fn double(im: &InteriorMutability) {
im.x.set(im.x.get() + im.x.get())
}

#[kani::proof_for_contract(double)]
fn double_harness() {
let im: InteriorMutability = InteriorMutability { x: Cell::new(kani::any()) };
double(&im);
}

#[kani::ensures(|_| old(im.x.get() + im.x.get() + im.x.get() + im.x.get()) == im.x.get())]
#[kani::requires(im.x.get() < 50)]
#[kani::modifies(im.x.as_ptr())]
fn quadruple(im: &InteriorMutability) {
double(im);
double(im)
}

#[kani::proof_for_contract(quadruple)]
#[kani::stub_verified(double)]
fn quadruple_harness() {
let im: InteriorMutability = InteriorMutability { x: Cell::new(kani::any()) };
quadruple(&im);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
assertion\
- Status: SUCCESS\
- Description: "|_| unsafe{ *im.x.get() } < 101"\
in function modify

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

use std::cell::UnsafeCell;

/// This struct contains UnsafeCell which can be mutated
struct InteriorMutability {
x: UnsafeCell<u32>,
}

#[kani::requires(unsafe{*im.x.get()} < 100)]
#[kani::modifies(im.x.get())]
#[kani::ensures(|_| unsafe{*im.x.get()} < 101)]
/// `im` is an immutable reference with interior mutability
fn modify(im: &InteriorMutability) {
unsafe { *im.x.get() += 1 }
}

#[kani::proof_for_contract(modify)]
fn harness_for_modify() {
let im: InteriorMutability = InteriorMutability { x: UnsafeCell::new(kani::any()) };
modify(&im)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
assertion\
- Status: SUCCESS\
- Description: "|_| im.x.get() < 101"\
in function modify

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

/// The objective of this test is to check the modification of a Cell used as interior mutability in an immutable struct
use std::cell::Cell;

/// This struct contains Cell which can be mutated
struct InteriorMutability {
x: Cell<u32>,
}

#[kani::requires(im.x.get() < 100)]
#[kani::modifies(&im.x)]
#[kani::ensures(|_| im.x.get() < 101)]
/// `im` is an immutable reference with interior mutability
fn modify(im: &InteriorMutability) {
im.x.set(im.x.get() + 1)
}

#[kani::proof_for_contract(modify)]
fn harness_for_modify() {
let im: InteriorMutability = InteriorMutability { x: Cell::new(kani::any()) };
modify(&im)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
assertion\
- Status: SUCCESS\
- Description: "|_| im.x.get().is_some()"\
in function modify

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

/// The objective of this test is to check the modification of an OnceCell used as interior mutability in an immutable struct
use std::cell::OnceCell;

/// This struct contains OnceCell which can be mutated
struct InteriorMutability {
x: OnceCell<u32>,
}

#[kani::requires(im.x.get().is_none())]
#[kani::modifies(&im.x)]
#[kani::ensures(|_| im.x.get().is_some())]
fn modify(im: &InteriorMutability) {
im.x.set(5).expect("")
}

#[kani::proof_for_contract(modify)]
fn harness_for_modify() {
let im: InteriorMutability = InteriorMutability { x: OnceCell::new() };
modify(&im)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
assertion\
- Status: SUCCESS\
- Description: "|_| unsafe{ *im.x.as_ptr() } < 101"\
in function modify

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

/// The objective of this test is to check the modification of a RefCell used as interior mutability in an immutable struct
use std::cell::RefCell;

/// This struct contains Cell which can be mutated
struct InteriorMutability {
x: RefCell<u32>,
}

#[kani::requires(unsafe{*im.x.as_ptr()} < 100)]
#[kani::modifies(&im.x)]
#[kani::ensures(|_| unsafe{*im.x.as_ptr()} < 101)]
/// `im` is an immutable reference with interior mutability
fn modify(im: &InteriorMutability) {
im.x.replace_with(|&mut old| old + 1);
}

#[kani::proof_for_contract(modify)]
fn harness_for_modify() {
let im: InteriorMutability = InteriorMutability { x: RefCell::new(kani::any()) };
modify(&im)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
assertion\
- Status: SUCCESS\
- Description: "|_| unsafe{ *im.x.get() } < 101"\
in function modify

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

/// The objective of this test is to check the modification of an UnsafeCell used as interior mutability in an immutable struct
use std::cell::UnsafeCell;

/// This struct contains UnsafeCell which can be mutated
struct InteriorMutability {
x: UnsafeCell<u32>,
}

#[kani::requires(unsafe{*im.x.get()} < 100)]
#[kani::modifies(im.x.get())]
#[kani::ensures(|_| unsafe{*im.x.get()} < 101)]
/// `im` is an immutable reference with interior mutability
fn modify(im: &InteriorMutability) {
unsafe { *im.x.get() += 1 }
}

#[kani::proof_for_contract(modify)]
fn harness_for_modify() {
let im: InteriorMutability = InteriorMutability { x: UnsafeCell::new(kani::any()) };
modify(&im)
}
Loading