|
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