Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ where
let ptr = self as *mut Self;
ptr::drop_in_place(ptr);
ptr::write_bytes(ptr as *mut u8, 0, size);
hide_mem_impl::<Self>(ptr);

if !cfg!(miri) {
hide_mem_impl::<Self>(ptr);
}

Self::initialize(ptr);
}
}
Expand Down Expand Up @@ -135,7 +139,7 @@ macro_rules! array_impl_zerosafe {
}

// Implement for fixed-size arrays of ZeroSafe up to 64
array_impl_zerosafe!{
array_impl_zerosafe! {
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
Expand Down
63 changes: 40 additions & 23 deletions src/clear_on_drop.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::mem;
use core::mem::ManuallyDrop;
use core::ops::{Deref, DerefMut};
use core::ptr;
use core::{fmt, mem};

use crate::clear::Clear;

Expand Down Expand Up @@ -37,7 +37,7 @@ where
P: DerefMut,
P::Target: Clear,
{
_place: P,
_place: ManuallyDrop<P>,
}

impl<P> ClearOnDrop<P>
Expand All @@ -56,7 +56,9 @@ where
/// back, use `ClearOnDrop::into_place(...)` instead of a borrow.
#[inline]
pub fn new(place: P) -> Self {
ClearOnDrop { _place: place }
ClearOnDrop {
_place: ManuallyDrop::new(place),
}
}

/// Consumes the `ClearOnDrop`, returning the `place` after clearing.
Expand All @@ -78,11 +80,15 @@ where
/// `c.into_uncleared_place()`. This is so that there is no conflict
/// with a method on the inner type.
#[inline]
pub fn into_uncleared_place(c: Self) -> P {
pub fn into_uncleared_place(mut c: Self) -> P {
unsafe {
let place = ptr::read(&c._place);
mem::forget(c);
place
ptr::write_bytes(
&mut c._place as *mut _ as *mut u8,
0,
mem::size_of::<ManuallyDrop<P>>(),
);
ManuallyDrop::into_inner(place)
}
}
}
Expand Down Expand Up @@ -126,7 +132,7 @@ where

#[inline]
fn deref(&self) -> &Self::Target {
Deref::deref(&self._place)
Deref::deref(&self._place as &P)
}
}

Expand All @@ -137,7 +143,7 @@ where
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
DerefMut::deref_mut(&mut self._place)
DerefMut::deref_mut(&mut self._place as &mut P)
}
}

Expand All @@ -148,7 +154,16 @@ where
{
#[inline]
fn drop(&mut self) {
self.clear();
let ptr = &mut self._place as *mut _ as *mut u8;
unsafe {
if (0..mem::size_of::<ManuallyDrop<P>>() as isize)
.fold(0, |acc, i| acc + *ptr.offset(i) as i32)
!= 0
{
self.clear();
ManuallyDrop::drop(&mut self._place);
}
}
}
}

Expand All @@ -161,7 +176,7 @@ where
{
#[inline]
fn as_ref(&self) -> &T {
AsRef::as_ref(&self._place)
AsRef::as_ref(&self._place as &P)
}
}

Expand All @@ -172,7 +187,7 @@ where
{
#[inline]
fn as_mut(&mut self) -> &mut T {
AsMut::as_mut(&mut self._place)
AsMut::as_mut(&mut self._place as &mut P)
}
}

Expand All @@ -190,7 +205,7 @@ where
{
#[inline]
fn borrow(&self) -> &T {
Borrow::borrow(&self._place)
Borrow::borrow(&self._place as &P)
}
}

Expand All @@ -202,7 +217,7 @@ where
{
#[inline]
fn borrow_mut(&mut self) -> &mut T {
BorrowMut::borrow_mut(&mut self._place)
BorrowMut::borrow_mut(&mut self._place as &mut P)
}
}

Expand All @@ -215,7 +230,7 @@ where
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
Hash::hash(&self._place, state)
Hash::hash(&self._place as &P, state)
}
}

Expand All @@ -230,12 +245,12 @@ where
{
#[inline]
fn eq(&self, other: &ClearOnDrop<Q>) -> bool {
PartialEq::eq(&self._place, &other._place)
PartialEq::eq(&self._place as &P, &other._place as &Q)
}

#[inline]
fn ne(&self, other: &ClearOnDrop<Q>) -> bool {
PartialEq::ne(&self._place, &other._place)
PartialEq::ne(&self._place as &P, &other._place as &Q)
}
}

Expand All @@ -255,27 +270,27 @@ where
{
#[inline]
fn partial_cmp(&self, other: &ClearOnDrop<Q>) -> Option<Ordering> {
PartialOrd::partial_cmp(&self._place, &other._place)
PartialOrd::partial_cmp(&self._place as &P, &other._place as &Q)
}

#[inline]
fn lt(&self, other: &ClearOnDrop<Q>) -> bool {
PartialOrd::lt(&self._place, &other._place)
PartialOrd::lt(&self._place as &P, &other._place as &Q)
}

#[inline]
fn le(&self, other: &ClearOnDrop<Q>) -> bool {
PartialOrd::le(&self._place, &other._place)
PartialOrd::le(&self._place as &P, &other._place as &Q)
}

#[inline]
fn gt(&self, other: &ClearOnDrop<Q>) -> bool {
PartialOrd::gt(&self._place, &other._place)
PartialOrd::gt(&self._place as &P, &other._place as &Q)
}

#[inline]
fn ge(&self, other: &ClearOnDrop<Q>) -> bool {
PartialOrd::ge(&self._place, &other._place)
PartialOrd::ge(&self._place as &P, &other._place as &Q)
}
}

Expand All @@ -286,7 +301,7 @@ where
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&self._place, &other._place)
Ord::cmp(&self._place as &P, &other._place as &P)
}
}

Expand Down Expand Up @@ -320,6 +335,7 @@ mod tests {
assert_eq!(clear.data, DATA);
}

#[cfg(not(miri))]
#[test]
fn into_box() {
let place: Box<Place> = Box::new(Default::default());
Expand Down Expand Up @@ -389,6 +405,7 @@ mod tests {
assert_eq!(&clear[..], "test");
}

#[cfg(not(miri))]
#[test]
fn into_string() {
let place: String = "test".into();
Expand Down
1 change: 1 addition & 0 deletions src/hide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ mod impls {
}

#[cfg(test)]
#[cfg(not(miri))]
mod tests {
struct Place {
data: [u32; 4],
Expand Down