Skip to content

Commit e1c598c

Browse files
committed
Cleanup contracts
1 parent 70a0fcc commit e1c598c

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

library/core/src/alloc/layout.rs

+27-13
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ impl Layout {
215215
#[unstable(feature = "layout_for_ptr", issue = "69835")]
216216
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
217217
#[must_use]
218+
// TODO: we should try to capture the above constraints on T in a `requires` clause, and the
219+
// metadata helpers from https://github.com/model-checking/verify-rust-std/pull/37 may be able
220+
// to accomplish this.
218221
#[ensures(|result| result.align().is_power_of_two())]
219222
pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
220223
// SAFETY: we pass along the prerequisites of these functions to the caller
@@ -345,13 +348,20 @@ impl Layout {
345348
/// On arithmetic overflow, returns `LayoutError`.
346349
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
347350
#[inline]
348-
// the below modulo operation might be too costly to prove
349-
#[cfg_attr(not(kani), ensures(|result| result.is_err() || n == 0 || result.as_ref().unwrap().0.size() % n == 0))]
350-
#[cfg_attr(kani, ensures(|result| result.is_err() || n == 0 || result.as_ref().unwrap().0.size() >= self.size()))]
351-
// the below multiplication might be too costly to prove at this time
352-
// #[ensures(|result| result.is_err() || result.as_ref().unwrap().0.size() == n * result.as_ref().unwrap().1)]
353-
// use the weaker statement below for now
354-
#[ensures(|result| result.is_err() || n == 0 || result.as_ref().unwrap().0.size() >= result.as_ref().unwrap().1)]
351+
// for Kani (v0.54.0), the below modulo operation is too costly to prove (running into the
352+
// 6-hours timeout on GitHub); we use a weaker postcondition instead
353+
#[cfg_attr(not(kani),
354+
ensures(|result| result.is_err() || n == 0 || result.as_ref().unwrap().0.size() % n == 0))]
355+
#[cfg_attr(kani,
356+
ensures(|result| result.is_err() || n == 0 || result.as_ref().unwrap().0.size() >= self.size()))]
357+
// for Kani (v0.54.0), the below multiplication is too costly to prove (running into the
358+
// 6-hours timeout on GitHub); we use a weaker postcondition instead
359+
#[cfg_attr(not(kani),
360+
ensures(|result| result.is_err() ||
361+
result.as_ref().unwrap().0.size() == n * result.as_ref().unwrap().1))]
362+
#[cfg_attr(kani,
363+
ensures(|result| result.is_err() || n == 0 ||
364+
result.as_ref().unwrap().0.size() >= result.as_ref().unwrap().1))]
355365
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
356366
// This cannot overflow. Quoting from the invariant of Layout:
357367
// > `size`, when rounded up to the nearest multiple of `align`,
@@ -442,10 +452,12 @@ impl Layout {
442452
/// On arithmetic overflow, returns `LayoutError`.
443453
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
444454
#[inline]
445-
// the below multiplication might be too costly to prove at this time
446-
// #[ensures(|result| result.is_err() || result.as_ref().unwrap().size() == n * self.size())]
447-
// use the weaker statement below for now
448-
#[ensures(|result| result.is_err() || n == 0 || result.as_ref().unwrap().size() >= self.size())]
455+
// for Kani (v0.54.0), the below multiplication is too costly to prove (running into the
456+
// 6-hours timeout on GitHub); we use a weaker postcondition instead
457+
#[cfg_attr(not(kani),
458+
ensures(|result| result.is_err() || result.as_ref().unwrap().size() == n * self.size()))]
459+
#[cfg_attr(kani,
460+
ensures(|result| result.is_err() || n == 0 || result.as_ref().unwrap().size() >= self.size()))]
449461
#[ensures(|result| result.is_err() || result.as_ref().unwrap().align() == self.align())]
450462
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
451463
let size = self.size().checked_mul(n).ok_or(LayoutError)?;
@@ -602,7 +614,8 @@ mod verify {
602614
let _ = Layout::for_value::<i32>(&x);
603615
let array : [i32; 2] = [1, 2];
604616
let _ = Layout::for_value::<[i32]>(&array[1 .. 1]);
605-
// TODO: the case of a trait object as unsized tail is not yet covered
617+
let trait_ref: &dyn core::fmt::Debug = &x;
618+
let _ = Layout::for_value::<dyn core::fmt::Debug>(trait_ref);
606619
// TODO: the case of an extern type as unsized tail is not yet covered
607620
}
608621

@@ -613,7 +626,8 @@ mod verify {
613626
let x = kani::any::<i32>();
614627
let _ = Layout::for_value_raw::<i32>(&x as *const i32);
615628
let _ = Layout::for_value_raw::<[i32]>(&[] as *const [i32]);
616-
// TODO: the case of a trait object as unsized tail is not yet covered
629+
let trait_ref: &dyn core::fmt::Debug = &x;
630+
let _ = Layout::for_value_raw::<dyn core::fmt::Debug>(trait_ref);
617631
// TODO: the case of an extern type as unsized tail is not yet covered
618632
}
619633
}

0 commit comments

Comments
 (0)