Skip to content

Commit d4a3f7b

Browse files
authoredJun 10, 2024
Use cfg=kani_host for host crates (rust-lang#3244)
We want to run the proofs in the target crate and don't need to build (or run) the proofs in any of the host crates. This avoids a need to make available the `kani` crate to any such host crates. Resolves rust-lang#3101, rust-lang#3238
1 parent e7d1624 commit d4a3f7b

File tree

11 files changed

+114
-8
lines changed

11 files changed

+114
-8
lines changed
 

‎docs/src/usage.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,11 @@ For more information please consult this [blog post](https://blog.rust-lang.org/
8080

8181
## The build process
8282

83-
When Kani builds your code, it does two important things:
83+
When Kani builds your code, it does three important things:
8484

85-
1. It sets `cfg(kani)`.
85+
1. It sets `cfg(kani)` for target crate compilation (including dependencies).
8686
2. It injects the `kani` crate.
87+
3. It sets `cfg(kani_host)` for host build targets such as any build script and procedural macro crates.
8788

8889
A proof harness (which you can [learn more about in the tutorial](./kani-tutorial.md)), is a function annotated with `#[kani::proof]` much like a test is annotated with `#[test]`.
8990
But you may experience a similar problem using Kani as you would with `dev-dependencies`: if you try writing `#[kani::proof]` directly in your code, `cargo build` will fail because it doesn't know what the `kani` crate is.

‎kani-driver/src/call_cargo.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,10 @@ pub fn cargo_config_args() -> Vec<OsString> {
326326
[
327327
"--target",
328328
env!("TARGET"),
329-
// Propagate `--cfg=kani` to build scripts.
329+
// Propagate `--cfg=kani_host` to build scripts.
330330
"-Zhost-config",
331331
"-Ztarget-applies-to-host",
332-
"--config=host.rustflags=[\"--cfg=kani\"]",
332+
"--config=host.rustflags=[\"--cfg=kani_host\"]",
333333
]
334334
.map(OsString::from)
335335
.to_vec()
@@ -561,7 +561,7 @@ fn package_targets(args: &VerificationArgs, package: &Package) -> Vec<Verificati
561561
}
562562
if !ignored_unsupported.is_empty() {
563563
println!(
564-
"Skipped the following unsupported targets: '{}'.",
564+
"Skipped verification of the following unsupported targets: '{}'.",
565565
ignored_unsupported.join("', '")
566566
);
567567
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This repo contains contains a minimal example that used to break compilation
2+
when using Kani. See https://github.com/model-checking/kani/issues/3101.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
[package]
4+
name = "binary"
5+
version = "0.1.0"
6+
edition = "2021"
7+
8+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
9+
10+
[dependencies]
11+
constants = { path = "../constants" }
12+
13+
[build-dependencies]
14+
constants = { path = "../constants" }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// From https://github.com/model-checking/kani/issues/3101
5+
6+
use constants::SOME_CONSTANT;
7+
8+
fn main() {
9+
// build.rs changes should trigger rebuild
10+
println!("cargo:rerun-if-changed=build.rs");
11+
12+
#[cfg(not(kani_host))]
13+
assert_eq!(constants::SOME_CONSTANT, 0);
14+
#[cfg(kani_host)]
15+
assert_eq!(constants::SOME_CONSTANT, 2);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// From https://github.com/model-checking/kani/issues/3101
5+
// This file demonstrates that Kani is working on the `binary` crate itself.
6+
7+
use constants::SomeStruct;
8+
9+
fn function_that_does_something(b: bool) -> SomeStruct {
10+
SomeStruct { some_field: if b { 42 } else { 24 } }
11+
}
12+
13+
fn main() {
14+
println!("The constant is {}", constants::SOME_CONSTANT);
15+
16+
let some_struct = function_that_does_something(true);
17+
18+
println!("some_field is {:?}", some_struct.some_field);
19+
}
20+
21+
#[cfg(kani)]
22+
mod verification {
23+
use super::*;
24+
25+
#[kani::proof]
26+
fn function_never_returns_zero_struct() {
27+
let input: bool = kani::any();
28+
let output = function_that_does_something(input);
29+
30+
assert!(output.some_field != 0);
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
[package]
4+
name = "constants"
5+
version = "0.1.0"
6+
edition = "2021"
7+
8+
9+
[dependencies]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
// From https://github.com/model-checking/kani/issues/3101
5+
6+
#[cfg(not(any(kani, kani_host)))]
7+
pub const SOME_CONSTANT: u32 = 0;
8+
#[cfg(kani)]
9+
pub const SOME_CONSTANT: u32 = 1;
10+
#[cfg(kani_host)]
11+
pub const SOME_CONSTANT: u32 = 2;
12+
13+
pub struct SomeStruct {
14+
pub some_field: u32,
15+
}
16+
17+
#[cfg(kani)]
18+
impl kani::Arbitrary for SomeStruct {
19+
fn any() -> Self {
20+
SomeStruct { some_field: kani::any() }
21+
}
22+
}
23+
24+
#[cfg(kani)]
25+
mod verification {
26+
use super::*;
27+
28+
#[kani::proof]
29+
fn one() {
30+
assert_eq!(constants::SOME_CONSTANT, 1);
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Skipped the following unsupported targets: 'lib'.
1+
Skipped verification of the following unsupported targets: 'lib'.
22
error: No supported targets were found.

‎tests/script-based-pre/build-rs-conditional/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ edition = "2021"
88
[dependencies]
99

1010
[lints.rust]
11-
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)'] }
11+
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)', 'cfg(kani_host)'] }

‎tests/script-based-pre/build-rs-conditional/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Verify that build scripts can check if they are running under `kani`.
44
55
fn main() {
6-
if cfg!(kani) {
6+
if cfg!(kani_host) {
77
println!("cargo:rustc-env=RUNNING_KANI=Yes");
88
} else {
99
println!("cargo:rustc-env=RUNNING_KANI=No");

0 commit comments

Comments
 (0)
Please sign in to comment.