From 6276dbd9533e05bd577f408047ea1d0e97293217 Mon Sep 17 00:00:00 2001 From: Lance Roy Date: Sun, 3 Sep 2017 23:27:20 -0700 Subject: [PATCH 1/2] Derive std::mem::ManuallyDrop from Clone and Copy. Although types that don't implement Drop can't be Copyable, this can still be useful when ManuallyDrop is used inside a generic type. This doesn't derive from Copy as that would require T: Copy + Clone, instead it provides an impl of Clone for T: Clone. --- src/libcore/mem.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index a57d8355289..4cc0a5e49d9 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -821,6 +821,7 @@ pub fn discriminant(v: &T) -> Discriminant { /// ``` #[stable(feature = "manually_drop", since = "1.20.0")] #[allow(unions_with_drop_fields)] +#[derive(Copy)] pub union ManuallyDrop{ value: T } impl ManuallyDrop { @@ -899,6 +900,19 @@ impl ::fmt::Debug for ManuallyDrop { } } +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Clone for ManuallyDrop { + fn clone(&self) -> Self { + use ::ops::Deref; + ManuallyDrop::new(self.deref().clone()) + } + + fn clone_from(&mut self, source: &Self) { + use ::ops::DerefMut; + self.deref_mut().clone_from(source); + } +} + /// Tells LLVM that this point in the code is not reachable, enabling further /// optimizations. /// From 94301c405c5382c482a4bc5fc2561257418f9323 Mon Sep 17 00:00:00 2001 From: Lance Roy Date: Mon, 4 Sep 2017 02:29:16 -0700 Subject: [PATCH 2/2] Additional traits for std::mem::ManuallyDrop Add pass-through implementations for all of the derivable traits. These cannot be derived since ManuallyDrop is a union. --- src/libcore/mem.rs | 65 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 4cc0a5e49d9..af2f876a2f3 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -22,6 +22,7 @@ use hash; use intrinsics; use marker::{Copy, PhantomData, Sized}; use ptr; +use ops::{Deref, DerefMut}; #[stable(feature = "rust1", since = "1.0.0")] pub use intrinsics::transmute; @@ -871,7 +872,7 @@ impl ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -impl ::ops::Deref for ManuallyDrop { +impl Deref for ManuallyDrop { type Target = T; #[inline] fn deref(&self) -> &Self::Target { @@ -882,7 +883,7 @@ impl ::ops::Deref for ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -impl ::ops::DerefMut for ManuallyDrop { +impl DerefMut for ManuallyDrop { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { unsafe { @@ -903,16 +904,72 @@ impl ::fmt::Debug for ManuallyDrop { #[stable(feature = "manually_drop", since = "1.20.0")] impl Clone for ManuallyDrop { fn clone(&self) -> Self { - use ::ops::Deref; ManuallyDrop::new(self.deref().clone()) } fn clone_from(&mut self, source: &Self) { - use ::ops::DerefMut; self.deref_mut().clone_from(source); } } +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Default for ManuallyDrop { + fn default() -> Self { + ManuallyDrop::new(Default::default()) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialEq for ManuallyDrop { + fn eq(&self, other: &Self) -> bool { + self.deref().eq(other) + } + + fn ne(&self, other: &Self) -> bool { + self.deref().ne(other) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Eq for ManuallyDrop {} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl PartialOrd for ManuallyDrop { + fn partial_cmp(&self, other: &Self) -> Option<::cmp::Ordering> { + self.deref().partial_cmp(other) + } + + fn lt(&self, other: &Self) -> bool { + self.deref().lt(other) + } + + fn le(&self, other: &Self) -> bool { + self.deref().le(other) + } + + fn gt(&self, other: &Self) -> bool { + self.deref().gt(other) + } + + fn ge(&self, other: &Self) -> bool { + self.deref().ge(other) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl Ord for ManuallyDrop { + fn cmp(&self, other: &Self) -> ::cmp::Ordering { + self.deref().cmp(other) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl ::hash::Hash for ManuallyDrop { + fn hash(&self, state: &mut H) { + self.deref().hash(state); + } +} + /// Tells LLVM that this point in the code is not reachable, enabling further /// optimizations. ///