1
Fork 0

Add support for NonNull in ambiguous_wide_ptr_comparisions

This commit is contained in:
Urgau 2024-02-19 21:50:33 +01:00
parent af4a5a13a1
commit 16d11c539f
5 changed files with 139 additions and 65 deletions

View file

@ -1632,11 +1632,13 @@ pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
pub ne: &'a str,
pub deref_left: &'a str,
pub deref_right: &'a str,
pub l_modifiers: &'a str,
pub r_modifiers: &'a str,
#[suggestion_part(code = "{ne}std::ptr::eq({deref_left}")]
pub left: Span,
#[suggestion_part(code = ", {deref_right}")]
#[suggestion_part(code = "{l_modifiers}, {deref_right}")]
pub middle: Span,
#[suggestion_part(code = ")")]
#[suggestion_part(code = "{r_modifiers})")]
pub right: Span,
}
@ -1652,11 +1654,13 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
ne: &'a str,
deref_left: &'a str,
deref_right: &'a str,
l_modifiers: &'a str,
r_modifiers: &'a str,
#[suggestion_part(code = "{ne}std::ptr::addr_eq({deref_left}")]
left: Span,
#[suggestion_part(code = ", {deref_right}")]
#[suggestion_part(code = "{l_modifiers}, {deref_right}")]
middle: Span,
#[suggestion_part(code = ")")]
#[suggestion_part(code = "{r_modifiers})")]
right: Span,
},
#[multipart_suggestion(
@ -1670,13 +1674,15 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
deref_right: &'a str,
paren_left: &'a str,
paren_right: &'a str,
l_modifiers: &'a str,
r_modifiers: &'a str,
#[suggestion_part(code = "({deref_left}")]
left_before: Option<Span>,
#[suggestion_part(code = "{paren_left}.cast::<()>()")]
#[suggestion_part(code = "{l_modifiers}{paren_left}.cast::<()>()")]
left_after: Span,
#[suggestion_part(code = "({deref_right}")]
right_before: Option<Span>,
#[suggestion_part(code = "{paren_right}.cast::<()>()")]
#[suggestion_part(code = "{r_modifiers}{paren_right}.cast::<()>()")]
right_after: Span,
},
}

View file

@ -670,7 +670,11 @@ fn lint_wide_pointer<'tcx>(
l: &'tcx hir::Expr<'tcx>,
r: &'tcx hir::Expr<'tcx>,
) {
let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(usize, bool)> {
let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(
/* number of refs */ usize,
/* modifiers */ String,
/* is dyn */ 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
@ -678,11 +682,20 @@ fn lint_wide_pointer<'tcx>(
ty = *inner_ty;
refs += 1;
}
match ty.kind() {
ty::RawPtr(ty, _) => (!ty.is_sized(cx.tcx, cx.param_env))
.then(|| (refs, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn)))),
_ => None,
}
// get the inner type of a pointer (or akin)
let mut modifiers = String::new();
ty = match ty.kind() {
ty::RawPtr(ty, _) => *ty,
ty::Adt(def, args) if cx.tcx.is_diagnostic_item(sym::NonNull, def.did()) => {
modifiers.push_str(".as_ptr()");
args.type_at(0)
}
_ => return None,
};
(!ty.is_sized(cx.tcx, cx.param_env))
.then(|| (refs, modifiers, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn))))
};
// the left and right operands can have references, remove any explicit references
@ -696,10 +709,10 @@ fn lint_wide_pointer<'tcx>(
return;
};
let Some((l_ty_refs, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else {
let Some((l_ty_refs, l_modifiers, 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 {
let Some((r_ty_refs, r_modifiers, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else {
return;
};
@ -724,6 +737,9 @@ fn lint_wide_pointer<'tcx>(
let deref_left = &*"*".repeat(l_ty_refs);
let deref_right = &*"*".repeat(r_ty_refs);
let l_modifiers = &*l_modifiers;
let r_modifiers = &*r_modifiers;
cx.emit_span_lint(
AMBIGUOUS_WIDE_POINTER_COMPARISONS,
e.span,
@ -733,6 +749,8 @@ fn lint_wide_pointer<'tcx>(
ne,
deref_left,
deref_right,
l_modifiers,
r_modifiers,
left,
middle,
right,
@ -743,6 +761,8 @@ fn lint_wide_pointer<'tcx>(
ne,
deref_left,
deref_right,
l_modifiers,
r_modifiers,
left,
middle,
right,
@ -751,6 +771,8 @@ fn lint_wide_pointer<'tcx>(
AmbiguousWidePointerComparisonsAddrSuggestion::Cast {
deref_left,
deref_right,
l_modifiers,
r_modifiers,
paren_left: if l_ty_refs != 0 { ")" } else { "" },
paren_right: if r_ty_refs != 0 { ")" } else { "" },
left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()),