|  | 
| 2 | 2 | //! <https://github.com/matthieu-m/rfc2580/blob/b58d1d3cba0d4b5e859d3617ea2d0943aaa31329/examples/thin.rs> | 
| 3 | 3 | //! by matthieu-m | 
| 4 | 4 | 
 | 
|  | 5 | +use safety::requires; | 
|  | 6 | +#[cfg(kani)] | 
|  | 7 | +use crate::kani; | 
|  | 8 | + | 
| 5 | 9 | use core::error::Error; | 
| 6 | 10 | use core::fmt::{self, Debug, Display, Formatter}; | 
| 7 | 11 | #[cfg(not(no_global_oom_handling))] | 
| @@ -185,6 +189,7 @@ impl<T: ?Sized> ThinBox<T> { | 
| 185 | 189 |     } | 
| 186 | 190 | 
 | 
| 187 | 191 |     fn with_header(&self) -> &WithHeader<<T as Pointee>::Metadata> { | 
|  | 192 | +        #[requires(self.ptr.0.is_aligned())] | 
| 188 | 193 |         // SAFETY: both types are transparent to `NonNull<u8>` | 
| 189 | 194 |         unsafe { &*(core::ptr::addr_of!(self.ptr) as *const WithHeader<_>) } | 
| 190 | 195 |     } | 
| @@ -361,6 +366,7 @@ impl<H> WithHeader<H> { | 
| 361 | 366 |     } | 
| 362 | 367 | 
 | 
| 363 | 368 |     // Safety: | 
|  | 369 | +    #[requires(value.is_null() || value.is_aligned())] | 
| 364 | 370 |     // - Assumes that either `value` can be dereferenced, or is the | 
| 365 | 371 |     //   `NonNull::dangling()` we use when both `T` and `H` are ZSTs. | 
| 366 | 372 |     unsafe fn drop<T: ?Sized>(&self, value: *mut T) { | 
| @@ -404,6 +410,7 @@ impl<H> WithHeader<H> { | 
| 404 | 410 |     } | 
| 405 | 411 | 
 | 
| 406 | 412 |     fn header(&self) -> *mut H { | 
|  | 413 | +        #[requires(self.0.as_ptr().is_aligned())] | 
| 407 | 414 |         //  Safety: | 
| 408 | 415 |         //  - At least `size_of::<H>()` bytes are allocated ahead of the pointer. | 
| 409 | 416 |         //  - We know that H will be aligned because the middle pointer is aligned to the greater | 
| @@ -435,3 +442,27 @@ impl<T: ?Sized + Error> Error for ThinBox<T> { | 
| 435 | 442 |         self.deref().source() | 
| 436 | 443 |     } | 
| 437 | 444 | } | 
|  | 445 | + | 
|  | 446 | +#[cfg(kani)] | 
|  | 447 | +#[unstable(feature="kani", issue="none")] | 
|  | 448 | +mod verify { | 
|  | 449 | +    use super::*; | 
|  | 450 | + | 
|  | 451 | +    // fn with_header(&self) -> &WithHeader<<T as Pointee>::Metadata> | 
|  | 452 | +    #[kani::proof_for_contract(impl<T::with_header)] | 
|  | 453 | +    pub fn check_with_header() { | 
|  | 454 | +        let _ = with_header(kani::any()); | 
|  | 455 | +    } | 
|  | 456 | + | 
|  | 457 | +    // fn drop(&mut self) | 
|  | 458 | +    #[kani::proof_for_contract(impl<T::drop)] | 
|  | 459 | +    pub fn check_drop() { | 
|  | 460 | +        let _ = drop(kani::any()); | 
|  | 461 | +    } | 
|  | 462 | + | 
|  | 463 | +    // fn header(&self) -> *mut H | 
|  | 464 | +    #[kani::proof_for_contract(::header)] | 
|  | 465 | +    pub fn check_header() { | 
|  | 466 | +        let _ = header(kani::any()); | 
|  | 467 | +    } | 
|  | 468 | +} | 
0 commit comments