Skip to content

Commit 27dd072

Browse files
Support flags for function/method stubbing (rust-lang#1820)
Co-authored-by: Adrian Palacios <[email protected]>
1 parent f5667f4 commit 27dd072

File tree

9 files changed

+109
-0
lines changed

9 files changed

+109
-0
lines changed

kani-compiler/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ fn main() -> Result<(), &'static str> {
106106
// Generate rustc args.
107107
let rustc_args = generate_rustc_args(&matches);
108108

109+
if matches.is_present(parser::ENABLE_STUBBING) {
110+
eprintln!("warning: Kani currently does not perform any stubbing.");
111+
}
112+
109113
// Configure and run compiler.
110114
let mut callbacks = KaniCallbacks {};
111115
let mut compiler = RunCompiler::new(&rustc_args, &mut callbacks);

kani-compiler/src/parser.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ pub const SYSROOT: &str = "sysroot";
4747
pub const REACHABILITY: &str = "reachability";
4848
pub const REACHABILITY_FLAG: &str = "--reachability";
4949

50+
/// Option name used to specify which harness is the target.
51+
pub const HARNESS: &str = "harness";
52+
53+
/// Option name used to enable stubbing.
54+
pub const ENABLE_STUBBING: &str = "enable-stubbing";
55+
5056
/// Option name used to pass extra rustc-options.
5157
pub const RUSTC_OPTIONS: &str = "rustc-options";
5258

@@ -157,6 +163,21 @@ pub fn parser<'a, 'b>() -> App<'a, 'b> {
157163
Arg::with_name(IGNORE_GLOBAL_ASM)
158164
.long("--ignore-global-asm")
159165
.help("Suppress error due to the existence of global_asm in a crate"),
166+
)
167+
.arg(
168+
// TODO: Remove this argument once stubbing works for multiple harnesses at a time.
169+
// <https://github.com/model-checking/kani/issues/1841>
170+
Arg::with_name(HARNESS)
171+
.long("--harness")
172+
.help("Selects the harness to target.")
173+
.value_name("HARNESS")
174+
.takes_value(true),
175+
)
176+
.arg(
177+
Arg::with_name(ENABLE_STUBBING)
178+
.long("--enable-stubbing")
179+
.help("Instruct the compiler to perform stubbing.")
180+
.requires(HARNESS),
160181
);
161182
#[cfg(feature = "unsound_experiments")]
162183
let app = crate::unsound_experiments::arg_parser::add_unsound_experiments_to_parser(app);
@@ -214,6 +235,8 @@ pub fn command_arguments(args: &Vec<String>) -> Vec<String> {
214235

215236
#[cfg(test)]
216237
mod parser_test {
238+
use clap::ErrorKind;
239+
217240
use super::*;
218241

219242
#[test]
@@ -231,6 +254,19 @@ mod parser_test {
231254
assert_eq!(matches.value_of("kani-lib"), Some("some/path"));
232255
}
233256

257+
#[test]
258+
fn test_stubbing_flags() {
259+
let args = vec!["kani-compiler", "--enable-stubbing", "--harness", "foo"];
260+
let matches = parser().get_matches_from(args);
261+
assert!(matches.is_present("enable-stubbing"));
262+
assert_eq!(matches.value_of("harness"), Some("foo"));
263+
264+
// `--enable-stubbing` cannot be called without `--harness`
265+
let args = vec!["kani-compiler", "--enable-stubbing"];
266+
let err = parser().get_matches_from_safe(args).unwrap_err();
267+
assert_eq!(err.kind, ErrorKind::MissingRequiredArgument);
268+
}
269+
234270
#[test]
235271
fn test_cargo_kani_hack_noop() {
236272
let args = ["kani-compiler", "some/path"];

kani-driver/src/args.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ pub struct KaniArgs {
226226
/// See the `-Z randomize-layout` and `-Z layout-seed` arguments of the rust compiler.
227227
#[structopt(long)]
228228
pub randomize_layout: Option<Option<u64>>,
229+
230+
/// Enable the stubbing of functions and methods.
231+
/// TODO: Stubbing should in principle work with concrete playback.
232+
/// <https://github.com/model-checking/kani/issues/1842>
233+
#[structopt(
234+
long,
235+
hidden_short_help(true),
236+
requires("enable-unstable"),
237+
requires("harness"),
238+
conflicts_with("concrete-playback")
239+
)]
240+
pub enable_stubbing: bool,
229241
/*
230242
The below is a "TODO list" of things not yet implemented from the kani_flags.py script.
231243
@@ -577,4 +589,19 @@ mod tests {
577589
ErrorKind::ArgumentConflict,
578590
);
579591
}
592+
593+
#[test]
594+
fn check_enable_stubbing() {
595+
check_unstable_flag("--enable-stubbing --harness foo");
596+
597+
// `--enable-stubbing` cannot be called without `--harness`
598+
let err = parse_unstable_enabled("--enable-stubbing").unwrap_err();
599+
assert_eq!(err.kind, ErrorKind::MissingRequiredArgument);
600+
601+
// `--enable-stubbing` cannot be called with `--concrete-playback`
602+
let err =
603+
parse_unstable_enabled("--enable-stubbing --harness foo --concrete-playback=print")
604+
.unwrap_err();
605+
assert_eq!(err.kind, ErrorKind::ArgumentConflict);
606+
}
580607
}

kani-driver/src/call_single_file.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ impl KaniSession {
129129
flags.push("--ignore-global-asm".into());
130130
}
131131

132+
if self.args.enable_stubbing {
133+
flags.push("--enable-stubbing".into());
134+
}
135+
if let Some(harness) = &self.args.harness {
136+
flags.push(format!("--harness={harness}").into());
137+
}
138+
132139
#[cfg(feature = "unsound_experiments")]
133140
flags.extend(self.args.unsound_experiments.process_args());
134141

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright Kani Contributors
2+
# SPDX-License-Identifier: Apache-2.0 OR MIT
3+
[package]
4+
name = "stubbing-flag"
5+
version = "0.1.0"
6+
edition = "2021"
7+
8+
[dependencies]
9+
10+
[package.metadata.kani]
11+
flags = { enable-unstable=true, enable-stubbing=true, harness="main" }

tests/cargo-ui/stubbing-flag/expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
warning: Kani currently does not perform any stubbing.
2+
3+
VERIFICATION:- SUCCESSFUL
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//
4+
//! This tests that the `--enable-stubbing` and `--harness` arguments flow from `kani-driver` to `kani-compiler`
5+
//! (and that we warn that no actual stubbing is being performed).
6+
7+
#[kani::proof]
8+
fn main() {}

tests/ui/stubbing-flag/expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
warning: Kani currently does not perform any stubbing.
2+
3+
VERIFICATION:- SUCCESSFUL

tests/ui/stubbing-flag/main.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//
4+
// kani-flags: --harness main --enable-unstable --enable-stubbing
5+
//
6+
//! This tests that the `--enable-stubbing` and `--harness` arguments flow from `kani-driver` to `kani-compiler`
7+
//! (and that we warn that no actual stubbing is being performed).
8+
9+
#[kani::proof]
10+
fn main() {}

0 commit comments

Comments
 (0)