diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 934e4b1786faa..3607b7cd9448b 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -11,7 +11,7 @@ thread_local )] #![no_core] -#![allow(dead_code, internal_features)] +#![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] #[lang = "sized"] pub trait Sized {} diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 2db610d640c29..40e6b1b579f5b 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -1,3 +1,7 @@ +lint_ambiguous_wide_pointer_comparisons = ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + .addr_metadata_suggestion = use explicit `std::ptr::eq` method to compare metadata and addresses + .addr_suggestion = use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + lint_array_into_iter = this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <{$target} as IntoIterator>::into_iter in Rust 2021 .use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 9fda53c25334a..d0b895f735482 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1574,6 +1574,76 @@ pub enum InvalidNanComparisonsSuggestion { Spanless, } +#[derive(LintDiagnostic)] +pub enum AmbiguousWidePointerComparisons<'a> { + #[diag(lint_ambiguous_wide_pointer_comparisons)] + Spanful { + #[subdiagnostic] + addr_suggestion: AmbiguousWidePointerComparisonsAddrSuggestion<'a>, + #[subdiagnostic] + addr_metadata_suggestion: Option>, + }, + #[diag(lint_ambiguous_wide_pointer_comparisons)] + #[help(lint_addr_metadata_suggestion)] + #[help(lint_addr_suggestion)] + Spanless, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + lint_addr_metadata_suggestion, + style = "verbose", + applicability = "machine-applicable" +)] +pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> { + pub ne: &'a str, + pub deref_left: &'a str, + pub deref_right: &'a str, + #[suggestion_part(code = "{ne}std::ptr::eq({deref_left}")] + pub left: Span, + #[suggestion_part(code = ", {deref_right}")] + pub middle: Span, + #[suggestion_part(code = ")")] + pub right: Span, +} + +#[derive(Subdiagnostic)] +pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { + #[multipart_suggestion( + lint_addr_suggestion, + style = "verbose", + applicability = "machine-applicable" + )] + AddrEq { + ne: &'a str, + deref_left: &'a str, + deref_right: &'a str, + #[suggestion_part(code = "{ne}std::ptr::addr_eq({deref_left}")] + left: Span, + #[suggestion_part(code = ", {deref_right}")] + middle: Span, + #[suggestion_part(code = ")")] + right: Span, + }, + #[multipart_suggestion( + lint_addr_suggestion, + style = "verbose", + applicability = "machine-applicable" + )] + Cast { + deref_left: &'a str, + deref_right: &'a str, + #[suggestion_part(code = "{deref_left}")] + left_before: Option, + #[suggestion_part(code = " as *const ()")] + left: Span, + #[suggestion_part(code = "{deref_right}")] + right_before: Option, + #[suggestion_part(code = " as *const ()")] + right: Span, + }, +} + pub struct ImproperCTypes<'a> { pub ty: Ty<'a>, pub desc: &'a str, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index bae63ae171645..810d691d16afd 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1,12 +1,13 @@ use crate::{ fluent_generated as fluent, lints::{ - AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes, - InvalidAtomicOrderingDiag, InvalidNanComparisons, InvalidNanComparisonsSuggestion, - OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign, OverflowingBinHexSignBitSub, - OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, - OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, UseInclusiveRange, - VariantSizeDifferencesDiag, + AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion, + AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad, + AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons, + InvalidNanComparisonsSuggestion, OnlyCastu8ToChar, OverflowingBinHex, + OverflowingBinHexSign, OverflowingBinHexSignBitSub, OverflowingBinHexSub, OverflowingInt, + OverflowingIntHelp, OverflowingLiteral, OverflowingUInt, RangeEndpointOutOfRange, + UnusedComparisons, UseInclusiveRange, VariantSizeDifferencesDiag, }, }; use crate::{LateContext, LateLintPass, LintContext}; @@ -17,10 +18,10 @@ use rustc_errors::DiagnosticMessage; use rustc_hir as hir; use rustc_hir::{is_range_literal, Expr, ExprKind, Node}; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton}; -use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{ self, AdtKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; +use rustc_middle::ty::{GenericArgsRef, TypeAndMut}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map; use rustc_span::symbol::sym; @@ -28,6 +29,7 @@ use rustc_span::{Span, Symbol}; use rustc_target::abi::{Abi, Size, WrappingRange}; use rustc_target::abi::{Integer, TagEncoding, Variants}; use rustc_target::spec::abi::Abi as SpecAbi; +use rustc_type_ir::DynKind; use std::iter; use std::ops::ControlFlow; @@ -136,6 +138,37 @@ declare_lint! { "detects invalid floating point NaN comparisons" } +declare_lint! { + /// The `ambiguous_wide_pointer_comparisons` lint checks comparison + /// of `*const/*mut ?Sized` as the operands. + /// + /// ### Example + /// + /// ```rust + /// # struct A; + /// # struct B; + /// + /// # trait T {} + /// # impl T for A {} + /// # impl T for B {} + /// + /// let ab = (A, B); + /// let a = &ab.0 as *const dyn T; + /// let b = &ab.1 as *const dyn T; + /// + /// let _ = a == b; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The comparison includes metadata which may not be expected. + AMBIGUOUS_WIDE_POINTER_COMPARISONS, + Warn, + "detects ambiguous wide pointer comparisons" +} + #[derive(Copy, Clone)] pub struct TypeLimits { /// Id of the last visited negated expression @@ -144,7 +177,12 @@ pub struct TypeLimits { negated_expr_span: Option, } -impl_lint_pass!(TypeLimits => [UNUSED_COMPARISONS, OVERFLOWING_LITERALS, INVALID_NAN_COMPARISONS]); +impl_lint_pass!(TypeLimits => [ + UNUSED_COMPARISONS, + OVERFLOWING_LITERALS, + INVALID_NAN_COMPARISONS, + AMBIGUOUS_WIDE_POINTER_COMPARISONS +]); impl TypeLimits { pub fn new() -> TypeLimits { @@ -620,6 +658,106 @@ fn lint_nan<'tcx>( cx.emit_spanned_lint(INVALID_NAN_COMPARISONS, e.span, lint); } +fn lint_wide_pointer<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx hir::Expr<'tcx>, + binop: hir::BinOpKind, + l: &'tcx hir::Expr<'tcx>, + r: &'tcx hir::Expr<'tcx>, +) { + let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(usize, bool)> { + let mut refs = 0; + // here we remove any "implicit" references and count the number + // of them to correctly suggest the right number of deref + while let ty::Ref(_, inner_ty, _) = ty.kind() { + ty = *inner_ty; + refs += 1; + } + match ty.kind() { + ty::RawPtr(TypeAndMut { mutbl: _, ty }) => (!ty.is_sized(cx.tcx, cx.param_env)) + .then(|| (refs, matches!(ty.kind(), ty::Dynamic(_, _, DynKind::Dyn)))), + _ => None, + } + }; + + // PartialEq::{eq,ne} takes references, remove any explicit references + let l = l.peel_borrows(); + let r = r.peel_borrows(); + + let Some(l_ty) = cx.typeck_results().expr_ty_opt(l) else { + return; + }; + let Some(r_ty) = cx.typeck_results().expr_ty_opt(r) else { + return; + }; + + let Some((l_ty_refs, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else { + return; + }; + let Some((r_ty_refs, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else { + return; + }; + + let (Some(l_span), Some(r_span)) = + (l.span.find_ancestor_inside(e.span), r.span.find_ancestor_inside(e.span)) + else { + return cx.emit_spanned_lint( + AMBIGUOUS_WIDE_POINTER_COMPARISONS, + e.span, + AmbiguousWidePointerComparisons::Spanless, + ); + }; + + let ne = if binop == hir::BinOpKind::Ne { "!" } else { "" }; + let is_eq_ne = matches!(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()); + let middle = l_span.shrink_to_hi().until(r_span.shrink_to_lo()); + let right = r_span.shrink_to_hi().until(e.span.shrink_to_hi()); + + let deref_left = &*"*".repeat(l_ty_refs); + let deref_right = &*"*".repeat(r_ty_refs); + + cx.emit_spanned_lint( + AMBIGUOUS_WIDE_POINTER_COMPARISONS, + e.span, + AmbiguousWidePointerComparisons::Spanful { + addr_metadata_suggestion: (is_eq_ne && !is_dyn_comparison).then(|| { + AmbiguousWidePointerComparisonsAddrMetadataSuggestion { + ne, + deref_left, + deref_right, + left, + middle, + right, + } + }), + addr_suggestion: if is_eq_ne { + AmbiguousWidePointerComparisonsAddrSuggestion::AddrEq { + ne, + deref_left, + deref_right, + left, + middle, + right, + } + } else { + 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, + } + }, + }, + ); +} + impl<'tcx> LateLintPass<'tcx> for TypeLimits { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>) { match e.kind { @@ -636,10 +774,26 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { cx.emit_spanned_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons); } else { lint_nan(cx, e, binop, l, r); + lint_wide_pointer(cx, e, binop.node, l, r); } } } hir::ExprKind::Lit(lit) => lint_literal(cx, self, e, lit), + hir::ExprKind::Call(path, [l, r]) + 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) => + { + lint_wide_pointer(cx, e, binop, 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) => + { + lint_wide_pointer(cx, e, binop, l, r); + } _ => {} }; @@ -722,6 +876,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { | hir::BinOpKind::Gt ) } + + 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 + } + } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f3c5138716d49..0333b5f04c3bc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -520,6 +520,8 @@ symbols! { cmp, cmp_max, cmp_min, + cmp_partialeq_eq, + cmp_partialeq_ne, cmpxchg16b_target_feature, cmse_nonsecure_entry, coerce_unsized, diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 9e5910bf126da..364dc920187d1 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1980,7 +1980,7 @@ fn vec_macro_repeating_null_raw_fat_pointer() { let vec = vec![null_raw_dyn; 1]; dbg!(ptr_metadata(vec[0])); - assert!(vec[0] == null_raw_dyn); + assert!(std::ptr::eq(vec[0], null_raw_dyn)); // Polyfill for https://github.com/rust-lang/rfcs/pull/2580 diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 85246f4f3dc4d..d7c41ac5c063b 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -230,6 +230,7 @@ pub trait PartialEq { /// by `==`. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialeq_eq")] fn eq(&self, other: &Rhs) -> bool; /// This method tests for `!=`. The default implementation is almost always @@ -237,6 +238,7 @@ pub trait PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), rustc_diagnostic_item = "cmp_partialeq_ne")] fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index bdf4ceeba4f6c..a444c30c7560e 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1772,6 +1772,7 @@ impl *const [T] { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for *const T { #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn eq(&self, other: &*const T) -> bool { *self == *other } @@ -1784,6 +1785,7 @@ impl Eq for *const T {} #[stable(feature = "rust1", since = "1.0.0")] impl Ord for *const T { #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn cmp(&self, other: &*const T) -> Ordering { if self < other { Less @@ -1803,21 +1805,25 @@ impl PartialOrd for *const T { } #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn lt(&self, other: &*const T) -> bool { *self < *other } #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn le(&self, other: &*const T) -> bool { *self <= *other } #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn gt(&self, other: &*const T) -> bool { *self > *other } #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn ge(&self, other: &*const T) -> bool { *self >= *other } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 50cf29227ca74..d6603681a0b88 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1897,6 +1897,7 @@ pub(crate) const unsafe fn align_offset(p: *const T, a: usize) -> usiz #[inline(always)] #[must_use = "pointer comparison produces a value"] #[rustc_diagnostic_item = "ptr_eq"] +#[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] // it's actually clear here pub fn eq(a: *const T, b: *const T) -> bool { a == b } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index b07403bd53f59..9e7b8ec64acb3 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -2199,6 +2199,7 @@ impl *mut [T] { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for *mut T { #[inline(always)] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn eq(&self, other: &*mut T) -> bool { *self == *other } @@ -2210,6 +2211,7 @@ impl Eq for *mut T {} #[stable(feature = "rust1", since = "1.0.0")] impl Ord for *mut T { #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn cmp(&self, other: &*mut T) -> Ordering { if self < other { Less @@ -2229,21 +2231,25 @@ impl PartialOrd for *mut T { } #[inline(always)] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn lt(&self, other: &*mut T) -> bool { *self < *other } #[inline(always)] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn le(&self, other: &*mut T) -> bool { *self <= *other } #[inline(always)] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn gt(&self, other: &*mut T) -> bool { *self > *other } #[inline(always)] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn ge(&self, other: &*mut T) -> bool { *self >= *other } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 97fd7593ee1f2..77961506e13c9 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1791,6 +1791,7 @@ impl Eq for NonNull {} #[stable(feature = "nonnull", since = "1.25.0")] impl PartialEq for NonNull { #[inline] + #[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))] fn eq(&self, other: &Self) -> bool { self.as_ptr() == other.as_ptr() } diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index b440e267efe34..3627096ed91bb 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -684,7 +684,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::unit_types::UNIT_ARG_INFO, crate::unit_types::UNIT_CMP_INFO, crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO, - crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO, crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO, crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO, crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO, diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index 613f1ecc6fbee..9f5897d2ca74a 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -58,4 +58,5 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::undropped_manually_drops", "undropped_manually_drops"), ("clippy::unknown_clippy_lints", "unknown_lints"), ("clippy::unused_label", "unused_labels"), + ("clippy::vtable_address_comparisons", "ambiguous_wide_pointer_comparisons"), ]; diff --git a/src/tools/clippy/clippy_lints/src/unnamed_address.rs b/src/tools/clippy/clippy_lints/src/unnamed_address.rs index 41e13e13e56c0..cd2dacc9f099c 100644 --- a/src/tools/clippy/clippy_lints/src/unnamed_address.rs +++ b/src/tools/clippy/clippy_lints/src/unnamed_address.rs @@ -1,9 +1,8 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; +use clippy_utils::diagnostics::span_lint; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::declare_lint_pass; -use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -29,31 +28,7 @@ declare_clippy_lint! { "comparison with an address of a function item" } -declare_clippy_lint! { - /// ### What it does - /// Checks for comparisons with an address of a trait vtable. - /// - /// ### Why is this bad? - /// Comparing trait objects pointers compares an vtable addresses which - /// are not guaranteed to be unique and could vary between different code generation units. - /// Furthermore vtables for different types could have the same address after being merged - /// together. - /// - /// ### Example - /// ```rust,ignore - /// let a: Rc = ... - /// let b: Rc = ... - /// if Rc::ptr_eq(&a, &b) { - /// ... - /// } - /// ``` - #[clippy::version = "1.44.0"] - pub VTABLE_ADDRESS_COMPARISONS, - correctness, - "comparison with an address of a trait vtable" -} - -declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS, VTABLE_ADDRESS_COMPARISONS]); +declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS]); impl LateLintPass<'_> for UnnamedAddress { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { @@ -64,49 +39,10 @@ impl LateLintPass<'_> for UnnamedAddress { ) } - fn is_trait_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - match cx.typeck_results().expr_ty_adjusted(expr).kind() { - ty::RawPtr(ty::TypeAndMut { ty, .. }) => ty.is_trait(), - _ => false, - } - } - fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { matches!(cx.typeck_results().expr_ty(expr).kind(), ty::FnDef(..)) } - if let ExprKind::Binary(binop, left, right) = expr.kind - && is_comparison(binop.node) - && is_trait_ptr(cx, left) - && is_trait_ptr(cx, right) - { - span_lint_and_help( - cx, - VTABLE_ADDRESS_COMPARISONS, - expr.span, - "comparing trait object pointers compares a non-unique vtable address", - None, - "consider extracting and comparing data pointers only", - ); - } - - if let ExprKind::Call(func, [ref _left, ref _right]) = expr.kind - && let ExprKind::Path(ref func_qpath) = func.kind - && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id() - && cx.tcx.is_diagnostic_item(sym::ptr_eq, def_id) - && let ty_param = cx.typeck_results().node_args(func.hir_id).type_at(0) - && ty_param.is_trait() - { - span_lint_and_help( - cx, - VTABLE_ADDRESS_COMPARISONS, - expr.span, - "comparing trait object pointers compares a non-unique vtable address", - None, - "consider extracting and comparing data pointers only", - ); - } - if let ExprKind::Binary(binop, left, right) = expr.kind && is_comparison(binop.node) && cx.typeck_results().expr_ty_adjusted(left).is_fn_ptr() diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 4df9be2c21d9a..31f1ee6a86d1f 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -51,6 +51,7 @@ #![allow(undropped_manually_drops)] #![allow(unknown_lints)] #![allow(unused_labels)] +#![allow(ambiguous_wide_pointer_comparisons)] #![warn(clippy::almost_complete_range)] #![warn(clippy::disallowed_names)] #![warn(clippy::blocks_in_if_conditions)] @@ -107,5 +108,6 @@ #![warn(undropped_manually_drops)] #![warn(unknown_lints)] #![warn(unused_labels)] +#![warn(ambiguous_wide_pointer_comparisons)] fn main() {} diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 940e60068e7b9..325bc356c15f6 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -51,6 +51,7 @@ #![allow(undropped_manually_drops)] #![allow(unknown_lints)] #![allow(unused_labels)] +#![allow(ambiguous_wide_pointer_comparisons)] #![warn(clippy::almost_complete_letter_range)] #![warn(clippy::blacklisted_name)] #![warn(clippy::block_in_if_condition_expr)] @@ -107,5 +108,6 @@ #![warn(clippy::undropped_manually_drops)] #![warn(clippy::unknown_clippy_lints)] #![warn(clippy::unused_label)] +#![warn(clippy::vtable_address_comparisons)] fn main() {} diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 30824e154b8bf..a6164338c20cb 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -8,334 +8,340 @@ LL | #![warn(clippy::almost_complete_letter_range)] = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl` error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl` error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::integer_arithmetic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:75:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:76:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:78:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:79:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:83:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:84:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default` - --> $DIR/rename.rs:84:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::unwrap_or_else_default)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:85:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting` - --> $DIR/rename.rs:86:9 + --> $DIR/rename.rs:87:9 | LL | #![warn(clippy::cast_ref_to_mut)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> $DIR/rename.rs:87:9 + --> $DIR/rename.rs:88:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons` - --> $DIR/rename.rs:88:9 + --> $DIR/rename.rs:89:9 | LL | #![warn(clippy::cmp_nan)] | ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:89:9 + --> $DIR/rename.rs:90:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types` - --> $DIR/rename.rs:90:9 + --> $DIR/rename.rs:91:9 | LL | #![warn(clippy::drop_copy)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types` error: lint `clippy::drop_ref` has been renamed to `dropping_references` - --> $DIR/rename.rs:91:9 + --> $DIR/rename.rs:92:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references` error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks` - --> $DIR/rename.rs:92:9 + --> $DIR/rename.rs:93:9 | LL | #![warn(clippy::fn_null_check)] | ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:93:9 + --> $DIR/rename.rs:94:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:94:9 + --> $DIR/rename.rs:95:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:95:9 + --> $DIR/rename.rs:96:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types` - --> $DIR/rename.rs:96:9 + --> $DIR/rename.rs:97:9 | LL | #![warn(clippy::forget_copy)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types` error: lint `clippy::forget_ref` has been renamed to `forgetting_references` - --> $DIR/rename.rs:97:9 + --> $DIR/rename.rs:98:9 | LL | #![warn(clippy::forget_ref)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:98:9 + --> $DIR/rename.rs:99:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:99:9 + --> $DIR/rename.rs:100:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:100:9 + --> $DIR/rename.rs:101:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked` - --> $DIR/rename.rs:101:9 + --> $DIR/rename.rs:102:9 | LL | #![warn(clippy::invalid_utf8_in_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:102:9 + --> $DIR/rename.rs:103:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:103:9 + --> $DIR/rename.rs:104:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:104:9 + --> $DIR/rename.rs:105:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:105:9 + --> $DIR/rename.rs:106:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:106:9 + --> $DIR/rename.rs:107:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops` - --> $DIR/rename.rs:107:9 + --> $DIR/rename.rs:108:9 | LL | #![warn(clippy::undropped_manually_drops)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:108:9 + --> $DIR/rename.rs:109:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:109:9 + --> $DIR/rename.rs:110:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 56 previous errors +error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons` + --> $DIR/rename.rs:111:9 + | +LL | #![warn(clippy::vtable_address_comparisons)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons` + +error: aborting due to 57 previous errors diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.rs b/src/tools/clippy/tests/ui/vtable_address_comparisons.rs deleted file mode 100644 index 75647c027e146..0000000000000 --- a/src/tools/clippy/tests/ui/vtable_address_comparisons.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::fmt::Debug; -use std::ptr; -use std::rc::Rc; -use std::sync::Arc; - -#[warn(clippy::vtable_address_comparisons)] -#[allow(clippy::borrow_as_ptr)] - -fn main() { - let a: *const dyn Debug = &1 as &dyn Debug; - let b: *const dyn Debug = &1 as &dyn Debug; - - // These should fail: - let _ = a == b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a != b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a < b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a <= b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a > b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - let _ = a >= b; - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - ptr::eq(a, b); - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - - let a = &1 as &dyn Debug; - let b = &1 as &dyn Debug; - ptr::eq(a, b); - //~^ ERROR: comparing trait object pointers compares a non-unique vtable address - - // These should be fine: - let a = &1; - ptr::eq(a, a); - - let a = Rc::new(1); - Rc::ptr_eq(&a, &a); - - let a = Arc::new(1); - Arc::ptr_eq(&a, &a); - - let a: Rc = Rc::new(1); - Rc::ptr_eq(&a, &a); - - let a: Arc = Arc::new(1); - Arc::ptr_eq(&a, &a); - - let a: &[u8] = b""; - ptr::eq(a, a); -} diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr deleted file mode 100644 index 83c82f3796eb4..0000000000000 --- a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr +++ /dev/null @@ -1,68 +0,0 @@ -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:14:13 - | -LL | let _ = a == b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - = note: `-D clippy::vtable-address-comparisons` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::vtable_address_comparisons)]` - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:16:13 - | -LL | let _ = a != b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:18:13 - | -LL | let _ = a < b; - | ^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:20:13 - | -LL | let _ = a <= b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:22:13 - | -LL | let _ = a > b; - | ^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:24:13 - | -LL | let _ = a >= b; - | ^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:26:5 - | -LL | ptr::eq(a, b); - | ^^^^^^^^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: comparing trait object pointers compares a non-unique vtable address - --> $DIR/vtable_address_comparisons.rs:31:5 - | -LL | ptr::eq(a, b); - | ^^^^^^^^^^^^^ - | - = help: consider extracting and comparing data pointers only - -error: aborting due to 8 previous errors - diff --git a/src/tools/miri/tests/pass/pointers.rs b/src/tools/miri/tests/pass/pointers.rs index 1525ded6151e8..c7b720dafa20b 100644 --- a/src/tools/miri/tests/pass/pointers.rs +++ b/src/tools/miri/tests/pass/pointers.rs @@ -2,6 +2,7 @@ //@[tree]compile-flags: -Zmiri-tree-borrows //@compile-flags: -Zmiri-permissive-provenance #![feature(ptr_metadata, const_raw_ptr_comparison)] +#![allow(ambiguous_wide_pointer_comparisons)] use std::mem::{self, transmute}; use std::ptr; diff --git a/src/tools/miri/tests/pass/rc.rs b/src/tools/miri/tests/pass/rc.rs index 6375abcd23286..6dd1b3aff9e72 100644 --- a/src/tools/miri/tests/pass/rc.rs +++ b/src/tools/miri/tests/pass/rc.rs @@ -3,6 +3,7 @@ //@compile-flags: -Zmiri-strict-provenance #![feature(new_uninit)] #![feature(get_mut_unchecked)] +#![allow(ambiguous_wide_pointer_comparisons)] use std::cell::{Cell, RefCell}; use std::fmt::Debug; diff --git a/tests/ui/issues/issue-17336.rs b/tests/ui/issues/issue-17336.rs index 89ce59b11f259..97782ff9f0ef5 100644 --- a/tests/ui/issues/issue-17336.rs +++ b/tests/ui/issues/issue-17336.rs @@ -1,5 +1,8 @@ // build-pass + #![allow(unused_must_use)] +#![allow(ambiguous_wide_pointer_comparisons)] + #[allow(dead_code)] fn check(a: &str) { let x = a as *const str; diff --git a/tests/ui/lint/wide_pointer_comparisons.rs b/tests/ui/lint/wide_pointer_comparisons.rs new file mode 100644 index 0000000000000..8334575cf5297 --- /dev/null +++ b/tests/ui/lint/wide_pointer_comparisons.rs @@ -0,0 +1,138 @@ +// check-pass + +use std::rc::Rc; +use std::sync::Arc; +use std::cmp::PartialEq; + +struct A; +struct B; + +trait T {} +impl T for A {} +impl T for B {} + +fn main() { + let ab = (A, B); + let a = &ab.0 as *const dyn T; + let b = &ab.1 as *const dyn T; + + let _ = a == b; + //~^ WARN ambiguous wide pointer comparison + let _ = a != b; + //~^ WARN ambiguous wide pointer comparison + let _ = a < b; + //~^ WARN ambiguous wide pointer comparison + let _ = a <= b; + //~^ WARN ambiguous wide pointer comparison + let _ = a > b; + //~^ WARN ambiguous wide pointer comparison + let _ = a >= b; + //~^ WARN ambiguous wide pointer comparison + + let _ = PartialEq::eq(&a, &b); + //~^ WARN ambiguous wide pointer comparison + let _ = PartialEq::ne(&a, &b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.eq(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.ne(&b); + //~^ WARN ambiguous wide pointer comparison + + { + // &*const ?Sized + let a = &a; + let b = &b; + + let _ = a == b; + //~^ WARN ambiguous wide pointer comparison + let _ = a != b; + //~^ WARN ambiguous wide pointer comparison + let _ = a < b; + //~^ WARN ambiguous wide pointer comparison + let _ = a <= b; + //~^ WARN ambiguous wide pointer comparison + let _ = a > b; + //~^ WARN ambiguous wide pointer comparison + let _ = a >= b; + //~^ WARN ambiguous wide pointer comparison + + let _ = PartialEq::eq(a, b); + //~^ WARN ambiguous wide pointer comparison + let _ = PartialEq::ne(a, b); + //~^ WARN ambiguous wide pointer comparison + let _ = PartialEq::eq(&a, &b); + //~^ WARN ambiguous wide pointer comparison + let _ = PartialEq::ne(&a, &b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.eq(b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.ne(b); + //~^ WARN ambiguous wide pointer comparison + } + + let s = "" as *const str; + let _ = s == s; + //~^ WARN ambiguous wide pointer comparison + + let s = &[8, 7][..] as *const [i32]; + let _ = s == s; + //~^ WARN ambiguous wide pointer comparison + + fn cmp(a: *mut T, b: *mut T) -> bool { + let _ = a == b; + //~^ WARN ambiguous wide pointer comparison + let _ = a != b; + //~^ WARN ambiguous wide pointer comparison + let _ = a < b; + //~^ WARN ambiguous wide pointer comparison + let _ = a <= b; + //~^ WARN ambiguous wide pointer comparison + let _ = a > b; + //~^ WARN ambiguous wide pointer comparison + let _ = a >= b; + //~^ WARN ambiguous wide pointer comparison + + let _ = PartialEq::eq(&a, &b); + //~^ WARN ambiguous wide pointer comparison + let _ = PartialEq::ne(&a, &b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.eq(&b); + //~^ WARN ambiguous wide pointer comparison + let _ = a.ne(&b); + //~^ WARN ambiguous wide pointer comparison + + let a = &a; + let b = &b; + &*a == &*b + //~^ WARN ambiguous wide pointer comparison + } + + { + macro_rules! cmp { + ($a:ident, $b:ident) => { $a == $b } + //~^ WARN ambiguous wide pointer comparison + } + + cmp!(a, b); + } + + { + // this produce weird diagnostics + macro_rules! cmp { + ($a:expr, $b:expr) => { $a == $b } + //~^ WARN ambiguous wide pointer comparison + } + + cmp!(&a, &b); + } + + let _ = std::ptr::eq(a, b); + let _ = std::ptr::addr_eq(a, b); + let _ = a as *const () == b as *const (); + + let a: Rc = Rc::new(1); + Rc::ptr_eq(&a, &a); + + let a: Arc = Arc::new(1); + Arc::ptr_eq(&a, &a); +} diff --git a/tests/ui/lint/wide_pointer_comparisons.stderr b/tests/ui/lint/wide_pointer_comparisons.stderr new file mode 100644 index 0000000000000..926b8775902c7 --- /dev/null +++ b/tests/ui/lint/wide_pointer_comparisons.stderr @@ -0,0 +1,452 @@ +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:19:13 + | +LL | let _ = a == b; + | ^^^^^^ + | + = note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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:21:13 + | +LL | let _ = a != b; + | ^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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:23:13 + | +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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:25:13 + | +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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:27:13 + | +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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:29:13 + | +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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:32:13 + | +LL | let _ = PartialEq::eq(&a, &b); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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:34:13 + | +LL | let _ = PartialEq::ne(&a, &b); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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:36:13 + | +LL | let _ = a.eq(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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:38:13 + | +LL | let _ = a.ne(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = a == b; + | ^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = a != b; + | ^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +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 (); + | + ++++++++++++ + ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:52: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 (); + | + ++++++++++++ + ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:54: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 (); + | + ++++++++++++ + ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:56: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 (); + | + ++++++++++++ + ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:59:17 + | +LL | let _ = PartialEq::eq(a, b); + | ^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = PartialEq::ne(a, b); + | ^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = PartialEq::eq(&a, &b); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = PartialEq::ne(&a, &b); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = a.eq(b); + | ^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = a.ne(b); + | ^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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 + | +LL | let _ = s == s; + | ^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = std::ptr::addr_eq(s, s); + | ++++++++++++++++++ ~ + +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +LL | let _ = s == s; + | ^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = std::ptr::addr_eq(s, s); + | ++++++++++++++++++ ~ + +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +LL | let _ = a == b; + | ^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = std::ptr::addr_eq(a, b); + | ++++++++++++++++++ ~ + +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +LL | let _ = a != b; + | ^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = !std::ptr::addr_eq(a, b); + | +++++++++++++++++++ ~ + +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:88: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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:90: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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:92: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 (); + | ++++++++++++ ++++++++++++ + +warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected + --> $DIR/wide_pointer_comparisons.rs:95:17 + | +LL | let _ = PartialEq::eq(&a, &b); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = std::ptr::addr_eq(a, b); + | ~~~~~~~~~~~~~~~~~~ ~ ~ +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +LL | let _ = PartialEq::ne(&a, &b); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = !std::ptr::addr_eq(a, b); + | ~~~~~~~~~~~~~~~~~~~ ~ ~ +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +LL | let _ = a.eq(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = std::ptr::addr_eq(a, b); + | ++++++++++++++++++ ~ ~ +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +LL | let _ = a.ne(&b); + | ^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | let _ = !std::ptr::addr_eq(a, b); + | +++++++++++++++++++ ~ ~ +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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 + | +LL | &*a == &*b + | ^^^^^^^^^^ + | +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +LL | std::ptr::addr_eq(*a, *b) + | ~~~~~~~~~~~~~~~~~~ ~ + +help: use explicit `std::ptr::eq` method to compare metadata and addresses + | +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:112:39 + | +LL | ($a:ident, $b:ident) => { $a == $b } + | ^^^^^^^^ +... +LL | cmp!(a, b); + | ---------- in this macro invocation + | + = note: this warning originates in the macro `cmp` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses + | +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:122:37 + | +LL | ($a:expr, $b:expr) => { $a == $b } + | ^^ +... +LL | cmp!(&a, &b); + | ------------ in this macro invocation + | + = help: use explicit `std::ptr::eq` method to compare metadata and addresses + = 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: 37 warnings emitted + diff --git a/tests/ui/mir/mir_raw_fat_ptr.rs b/tests/ui/mir/mir_raw_fat_ptr.rs index 6aceefbe7159d..f4a9afd2308ad 100644 --- a/tests/ui/mir/mir_raw_fat_ptr.rs +++ b/tests/ui/mir/mir_raw_fat_ptr.rs @@ -1,7 +1,9 @@ // run-pass // check raw fat pointer ops in mir // FIXME: please improve this when we get monomorphization support + #![feature(raw_ref_op)] +#![allow(ambiguous_wide_pointer_comparisons)] use std::mem;