ptr::eq: clarify that comparing dyn Trait is fragile
This commit is contained in:
parent
a5406feb1c
commit
99a74afa5f
@ -1110,8 +1110,8 @@ pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
|
||||
|
||||
#[inline]
|
||||
#[stable(feature = "ptr_eq", since = "1.17.0")]
|
||||
/// Returns `true` if the two `Rc`s point to the same allocation
|
||||
/// (in a vein similar to [`ptr::eq`]).
|
||||
/// Returns `true` if the two `Rc`s point to the same allocation in a vein similar to
|
||||
/// [`ptr::eq`]. See [that function][`ptr::eq`] for caveats when comparing `dyn Trait` pointers.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -2419,9 +2419,9 @@ fn inner(&self) -> Option<WeakInner<'_>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the two `Weak`s point to the same allocation (similar to
|
||||
/// [`ptr::eq`]), or if both don't point to any allocation
|
||||
/// (because they were created with `Weak::new()`).
|
||||
/// Returns `true` if the two `Weak`s point to the same allocation similar to [`ptr::eq`], or if
|
||||
/// both don't point to any allocation (because they were created with `Weak::new()`). See [that
|
||||
/// function][`ptr::eq`] for caveats when comparing `dyn Trait` pointers.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
|
@ -1117,8 +1117,8 @@ unsafe fn drop_slow(&mut self) {
|
||||
drop(Weak { ptr: self.ptr });
|
||||
}
|
||||
|
||||
/// Returns `true` if the two `Arc`s point to the same allocation
|
||||
/// (in a vein similar to [`ptr::eq`]).
|
||||
/// Returns `true` if the two `Arc`s point to the same allocation in a vein similar to
|
||||
/// [`ptr::eq`]. See [that function][`ptr::eq`] for caveats when comparing `dyn Trait` pointers.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -2069,9 +2069,9 @@ fn inner(&self) -> Option<WeakInner<'_>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the two `Weak`s point to the same allocation (similar to
|
||||
/// [`ptr::eq`]), or if both don't point to any allocation
|
||||
/// (because they were created with `Weak::new()`).
|
||||
/// Returns `true` if the two `Weak`s point to the same allocation similar to [`ptr::eq`], or if
|
||||
/// both don't point to any allocation (because they were created with `Weak::new()`). See [that
|
||||
/// function][`ptr::eq`] for caveats when comparing `dyn Trait` pointers.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
|
@ -1733,6 +1733,11 @@ unsafe fn mod_inv(x: usize, m: usize) -> usize {
|
||||
/// by their address rather than comparing the values they point to
|
||||
/// (which is what the `PartialEq for &T` implementation does).
|
||||
///
|
||||
/// However, note that comparing trait object pointers (`*const dyn Trait`) is unrealiable: pointers
|
||||
/// to values of the same underlying type can compare inequal (because vtables are duplicated in
|
||||
/// multiple codegen units), and pointers to values of *different* underlying type can compare equal
|
||||
/// (since identical vtables can be deduplicated within a codegen unit).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
@ -1759,41 +1764,6 @@ unsafe fn mod_inv(x: usize, m: usize) -> usize {
|
||||
/// assert!(!std::ptr::eq(&a[..2], &a[..3]));
|
||||
/// assert!(!std::ptr::eq(&a[0..2], &a[1..3]));
|
||||
/// ```
|
||||
///
|
||||
/// Traits are also compared by their implementation:
|
||||
///
|
||||
/// ```
|
||||
/// #[repr(transparent)]
|
||||
/// struct Wrapper { member: i32 }
|
||||
///
|
||||
/// trait Trait {}
|
||||
/// impl Trait for Wrapper {}
|
||||
/// impl Trait for i32 {}
|
||||
///
|
||||
/// let wrapper = Wrapper { member: 10 };
|
||||
///
|
||||
/// // Pointers have equal addresses.
|
||||
/// assert!(std::ptr::eq(
|
||||
/// &wrapper as *const Wrapper as *const u8,
|
||||
/// &wrapper.member as *const i32 as *const u8
|
||||
/// ));
|
||||
///
|
||||
/// // Objects have equal addresses, but `Trait` has different implementations.
|
||||
/// assert!(!std::ptr::eq(
|
||||
/// &wrapper as &dyn Trait,
|
||||
/// &wrapper.member as &dyn Trait,
|
||||
/// ));
|
||||
/// assert!(!std::ptr::eq(
|
||||
/// &wrapper as &dyn Trait as *const dyn Trait,
|
||||
/// &wrapper.member as &dyn Trait as *const dyn Trait,
|
||||
/// ));
|
||||
///
|
||||
/// // Converting the reference to a `*const u8` compares by address.
|
||||
/// assert!(std::ptr::eq(
|
||||
/// &wrapper as &dyn Trait as *const dyn Trait as *const u8,
|
||||
/// &wrapper.member as &dyn Trait as *const dyn Trait as *const u8,
|
||||
/// ));
|
||||
/// ```
|
||||
#[stable(feature = "ptr_eq", since = "1.17.0")]
|
||||
#[inline]
|
||||
pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
|
||||
|
Loading…
Reference in New Issue
Block a user