Skip to content

Commit 2ee5aed

Browse files
committed
Short-circuit Rc/Arc equality checking on equal pointers where T: Eq
Closes #42655
1 parent 7acce37 commit 2ee5aed

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/liballoc/arc.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(specialization)]
1112
#![stable(feature = "rust1", since = "1.0.0")]
1213

1314
//! Thread-safe reference-counting pointers.
@@ -1018,6 +1019,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
10181019
///
10191020
/// Two `Arc`s are equal if their inner values are equal.
10201021
///
1022+
/// If `T` also implements `Eq`, two `Arc`s that point to the same value are
1023+
/// always equal.
1024+
///
10211025
/// # Examples
10221026
///
10231027
/// ```
@@ -1027,14 +1031,17 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
10271031
///
10281032
/// assert!(five == Arc::new(5));
10291033
/// ```
1030-
fn eq(&self, other: &Arc<T>) -> bool {
1034+
default fn eq(&self, other: &Arc<T>) -> bool {
10311035
*(*self) == *(*other)
10321036
}
10331037

10341038
/// Inequality for two `Arc`s.
10351039
///
10361040
/// Two `Arc`s are unequal if their inner values are unequal.
10371041
///
1042+
/// If `T` also implements `Eq`, two `Arc`s that point to the same value are
1043+
/// never unequal.
1044+
///
10381045
/// # Examples
10391046
///
10401047
/// ```
@@ -1044,10 +1051,23 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
10441051
///
10451052
/// assert!(five != Arc::new(6));
10461053
/// ```
1047-
fn ne(&self, other: &Arc<T>) -> bool {
1054+
default fn ne(&self, other: &Arc<T>) -> bool {
10481055
*(*self) != *(*other)
10491056
}
10501057
}
1058+
#[doc(hidden)]
1059+
#[stable(feature = "rust1", since = "1.0.0")]
1060+
impl<T: ?Sized + Eq> PartialEq for Arc<T> {
1061+
#[inline(always)]
1062+
fn eq(&self, other: &Arc<T>) -> bool {
1063+
Arc::ptr_eq(self, other) || *(*self) == *(*other)
1064+
}
1065+
1066+
#[inline(always)]
1067+
fn ne(&self, other: &Arc<T>) -> bool {
1068+
!Arc::ptr_eq(self, other) && *(*self) != *(*other)
1069+
}
1070+
}
10511071
#[stable(feature = "rust1", since = "1.0.0")]
10521072
impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
10531073
/// Partial comparison for two `Arc`s.

src/liballoc/rc.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(specialization)]
1112
#![allow(deprecated)]
1213

1314
//! Single-threaded reference-counting pointers. 'Rc' stands for 'Reference
@@ -773,6 +774,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
773774
///
774775
/// Two `Rc`s are equal if their inner values are equal.
775776
///
777+
/// If `T` also implements `Eq`, two `Rc`s that point to the same value are
778+
/// always equal.
779+
///
776780
/// # Examples
777781
///
778782
/// ```
@@ -783,14 +787,17 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
783787
/// assert!(five == Rc::new(5));
784788
/// ```
785789
#[inline(always)]
786-
fn eq(&self, other: &Rc<T>) -> bool {
790+
default fn eq(&self, other: &Rc<T>) -> bool {
787791
**self == **other
788792
}
789793

790794
/// Inequality for two `Rc`s.
791795
///
792796
/// Two `Rc`s are unequal if their inner values are unequal.
793797
///
798+
/// If `T` also implements `Eq`, two `Rc`s that point to the same value are
799+
/// never unequal.
800+
///
794801
/// # Examples
795802
///
796803
/// ```
@@ -801,11 +808,25 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
801808
/// assert!(five != Rc::new(6));
802809
/// ```
803810
#[inline(always)]
804-
fn ne(&self, other: &Rc<T>) -> bool {
811+
default fn ne(&self, other: &Rc<T>) -> bool {
805812
**self != **other
806813
}
807814
}
808815

816+
#[doc(hidden)]
817+
#[stable(feature = "rust1", since = "1.0.0")]
818+
impl<T: ?Sized + Eq> PartialEq for Rc<T> {
819+
#[inline(always)]
820+
fn eq(&self, other: &Rc<T>) -> bool {
821+
Rc::ptr_eq(self, other) || **self == **other
822+
}
823+
824+
#[inline(always)]
825+
fn ne(&self, other: &Rc<T>) -> bool {
826+
!Rc::ptr_eq(self, other) && **self != **other
827+
}
828+
}
829+
809830
#[stable(feature = "rust1", since = "1.0.0")]
810831
impl<T: ?Sized + Eq> Eq for Rc<T> {}
811832

0 commit comments

Comments
 (0)