diff options
| author | Jason Newcomb <jsnewcomb@pm.me> | 2022-06-01 10:37:37 -0400 |
|---|---|---|
| committer | Jason Newcomb <jsnewcomb@pm.me> | 2022-06-28 12:51:30 -0400 |
| commit | 92891a01a1a8c9a703dd6323567ed8d9914e562f (patch) | |
| tree | 43e7a0e983489a40726465c0f8d27ceed07aeb94 | |
| parent | fc5eac58948d5a93304bd2eaa8b566de7018e408 (diff) | |
| download | rust-92891a01a1a8c9a703dd6323567ed8d9914e562f.tar.gz rust-92891a01a1a8c9a703dd6323567ed8d9914e562f.zip | |
Move `PtrEq` into `Operators` lin pass
| -rw-r--r-- | clippy_lints/src/lib.register_all.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.register_lints.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.register_style.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/operators/mod.rs | 32 | ||||
| -rw-r--r-- | clippy_lints/src/operators/ptr_eq.rs | 65 | ||||
| -rw-r--r-- | clippy_lints/src/ptr_eq.rs | 97 |
7 files changed, 100 insertions, 102 deletions
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs index 06f8a6325ff..b8aac47202c 100644 --- a/clippy_lints/src/lib.register_all.rs +++ b/clippy_lints/src/lib.register_all.rs @@ -260,6 +260,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![ LintId::of(operators::MISREFACTORED_ASSIGN_OP), LintId::of(operators::MODULO_ONE), LintId::of(operators::OP_REF), + LintId::of(operators::PTR_EQ), LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP), LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL), LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL), @@ -268,7 +269,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![ LintId::of(ptr::INVALID_NULL_PTR_USAGE), LintId::of(ptr::MUT_FROM_REF), LintId::of(ptr::PTR_ARG), - LintId::of(ptr_eq::PTR_EQ), LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST), LintId::of(question_mark::QUESTION_MARK), LintId::of(ranges::MANUAL_RANGE_CONTAINS), diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs index d006aa4bce5..408f2857263 100644 --- a/clippy_lints/src/lib.register_lints.rs +++ b/clippy_lints/src/lib.register_lints.rs @@ -436,6 +436,7 @@ store.register_lints(&[ operators::MODULO_ONE, operators::NEEDLESS_BITWISE_BOOL, operators::OP_REF, + operators::PTR_EQ, operators::VERBOSE_BIT_MASK, option_env_unwrap::OPTION_ENV_UNWRAP, option_if_let_else::OPTION_IF_LET_ELSE, @@ -455,7 +456,6 @@ store.register_lints(&[ ptr::INVALID_NULL_PTR_USAGE, ptr::MUT_FROM_REF, ptr::PTR_ARG, - ptr_eq::PTR_EQ, ptr_offset_with_cast::PTR_OFFSET_WITH_CAST, pub_use::PUB_USE, question_mark::QUESTION_MARK, diff --git a/clippy_lints/src/lib.register_style.rs b/clippy_lints/src/lib.register_style.rs index a438577d992..15a1bc569af 100644 --- a/clippy_lints/src/lib.register_style.rs +++ b/clippy_lints/src/lib.register_style.rs @@ -98,9 +98,9 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![ LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS), LintId::of(operators::ASSIGN_OP_PATTERN), LintId::of(operators::OP_REF), + LintId::of(operators::PTR_EQ), LintId::of(ptr::CMP_NULL), LintId::of(ptr::PTR_ARG), - LintId::of(ptr_eq::PTR_EQ), LintId::of(question_mark::QUESTION_MARK), LintId::of(ranges::MANUAL_RANGE_CONTAINS), LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES), diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 42d4abcde43..7b618831ae0 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -335,7 +335,6 @@ mod path_buf_push_overwrite; mod pattern_type_mismatch; mod precedence; mod ptr; -mod ptr_eq; mod ptr_offset_with_cast; mod pub_use; mod question_mark; @@ -571,7 +570,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| Box::new(enum_clike::UnportableVariant)); store.register_late_pass(|| Box::new(float_literal::FloatLiteral)); store.register_late_pass(|| Box::new(ptr::Ptr)); - store.register_late_pass(|| Box::new(ptr_eq::PtrEq)); store.register_late_pass(|| Box::new(needless_bool::NeedlessBool)); store.register_late_pass(|| Box::new(needless_bool::BoolComparison)); store.register_late_pass(|| Box::new(needless_for_each::NeedlessForEach)); diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 0c5b8f3da6a..b2cf1660ae0 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -21,6 +21,7 @@ mod modulo_one; mod needless_bitwise_bool; mod numeric_arithmetic; mod op_ref; +mod ptr_eq; mod verbose_bit_mask; declare_clippy_lint! { @@ -671,6 +672,35 @@ declare_clippy_lint! { "Boolean expressions that use bitwise rather than lazy operators" } +declare_clippy_lint! { + /// ### What it does + /// Use `std::ptr::eq` when applicable + /// + /// ### Why is this bad? + /// `ptr::eq` can be used to compare `&T` references + /// (which coerce to `*const T` implicitly) by their address rather than + /// comparing the values they point to. + /// + /// ### Example + /// ```rust + /// let a = &[1, 2, 3]; + /// let b = &[1, 2, 3]; + /// + /// assert!(a as *const _ as usize == b as *const _ as usize); + /// ``` + /// Use instead: + /// ```rust + /// let a = &[1, 2, 3]; + /// let b = &[1, 2, 3]; + /// + /// assert!(std::ptr::eq(a, b)); + /// ``` + #[clippy::version = "1.49.0"] + pub PTR_EQ, + style, + "use `std::ptr::eq` when comparing raw pointers" +} + pub struct Operators { arithmetic_context: numeric_arithmetic::Context, verbose_bit_mask_threshold: u64, @@ -699,6 +729,7 @@ impl_lint_pass!(Operators => [ MODULO_ONE, MODULO_ARITHMETIC, NEEDLESS_BITWISE_BOOL, + PTR_EQ, ]); impl Operators { pub fn new(verbose_bit_mask_threshold: u64) -> Self { @@ -722,6 +753,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators { erasing_op::check(cx, e, op.node, lhs, rhs); identity_op::check(cx, e, op.node, lhs, rhs); needless_bitwise_bool::check(cx, e, op.node, lhs, rhs); + ptr_eq::check(cx, e, op.node, lhs, rhs); } self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs); bit_mask::check(cx, e, op.node, lhs, rhs); diff --git a/clippy_lints/src/operators/ptr_eq.rs b/clippy_lints/src/operators/ptr_eq.rs new file mode 100644 index 00000000000..1aefc2741c2 --- /dev/null +++ b/clippy_lints/src/operators/ptr_eq.rs @@ -0,0 +1,65 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_opt; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_hir::{BinOpKind, Expr, ExprKind}; +use rustc_lint::LateContext; + +use super::PTR_EQ; + +static LINT_MSG: &str = "use `std::ptr::eq` when comparing raw pointers"; + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + op: BinOpKind, + left: &'tcx Expr<'_>, + right: &'tcx Expr<'_>, +) { + if BinOpKind::Eq == op { + let (left, right) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) { + (Some(lhs), Some(rhs)) => (lhs, rhs), + _ => (left, right), + }; + + if_chain! { + if let Some(left_var) = expr_as_cast_to_raw_pointer(cx, left); + if let Some(right_var) = expr_as_cast_to_raw_pointer(cx, right); + if let Some(left_snip) = snippet_opt(cx, left_var.span); + if let Some(right_snip) = snippet_opt(cx, right_var.span); + then { + span_lint_and_sugg( + cx, + PTR_EQ, + expr.span, + LINT_MSG, + "try", + format!("std::ptr::eq({}, {})", left_snip, right_snip), + Applicability::MachineApplicable, + ); + } + } + } +} + +// If the given expression is a cast to a usize, return the lhs of the cast +// E.g., `foo as *const _ as usize` returns `foo as *const _`. +fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { + if cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize { + if let ExprKind::Cast(expr, _) = cast_expr.kind { + return Some(expr); + } + } + None +} + +// If the given expression is a cast to a `*const` pointer, return the lhs of the cast +// E.g., `foo as *const _` returns `foo`. +fn expr_as_cast_to_raw_pointer<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { + if cx.typeck_results().expr_ty(cast_expr).is_unsafe_ptr() { + if let ExprKind::Cast(expr, _) = cast_expr.kind { + return Some(expr); + } + } + None +} diff --git a/clippy_lints/src/ptr_eq.rs b/clippy_lints/src/ptr_eq.rs deleted file mode 100644 index 2bec93ac606..00000000000 --- a/clippy_lints/src/ptr_eq.rs +++ /dev/null @@ -1,97 +0,0 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_opt; -use if_chain::if_chain; -use rustc_errors::Applicability; -use rustc_hir::{BinOpKind, Expr, ExprKind}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; - -declare_clippy_lint! { - /// ### What it does - /// Use `std::ptr::eq` when applicable - /// - /// ### Why is this bad? - /// `ptr::eq` can be used to compare `&T` references - /// (which coerce to `*const T` implicitly) by their address rather than - /// comparing the values they point to. - /// - /// ### Example - /// ```rust - /// let a = &[1, 2, 3]; - /// let b = &[1, 2, 3]; - /// - /// assert!(a as *const _ as usize == b as *const _ as usize); - /// ``` - /// Use instead: - /// ```rust - /// let a = &[1, 2, 3]; - /// let b = &[1, 2, 3]; - /// - /// assert!(std::ptr::eq(a, b)); - /// ``` - #[clippy::version = "1.49.0"] - pub PTR_EQ, - style, - "use `std::ptr::eq` when comparing raw pointers" -} - -declare_lint_pass!(PtrEq => [PTR_EQ]); - -static LINT_MSG: &str = "use `std::ptr::eq` when comparing raw pointers"; - -impl<'tcx> LateLintPass<'tcx> for PtrEq { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if expr.span.from_expansion() { - return; - } - - if let ExprKind::Binary(ref op, left, right) = expr.kind { - if BinOpKind::Eq == op.node { - let (left, right) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) { - (Some(lhs), Some(rhs)) => (lhs, rhs), - _ => (left, right), - }; - - if_chain! { - if let Some(left_var) = expr_as_cast_to_raw_pointer(cx, left); - if let Some(right_var) = expr_as_cast_to_raw_pointer(cx, right); - if let Some(left_snip) = snippet_opt(cx, left_var.span); - if let Some(right_snip) = snippet_opt(cx, right_var.span); - then { - span_lint_and_sugg( - cx, - PTR_EQ, - expr.span, - LINT_MSG, - "try", - format!("std::ptr::eq({}, {})", left_snip, right_snip), - Applicability::MachineApplicable, - ); - } - } - } - } - } -} - -// If the given expression is a cast to a usize, return the lhs of the cast -// E.g., `foo as *const _ as usize` returns `foo as *const _`. -fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize { - if let ExprKind::Cast(expr, _) = cast_expr.kind { - return Some(expr); - } - } - None -} - -// If the given expression is a cast to a `*const` pointer, return the lhs of the cast -// E.g., `foo as *const _` returns `foo`. -fn expr_as_cast_to_raw_pointer<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if cx.typeck_results().expr_ty(cast_expr).is_unsafe_ptr() { - if let ExprKind::Cast(expr, _) = cast_expr.kind { - return Some(expr); - } - } - None -} |
