Skip to content

Commit ca110f7

Browse files
authored
Fix a few issues with std verification (rust-lang#3255)
- Contracts cannot duplicate some attributes. I think we need a better solution than just duplicate all attributes, but for now just filter the ones we know are problematic. - Do not make contract generated functions `const` when annotating constant functions. - I also moved the compilation of no_core up since it is much faster. ## Call-out Need to add a test. Resolves rust-lang#3251 Resolves rust-lang#3254
1 parent b6e4972 commit ca110f7

File tree

12 files changed

+466
-13
lines changed

12 files changed

+466
-13
lines changed

kani-driver/src/call_cargo.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,19 @@ impl KaniSession {
8484
.env("CARGO_TERM_PROGRESS_WHEN", "never")
8585
.env("__CARGO_TESTS_ONLY_SRC_ROOT", std_path.as_os_str());
8686

87-
let build_artifacts = self.run_build(cmd)?;
88-
Ok(build_artifacts.into_iter().filter_map(map_kani_artifact).collect())
87+
Ok(self
88+
.run_build(cmd)?
89+
.into_iter()
90+
.filter_map(|artifact| {
91+
if artifact.target.crate_types.contains(&CRATE_TYPE_LIB.to_string())
92+
|| artifact.target.crate_types.contains(&CRATE_TYPE_RLIB.to_string())
93+
{
94+
map_kani_artifact(artifact)
95+
} else {
96+
None
97+
}
98+
})
99+
.collect())
89100
}
90101

91102
/// Calls `cargo_build` to generate `*.symtab.json` files in `target_dir`

library/kani_core/src/lib.rs

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#![no_core]
2020

2121
mod arbitrary;
22+
mod mem;
2223

2324
pub use kani_macros::*;
2425

@@ -34,15 +35,21 @@ macro_rules! kani_lib {
3435
#[cfg(kani)]
3536
#[unstable(feature = "kani", issue = "none")]
3637
pub mod kani {
37-
pub use kani_core::{ensures, proof, proof_for_contract, requires, should_panic};
38-
kani_core::kani_intrinsics!();
38+
pub use kani_core::{
39+
ensures, modifies, proof, proof_for_contract, requires, should_panic,
40+
};
41+
kani_core::kani_intrinsics!(core);
3942
kani_core::generate_arbitrary!(core);
43+
44+
pub mod mem {
45+
kani_core::kani_mem!(core);
46+
}
4047
}
4148
};
4249

4350
(kani) => {
4451
pub use kani_core::*;
45-
kani_core::kani_intrinsics!();
52+
kani_core::kani_intrinsics!(std);
4653
kani_core::generate_arbitrary!(std);
4754
};
4855
}
@@ -54,7 +61,7 @@ macro_rules! kani_lib {
5461
/// TODO: Use this inside kani library so that we dont have to maintain two copies of the same intrinsics.
5562
#[macro_export]
5663
macro_rules! kani_intrinsics {
57-
() => {
64+
($core:tt) => {
5865
/// Creates an assumption that will be valid after this statement run. Note that the assumption
5966
/// will only be applied for paths that follow the assumption. If the assumption doesn't hold, the
6067
/// program will exit successfully.
@@ -262,6 +269,74 @@ macro_rules! kani_intrinsics {
262269
}
263270

264271
pub mod internal {
272+
273+
/// Helper trait for code generation for `modifies` contracts.
274+
///
275+
/// We allow the user to provide us with a pointer-like object that we convert as needed.
276+
#[doc(hidden)]
277+
pub trait Pointer<'a> {
278+
/// Type of the pointed-to data
279+
type Inner;
280+
281+
/// Used for checking assigns contracts where we pass immutable references to the function.
282+
///
283+
/// We're using a reference to self here, because the user can use just a plain function
284+
/// argument, for instance one of type `&mut _`, in the `modifies` clause which would move it.
285+
unsafe fn decouple_lifetime(&self) -> &'a Self::Inner;
286+
287+
/// used for havocking on replecement of a `modifies` clause.
288+
unsafe fn assignable(self) -> &'a mut Self::Inner;
289+
}
290+
291+
impl<'a, 'b, T> Pointer<'a> for &'b T {
292+
type Inner = T;
293+
unsafe fn decouple_lifetime(&self) -> &'a Self::Inner {
294+
$core::mem::transmute(*self)
295+
}
296+
297+
#[allow(clippy::transmute_ptr_to_ref)]
298+
unsafe fn assignable(self) -> &'a mut Self::Inner {
299+
$core::mem::transmute(self as *const T)
300+
}
301+
}
302+
303+
impl<'a, 'b, T> Pointer<'a> for &'b mut T {
304+
type Inner = T;
305+
306+
#[allow(clippy::transmute_ptr_to_ref)]
307+
unsafe fn decouple_lifetime(&self) -> &'a Self::Inner {
308+
$core::mem::transmute::<_, &&'a T>(self)
309+
}
310+
311+
unsafe fn assignable(self) -> &'a mut Self::Inner {
312+
$core::mem::transmute(self)
313+
}
314+
}
315+
316+
impl<'a, T> Pointer<'a> for *const T {
317+
type Inner = T;
318+
unsafe fn decouple_lifetime(&self) -> &'a Self::Inner {
319+
&**self as &'a T
320+
}
321+
322+
#[allow(clippy::transmute_ptr_to_ref)]
323+
unsafe fn assignable(self) -> &'a mut Self::Inner {
324+
$core::mem::transmute(self)
325+
}
326+
}
327+
328+
impl<'a, T> Pointer<'a> for *mut T {
329+
type Inner = T;
330+
unsafe fn decouple_lifetime(&self) -> &'a Self::Inner {
331+
&**self as &'a T
332+
}
333+
334+
#[allow(clippy::transmute_ptr_to_ref)]
335+
unsafe fn assignable(self) -> &'a mut Self::Inner {
336+
$core::mem::transmute(self)
337+
}
338+
}
339+
265340
/// A way to break the ownerhip rules. Only used by contracts where we can
266341
/// guarantee it is done safely.
267342
#[inline(never)]

0 commit comments

Comments
 (0)