Auto merge of #117758 - Urgau:lint_pointer_trait_comparisons, r=davidtwco
Add lint against ambiguous wide pointer comparisons This PR is the resolution of https://github.com/rust-lang/rust/issues/106447 decided in https://github.com/rust-lang/rust/issues/117717 by T-lang. ## `ambiguous_wide_pointer_comparisons` *warn-by-default* The `ambiguous_wide_pointer_comparisons` lint checks comparison of `*const/*mut ?Sized` as the operands. ### Example ```rust let ab = (A, B); let a = &ab.0 as *const dyn T; let b = &ab.1 as *const dyn T; let _ = a == b; ``` ### Explanation The comparison includes metadata which may not be expected. ------- This PR also drops `clippy::vtable_address_comparisons` which is superseded by this one. ~~One thing: is the current naming right? `invalid` seems a bit too much.~~ Fixes https://github.com/rust-lang/rust/issues/117717
This commit is contained in:
commit
8a3765582c
@ -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 {}
|
||||
|
@ -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
|
||||
|
@ -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<AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a>>,
|
||||
},
|
||||
#[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<Span>,
|
||||
#[suggestion_part(code = " as *const ()")]
|
||||
left: Span,
|
||||
#[suggestion_part(code = "{deref_right}")]
|
||||
right_before: Option<Span>,
|
||||
#[suggestion_part(code = " as *const ()")]
|
||||
right: Span,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct ImproperCTypes<'a> {
|
||||
pub ty: Ty<'a>,
|
||||
pub desc: &'a str,
|
||||
|
@ -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<Span>,
|
||||
}
|
||||
|
||||
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<hir::BinOpKind> {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,6 +520,8 @@ symbols! {
|
||||
cmp,
|
||||
cmp_max,
|
||||
cmp_min,
|
||||
cmp_partialeq_eq,
|
||||
cmp_partialeq_ne,
|
||||
cmpxchg16b_target_feature,
|
||||
cmse_nonsecure_entry,
|
||||
coerce_unsized,
|
||||
|
@ -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
|
||||
|
||||
|
@ -230,6 +230,7 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
|
||||
/// 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<Rhs: ?Sized = Self> {
|
||||
#[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)
|
||||
}
|
||||
|
@ -1772,6 +1772,7 @@ impl<T> *const [T] {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> 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<T: ?Sized> Eq for *const T {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> 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<T: ?Sized> 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
|
||||
}
|
||||
|
@ -1897,6 +1897,7 @@ pub(crate) const unsafe fn align_offset<T: Sized>(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<T: ?Sized>(a: *const T, b: *const T) -> bool {
|
||||
a == b
|
||||
}
|
||||
|
@ -2199,6 +2199,7 @@ impl<T> *mut [T] {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> 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<T: ?Sized> Eq for *mut T {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> 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<T: ?Sized> 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
|
||||
}
|
||||
|
@ -1791,6 +1791,7 @@ impl<T: ?Sized> Eq for NonNull<T> {}
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> PartialEq for NonNull<T> {
|
||||
#[inline]
|
||||
#[cfg_attr(not(bootstrap), allow(ambiguous_wide_pointer_comparisons))]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_ptr() == other.as_ptr()
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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"),
|
||||
];
|
||||
|
@ -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<dyn Trait> = ...
|
||||
/// let b: Rc<dyn Trait> = ...
|
||||
/// 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()
|
||||
|
@ -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() {}
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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<dyn Debug> = Rc::new(1);
|
||||
Rc::ptr_eq(&a, &a);
|
||||
|
||||
let a: Arc<dyn Debug> = Arc::new(1);
|
||||
Arc::ptr_eq(&a, &a);
|
||||
|
||||
let a: &[u8] = b"";
|
||||
ptr::eq(a, a);
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
138
tests/ui/lint/wide_pointer_comparisons.rs
Normal file
138
tests/ui/lint/wide_pointer_comparisons.rs
Normal file
@ -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<T: ?Sized>(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<dyn std::fmt::Debug> = Rc::new(1);
|
||||
Rc::ptr_eq(&a, &a);
|
||||
|
||||
let a: Arc<dyn std::fmt::Debug> = Arc::new(1);
|
||||
Arc::ptr_eq(&a, &a);
|
||||
}
|
452
tests/ui/lint/wide_pointer_comparisons.stderr
Normal file
452
tests/ui/lint/wide_pointer_comparisons.stderr
Normal file
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user