diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2025-02-25 09:20:55 +0100 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2025-06-20 09:42:27 +0200 |
| commit | 0fdd0b928ed391f89ba4aec6714a1ca4dd67cefd (patch) | |
| tree | b6eccf29c803cdae733d2c8085478b9748de809b | |
| parent | 8ec6f1a96f471a72e7cfed072b5eb4f4b85bc6d6 (diff) | |
| download | rust-0fdd0b928ed391f89ba4aec6714a1ca4dd67cefd.tar.gz rust-0fdd0b928ed391f89ba4aec6714a1ca4dd67cefd.zip | |
Add `integer_const()` and `is_zero_integer_const()` utility functions
| -rw-r--r-- | clippy_lints/src/if_not_else.rs | 11 | ||||
| -rw-r--r-- | clippy_lints/src/operators/identity_op.rs | 6 | ||||
| -rw-r--r-- | clippy_utils/src/consts.rs | 15 |
3 files changed, 19 insertions, 13 deletions
diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs index 45f9aa0a53e..ab7a965b367 100644 --- a/clippy_lints/src/if_not_else.rs +++ b/clippy_lints/src/if_not_else.rs @@ -1,4 +1,4 @@ -use clippy_utils::consts::{ConstEvalCtxt, Constant}; +use clippy_utils::consts::is_zero_integer_const; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::is_else_clause; use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet}; @@ -48,13 +48,6 @@ declare_clippy_lint! { declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]); -fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool { - if let Some(value) = ConstEvalCtxt::new(cx).eval_simple(expr) { - return Constant::Int(0) == value; - } - false -} - impl LateLintPass<'_> for IfNotElse { fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) { if let ExprKind::If(cond, cond_inner, Some(els)) = e.kind @@ -68,7 +61,7 @@ impl LateLintPass<'_> for IfNotElse { ), // Don't lint on `… != 0`, as these are likely to be bit tests. // For example, `if foo & 0x0F00 != 0 { … } else { … }` is already in the "proper" order. - ExprKind::Binary(op, _, rhs) if op.node == BinOpKind::Ne && !is_zero_const(rhs, cx) => ( + ExprKind::Binary(op, _, rhs) if op.node == BinOpKind::Ne && !is_zero_integer_const(cx, rhs) => ( "unnecessary `!=` operation", "change to `==` and swap the blocks of the `if`/`else`", ), diff --git a/clippy_lints/src/operators/identity_op.rs b/clippy_lints/src/operators/identity_op.rs index 7e515e83cc9..3efbb896358 100644 --- a/clippy_lints/src/operators/identity_op.rs +++ b/clippy_lints/src/operators/identity_op.rs @@ -1,4 +1,4 @@ -use clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt}; +use clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt, integer_const, is_zero_integer_const}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{ExprUseNode, clip, expr_use_ctxt, peel_hir_expr_refs, unsext}; @@ -186,9 +186,7 @@ fn is_allowed<'tcx>( cx.typeck_results().expr_ty(left).peel_refs().is_integral() && cx.typeck_results().expr_ty(right).peel_refs().is_integral() // `1 << 0` is a common pattern in bit manipulation code - && !(cmp == BinOpKind::Shl - && ConstEvalCtxt::new(cx).eval_simple(right) == Some(Constant::Int(0)) - && ConstEvalCtxt::new(cx).eval_simple(left) == Some(Constant::Int(1))) + && !(cmp == BinOpKind::Shl && is_zero_integer_const(cx, right) && integer_const(cx, left) == Some(1)) } fn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span: Span, arg: Span) { diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 1ec5d11384f..aaa071fd5c9 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -958,3 +958,18 @@ fn field_of_struct<'tcx>( None } } + +/// If `expr` evaluates to an integer constant, return its value. +pub fn integer_const(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u128> { + if let Some(Constant::Int(value)) = ConstEvalCtxt::new(cx).eval_simple(expr) { + Some(value) + } else { + None + } +} + +/// Check if `expr` evaluates to an integer constant of 0. +#[inline] +pub fn is_zero_integer_const(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + integer_const(cx, expr) == Some(0) +} |
