Skip to content

Commit d1acabe

Browse files
authored
Auto merge of rust-lang#35992 - SimonSapin:rc-arc-ptr-eq, r=alexcrichton
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.
2 parents dc75933 + 5ce9fee commit d1acabe

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

src/liballoc/arc.rs

+37
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,33 @@ impl<T: ?Sized> Arc<T> {
331331
deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr))
332332
}
333333
}
334+
335+
#[inline]
336+
#[unstable(feature = "ptr_eq",
337+
reason = "newly added",
338+
issue = "36497")]
339+
/// Return whether two `Arc` references point to the same value
340+
/// (not just values that compare equal).
341+
///
342+
/// # Examples
343+
///
344+
/// ```
345+
/// #![feature(ptr_eq)]
346+
///
347+
/// use std::sync::Arc;
348+
///
349+
/// let five = Arc::new(5);
350+
/// let same_five = five.clone();
351+
/// let other_five = Arc::new(5);
352+
///
353+
/// assert!(Arc::ptr_eq(&five, &same_five));
354+
/// assert!(!Arc::ptr_eq(&five, &other_five));
355+
/// ```
356+
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
357+
let this_ptr: *const ArcInner<T> = *this.ptr;
358+
let other_ptr: *const ArcInner<T> = *other.ptr;
359+
this_ptr == other_ptr
360+
}
334361
}
335362

336363
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1200,6 +1227,16 @@ mod tests {
12001227
let foo: Weak<usize> = Weak::new();
12011228
assert!(foo.upgrade().is_none());
12021229
}
1230+
1231+
#[test]
1232+
fn test_ptr_eq() {
1233+
let five = Arc::new(5);
1234+
let same_five = five.clone();
1235+
let other_five = Arc::new(5);
1236+
1237+
assert!(Arc::ptr_eq(&five, &same_five));
1238+
assert!(!Arc::ptr_eq(&five, &other_five));
1239+
}
12031240
}
12041241

12051242
#[stable(feature = "rust1", since = "1.0.0")]

src/liballoc/rc.rs

+37
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,33 @@ impl<T: ?Sized> Rc<T> {
376376
None
377377
}
378378
}
379+
380+
#[inline]
381+
#[unstable(feature = "ptr_eq",
382+
reason = "newly added",
383+
issue = "36497")]
384+
/// Return whether two `Rc` references point to the same value
385+
/// (not just values that compare equal).
386+
///
387+
/// # Examples
388+
///
389+
/// ```
390+
/// #![feature(ptr_eq)]
391+
///
392+
/// use std::rc::Rc;
393+
///
394+
/// let five = Rc::new(5);
395+
/// let same_five = five.clone();
396+
/// let other_five = Rc::new(5);
397+
///
398+
/// assert!(Rc::ptr_eq(&five, &same_five));
399+
/// assert!(!Rc::ptr_eq(&five, &other_five));
400+
/// ```
401+
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
402+
let this_ptr: *const RcBox<T> = *this.ptr;
403+
let other_ptr: *const RcBox<T> = *other.ptr;
404+
this_ptr == other_ptr
405+
}
379406
}
380407

381408
impl<T: Clone> Rc<T> {
@@ -1174,6 +1201,16 @@ mod tests {
11741201
let foo: Weak<usize> = Weak::new();
11751202
assert!(foo.upgrade().is_none());
11761203
}
1204+
1205+
#[test]
1206+
fn test_ptr_eq() {
1207+
let five = Rc::new(5);
1208+
let same_five = five.clone();
1209+
let other_five = Rc::new(5);
1210+
1211+
assert!(Rc::ptr_eq(&five, &same_five));
1212+
assert!(!Rc::ptr_eq(&five, &other_five));
1213+
}
11771214
}
11781215

11791216
#[stable(feature = "rust1", since = "1.0.0")]

src/libcore/ptr.rs

+34
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,40 @@ impl<T: ?Sized> PartialEq for *mut T {
479479
#[stable(feature = "rust1", since = "1.0.0")]
480480
impl<T: ?Sized> Eq for *mut T {}
481481

482+
/// Compare raw pointers for equality.
483+
///
484+
/// This is the same as using the `==` operator, but less generic:
485+
/// the arguments have to be `*const T` raw pointers,
486+
/// not anything that implements `PartialEq`.
487+
///
488+
/// This can be used to compare `&T` references (which coerce to `*const T` implicitly)
489+
/// by their address rather than comparing the values they point to
490+
/// (which is what the `PartialEq for &T` implementation does).
491+
///
492+
/// # Examples
493+
///
494+
/// ```
495+
/// #![feature(ptr_eq)]
496+
/// use std::ptr;
497+
///
498+
/// let five = 5;
499+
/// let other_five = 5;
500+
/// let five_ref = &five;
501+
/// let same_five_ref = &five;
502+
/// let other_five_ref = &other_five;
503+
///
504+
/// assert!(five_ref == same_five_ref);
505+
/// assert!(five_ref == other_five_ref);
506+
///
507+
/// assert!(ptr::eq(five_ref, same_five_ref));
508+
/// assert!(!ptr::eq(five_ref, other_five_ref));
509+
/// ```
510+
#[unstable(feature = "ptr_eq", reason = "newly added", issue = "36497")]
511+
#[inline]
512+
pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
513+
a == b
514+
}
515+
482516
#[stable(feature = "rust1", since = "1.0.0")]
483517
impl<T: ?Sized> Clone for *const T {
484518
#[inline]

0 commit comments

Comments
 (0)