Auto merge of #56550 - chpio:rc-eq, r=alexcrichton
Short-circuit Rc/Arc equality checking on equal pointers where T: Eq based on #42965 Is the use of the private trait ok this way? Is there anything else needed for this to get pulled?
This commit is contained in:
commit
74ebf026fe
@ -900,12 +900,47 @@ impl<T: Default> Default for Rc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
trait RcEqIdent<T: ?Sized + PartialEq> {
|
||||
fn eq(&self, other: &Rc<T>) -> bool;
|
||||
fn ne(&self, other: &Rc<T>) -> bool;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + PartialEq> RcEqIdent<T> for Rc<T> {
|
||||
#[inline]
|
||||
default fn eq(&self, other: &Rc<T>) -> bool {
|
||||
**self == **other
|
||||
}
|
||||
|
||||
#[inline]
|
||||
default fn ne(&self, other: &Rc<T>) -> bool {
|
||||
**self != **other
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + Eq> RcEqIdent<T> for Rc<T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Rc<T>) -> bool {
|
||||
Rc::ptr_eq(self, other) || **self == **other
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ne(&self, other: &Rc<T>) -> bool {
|
||||
!Rc::ptr_eq(self, other) && **self != **other
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
|
||||
/// Equality for two `Rc`s.
|
||||
///
|
||||
/// 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
|
||||
///
|
||||
/// ```
|
||||
@ -915,15 +950,18 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
|
||||
///
|
||||
/// assert!(five == Rc::new(5));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
fn eq(&self, other: &Rc<T>) -> bool {
|
||||
**self == **other
|
||||
RcEqIdent::eq(self, other)
|
||||
}
|
||||
|
||||
/// Inequality for two `Rc`s.
|
||||
///
|
||||
/// 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
|
||||
///
|
||||
/// ```
|
||||
@ -933,9 +971,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
|
||||
///
|
||||
/// assert!(five != Rc::new(6));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
fn ne(&self, other: &Rc<T>) -> bool {
|
||||
**self != **other
|
||||
RcEqIdent::ne(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1287,12 +1287,46 @@ impl<T: ?Sized> Drop for Weak<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
trait ArcEqIdent<T: ?Sized + PartialEq> {
|
||||
fn eq(&self, other: &Arc<T>) -> bool;
|
||||
fn ne(&self, other: &Arc<T>) -> bool;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + PartialEq> ArcEqIdent<T> for Arc<T> {
|
||||
#[inline]
|
||||
default fn eq(&self, other: &Arc<T>) -> bool {
|
||||
**self == **other
|
||||
}
|
||||
#[inline]
|
||||
default fn ne(&self, other: &Arc<T>) -> bool {
|
||||
**self != **other
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + Eq> ArcEqIdent<T> for Arc<T> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Arc<T>) -> bool {
|
||||
Arc::ptr_eq(self, other) || **self == **other
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ne(&self, other: &Arc<T>) -> bool {
|
||||
!Arc::ptr_eq(self, other) && **self != **other
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
|
||||
/// Equality for two `Arc`s.
|
||||
///
|
||||
/// 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 +1336,18 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
|
||||
///
|
||||
/// assert!(five == Arc::new(5));
|
||||
/// ```
|
||||
#[inline]
|
||||
fn eq(&self, other: &Arc<T>) -> bool {
|
||||
*(*self) == *(*other)
|
||||
ArcEqIdent::eq(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,10 +1357,12 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
|
||||
///
|
||||
/// assert!(five != Arc::new(6));
|
||||
/// ```
|
||||
#[inline]
|
||||
fn ne(&self, other: &Arc<T>) -> bool {
|
||||
*(*self) != *(*other)
|
||||
ArcEqIdent::ne(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
|
||||
/// Partial comparison for two `Arc`s.
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
use std::any::Any;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::PartialEq;
|
||||
|
||||
#[test]
|
||||
fn uninhabited() {
|
||||
@ -53,3 +55,43 @@ fn trait_object() {
|
||||
b = b.clone();
|
||||
assert!(b.upgrade().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn float_nan_ne() {
|
||||
let x = Arc::new(std::f32::NAN);
|
||||
assert!(x != x);
|
||||
assert!(!(x == x));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partial_eq() {
|
||||
struct TestPEq (RefCell<usize>);
|
||||
impl PartialEq for TestPEq {
|
||||
fn eq(&self, other: &TestPEq) -> bool {
|
||||
*self.0.borrow_mut() += 1;
|
||||
*other.0.borrow_mut() += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
let x = Arc::new(TestPEq(RefCell::new(0)));
|
||||
assert!(x == x);
|
||||
assert!(!(x != x));
|
||||
assert_eq!(*x.0.borrow(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eq() {
|
||||
#[derive(Eq)]
|
||||
struct TestEq (RefCell<usize>);
|
||||
impl PartialEq for TestEq {
|
||||
fn eq(&self, other: &TestEq) -> bool {
|
||||
*self.0.borrow_mut() += 1;
|
||||
*other.0.borrow_mut() += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
let x = Arc::new(TestEq(RefCell::new(0)));
|
||||
assert!(x == x);
|
||||
assert!(!(x != x));
|
||||
assert_eq!(*x.0.borrow(), 0);
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
use std::any::Any;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::PartialEq;
|
||||
|
||||
#[test]
|
||||
fn uninhabited() {
|
||||
@ -53,3 +55,43 @@ fn trait_object() {
|
||||
b = b.clone();
|
||||
assert!(b.upgrade().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn float_nan_ne() {
|
||||
let x = Rc::new(std::f32::NAN);
|
||||
assert!(x != x);
|
||||
assert!(!(x == x));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partial_eq() {
|
||||
struct TestPEq (RefCell<usize>);
|
||||
impl PartialEq for TestPEq {
|
||||
fn eq(&self, other: &TestPEq) -> bool {
|
||||
*self.0.borrow_mut() += 1;
|
||||
*other.0.borrow_mut() += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
let x = Rc::new(TestPEq(RefCell::new(0)));
|
||||
assert!(x == x);
|
||||
assert!(!(x != x));
|
||||
assert_eq!(*x.0.borrow(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eq() {
|
||||
#[derive(Eq)]
|
||||
struct TestEq (RefCell<usize>);
|
||||
impl PartialEq for TestEq {
|
||||
fn eq(&self, other: &TestEq) -> bool {
|
||||
*self.0.borrow_mut() += 1;
|
||||
*other.0.borrow_mut() += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
let x = Rc::new(TestEq(RefCell::new(0)));
|
||||
assert!(x == x);
|
||||
assert!(!(x != x));
|
||||
assert_eq!(*x.0.borrow(), 0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user