From eba2270a9cc1c0785cf42fa87fe154f425a2eea0 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 25 Aug 2016 18:43:40 +0200 Subject: [PATCH 1/2] Add `pub fn ptr_eq(this: &Self, other: &Self) -> bool` to `Rc` and `Arc`. Servo and Kuchiki have had helper functions doing this for some time. --- src/liballoc/arc.rs | 37 +++++++++++++++++++++++++++++++++++++ src/liballoc/rc.rs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 3d579641b96..5f9ccd1820c 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -331,6 +331,33 @@ unsafe fn drop_slow(&mut self) { deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr)) } } + + #[inline] + #[unstable(feature = "ptr_eq", + reason = "newly added", + issue = "36497")] + /// Return whether two `Arc` references point to the same value + /// (not just values that compare equal). + /// + /// # Examples + /// + /// ``` + /// #![feature(ptr_eq)] + /// + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// let same_five = five.clone(); + /// let other_five = Arc::new(5); + /// + /// assert!(Arc::ptr_eq(&five, &same_five)); + /// assert!(!Arc::ptr_eq(&five, &other_five)); + /// ``` + pub fn ptr_eq(this: &Self, other: &Self) -> bool { + let this_ptr: *const ArcInner = *this.ptr; + let other_ptr: *const ArcInner = *other.ptr; + this_ptr == other_ptr + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1200,6 +1227,16 @@ fn test_new_weak() { let foo: Weak = Weak::new(); assert!(foo.upgrade().is_none()); } + + #[test] + fn test_ptr_eq() { + let five = Arc::new(5); + let same_five = five.clone(); + let other_five = Arc::new(5); + + assert!(Arc::ptr_eq(&five, &same_five)); + assert!(!Arc::ptr_eq(&five, &other_five)); + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index dadddbc2cb3..32e5587ff41 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -376,6 +376,33 @@ pub fn get_mut(this: &mut Self) -> Option<&mut T> { None } } + + #[inline] + #[unstable(feature = "ptr_eq", + reason = "newly added", + issue = "36497")] + /// Return whether two `Rc` references point to the same value + /// (not just values that compare equal). + /// + /// # Examples + /// + /// ``` + /// #![feature(ptr_eq)] + /// + /// use std::rc::Rc; + /// + /// let five = Rc::new(5); + /// let same_five = five.clone(); + /// let other_five = Rc::new(5); + /// + /// assert!(Rc::ptr_eq(&five, &same_five)); + /// assert!(!Rc::ptr_eq(&five, &other_five)); + /// ``` + pub fn ptr_eq(this: &Self, other: &Self) -> bool { + let this_ptr: *const RcBox = *this.ptr; + let other_ptr: *const RcBox = *other.ptr; + this_ptr == other_ptr + } } impl Rc { @@ -1174,6 +1201,16 @@ fn test_new_weak() { let foo: Weak = Weak::new(); assert!(foo.upgrade().is_none()); } + + #[test] + fn test_ptr_eq() { + let five = Rc::new(5); + let same_five = five.clone(); + let other_five = Rc::new(5); + + assert!(Rc::ptr_eq(&five, &same_five)); + assert!(!Rc::ptr_eq(&five, &other_five)); + } } #[stable(feature = "rust1", since = "1.0.0")] From 5ce9feeb8cb48a89feffe579cfc1a9281b4dfbb0 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 15 Sep 2016 11:19:19 +0200 Subject: [PATCH 2/2] Add std::ptr::eq, for referential equality of &T references. Fixes https://github.com/rust-lang/rfcs/issues/1155 --- src/libcore/ptr.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 8c8925251e5..69682652a6a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -479,6 +479,40 @@ fn eq(&self, other: &*mut T) -> bool { *self == *other } #[stable(feature = "rust1", since = "1.0.0")] impl Eq for *mut T {} +/// Compare raw pointers for equality. +/// +/// This is the same as using the `==` operator, but less generic: +/// the arguments have to be `*const T` raw pointers, +/// not anything that implements `PartialEq`. +/// +/// This can be used to compare `&T` references (which coerce to `*const T` implicitly) +/// by their address rather than comparing the values they point to +/// (which is what the `PartialEq for &T` implementation does). +/// +/// # Examples +/// +/// ``` +/// #![feature(ptr_eq)] +/// use std::ptr; +/// +/// let five = 5; +/// let other_five = 5; +/// let five_ref = &five; +/// let same_five_ref = &five; +/// let other_five_ref = &other_five; +/// +/// assert!(five_ref == same_five_ref); +/// assert!(five_ref == other_five_ref); +/// +/// assert!(ptr::eq(five_ref, same_five_ref)); +/// assert!(!ptr::eq(five_ref, other_five_ref)); +/// ``` +#[unstable(feature = "ptr_eq", reason = "newly added", issue = "36497")] +#[inline] +pub fn eq(a: *const T, b: *const T) -> bool { + a == b +} + #[stable(feature = "rust1", since = "1.0.0")] impl Clone for *const T { #[inline]