|
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