Add integer_const() and is_zero_integer_const() utility functions
This commit is contained in:
parent
8ec6f1a96f
commit
0fdd0b928e
3 changed files with 19 additions and 13 deletions
|
|
@ -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`",
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue