Skip to content

Commit 1537c29

Browse files
zhassan-awsCarolyn Zech
andauthored
Add an option to skip codegen (#4002)
This PR adds a new unstable option, `--no-codegen`, that can be used for running Kani, just to check if the code compiles, i.e. similar to running `cargo check`. This is useful as a lightweight check for compilation errors including code under `#[cfg(kani)]`. This is implemented through passing rustc's `-Zno-codegen` option, which is what `cargo check` passes to `rustc`. 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: Carolyn Zech <cmzech@amazon.com>
1 parent b70548f commit 1537c29

File tree

14 files changed

+105
-1
lines changed

14 files changed

+105
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ exclude = [
7373
"tests/script-based-pre/build-cache-dirty/target/new_dep",
7474
"tests/script-based-pre/verify_std_cmd/tmp_dir/target/kani_verify_std",
7575
"tests/script-based-pre/kani_lib_dep",
76+
"tests/script-based-pre/no_codegen",
77+
"tests/script-based-pre/no_codegen_error",
7678
]
7779

7880
[workspace.lints.clippy]

kani-driver/src/args/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ pub struct VerificationArgs {
242242
#[arg(long, hide_short_help = true)]
243243
pub only_codegen: bool,
244244

245+
/// Run Kani without codegen. Useful for quick feedback on whether the code would compile successfully (similar to `cargo check`).
246+
/// This feature is unstable and requires `-Z unstable-options` to be used
247+
#[arg(long, hide_short_help = true)]
248+
pub no_codegen: bool,
249+
245250
/// Specify the value used for loop unwinding in CBMC
246251
#[arg(long)]
247252
pub default_unwind: Option<u32>,
@@ -660,6 +665,12 @@ impl ValidateArgs for VerificationArgs {
660665
UnstableFeature::UnstableOptions,
661666
)?;
662667

668+
self.common_args.check_unstable(
669+
self.no_codegen,
670+
"--no-codegen",
671+
UnstableFeature::UnstableOptions,
672+
)?;
673+
663674
self.common_args.check_unstable(
664675
self.jobs.is_some(),
665676
"--jobs",

kani-driver/src/call_single_file.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ impl KaniSession {
182182
.map(OsString::from),
183183
);
184184

185+
if self.args.no_codegen {
186+
flags.push("-Z".into());
187+
flags.push("no-codegen".into());
188+
}
189+
185190
if let Some(seed_opt) = self.args.randomize_layout {
186191
flags.push("-Z".into());
187192
flags.push("randomize-layout".into());

kani-driver/src/project.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use crate::metadata::from_json;
88
use crate::session::KaniSession;
9-
use crate::util::crate_name;
9+
use crate::util::{crate_name, info_operation};
1010
use anyhow::{Context, Result};
1111
use kani_metadata::{
1212
ArtifactType, ArtifactType::*, HarnessMetadata, KaniMetadata, artifact::convert_type,
@@ -177,6 +177,13 @@ impl Artifact {
177177
/// be collected from the project.
178178
pub fn cargo_project(session: &mut KaniSession, keep_going: bool) -> Result<Project> {
179179
let outputs = session.cargo_build(keep_going)?;
180+
if session.args.no_codegen {
181+
info_operation(
182+
"info:",
183+
"Compilation succeeded up until codegen. Skipping codegen because of `--no-codegen` option. Rerun without `--no-codegen` to perform codegen.",
184+
);
185+
return Ok(Project::default());
186+
}
180187
let outdir = outputs.outdir.canonicalize()?;
181188
// For the MIR Linker we know there is only one metadata per crate. Use that in our favor.
182189
let metadata =
Lines changed: 9 additions & 0 deletions
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+
4+
[package]
5+
name = "no_codegen"
6+
version = "0.1.0"
7+
edition = "2024"
8+
9+
[dependencies]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
script: run.sh
4+
expected: expected
5+
exit_code: 0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
info: Compilation succeeded up until codegen. Skipping codegen because of `--no-codegen` option. Rerun without `--no-codegen` to perform codegen.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
# Copyright Kani Contributors
3+
# SPDX-License-Identifier: Apache-2.0 OR MIT
4+
5+
rm -rf target
6+
7+
# Test the behavior of the `--no-codegen` option
8+
cargo kani --no-codegen -Zunstable-options
9+
10+
# Ensure no goto binaries (*.out) are generated
11+
[[ -z $(find target -name "*.out") ]] || {
12+
echo "ERROR: Found goto binaries (*.out) in target directory"
13+
exit 1
14+
}
Lines changed: 14 additions & 0 deletions
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+
4+
//! This test checks the behavior of Kani's `--no-codegen` option
5+
6+
#[kani::proof]
7+
fn main() {
8+
let x: u8 = kani::any();
9+
if x < 100 {
10+
assert!(x < 101);
11+
} else {
12+
assert!(x > 99);
13+
}
14+
}
Lines changed: 9 additions & 0 deletions
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+
4+
[package]
5+
name = "no_codegen_error"
6+
version = "0.1.0"
7+
edition = "2024"
8+
9+
[dependencies]

0 commit comments

Comments
 (0)