Skip to content

Commit 2a916a6

Browse files
jolisschpio
authored andcommitted
Short-circuit Rc/Arc equality checking on equal pointers where T: Eq
Closes #42655
1 parent 9772d02 commit 2a916a6

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

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
@@ -906,6 +907,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
906907
///
907908
/// Two `Rc`s are equal if their inner values are equal.
908909
///
910+
/// If `T` also implements `Eq`, two `Rc`s that point to the same value are
911+
/// always equal.
912+
///
909913
/// # Examples
910914
///
911915
/// ```
@@ -916,14 +920,17 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
916920
/// assert!(five == Rc::new(5));
917921
/// ```
918922
#[inline(always)]
919-
fn eq(&self, other: &Rc<T>) -> bool {
923+
default fn eq(&self, other: &Rc<T>) -> bool {
920924
**self == **other
921925
}
922926

923927
/// Inequality for two `Rc`s.
924928
///
925929
/// Two `Rc`s are unequal if their inner values are unequal.
926930
///
931+
/// If `T` also implements `Eq`, two `Rc`s that point to the same value are
932+
/// never unequal.
933+
///
927934
/// # Examples
928935
///
929936
/// ```
@@ -934,11 +941,25 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
934941
/// assert!(five != Rc::new(6));
935942
/// ```
936943
#[inline(always)]
937-
fn ne(&self, other: &Rc<T>) -> bool {
944+
default fn ne(&self, other: &Rc<T>) -> bool {
938945
**self != **other
939946
}
940947
}
941948

949+
#[doc(hidden)]
950+
#[stable(feature = "rust1", since = "1.0.0")]
951+
impl<T: ?Sized + Eq> PartialEq for Rc<T> {
952+
#[inline(always)]
953+
fn eq(&self, other: &Rc<T>) -> bool {
954+
Rc::ptr_eq(self, other) || **self == **other
955+
}
956+
957+
#[inline(always)]
958+
fn ne(&self, other: &Rc<T>) -> bool {
959+
!Rc::ptr_eq(self, other) && **self != **other
960+
}
961+
}
962+
942963
#[stable(feature = "rust1", since = "1.0.0")]
943964
impl<T: ?Sized + Eq> Eq for Rc<T> {}
944965

src/liballoc/sync.rs

Lines changed: 23 additions & 3 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.
@@ -1293,6 +1294,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
12931294
///
12941295
/// Two `Arc`s are equal if their inner values are equal.
12951296
///
1297+
/// If `T` also implements `Eq`, two `Arc`s that point to the same value are
1298+
/// always equal.
1299+
///
12961300
/// # Examples
12971301
///
12981302
/// ```
@@ -1302,14 +1306,17 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
13021306
///
13031307
/// assert!(five == Arc::new(5));
13041308
/// ```
1305-
fn eq(&self, other: &Arc<T>) -> bool {
1306-
*(*self) == *(*other)
1309+
default fn eq(&self, other: &Arc<T>) -> bool {
1310+
**self == **other
13071311
}
13081312

13091313
/// Inequality for two `Arc`s.
13101314
///
13111315
/// Two `Arc`s are unequal if their inner values are unequal.
13121316
///
1317+
/// If `T` also implements `Eq`, two `Arc`s that point to the same value are
1318+
/// never unequal.
1319+
///
13131320
/// # Examples
13141321
///
13151322
/// ```
@@ -1319,8 +1326,21 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
13191326
///
13201327
/// assert!(five != Arc::new(6));
13211328
/// ```
1329+
default fn ne(&self, other: &Arc<T>) -> bool {
1330+
**self != **other
1331+
}
1332+
}
1333+
#[doc(hidden)]
1334+
#[stable(feature = "rust1", since = "1.0.0")]
1335+
impl<T: ?Sized + Eq> PartialEq for Arc<T> {
1336+
#[inline(always)]
1337+
fn eq(&self, other: &Arc<T>) -> bool {
1338+
Arc::ptr_eq(self, other) || **self == **other
1339+
}
1340+
1341+
#[inline(always)]
13221342
fn ne(&self, other: &Arc<T>) -> bool {
1323-
*(*self) != *(*other)
1343+
!Arc::ptr_eq(self, other) && **self != **other
13241344
}
13251345
}
13261346
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)