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