Skip to content

Commit

Permalink
Use cfg=kani_host for host crates (rust-lang#3244)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tautschnig authored Jun 10, 2024
1 parent e7d1624 commit d4a3f7b
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 8 deletions.
5 changes: 3 additions & 2 deletions docs/src/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ For more information please consult this [blog post](https://blog.rust-lang.org/

## The build process

When Kani builds your code, it does two important things:
When Kani builds your code, it does three important things:

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

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]`.
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.
Expand Down
6 changes: 3 additions & 3 deletions kani-driver/src/call_cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,10 @@ pub fn cargo_config_args() -> Vec<OsString> {
[
"--target",
env!("TARGET"),
// Propagate `--cfg=kani` to build scripts.
// Propagate `--cfg=kani_host` to build scripts.
"-Zhost-config",
"-Ztarget-applies-to-host",
"--config=host.rustflags=[\"--cfg=kani\"]",
"--config=host.rustflags=[\"--cfg=kani_host\"]",
]
.map(OsString::from)
.to_vec()
Expand Down Expand Up @@ -561,7 +561,7 @@ fn package_targets(args: &VerificationArgs, package: &Package) -> Vec<Verificati
}
if !ignored_unsupported.is_empty() {
println!(
"Skipped the following unsupported targets: '{}'.",
"Skipped verification of the following unsupported targets: '{}'.",
ignored_unsupported.join("', '")
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This repo contains contains a minimal example that used to break compilation
when using Kani. See https://github.com/model-checking/kani/issues/3101.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright Kani Contributors
# SPDX-License-Identifier: Apache-2.0 OR MIT
[package]
name = "binary"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
constants = { path = "../constants" }

[build-dependencies]
constants = { path = "../constants" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

// From https://github.com/model-checking/kani/issues/3101

use constants::SOME_CONSTANT;

fn main() {
// build.rs changes should trigger rebuild
println!("cargo:rerun-if-changed=build.rs");

#[cfg(not(kani_host))]
assert_eq!(constants::SOME_CONSTANT, 0);
#[cfg(kani_host)]
assert_eq!(constants::SOME_CONSTANT, 2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

// From https://github.com/model-checking/kani/issues/3101
// This file demonstrates that Kani is working on the `binary` crate itself.

use constants::SomeStruct;

fn function_that_does_something(b: bool) -> SomeStruct {
SomeStruct { some_field: if b { 42 } else { 24 } }
}

fn main() {
println!("The constant is {}", constants::SOME_CONSTANT);

let some_struct = function_that_does_something(true);

println!("some_field is {:?}", some_struct.some_field);
}

#[cfg(kani)]
mod verification {
use super::*;

#[kani::proof]
fn function_never_returns_zero_struct() {
let input: bool = kani::any();
let output = function_that_does_something(input);

assert!(output.some_field != 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright Kani Contributors
# SPDX-License-Identifier: Apache-2.0 OR MIT
[package]
name = "constants"
version = "0.1.0"
edition = "2021"


[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

// From https://github.com/model-checking/kani/issues/3101

#[cfg(not(any(kani, kani_host)))]
pub const SOME_CONSTANT: u32 = 0;
#[cfg(kani)]
pub const SOME_CONSTANT: u32 = 1;
#[cfg(kani_host)]
pub const SOME_CONSTANT: u32 = 2;

pub struct SomeStruct {
pub some_field: u32,
}

#[cfg(kani)]
impl kani::Arbitrary for SomeStruct {
fn any() -> Self {
SomeStruct { some_field: kani::any() }
}
}

#[cfg(kani)]
mod verification {
use super::*;

#[kani::proof]
fn one() {
assert_eq!(constants::SOME_CONSTANT, 1);
}
}
2 changes: 1 addition & 1 deletion tests/cargo-ui/unsupported-lib-types/proc-macro/expected
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Skipped the following unsupported targets: 'lib'.
Skipped verification of the following unsupported targets: 'lib'.
error: No supported targets were found.
2 changes: 1 addition & 1 deletion tests/script-based-pre/build-rs-conditional/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ edition = "2021"
[dependencies]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)'] }
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)', 'cfg(kani_host)'] }
2 changes: 1 addition & 1 deletion tests/script-based-pre/build-rs-conditional/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Verify that build scripts can check if they are running under `kani`.

fn main() {
if cfg!(kani) {
if cfg!(kani_host) {
println!("cargo:rustc-env=RUNNING_KANI=Yes");
} else {
println!("cargo:rustc-env=RUNNING_KANI=No");
Expand Down

0 comments on commit d4a3f7b

Please sign in to comment.