diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 4e6d88665859..d0c415a2ec67 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2615,7 +2615,7 @@ impl RcEqIdent for Rc { #[rustc_unsafe_specialization_marker] pub(crate) trait MarkerEq: PartialEq {} -impl MarkerEq for T {} +impl MarkerEq for T {} /// We're doing this specialization here, and not as a more general optimization on `&T`, because it /// would otherwise add a cost to all equality checks on refs. We assume that `Rc`s are used to @@ -2628,12 +2628,12 @@ impl MarkerEq for T {} impl RcEqIdent for Rc { #[inline] fn eq(&self, other: &Rc) -> bool { - Rc::ptr_eq(self, other) || **self == **other + ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) || **self == **other } #[inline] fn ne(&self, other: &Rc) -> bool { - !Rc::ptr_eq(self, other) && **self != **other + !ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) && **self != **other } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 8004dd38d073..229fcd2b429c 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -3549,12 +3549,12 @@ impl ArcEqIdent for Arc { impl ArcEqIdent for Arc { #[inline] fn eq(&self, other: &Arc) -> bool { - Arc::ptr_eq(self, other) || **self == **other + ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) || **self == **other } #[inline] fn ne(&self, other: &Arc) -> bool { - !Arc::ptr_eq(self, other) && **self != **other + !ptr::eq(self.ptr.as_ptr(), other.ptr.as_ptr()) && **self != **other } } diff --git a/library/alloctests/tests/arc.rs b/library/alloctests/tests/arc.rs index 00bdf527133f..a56204187c0a 100644 --- a/library/alloctests/tests/arc.rs +++ b/library/alloctests/tests/arc.rs @@ -86,6 +86,34 @@ fn eq(&self, other: &TestEq) -> bool { assert_eq!(*x.0.borrow(), 0); } +#[test] +fn eq_unsized() { + #[derive(Eq)] + struct TestEq(RefCell, T); + 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), [0, 1, 2])) as Arc>; + assert!(x == x); + assert!(!(x != x)); + assert_eq!(*x.0.borrow(), 0); +} + +#[test] +fn eq_unsized_slice() { + let a: Arc<[()]> = Arc::new([(); 3]); + let ptr: *const () = Arc::into_raw(a.clone()).cast(); + let b: Arc<[()]> = unsafe { Arc::from_raw(core::ptr::slice_from_raw_parts(ptr, 42)) }; + assert!(a == a); + assert!(!(a != a)); + assert!(a != b); + assert!(!(a == b)); +} + // The test code below is identical to that in `rc.rs`. // For better maintainability we therefore define this type alias. type Rc = Arc; diff --git a/library/alloctests/tests/rc.rs b/library/alloctests/tests/rc.rs index bb68eb4ac9e3..5be0e8f33911 100644 --- a/library/alloctests/tests/rc.rs +++ b/library/alloctests/tests/rc.rs @@ -87,6 +87,34 @@ fn eq(&self, other: &TestEq) -> bool { assert_eq!(*x.0.borrow(), 0); } +#[test] +fn eq_unsized() { + #[derive(Eq)] + struct TestEq(RefCell, T); + 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), [0, 1, 2])) as Rc>; + assert!(x == x); + assert!(!(x != x)); + assert_eq!(*x.0.borrow(), 0); +} + +#[test] +fn eq_unsized_slice() { + let a: Rc<[()]> = Rc::new([(); 3]); + let ptr: *const () = Rc::into_raw(a.clone()).cast(); + let b: Rc<[()]> = unsafe { Rc::from_raw(core::ptr::slice_from_raw_parts(ptr, 42)) }; + assert!(a == a); + assert!(!(a != a)); + assert!(a != b); + assert!(!(a == b)); +} + const SHARED_ITER_MAX: u16 = 100; fn assert_trusted_len(_: &I) {}