From 234e383c3426281447da140e24ccf6bf5402f6f5 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 14 Mar 2024 15:08:53 -0700 Subject: Stabilize `unchecked_{add,sub,mul}` --- library/core/src/intrinsics.rs | 15 +++++++----- library/core/src/lib.rs | 2 -- library/core/src/num/int_macros.rs | 48 +++++++++++++++++++++++-------------- library/core/src/num/uint_macros.rs | 48 +++++++++++++++++++++++-------------- library/core/src/ptr/const_ptr.rs | 2 -- library/core/src/ptr/mut_ptr.rs | 2 -- library/core/src/ptr/non_null.rs | 2 -- 7 files changed, 69 insertions(+), 50 deletions(-) (limited to 'library/core') diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 86b9a39d68a..9b11a3cdbde 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2224,24 +2224,27 @@ extern "rust-intrinsic" { /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`. /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] + /// The stable counterpart of this intrinsic is `unchecked_add` on the various + /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`]. + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[rustc_nounwind] pub fn unchecked_add(x: T, y: T) -> T; /// Returns the result of an unchecked subtraction, resulting in /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`. /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] + /// The stable counterpart of this intrinsic is `unchecked_sub` on the various + /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`]. + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[rustc_nounwind] pub fn unchecked_sub(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`. /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] + /// The stable counterpart of this intrinsic is `unchecked_mul` on the various + /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`]. + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[rustc_nounwind] pub fn unchecked_mul(x: T, y: T) -> T; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 9b786feba89..5aeeacc4372 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -134,7 +134,6 @@ #![feature(const_heap)] #![feature(const_hint_assert_unchecked)] #![feature(const_index_range_slice_index)] -#![feature(const_int_unchecked_arith)] #![feature(const_intrinsic_copy)] #![feature(const_intrinsic_forget)] #![feature(const_ipv4)] @@ -193,7 +192,6 @@ #![feature(str_split_inclusive_remainder)] #![feature(str_split_remainder)] #![feature(strict_provenance)] -#![feature(unchecked_math)] #![feature(unchecked_shifts)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index fa37ee4ffb2..9101d5064f9 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -492,21 +492,25 @@ macro_rules! int_impl { /// Unchecked integer addition. Computes `self + rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_add(y)` is semantically equivalent to calling + /// `x.`[`checked_add`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_add`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self + rhs > ", stringify!($SelfT), "::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_add`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { @@ -630,21 +634,25 @@ macro_rules! int_impl { /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_sub(y)` is semantically equivalent to calling + /// `x.`[`checked_sub`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_sub`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self - rhs > ", stringify!($SelfT), "::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_sub`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { @@ -768,21 +776,25 @@ macro_rules! int_impl { /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_mul(y)` is semantically equivalent to calling + /// `x.`[`checked_mul`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_mul`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self * rhs > ", stringify!($SelfT), "::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_mul`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 081a3c0b118..c098f1894a6 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -500,21 +500,25 @@ macro_rules! uint_impl { /// Unchecked integer addition. Computes `self + rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_add(y)` is semantically equivalent to calling + /// `x.`[`checked_add`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_add`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self + rhs > ", stringify!($SelfT), "::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_add`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { @@ -644,21 +648,25 @@ macro_rules! uint_impl { /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_sub(y)` is semantically equivalent to calling + /// `x.`[`checked_sub`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_sub`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self - rhs > ", stringify!($SelfT), "::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_sub`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { @@ -726,21 +734,25 @@ macro_rules! uint_impl { /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_mul(y)` is semantically equivalent to calling + /// `x.`[`checked_mul`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_mul`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self * rhs > ", stringify!($SelfT), "::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_mul`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index a0c04d3f65d..a49c6e9d815 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1038,8 +1038,6 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - // We could always go back to wrapping if unchecked becomes unacceptable - #[rustc_allow_const_fn_unstable(const_int_unchecked_arith)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 6a9033a144d..bfb99630aa9 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1123,8 +1123,6 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - // We could always go back to wrapping if unchecked becomes unacceptable - #[rustc_allow_const_fn_unstable(const_int_unchecked_arith)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 9c0236c172a..0bde64adda4 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -702,8 +702,6 @@ impl NonNull { #[unstable(feature = "non_null_convenience", issue = "117691")] #[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")] #[must_use = "returns a new pointer rather than modifying its argument"] - // We could always go back to wrapping if unchecked becomes unacceptable - #[rustc_allow_const_fn_unstable(const_int_unchecked_arith)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self -- cgit 1.4.1-3-g733a5 From 50392ccc5a38f2e4580c67d51836f5add64f7d48 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 15 Mar 2024 13:09:04 -0700 Subject: Workaround issue 122566 --- library/core/src/num/int_macros.rs | 6 +++--- library/core/src/num/uint_macros.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'library/core') diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 9101d5064f9..2fec8ef2381 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -504,7 +504,7 @@ macro_rules! int_impl { #[doc = concat!("`self + rhs > ", stringify!($SelfT), "::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_add`] would return `None`. /// - /// [`unwrap_unchecked`]: Option::unwrap_unchecked + /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] @@ -646,7 +646,7 @@ macro_rules! int_impl { #[doc = concat!("`self - rhs > ", stringify!($SelfT), "::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_sub`] would return `None`. /// - /// [`unwrap_unchecked`]: Option::unwrap_unchecked + /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] @@ -788,7 +788,7 @@ macro_rules! int_impl { #[doc = concat!("`self * rhs > ", stringify!($SelfT), "::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_mul`] would return `None`. /// - /// [`unwrap_unchecked`]: Option::unwrap_unchecked + /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index c098f1894a6..f76f110fc4e 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -512,7 +512,7 @@ macro_rules! uint_impl { #[doc = concat!("`self + rhs > ", stringify!($SelfT), "::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_add`] would return `None`. /// - /// [`unwrap_unchecked`]: Option::unwrap_unchecked + /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] @@ -660,7 +660,7 @@ macro_rules! uint_impl { #[doc = concat!("`self - rhs > ", stringify!($SelfT), "::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_sub`] would return `None`. /// - /// [`unwrap_unchecked`]: Option::unwrap_unchecked + /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] @@ -746,7 +746,7 @@ macro_rules! uint_impl { #[doc = concat!("`self * rhs > ", stringify!($SelfT), "::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_mul`] would return `None`. /// - /// [`unwrap_unchecked`]: Option::unwrap_unchecked + /// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] -- cgit 1.4.1-3-g733a5 From 1c137b7582948fe35d040cd2f805b90284046951 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 16 Mar 2024 23:27:50 -0400 Subject: Optimize `core::char::CaseMappingIter` layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Godbolt says this saves a few instructions… --- library/core/src/char/mod.rs | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'library/core') diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 12bca0b438c..a31ac3e51b5 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -443,10 +443,10 @@ impl ExactSizeIterator for ToUppercase {} #[derive(Debug, Clone)] enum CaseMappingIter { - Three(char, char, char), - Two(char, char), - One(char), Zero, + One(char), + Two([char; 2]), + Three([char; 3]), } impl CaseMappingIter { @@ -455,10 +455,10 @@ impl CaseMappingIter { if chars[1] == '\0' { CaseMappingIter::One(chars[0]) // Including if chars[0] == '\0' } else { - CaseMappingIter::Two(chars[0], chars[1]) + CaseMappingIter::Two([chars[0], chars[1]]) } } else { - CaseMappingIter::Three(chars[0], chars[1], chars[2]) + CaseMappingIter::Three([chars[0], chars[1], chars[2]]) } } } @@ -467,28 +467,28 @@ impl Iterator for CaseMappingIter { type Item = char; fn next(&mut self) -> Option { match *self { - CaseMappingIter::Three(a, b, c) => { - *self = CaseMappingIter::Two(b, c); - Some(a) + CaseMappingIter::Zero => None, + CaseMappingIter::One(c) => { + *self = CaseMappingIter::Zero; + Some(c) } - CaseMappingIter::Two(b, c) => { + CaseMappingIter::Two([b, c]) => { *self = CaseMappingIter::One(c); Some(b) } - CaseMappingIter::One(c) => { - *self = CaseMappingIter::Zero; - Some(c) + CaseMappingIter::Three([a, b, c]) => { + *self = CaseMappingIter::Two([b, c]); + Some(a) } - CaseMappingIter::Zero => None, } } fn size_hint(&self) -> (usize, Option) { let size = match self { - CaseMappingIter::Three(..) => 3, - CaseMappingIter::Two(..) => 2, - CaseMappingIter::One(_) => 1, CaseMappingIter::Zero => 0, + CaseMappingIter::One(_) => 1, + CaseMappingIter::Two(..) => 2, + CaseMappingIter::Three(..) => 3, }; (size, Some(size)) } @@ -497,19 +497,19 @@ impl Iterator for CaseMappingIter { impl DoubleEndedIterator for CaseMappingIter { fn next_back(&mut self) -> Option { match *self { - CaseMappingIter::Three(a, b, c) => { - *self = CaseMappingIter::Two(a, b); + CaseMappingIter::Zero => None, + CaseMappingIter::One(c) => { + *self = CaseMappingIter::Zero; Some(c) } - CaseMappingIter::Two(b, c) => { + CaseMappingIter::Two([b, c]) => { *self = CaseMappingIter::One(b); Some(c) } - CaseMappingIter::One(c) => { - *self = CaseMappingIter::Zero; + CaseMappingIter::Three([a, b, c]) => { + *self = CaseMappingIter::Two([a, b]); Some(c) } - CaseMappingIter::Zero => None, } } } @@ -517,17 +517,17 @@ impl DoubleEndedIterator for CaseMappingIter { impl fmt::Display for CaseMappingIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - CaseMappingIter::Three(a, b, c) => { - f.write_char(a)?; + CaseMappingIter::Zero => Ok(()), + CaseMappingIter::One(c) => f.write_char(c), + CaseMappingIter::Two([b, c]) => { f.write_char(b)?; f.write_char(c) } - CaseMappingIter::Two(b, c) => { + CaseMappingIter::Three([a, b, c]) => { + f.write_char(a)?; f.write_char(b)?; f.write_char(c) } - CaseMappingIter::One(c) => f.write_char(c), - CaseMappingIter::Zero => Ok(()), } } } -- cgit 1.4.1-3-g733a5 From 2f1ab2ce0925af91d252aea2608284c34faa0446 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Mon, 18 Mar 2024 23:07:28 -0400 Subject: Reimplement `CaseMappingIter` with `core::array::IntoIter` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes the iterator 2*usize larger, but I doubt that matters much. In exchange, we save a lot on instruction count. In the absence of delegation syntax, we must forward all the specialized impls manually… --- library/core/src/char/mod.rs | 309 +++++++++++++++++++++++++------------------ 1 file changed, 181 insertions(+), 128 deletions(-) (limited to 'library/core') diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index a31ac3e51b5..a860c7c6aaa 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -42,7 +42,7 @@ use crate::ascii; use crate::error::Error; use crate::escape; use crate::fmt::{self, Write}; -use crate::iter::FusedIterator; +use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; use crate::num::NonZero; pub(crate) use self::methods::EscapeDebugExtArgs; @@ -373,176 +373,229 @@ impl fmt::Display for EscapeDebug { } } -/// Returns an iterator that yields the lowercase equivalent of a `char`. -/// -/// This `struct` is created by the [`to_lowercase`] method on [`char`]. See -/// its documentation for more. -/// -/// [`to_lowercase`]: char::to_lowercase -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug, Clone)] -pub struct ToLowercase(CaseMappingIter); +macro_rules! casemappingiter_impls { + ($(#[$attr:meta])* $ITER_NAME:ident) => { + $(#[$attr])* + #[stable(feature = "rust1", since = "1.0.0")] + #[derive(Debug, Clone)] + pub struct $ITER_NAME(CaseMappingIter); + + #[stable(feature = "rust1", since = "1.0.0")] + impl Iterator for $ITER_NAME { + type Item = char; + fn next(&mut self) -> Option { + self.0.next() + } -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for ToLowercase { - type Item = char; - fn next(&mut self) -> Option { - self.0.next() - } - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } -#[stable(feature = "case_mapping_double_ended", since = "1.59.0")] -impl DoubleEndedIterator for ToLowercase { - fn next_back(&mut self) -> Option { - self.0.next_back() - } -} + fn fold(self, init: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.0.fold(init, fold) + } -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for ToLowercase {} + fn count(self) -> usize { + self.0.count() + } -#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] -impl ExactSizeIterator for ToLowercase {} + fn last(self) -> Option { + self.0.last() + } -/// Returns an iterator that yields the uppercase equivalent of a `char`. -/// -/// This `struct` is created by the [`to_uppercase`] method on [`char`]. See -/// its documentation for more. -/// -/// [`to_uppercase`]: char::to_uppercase -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug, Clone)] -pub struct ToUppercase(CaseMappingIter); + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_by(n) + } -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for ToUppercase { - type Item = char; - fn next(&mut self) -> Option { - self.0.next() - } - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { + // SAFETY: just forwarding requirements to caller + unsafe { self.0.__iterator_get_unchecked(idx) } + } + } -#[stable(feature = "case_mapping_double_ended", since = "1.59.0")] -impl DoubleEndedIterator for ToUppercase { - fn next_back(&mut self) -> Option { - self.0.next_back() + #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] + impl DoubleEndedIterator for $ITER_NAME { + fn next_back(&mut self) -> Option { + self.0.next_back() + } + + fn rfold(self, init: Acc, rfold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.0.rfold(init, rfold) + } + + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_back_by(n) + } + } + + #[stable(feature = "fused", since = "1.26.0")] + impl FusedIterator for $ITER_NAME {} + + #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] + impl ExactSizeIterator for $ITER_NAME { + fn len(&self) -> usize { + self.0.len() + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } + } + + // SAFETY: forwards to inner `array::IntoIter` + #[unstable(feature = "trusted_len", issue = "37572")] + unsafe impl TrustedLen for $ITER_NAME {} + + // SAFETY: forwards to inner `array::IntoIter` + #[doc(hidden)] + #[unstable(feature = "std_internals", issue = "none")] + unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME { + const MAY_HAVE_SIDE_EFFECT: bool = false; + } + + // SAFETY: this iter has no subtypes/supertypes + #[doc(hidden)] + #[unstable(feature = "std_internals", issue = "none")] + unsafe impl TrustedRandomAccess for $ITER_NAME {} + + #[stable(feature = "char_struct_display", since = "1.16.0")] + impl fmt::Display for $ITER_NAME { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } + } } } -#[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for ToUppercase {} +casemappingiter_impls! { + /// Returns an iterator that yields the lowercase equivalent of a `char`. + /// + /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See + /// its documentation for more. + /// + /// [`to_lowercase`]: char::to_lowercase + ToLowercase +} -#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] -impl ExactSizeIterator for ToUppercase {} +casemappingiter_impls! { + /// Returns an iterator that yields the uppercase equivalent of a `char`. + /// + /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See + /// its documentation for more. + /// + /// [`to_uppercase`]: char::to_uppercase + ToUppercase +} #[derive(Debug, Clone)] -enum CaseMappingIter { - Zero, - One(char), - Two([char; 2]), - Three([char; 3]), -} +struct CaseMappingIter(core::array::IntoIter); impl CaseMappingIter { + #[inline] fn new(chars: [char; 3]) -> CaseMappingIter { + let mut iter = chars.into_iter(); if chars[2] == '\0' { + iter.next_back(); if chars[1] == '\0' { - CaseMappingIter::One(chars[0]) // Including if chars[0] == '\0' - } else { - CaseMappingIter::Two([chars[0], chars[1]]) + iter.next_back(); + + // Deliberately don't check `chars[0]`, + // as '\0' lowercases to itself } - } else { - CaseMappingIter::Three([chars[0], chars[1], chars[2]]) } + CaseMappingIter(iter) } } impl Iterator for CaseMappingIter { type Item = char; + fn next(&mut self) -> Option { - match *self { - CaseMappingIter::Zero => None, - CaseMappingIter::One(c) => { - *self = CaseMappingIter::Zero; - Some(c) - } - CaseMappingIter::Two([b, c]) => { - *self = CaseMappingIter::One(c); - Some(b) - } - CaseMappingIter::Three([a, b, c]) => { - *self = CaseMappingIter::Two([b, c]); - Some(a) - } - } + self.0.next() } fn size_hint(&self) -> (usize, Option) { - let size = match self { - CaseMappingIter::Zero => 0, - CaseMappingIter::One(_) => 1, - CaseMappingIter::Two(..) => 2, - CaseMappingIter::Three(..) => 3, - }; - (size, Some(size)) + self.0.size_hint() + } + + fn fold(self, init: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.0.fold(init, fold) + } + + fn count(self) -> usize { + self.0.count() + } + + fn last(self) -> Option { + self.0.last() + } + + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_by(n) + } + + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { + // SAFETY: just forwarding requirements to caller + unsafe { self.0.__iterator_get_unchecked(idx) } } } impl DoubleEndedIterator for CaseMappingIter { fn next_back(&mut self) -> Option { - match *self { - CaseMappingIter::Zero => None, - CaseMappingIter::One(c) => { - *self = CaseMappingIter::Zero; - Some(c) - } - CaseMappingIter::Two([b, c]) => { - *self = CaseMappingIter::One(b); - Some(c) - } - CaseMappingIter::Three([a, b, c]) => { - *self = CaseMappingIter::Two([a, b]); - Some(c) - } - } + self.0.next_back() } -} -impl fmt::Display for CaseMappingIter { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - CaseMappingIter::Zero => Ok(()), - CaseMappingIter::One(c) => f.write_char(c), - CaseMappingIter::Two([b, c]) => { - f.write_char(b)?; - f.write_char(c) - } - CaseMappingIter::Three([a, b, c]) => { - f.write_char(a)?; - f.write_char(b)?; - f.write_char(c) - } - } + fn rfold(self, init: Acc, rfold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.0.rfold(init, rfold) + } + + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_back_by(n) } } -#[stable(feature = "char_struct_display", since = "1.16.0")] -impl fmt::Display for ToLowercase { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, f) +impl ExactSizeIterator for CaseMappingIter { + fn len(&self) -> usize { + self.0.len() + } + + fn is_empty(&self) -> bool { + self.0.is_empty() } } -#[stable(feature = "char_struct_display", since = "1.16.0")] -impl fmt::Display for ToUppercase { +impl FusedIterator for CaseMappingIter {} + +// SAFETY: forwards to inner `array::IntoIter` +unsafe impl TrustedLen for CaseMappingIter {} + +// SAFETY: forwards to inner `array::IntoIter` +unsafe impl TrustedRandomAccessNoCoerce for CaseMappingIter { + const MAY_HAVE_SIDE_EFFECT: bool = false; +} + +// SAFETY: `CaseMappingIter` has no subtypes/supertypes +unsafe impl TrustedRandomAccess for CaseMappingIter {} + +impl fmt::Display for CaseMappingIter { + #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, f) + for c in self.0.clone() { + f.write_char(c)?; + } + Ok(()) } } -- cgit 1.4.1-3-g733a5 From 4a9f3cac887023d0230729e898240b85508aa791 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 18 Feb 2024 15:21:44 +0100 Subject: Add diagnostic items for Ord and PartialOrd methods --- compiler/rustc_span/src/symbol.rs | 7 +++++++ library/core/src/cmp.rs | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'library/core') diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 891ddb7af5b..1f2c44ca71e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -531,8 +531,15 @@ symbols! { cmp, cmp_max, cmp_min, + cmp_ord_max, + cmp_ord_min, cmp_partialeq_eq, cmp_partialeq_ne, + cmp_partialord_cmp, + cmp_partialord_ge, + cmp_partialord_gt, + cmp_partialord_le, + cmp_partialord_lt, cmpxchg16b_target_feature, cmse_nonsecure_entry, coerce_unsized, diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index a2f07814726..cc9ef673da7 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -848,6 +848,7 @@ pub trait Ord: Eq + PartialOrd { #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] #[must_use] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_ord_max")] fn max(self, other: Self) -> Self where Self: Sized, @@ -868,6 +869,7 @@ pub trait Ord: Eq + PartialOrd { #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] #[must_use] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_ord_min")] fn min(self, other: Self) -> Self where Self: Sized, @@ -1154,6 +1156,7 @@ pub trait PartialOrd: PartialEq { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_cmp")] fn partial_cmp(&self, other: &Rhs) -> Option; /// This method tests less than (for `self` and `other`) and is used by the `<` operator. @@ -1168,6 +1171,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_lt")] fn lt(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Less)) } @@ -1185,6 +1189,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_le")] fn le(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Less | Equal)) } @@ -1201,6 +1206,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_gt")] fn gt(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Greater)) } @@ -1218,6 +1224,7 @@ pub trait PartialOrd: PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialord_ge")] fn ge(&self, other: &Rhs) -> bool { matches!(self.partial_cmp(other), Some(Greater | Equal)) } -- cgit 1.4.1-3-g733a5 From d4b514f982e4214e0f9237c905670b1207ae0c95 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 18 Feb 2024 15:23:03 +0100 Subject: Add detection of [Partial]Ord methods to the ambiguous wide ptr cmp lint --- compiler/rustc_lint/src/lints.rs | 14 +- compiler/rustc_lint/src/types.rs | 58 ++++--- library/core/src/ptr/const_ptr.rs | 1 + library/core/src/ptr/metadata.rs | 1 + library/core/src/ptr/mut_ptr.rs | 1 + library/core/src/ptr/non_null.rs | 2 + tests/ui/lint/wide_pointer_comparisons.rs | 24 +++ tests/ui/lint/wide_pointer_comparisons.stderr | 238 ++++++++++++++++++++------ 8 files changed, 257 insertions(+), 82 deletions(-) (limited to 'library/core') diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 1dac2d89c6b..cf3890dc61c 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1668,14 +1668,16 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { Cast { deref_left: &'a str, deref_right: &'a str, - #[suggestion_part(code = "{deref_left}")] + paren_left: &'a str, + paren_right: &'a str, + #[suggestion_part(code = "({deref_left}")] left_before: Option, - #[suggestion_part(code = " as *const ()")] - left: Span, - #[suggestion_part(code = "{deref_right}")] + #[suggestion_part(code = "{paren_left}.cast::<()>()")] + left_after: Span, + #[suggestion_part(code = "({deref_right}")] right_before: Option, - #[suggestion_part(code = " as *const ()")] - right: Span, + #[suggestion_part(code = "{paren_right}.cast::<()>()")] + right_after: Span, }, } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 5331d2fb752..68cc024d9c7 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -657,10 +657,16 @@ fn lint_nan<'tcx>( cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint); } +#[derive(Debug, PartialEq)] +enum ComparisonOp { + BinOp(hir::BinOpKind), + Other, +} + fn lint_wide_pointer<'tcx>( cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>, - binop: hir::BinOpKind, + cmpop: ComparisonOp, l: &'tcx hir::Expr<'tcx>, r: &'tcx hir::Expr<'tcx>, ) { @@ -679,7 +685,7 @@ fn lint_wide_pointer<'tcx>( } }; - // PartialEq::{eq,ne} takes references, remove any explicit references + // the left and right operands can have references, remove any explicit references let l = l.peel_borrows(); let r = r.peel_borrows(); @@ -707,8 +713,8 @@ fn lint_wide_pointer<'tcx>( ); }; - let ne = if binop == hir::BinOpKind::Ne { "!" } else { "" }; - let is_eq_ne = matches!(binop, hir::BinOpKind::Eq | hir::BinOpKind::Ne); + let ne = if cmpop == ComparisonOp::BinOp(hir::BinOpKind::Ne) { "!" } else { "" }; + let is_eq_ne = matches!(cmpop, ComparisonOp::BinOp(hir::BinOpKind::Eq | hir::BinOpKind::Ne)); let is_dyn_comparison = l_inner_ty_is_dyn && r_inner_ty_is_dyn; let left = e.span.shrink_to_lo().until(l_span.shrink_to_lo()); @@ -745,12 +751,12 @@ fn lint_wide_pointer<'tcx>( AmbiguousWidePointerComparisonsAddrSuggestion::Cast { deref_left, deref_right, - // those two Options are required for correctness as having - // an empty span and an empty suggestion is not permitted - left_before: (l_ty_refs != 0).then_some(left), - right_before: (r_ty_refs != 0).then(|| r_span.shrink_to_lo()), - left: l_span.shrink_to_hi(), - right, + paren_left: if l_ty_refs != 0 { ")" } else { "" }, + paren_right: if r_ty_refs != 0 { ")" } else { "" }, + left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()), + left_after: l_span.shrink_to_hi(), + right_before: (r_ty_refs != 0).then_some(r_span.shrink_to_lo()), + right_after: r_span.shrink_to_hi(), } }, }, @@ -773,7 +779,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons); } else { lint_nan(cx, e, binop, l, r); - lint_wide_pointer(cx, e, binop.node, l, r); + lint_wide_pointer(cx, e, ComparisonOp::BinOp(binop.node), l, r); } } } @@ -782,16 +788,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { if let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id) - && let Some(binop) = partialeq_binop(diag_item) => + && let Some(cmpop) = diag_item_cmpop(diag_item) => { - lint_wide_pointer(cx, e, binop, l, r); + lint_wide_pointer(cx, e, cmpop, l, r); } hir::ExprKind::MethodCall(_, l, [r], _) if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id) - && let Some(binop) = partialeq_binop(diag_item) => + && let Some(cmpop) = diag_item_cmpop(diag_item) => { - lint_wide_pointer(cx, e, binop, l, r); + lint_wide_pointer(cx, e, cmpop, l, r); } _ => {} }; @@ -876,14 +882,20 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { ) } - fn partialeq_binop(diag_item: Symbol) -> Option { - if diag_item == sym::cmp_partialeq_eq { - Some(hir::BinOpKind::Eq) - } else if diag_item == sym::cmp_partialeq_ne { - Some(hir::BinOpKind::Ne) - } else { - None - } + fn diag_item_cmpop(diag_item: Symbol) -> Option { + Some(match diag_item { + sym::cmp_ord_max => ComparisonOp::Other, + sym::cmp_ord_min => ComparisonOp::Other, + sym::ord_cmp_method => ComparisonOp::Other, + sym::cmp_partialeq_eq => ComparisonOp::BinOp(hir::BinOpKind::Eq), + sym::cmp_partialeq_ne => ComparisonOp::BinOp(hir::BinOpKind::Ne), + sym::cmp_partialord_cmp => ComparisonOp::Other, + sym::cmp_partialord_ge => ComparisonOp::BinOp(hir::BinOpKind::Ge), + sym::cmp_partialord_gt => ComparisonOp::BinOp(hir::BinOpKind::Gt), + sym::cmp_partialord_le => ComparisonOp::BinOp(hir::BinOpKind::Le), + sym::cmp_partialord_lt => ComparisonOp::BinOp(hir::BinOpKind::Lt), + _ => return None, + }) } } } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index a6c00ff28d4..4081ad124d3 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1857,6 +1857,7 @@ impl Ord for *const T { #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for *const T { #[inline] + #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*const T) -> Option { Some(self.cmp(other)) } diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index fe19f66a31a..7f9d8e677d2 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -258,6 +258,7 @@ impl PartialEq for DynMetadata { impl Ord for DynMetadata { #[inline] + #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> crate::cmp::Ordering { (self.vtable_ptr as *const VTable).cmp(&(other.vtable_ptr as *const VTable)) } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 1add9ca2311..2ff7d829918 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -2275,6 +2275,7 @@ impl Ord for *mut T { #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for *mut T { #[inline(always)] + #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*mut T) -> Option { Some(self.cmp(other)) } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index e9488917acc..70e6f3f9e79 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1821,6 +1821,7 @@ impl PartialEq for NonNull { #[stable(feature = "nonnull", since = "1.25.0")] impl Ord for NonNull { #[inline] + #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> Ordering { self.as_ptr().cmp(&other.as_ptr()) } @@ -1829,6 +1830,7 @@ impl Ord for NonNull { #[stable(feature = "nonnull", since = "1.25.0")] impl PartialOrd for NonNull { #[inline] + #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &Self) -> Option { self.as_ptr().partial_cmp(&other.as_ptr()) } diff --git a/tests/ui/lint/wide_pointer_comparisons.rs b/tests/ui/lint/wide_pointer_comparisons.rs index 31369001075..bc4b3cecabc 100644 --- a/tests/ui/lint/wide_pointer_comparisons.rs +++ b/tests/ui/lint/wide_pointer_comparisons.rs @@ -37,6 +37,18 @@ fn main() { //~^ WARN ambiguous wide pointer comparison let _ = a.ne(&b); //~^ WARN ambiguous wide pointer comparison + let _ = a.cmp(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.partial_cmp(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.le(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.lt(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.ge(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.gt(&b); + //~^ WARN ambiguous wide pointer comparison { // &*const ?Sized @@ -68,6 +80,18 @@ fn main() { //~^ WARN ambiguous wide pointer comparison let _ = a.ne(b); //~^ WARN ambiguous wide pointer comparison + let _ = a.cmp(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.partial_cmp(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.le(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.lt(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.ge(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.gt(&b); + //~^ WARN ambiguous wide pointer comparison } let s = "" as *const str; diff --git a/tests/ui/lint/wide_pointer_comparisons.stderr b/tests/ui/lint/wide_pointer_comparisons.stderr index 6ef117c63c5..8140f9fa5aa 100644 --- a/tests/ui/lint/wide_pointer_comparisons.stderr +++ b/tests/ui/lint/wide_pointer_comparisons.stderr @@ -29,8 +29,8 @@ LL | let _ = a < b; | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () < b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() < b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected --> $DIR/wide_pointer_comparisons.rs:25:13 @@ -40,8 +40,8 @@ LL | let _ = a <= b; | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () <= b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() <= b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected --> $DIR/wide_pointer_comparisons.rs:27:13 @@ -51,8 +51,8 @@ LL | let _ = a > b; | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () > b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() > b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected --> $DIR/wide_pointer_comparisons.rs:29:13 @@ -62,8 +62,8 @@ LL | let _ = a >= b; | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () >= b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() >= b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected --> $DIR/wide_pointer_comparisons.rs:32:13 @@ -110,7 +110,73 @@ LL | let _ = !std::ptr::addr_eq(a, b); | +++++++++++++++++++ ~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:46:17 + --> $DIR/wide_pointer_comparisons.rs:40:13 + | +LL | let _ = a.cmp(&b); + | ^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = a.cast::<()>().cmp(&b.cast::<()>()); + | +++++++++++++ +++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:42:13 + | +LL | let _ = a.partial_cmp(&b); + | ^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = a.cast::<()>().partial_cmp(&b.cast::<()>()); + | +++++++++++++ +++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:44:13 + | +LL | let _ = a.le(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = a.cast::<()>().le(&b.cast::<()>()); + | +++++++++++++ +++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:46:13 + | +LL | let _ = a.lt(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = a.cast::<()>().lt(&b.cast::<()>()); + | +++++++++++++ +++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:48:13 + | +LL | let _ = a.ge(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = a.cast::<()>().ge(&b.cast::<()>()); + | +++++++++++++ +++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:50:13 + | +LL | let _ = a.gt(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = a.cast::<()>().gt(&b.cast::<()>()); + | +++++++++++++ +++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:58:17 | LL | let _ = a == b; | ^^^^^^ @@ -121,7 +187,7 @@ LL | let _ = std::ptr::addr_eq(*a, *b); | +++++++++++++++++++ ~~~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:48:17 + --> $DIR/wide_pointer_comparisons.rs:60:17 | LL | let _ = a != b; | ^^^^^^ @@ -132,51 +198,51 @@ LL | let _ = !std::ptr::addr_eq(*a, *b); | ++++++++++++++++++++ ~~~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:50:17 + --> $DIR/wide_pointer_comparisons.rs:62:17 | LL | let _ = a < b; | ^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = *a as *const () < *b as *const (); - | + ++++++++++++ + ++++++++++++ +LL | let _ = (*a).cast::<()>() < (*b).cast::<()>(); + | ++ ++++++++++++++ ++ ++++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:52:17 + --> $DIR/wide_pointer_comparisons.rs:64:17 | LL | let _ = a <= b; | ^^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = *a as *const () <= *b as *const (); - | + ++++++++++++ + ++++++++++++ +LL | let _ = (*a).cast::<()>() <= (*b).cast::<()>(); + | ++ ++++++++++++++ ++ ++++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:54:17 + --> $DIR/wide_pointer_comparisons.rs:66:17 | LL | let _ = a > b; | ^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = *a as *const () > *b as *const (); - | + ++++++++++++ + ++++++++++++ +LL | let _ = (*a).cast::<()>() > (*b).cast::<()>(); + | ++ ++++++++++++++ ++ ++++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:56:17 + --> $DIR/wide_pointer_comparisons.rs:68:17 | LL | let _ = a >= b; | ^^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = *a as *const () >= *b as *const (); - | + ++++++++++++ + ++++++++++++ +LL | let _ = (*a).cast::<()>() >= (*b).cast::<()>(); + | ++ ++++++++++++++ ++ ++++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:59:17 + --> $DIR/wide_pointer_comparisons.rs:71:17 | LL | let _ = PartialEq::eq(a, b); | ^^^^^^^^^^^^^^^^^^^ @@ -187,7 +253,7 @@ LL | let _ = std::ptr::addr_eq(*a, *b); | ~~~~~~~~~~~~~~~~~~~ ~~~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:61:17 + --> $DIR/wide_pointer_comparisons.rs:73:17 | LL | let _ = PartialEq::ne(a, b); | ^^^^^^^^^^^^^^^^^^^ @@ -198,7 +264,7 @@ LL | let _ = !std::ptr::addr_eq(*a, *b); | ~~~~~~~~~~~~~~~~~~~~ ~~~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:63:17 + --> $DIR/wide_pointer_comparisons.rs:75:17 | LL | let _ = PartialEq::eq(&a, &b); | ^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +275,7 @@ LL | let _ = std::ptr::addr_eq(*a, *b); | ~~~~~~~~~~~~~~~~~~~ ~~~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:65:17 + --> $DIR/wide_pointer_comparisons.rs:77:17 | LL | let _ = PartialEq::ne(&a, &b); | ^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +286,7 @@ LL | let _ = !std::ptr::addr_eq(*a, *b); | ~~~~~~~~~~~~~~~~~~~~ ~~~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:67:17 + --> $DIR/wide_pointer_comparisons.rs:79:17 | LL | let _ = a.eq(b); | ^^^^^^^ @@ -231,7 +297,7 @@ LL | let _ = std::ptr::addr_eq(*a, *b); | +++++++++++++++++++ ~~~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:69:17 + --> $DIR/wide_pointer_comparisons.rs:81:17 | LL | let _ = a.ne(b); | ^^^^^^^ @@ -242,7 +308,73 @@ LL | let _ = !std::ptr::addr_eq(*a, *b); | ++++++++++++++++++++ ~~~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:74:13 + --> $DIR/wide_pointer_comparisons.rs:83:17 + | +LL | let _ = a.cmp(&b); + | ^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = (*a).cast::<()>().cmp(&(*b).cast::<()>()); + | ++ ++++++++++++++ ++ ++++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:85:17 + | +LL | let _ = a.partial_cmp(&b); + | ^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = (*a).cast::<()>().partial_cmp(&(*b).cast::<()>()); + | ++ ++++++++++++++ ++ ++++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:87:17 + | +LL | let _ = a.le(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = (*a).cast::<()>().le(&(*b).cast::<()>()); + | ++ ++++++++++++++ ++ ++++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:89:17 + | +LL | let _ = a.lt(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = (*a).cast::<()>().lt(&(*b).cast::<()>()); + | ++ ++++++++++++++ ++ ++++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:91:17 + | +LL | let _ = a.ge(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = (*a).cast::<()>().ge(&(*b).cast::<()>()); + | ++ ++++++++++++++ ++ ++++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:93:17 + | +LL | let _ = a.gt(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = (*a).cast::<()>().gt(&(*b).cast::<()>()); + | ++ ++++++++++++++ ++ ++++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:98:13 | LL | let _ = s == s; | ^^^^^^ @@ -257,7 +389,7 @@ LL | let _ = std::ptr::eq(s, s); | +++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:78:13 + --> $DIR/wide_pointer_comparisons.rs:102:13 | LL | let _ = s == s; | ^^^^^^ @@ -272,7 +404,7 @@ LL | let _ = std::ptr::eq(s, s); | +++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:82:17 + --> $DIR/wide_pointer_comparisons.rs:106:17 | LL | let _ = a == b; | ^^^^^^ @@ -287,7 +419,7 @@ LL | let _ = std::ptr::eq(a, b); | +++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:84:17 + --> $DIR/wide_pointer_comparisons.rs:108:17 | LL | let _ = a != b; | ^^^^^^ @@ -302,51 +434,51 @@ LL | let _ = !std::ptr::eq(a, b); | ++++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:86:17 + --> $DIR/wide_pointer_comparisons.rs:110:17 | LL | let _ = a < b; | ^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () < b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() < b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:88:17 + --> $DIR/wide_pointer_comparisons.rs:112:17 | LL | let _ = a <= b; | ^^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () <= b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() <= b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:90:17 + --> $DIR/wide_pointer_comparisons.rs:114:17 | LL | let _ = a > b; | ^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () > b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() > b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:92:17 + --> $DIR/wide_pointer_comparisons.rs:116:17 | LL | let _ = a >= b; | ^^^^^^ | help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | let _ = a as *const () >= b as *const (); - | ++++++++++++ ++++++++++++ +LL | let _ = a.cast::<()>() >= b.cast::<()>(); + | +++++++++++++ +++++++++++++ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:95:17 + --> $DIR/wide_pointer_comparisons.rs:119:17 | LL | let _ = PartialEq::eq(&a, &b); | ^^^^^^^^^^^^^^^^^^^^^ @@ -361,7 +493,7 @@ LL | let _ = std::ptr::eq(a, b); | ~~~~~~~~~~~~~ ~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:97:17 + --> $DIR/wide_pointer_comparisons.rs:121:17 | LL | let _ = PartialEq::ne(&a, &b); | ^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +508,7 @@ LL | let _ = !std::ptr::eq(a, b); | ~~~~~~~~~~~~~~ ~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:99:17 + --> $DIR/wide_pointer_comparisons.rs:123:17 | LL | let _ = a.eq(&b); | ^^^^^^^^ @@ -391,7 +523,7 @@ LL | let _ = std::ptr::eq(a, b); | +++++++++++++ ~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:101:17 + --> $DIR/wide_pointer_comparisons.rs:125:17 | LL | let _ = a.ne(&b); | ^^^^^^^^ @@ -406,7 +538,7 @@ LL | let _ = !std::ptr::eq(a, b); | ++++++++++++++ ~ ~ warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:106:9 + --> $DIR/wide_pointer_comparisons.rs:130:9 | LL | &*a == &*b | ^^^^^^^^^^ @@ -421,7 +553,7 @@ LL | std::ptr::eq(*a, *b) | ~~~~~~~~~~~~~ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:117:14 + --> $DIR/wide_pointer_comparisons.rs:141:14 | LL | cmp!(a, b); | ^^^^ @@ -432,7 +564,7 @@ LL | cmp!(std::ptr::addr_eq(a, b)); | ++++++++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:123:39 + --> $DIR/wide_pointer_comparisons.rs:147:39 | LL | ($a:ident, $b:ident) => { $a == $b } | ^^^^^^^^ @@ -447,7 +579,7 @@ LL | ($a:ident, $b:ident) => { std::ptr::addr_eq($a, $b) } | ++++++++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:133:37 + --> $DIR/wide_pointer_comparisons.rs:157:37 | LL | ($a:expr, $b:expr) => { $a == $b } | ^^ @@ -459,5 +591,5 @@ LL | cmp!(&a, &b); = help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses = note: this warning originates in the macro `cmp` (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 38 warnings emitted +warning: 50 warnings emitted -- cgit 1.4.1-3-g733a5