about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorJo Liss <joliss42@gmail.com>2017-06-27 17:23:31 +0000
committerThomas Heck <t@b128.net>2018-12-08 13:30:54 +0100
commit2a916a617f6c6c62536a3b164f4b15ea58eaa148 (patch)
tree30f5354f47c10620b07eada34f83fd651d7cc0c7 /src/liballoc
parent9772d02774534aa4ccd0b328364403d5b6cda1d0 (diff)
downloadrust-2a916a617f6c6c62536a3b164f4b15ea58eaa148.tar.gz
rust-2a916a617f6c6c62536a3b164f4b15ea58eaa148.zip
Short-circuit Rc/Arc equality checking on equal pointers where T: Eq
Closes #42655
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/rc.rs25
-rw-r--r--src/liballoc/sync.rs26
2 files changed, 46 insertions, 5 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 52ad30c411a..85bde5f63ce 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(specialization)]
 #![allow(deprecated)]
 
 //! Single-threaded reference-counting pointers. 'Rc' stands for 'Reference
@@ -906,6 +907,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
     ///
     /// Two `Rc`s are equal if their inner values are equal.
     ///
+    /// If `T` also implements `Eq`, two `Rc`s that point to the same value are
+    /// always equal.
+    ///
     /// # Examples
     ///
     /// ```
@@ -916,7 +920,7 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
     /// assert!(five == Rc::new(5));
     /// ```
     #[inline(always)]
-    fn eq(&self, other: &Rc<T>) -> bool {
+    default fn eq(&self, other: &Rc<T>) -> bool {
         **self == **other
     }
 
@@ -924,6 +928,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
     ///
     /// Two `Rc`s are unequal if their inner values are unequal.
     ///
+    /// If `T` also implements `Eq`, two `Rc`s that point to the same value are
+    /// never unequal.
+    ///
     /// # Examples
     ///
     /// ```
@@ -934,11 +941,25 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
     /// assert!(five != Rc::new(6));
     /// ```
     #[inline(always)]
-    fn ne(&self, other: &Rc<T>) -> bool {
+    default fn ne(&self, other: &Rc<T>) -> bool {
         **self != **other
     }
 }
 
+#[doc(hidden)]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized + Eq> PartialEq for Rc<T> {
+    #[inline(always)]
+    fn eq(&self, other: &Rc<T>) -> bool {
+        Rc::ptr_eq(self, other) || **self == **other
+    }
+
+    #[inline(always)]
+    fn ne(&self, other: &Rc<T>) -> bool {
+        !Rc::ptr_eq(self, other) && **self != **other
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Eq> Eq for Rc<T> {}
 
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 111459d12a4..d6863238cd4 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(specialization)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
 //! Thread-safe reference-counting pointers.
@@ -1293,6 +1294,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
     ///
     /// Two `Arc`s are equal if their inner values are equal.
     ///
+    /// If `T` also implements `Eq`, two `Arc`s that point to the same value are
+    /// always equal.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1302,14 +1306,17 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
     ///
     /// assert!(five == Arc::new(5));
     /// ```
-    fn eq(&self, other: &Arc<T>) -> bool {
-        *(*self) == *(*other)
+    default fn eq(&self, other: &Arc<T>) -> bool {
+        **self == **other
     }
 
     /// Inequality for two `Arc`s.
     ///
     /// Two `Arc`s are unequal if their inner values are unequal.
     ///
+    /// If `T` also implements `Eq`, two `Arc`s that point to the same value are
+    /// never unequal.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1319,8 +1326,21 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
     ///
     /// assert!(five != Arc::new(6));
     /// ```
+    default fn ne(&self, other: &Arc<T>) -> bool {
+        **self != **other
+    }
+}
+#[doc(hidden)]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized + Eq> PartialEq for Arc<T> {
+    #[inline(always)]
+    fn eq(&self, other: &Arc<T>) -> bool {
+        Arc::ptr_eq(self, other) || **self == **other
+    }
+
+    #[inline(always)]
     fn ne(&self, other: &Arc<T>) -> bool {
-        *(*self) != *(*other)
+        !Arc::ptr_eq(self, other) && **self != **other
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]