1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::source::snippet_opt;
3 use if_chain::if_chain;
4 use rustc_errors::Applicability;
5 use rustc_hir::{BinOpKind, Expr, ExprKind};
6 use rustc_lint::LateContext;
10 static LINT_MSG: &str = "use `std::ptr::eq` when comparing raw pointers";
12 pub(super) fn check<'tcx>(
13 cx: &LateContext<'tcx>,
17 right: &'tcx Expr<'_>,
19 if BinOpKind::Eq == op {
20 let (left, right) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) {
21 (Some(lhs), Some(rhs)) => (lhs, rhs),
26 if let Some(left_var) = expr_as_cast_to_raw_pointer(cx, left);
27 if let Some(right_var) = expr_as_cast_to_raw_pointer(cx, right);
28 if let Some(left_snip) = snippet_opt(cx, left_var.span);
29 if let Some(right_snip) = snippet_opt(cx, right_var.span);
37 format!("std::ptr::eq({left_snip}, {right_snip})"),
38 Applicability::MachineApplicable,
45 // If the given expression is a cast to a usize, return the lhs of the cast
46 // E.g., `foo as *const _ as usize` returns `foo as *const _`.
47 fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
48 if cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize {
49 if let ExprKind::Cast(expr, _) = cast_expr.kind {
56 // If the given expression is a cast to a `*const` pointer, return the lhs of the cast
57 // E.g., `foo as *const _` returns `foo`.
58 fn expr_as_cast_to_raw_pointer<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
59 if cx.typeck_results().expr_ty(cast_expr).is_unsafe_ptr() {
60 if let ExprKind::Cast(expr, _) = cast_expr.kind {