|
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