use clippy_utils::source::snippet;
-use if_chain::if_chain;
use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use clippy_utils::{clip, unsext};
declare_clippy_lint! {
- /// **What it does:** Checks for identity operations, e.g., `x + 0`.
+ /// ### What it does
+ /// Checks for identity operations, e.g., `x + 0`.
///
- /// **Why is this bad?** This code can be removed without changing the
+ /// ### Why is this bad?
+ /// This code can be removed without changing the
/// meaning. So it just obscures what's going on. Delete it mercilessly.
///
- /// **Known problems:** None.
- ///
- /// **Example:**
+ /// ### Example
/// ```rust
/// # let x = 1;
/// x / 1 + 0 * 1 - 0 | 0;
/// ```
+ #[clippy::version = "pre 1.29.0"]
pub IDENTITY_OP,
complexity,
"using identity operations, e.g., `x + 0` or `y / 1`"
}
fn is_allowed(cx: &LateContext<'_>, cmp: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> bool {
- // `1 << 0` is a common pattern in bit manipulation code
- if_chain! {
- if let BinOpKind::Shl = cmp.node;
- if let Some(Constant::Int(0)) = constant_simple(cx, cx.typeck_results(), right);
- if let Some(Constant::Int(1)) = constant_simple(cx, cx.typeck_results(), left);
- then {
- return true;
- }
- }
-
- false
+ // This lint applies to integers
+ !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.node == BinOpKind::Shl
+ && constant_simple(cx, cx.typeck_results(), right) == Some(Constant::Int(0))
+ && constant_simple(cx, cx.typeck_results(), left) == Some(Constant::Int(1)))
}
-#[allow(clippy::cast_possible_wrap)]
fn check(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) {
- if let Some(Constant::Int(v)) = constant_simple(cx, cx.typeck_results(), e) {
- let check = match *cx.typeck_results().expr_ty(e).kind() {
+ if let Some(Constant::Int(v)) = constant_simple(cx, cx.typeck_results(), e).map(Constant::peel_refs) {
+ let check = match *cx.typeck_results().expr_ty(e).peel_refs().kind() {
ty::Int(ity) => unsext(cx.tcx, -1_i128, ity),
ty::Uint(uty) => clip(cx.tcx, !0, uty),
_ => return,