about summary refs log tree commit diff
path: root/src/libcore/nonzero.rs
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2018-11-03 13:03:05 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2018-12-04 10:17:36 +0100
commit02b22323f129446c9e2255d0eeab6c7ab17aac52 (patch)
tree93ab14678f78998875c30fe591f048599b5ea5b5 /src/libcore/nonzero.rs
parentcc3470ce3b0ef74eab0f46d865d4d6021911b284 (diff)
downloadrust-02b22323f129446c9e2255d0eeab6c7ab17aac52.tar.gz
rust-02b22323f129446c9e2255d0eeab6c7ab17aac52.zip
Make sure the initialization of constrained int range newtypes is unsafe
Diffstat (limited to 'src/libcore/nonzero.rs')
-rw-r--r--src/libcore/nonzero.rs10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 436cd1fc057..22d93a5301e 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -15,10 +15,18 @@ use ops::{CoerceUnsized, DispatchFromDyn};
 /// A wrapper type for raw pointers and integers that will never be
 /// NULL or 0 that might allow certain optimizations.
 #[rustc_layout_scalar_valid_range_start(1)]
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
 #[repr(transparent)]
 pub(crate) struct NonZero<T>(pub(crate) T);
 
+// Do not call `T::clone` as theoretically it could turn the field into `0`
+// invalidating `NonZero`'s invariant.
+impl<T: Copy> Clone for NonZero<T> {
+    fn clone(&self) -> Self {
+        unsafe { NonZero(self.0) }
+    }
+}
+
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {}
 
 impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<NonZero<U>> for NonZero<T> {}