Skip to content

Commit 9c81d9c

Browse files
committed
Some fixes + trying to clean up the metadata stuff
1 parent a38c161 commit 9c81d9c

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

library/core/src/intrinsics.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3323,7 +3323,7 @@ pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *cons
33233323
&& ub_checks::can_dereference(core::ptr::slice_from_raw_parts(src as *const crate::mem::MaybeUninit<T>, count))
33243324
&& ub_checks::can_write(core::ptr::slice_from_raw_parts_mut(dst, count))
33253325
&& ub_checks::is_nonoverlapping(src as *const (), dst as *const (), size_of::<T>(), count))]
3326-
#[ensures(|_| { check_copy_untyped(src, dst, count)}) ]
3326+
#[ensures(|_| { check_copy_untyped(src, dst, count)})]
33273327
#[cfg_attr(kani, kani::modifies(crate::ptr::slice_from_raw_parts(dst, count)))]
33283328
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
33293329
extern "rust-intrinsic" {
@@ -3427,7 +3427,6 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
34273427
#[inline(always)]
34283428
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
34293429
#[rustc_diagnostic_item = "ptr_copy"]
3430-
// FIXME(kani): How to verify safety for types that do not implement Copy and count > 1??
34313430
#[requires(!count.overflowing_mul(size_of::<T>()).1
34323431
&& ub_checks::can_dereference(core::ptr::slice_from_raw_parts(src as *const crate::mem::MaybeUninit<T>, count))
34333432
&& ub_checks::can_write(core::ptr::slice_from_raw_parts_mut(dst, count)))]
@@ -3543,10 +3542,14 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
35433542
}
35443543
}
35453544

3546-
// Ensures the initialization state is preserved.
3547-
// This is used for contracts only.
3545+
/// Return whether the initialization state is preserved.
3546+
///
3547+
/// This is used for contracts only.
3548+
/// FIXME: Change this once we add support to quantifiers.
35483549
#[allow(dead_code)]
3550+
#[allow(unused_variables)]
35493551
fn check_copy_untyped<T>(src: *const T, dst: *mut T, count: usize) -> bool {
3552+
#[cfg(kani)]
35503553
if count > 0 {
35513554
let byte = kani::any_where(| sz: &usize | *sz < size_of::< T >());
35523555
let elem = kani::any_where(| val: &usize | *val < count);
@@ -3557,6 +3560,8 @@ fn check_copy_untyped<T>(src: *const T, dst: *mut T, count: usize) -> bool {
35573560
} else {
35583561
true
35593562
}
3563+
#[cfg(not(kani))]
3564+
false
35603565
}
35613566

35623567
/// Inform Miri that a given pointer definitely has a certain alignment.
@@ -3706,7 +3711,7 @@ mod verify {
37063711
let mut generator = PointerGenerator::<char, 10>::new();
37073712
let src = generator.generate_ptr();
37083713
let dst = if kani::any() {
3709-
generator.generate_ptr();
3714+
generator.generate_ptr()
37103715
} else {
37113716
PointerGenerator::<char, 10>::new().generate_ptr()
37123717
};
@@ -3720,9 +3725,9 @@ mod verify {
37203725
fn check_copy_nonoverlapping() {
37213726
let mut generator = PointerGenerator::<char, 10>::new();
37223727
let src = generator.generate_ptr();
3723-
// Destination may or may not have the same precedence as src.
3728+
// Destination may or may not have the same provenance as src.
37243729
let dst = if kani::any() {
3725-
generator.generate_ptr();
3730+
generator.generate_ptr()
37263731
} else {
37273732
PointerGenerator::<char, 10>::new().generate_ptr()
37283733
};

library/core/src/ub_checks.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ pub(crate) const fn is_nonoverlapping(
164164

165165
pub use predicates::*;
166166

167-
pub trait MetadataPredicates<T> where T: ?Sized {
167+
/// Trait that allow us to inspect metadata independently on the type `T`.
168+
pub trait MetadataExt<T, M> where T: core::ptr::Pointee<Metadata=M> + ?Sized {
168169
/// If the metadata is the length of a slice or str, run the map function.
169-
fn map_len<U, F>(metadata: *const Self, map: F) -> Option<U>
170+
unsafe fn map_len<U, F>(ptr: *const T, map: F) -> Option<U>
170171
where
171172
F: Fn(*const usize) -> U;
172173

@@ -176,61 +177,62 @@ pub trait MetadataPredicates<T> where T: ?Sized {
176177
F: Fn(*const crate::ptr::DynMetadata<T>) -> U;
177178
}
178179

179-
impl<T> MetadataPredicates<T> for () {
180+
/// Sized types will have a metadata of type `()`.
181+
impl<T> MetadataExt<T> for () {
180182
/// Return None.
181-
fn map_len<U, F>(_metadata: *const Self, _map: F) -> Option<U>
183+
fn map_len<U, F>(&self, map: F) -> Option<U>
182184
where
183185
F: Fn(*const usize) -> U,
184186
{
185187
None
186188
}
187189

188190
/// Return None.
189-
fn map_dyn<U, F>(_metadata: *const Self, _map: F) -> Option<U>
191+
fn map_dyn<U, F>(&self, map: F) -> Option<U>
190192
where
191193
F: Fn(*const crate::ptr::DynMetadata<T>) -> U,
192194
{
193195
None
194196
}
195197
}
196198

197-
impl<T> MetadataPredicates<T> for usize
198-
where
199-
T: ?Sized
199+
/// Slices and string slices will have metadata of type `usize`.
200+
impl<T> MetadataExt<T> for usize
200201
{
201202
/// Return the result of the map function.
202-
fn map_len<U, F>(metadata: *const Self, map: F) -> Option<U>
203+
fn map_len<U, F>(&self, map: F) -> Option<U>
203204
where
204-
F: Fn(*const usize) -> U,
205+
F: Fn(usize) -> U,
205206
{
206207
Some(map(metadata))
207208
}
208209

209210
/// This is not a DynMetadata. Return `None`.
210-
fn map_dyn<U, F>(_metadata: *const Self, _map: F) -> Option<U>
211+
fn map_dyn<U, F>(&self, map: F) -> Option<U>
211212
where
212-
F: Fn(*const crate::ptr::DynMetadata<T>) -> U
213+
F: Fn(crate::ptr::DynMetadata<T>) -> U,
213214
{
214215
None
215216
}
216217
}
217218

218-
impl<T> MetadataPredicates<T> for crate::ptr::DynMetadata<T>
219+
#[cfg(kani)]
220+
impl<T> MetadataExt<T> for crate::ptr::DynMetadata<T>
219221
where
220222
T: ?Sized
221223
{
222224
/// Not a length. Return None.
223-
fn map_len<U, F>(_metadata: *const Self, _map: F) -> Option<U>
225+
fn map_len<U, F>(&self, map: F) -> Option<U>
224226
where
225-
F: Fn(*const usize) -> U,
227+
F: Fn(usize) -> U,
226228
{
227229
None
228230
}
229231

230232
/// Return the result of the map function.
231-
fn map_dyn<U, F>(metadata: *const Self, map: F) -> Option<U>
233+
fn map_dyn<U, F>(&self, map: F) -> Option<U>
232234
where
233-
F: Fn(*const crate::ptr::DynMetadata<T>) -> U,
235+
F: Fn(crate::ptr::DynMetadata<T>) -> U,
234236
{
235237
Some(map(metadata))
236238
}

0 commit comments

Comments
 (0)