19
19
#![ no_core]
20
20
21
21
mod arbitrary;
22
+ mod mem;
22
23
23
24
pub use kani_macros:: * ;
24
25
@@ -34,15 +35,21 @@ macro_rules! kani_lib {
34
35
#[ cfg( kani) ]
35
36
#[ unstable( feature = "kani" , issue = "none" ) ]
36
37
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) ;
39
42
kani_core:: generate_arbitrary!( core) ;
43
+
44
+ pub mod mem {
45
+ kani_core:: kani_mem!( core) ;
46
+ }
40
47
}
41
48
} ;
42
49
43
50
( kani) => {
44
51
pub use kani_core:: * ;
45
- kani_core:: kani_intrinsics!( ) ;
52
+ kani_core:: kani_intrinsics!( std ) ;
46
53
kani_core:: generate_arbitrary!( std) ;
47
54
} ;
48
55
}
@@ -54,7 +61,7 @@ macro_rules! kani_lib {
54
61
/// TODO: Use this inside kani library so that we dont have to maintain two copies of the same intrinsics.
55
62
#[ macro_export]
56
63
macro_rules! kani_intrinsics {
57
- ( ) => {
64
+ ( $core : tt ) => {
58
65
/// Creates an assumption that will be valid after this statement run. Note that the assumption
59
66
/// will only be applied for paths that follow the assumption. If the assumption doesn't hold, the
60
67
/// program will exit successfully.
@@ -262,6 +269,74 @@ macro_rules! kani_intrinsics {
262
269
}
263
270
264
271
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
+
265
340
/// A way to break the ownerhip rules. Only used by contracts where we can
266
341
/// guarantee it is done safely.
267
342
#[ inline( never) ]
0 commit comments