Auto merge of #121268 - Urgau:improve_ambi_wide_ptr_cmps, r=Nadrieril
Add detection of [Partial]Ord methods in the `ambiguous_wide_pointer_comparisons` lint Partially addresses https://github.com/rust-lang/rust/issues/121264 by adding diagnostics items for PartialOrd and Ord methods, detecting such diagnostics items as "binary operation" and suggesting the correct replacement. I also took the opportunity to change the suggestion to use new methods `.cast()` on `*mut T` an d `*const T`.
This commit is contained in:
commit
af4a5a13a1
10 changed files with 271 additions and 82 deletions
|
@ -1668,14 +1668,16 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
|
|||
Cast {
|
||||
deref_left: &'a str,
|
||||
deref_right: &'a str,
|
||||
#[suggestion_part(code = "{deref_left}")]
|
||||
paren_left: &'a str,
|
||||
paren_right: &'a str,
|
||||
#[suggestion_part(code = "({deref_left}")]
|
||||
left_before: Option<Span>,
|
||||
#[suggestion_part(code = " as *const ()")]
|
||||
left: Span,
|
||||
#[suggestion_part(code = "{deref_right}")]
|
||||
#[suggestion_part(code = "{paren_left}.cast::<()>()")]
|
||||
left_after: Span,
|
||||
#[suggestion_part(code = "({deref_right}")]
|
||||
right_before: Option<Span>,
|
||||
#[suggestion_part(code = " as *const ()")]
|
||||
right: Span,
|
||||
#[suggestion_part(code = "{paren_right}.cast::<()>()")]
|
||||
right_after: Span,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -657,10 +657,16 @@ fn lint_nan<'tcx>(
|
|||
cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum ComparisonOp {
|
||||
BinOp(hir::BinOpKind),
|
||||
Other,
|
||||
}
|
||||
|
||||
fn lint_wide_pointer<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
e: &'tcx hir::Expr<'tcx>,
|
||||
binop: hir::BinOpKind,
|
||||
cmpop: ComparisonOp,
|
||||
l: &'tcx hir::Expr<'tcx>,
|
||||
r: &'tcx hir::Expr<'tcx>,
|
||||
) {
|
||||
|
@ -679,7 +685,7 @@ fn lint_wide_pointer<'tcx>(
|
|||
}
|
||||
};
|
||||
|
||||
// PartialEq::{eq,ne} takes references, remove any explicit references
|
||||
// the left and right operands can have references, remove any explicit references
|
||||
let l = l.peel_borrows();
|
||||
let r = r.peel_borrows();
|
||||
|
||||
|
@ -707,8 +713,8 @@ fn lint_wide_pointer<'tcx>(
|
|||
);
|
||||
};
|
||||
|
||||
let ne = if binop == hir::BinOpKind::Ne { "!" } else { "" };
|
||||
let is_eq_ne = matches!(binop, hir::BinOpKind::Eq | hir::BinOpKind::Ne);
|
||||
let ne = if cmpop == ComparisonOp::BinOp(hir::BinOpKind::Ne) { "!" } else { "" };
|
||||
let is_eq_ne = matches!(cmpop, ComparisonOp::BinOp(hir::BinOpKind::Eq | hir::BinOpKind::Ne));
|
||||
let is_dyn_comparison = l_inner_ty_is_dyn && r_inner_ty_is_dyn;
|
||||
|
||||
let left = e.span.shrink_to_lo().until(l_span.shrink_to_lo());
|
||||
|
@ -745,12 +751,12 @@ fn lint_wide_pointer<'tcx>(
|
|||
AmbiguousWidePointerComparisonsAddrSuggestion::Cast {
|
||||
deref_left,
|
||||
deref_right,
|
||||
// those two Options are required for correctness as having
|
||||
// an empty span and an empty suggestion is not permitted
|
||||
left_before: (l_ty_refs != 0).then_some(left),
|
||||
right_before: (r_ty_refs != 0).then(|| r_span.shrink_to_lo()),
|
||||
left: l_span.shrink_to_hi(),
|
||||
right,
|
||||
paren_left: if l_ty_refs != 0 { ")" } else { "" },
|
||||
paren_right: if r_ty_refs != 0 { ")" } else { "" },
|
||||
left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()),
|
||||
left_after: l_span.shrink_to_hi(),
|
||||
right_before: (r_ty_refs != 0).then_some(r_span.shrink_to_lo()),
|
||||
right_after: r_span.shrink_to_hi(),
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -773,7 +779,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
|||
cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
|
||||
} else {
|
||||
lint_nan(cx, e, binop, l, r);
|
||||
lint_wide_pointer(cx, e, binop.node, l, r);
|
||||
lint_wide_pointer(cx, e, ComparisonOp::BinOp(binop.node), l, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -782,16 +788,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
|||
if let ExprKind::Path(ref qpath) = path.kind
|
||||
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
|
||||
&& let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
|
||||
&& let Some(binop) = partialeq_binop(diag_item) =>
|
||||
&& let Some(cmpop) = diag_item_cmpop(diag_item) =>
|
||||
{
|
||||
lint_wide_pointer(cx, e, binop, l, r);
|
||||
lint_wide_pointer(cx, e, cmpop, l, r);
|
||||
}
|
||||
hir::ExprKind::MethodCall(_, l, [r], _)
|
||||
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
|
||||
&& let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
|
||||
&& let Some(binop) = partialeq_binop(diag_item) =>
|
||||
&& let Some(cmpop) = diag_item_cmpop(diag_item) =>
|
||||
{
|
||||
lint_wide_pointer(cx, e, binop, l, r);
|
||||
lint_wide_pointer(cx, e, cmpop, l, r);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
@ -876,14 +882,20 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
|||
)
|
||||
}
|
||||
|
||||
fn partialeq_binop(diag_item: Symbol) -> Option<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
|
||||
}
|
||||
fn diag_item_cmpop(diag_item: Symbol) -> Option<ComparisonOp> {
|
||||
Some(match diag_item {
|
||||
sym::cmp_ord_max => ComparisonOp::Other,
|
||||
sym::cmp_ord_min => ComparisonOp::Other,
|
||||
sym::ord_cmp_method => ComparisonOp::Other,
|
||||
sym::cmp_partialeq_eq => ComparisonOp::BinOp(hir::BinOpKind::Eq),
|
||||
sym::cmp_partialeq_ne => ComparisonOp::BinOp(hir::BinOpKind::Ne),
|
||||
sym::cmp_partialord_cmp => ComparisonOp::Other,
|
||||
sym::cmp_partialord_ge => ComparisonOp::BinOp(hir::BinOpKind::Ge),
|
||||
sym::cmp_partialord_gt => ComparisonOp::BinOp(hir::BinOpKind::Gt),
|
||||
sym::cmp_partialord_le => ComparisonOp::BinOp(hir::BinOpKind::Le),
|
||||
sym::cmp_partialord_lt => ComparisonOp::BinOp(hir::BinOpKind::Lt),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue