Skip to content

Commit

Permalink
Fix suggestion with a less volatile approach
Browse files Browse the repository at this point in the history
Revert "Fix span issue on `implicit_saturating_sub`"
This reverts commit 140a127.
  • Loading branch information
blyxyas committed Oct 12, 2024
1 parent 48e98ec commit 2b562de
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 33 deletions.
82 changes: 71 additions & 11 deletions clippy_lints/src/implicit_saturating_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
}) = higher::If::hir(expr)
&& let ExprKind::Binary(ref cond_op, cond_left, cond_right) = cond.kind
{
check_manual_check(cx, cond_op, cond_left, cond_right, if_block, else_block, &self.msrv);
check_manual_check(
cx, expr, cond_op, cond_left, cond_right, if_block, else_block, &self.msrv,
);
}
}

Expand All @@ -117,6 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
#[allow(clippy::too_many_arguments)]
fn check_manual_check<'tcx>(
cx: &LateContext<'tcx>,
expr: &Expr<'tcx>,
condition: &BinOp,
left_hand: &Expr<'tcx>,
right_hand: &Expr<'tcx>,
Expand All @@ -127,12 +130,40 @@ fn check_manual_check<'tcx>(
let ty = cx.typeck_results().expr_ty(left_hand);
if ty.is_numeric() && !ty.is_signed() {
match condition.node {
BinOpKind::Gt | BinOpKind::Ge => {
check_gt(cx, condition.span, left_hand, right_hand, if_block, else_block, msrv);
},
BinOpKind::Lt | BinOpKind::Le => {
check_gt(cx, condition.span, right_hand, left_hand, if_block, else_block, msrv);
},
BinOpKind::Gt | BinOpKind::Ge => check_gt(
cx,
condition.span,
expr.span,
left_hand,
right_hand,
if_block,
else_block,
msrv,
matches!(
clippy_utils::get_parent_expr(cx, expr),
Some(Expr {
kind: ExprKind::If(..),
..
})
),
),
BinOpKind::Lt | BinOpKind::Le => check_gt(
cx,
condition.span,
expr.span,
right_hand,
left_hand,
if_block,
else_block,
msrv,
matches!(
clippy_utils::get_parent_expr(cx, expr),
Some(Expr {
kind: ExprKind::If(..),
..
})
),
),
_ => {},
}
}
Expand All @@ -142,16 +173,28 @@ fn check_manual_check<'tcx>(
fn check_gt(
cx: &LateContext<'_>,
condition_span: Span,
expr_span: Span,
big_var: &Expr<'_>,
little_var: &Expr<'_>,
if_block: &Expr<'_>,
else_block: &Expr<'_>,
msrv: &Msrv,
is_composited: bool,
) {
if let Some(big_var) = Var::new(big_var)
&& let Some(little_var) = Var::new(little_var)
{
check_subtraction(cx, condition_span, big_var, little_var, if_block, else_block, msrv);
check_subtraction(
cx,
condition_span,
expr_span,
big_var,
little_var,
if_block,
else_block,
msrv,
is_composited,
);
}
}

Expand All @@ -173,11 +216,13 @@ impl Var {
fn check_subtraction(
cx: &LateContext<'_>,
condition_span: Span,
expr_span: Span,
big_var: Var,
little_var: Var,
if_block: &Expr<'_>,
else_block: &Expr<'_>,
msrv: &Msrv,
is_composited: bool,
) {
let if_block = peel_blocks(if_block);
let else_block = peel_blocks(else_block);
Expand All @@ -189,7 +234,17 @@ fn check_subtraction(
}
// If the subtraction is done in the `else` block, then we need to also revert the two
// variables as it means that the check was reverted too.
check_subtraction(cx, condition_span, little_var, big_var, else_block, if_block, msrv);
check_subtraction(
cx,
condition_span,
expr_span,
little_var,
big_var,
else_block,
if_block,
msrv,
is_composited,
);
return;
}
if is_integer_literal(else_block, 0)
Expand All @@ -205,13 +260,18 @@ fn check_subtraction(
&& let Some(little_var_snippet) = snippet_opt(cx, little_var.span)
&& (!is_in_const_context(cx) || msrv.meets(msrvs::SATURATING_SUB_CONST))
{
let sugg = format!(
"{}{big_var_snippet}.saturating_sub({little_var_snippet}){}",
if is_composited { "{ " } else { "" },
if is_composited { " }" } else { "" }
);
span_lint_and_sugg(
cx,
IMPLICIT_SATURATING_SUB,
else_block.span,
expr_span,
"manual arithmetic check found",
"replace it with",
format!("{big_var_snippet}.saturating_sub({little_var_snippet})"),
sugg,
Applicability::MachineApplicable,
);
}
Expand Down
7 changes: 1 addition & 6 deletions tests/ui/implicit_saturating_sub.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,8 @@ fn main() {
};
}

// https://github.com/rust-lang/rust-clippy/issues/13524
fn regression_13524(a: usize, b: usize, c: bool) -> usize {
if c {
123
} else if a >= b {
b.saturating_sub(a)
} else {
b - a
}
} else { b.saturating_sub(a) }
}
1 change: 0 additions & 1 deletion tests/ui/implicit_saturating_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ fn main() {
};
}

// https://github.com/rust-lang/rust-clippy/issues/13524
fn regression_13524(a: usize, b: usize, c: bool) -> usize {
if c {
123
Expand Down
11 changes: 8 additions & 3 deletions tests/ui/implicit_saturating_sub.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,15 @@ LL | | }
| |_____^ help: try: `i_64 = i_64.saturating_sub(1);`

error: manual arithmetic check found
--> tests/ui/implicit_saturating_sub.rs:277:9
--> tests/ui/implicit_saturating_sub.rs:275:12
|
LL | 0
| ^ help: replace it with: `b.saturating_sub(a)`
LL | } else if a >= b {
| ____________^
LL | | 0
LL | | } else {
LL | | b - a
LL | | }
| |_____^ help: replace it with: `{ b.saturating_sub(a) }`

error: aborting due to 24 previous errors

8 changes: 4 additions & 4 deletions tests/ui/manual_arithmetic_check.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ fn main() {
let b = 13u32;
let c = 8u32;

let result = if a > b { a - b } else { a.saturating_sub(b) };
let result = a.saturating_sub(b);
//~^ ERROR: manual arithmetic check found
let result = if b < a { a - b } else { a.saturating_sub(b) };
let result = a.saturating_sub(b);
//~^ ERROR: manual arithmetic check found

let result = if a < b { a.saturating_sub(b) } else { a - b };
let result = a.saturating_sub(b);
//~^ ERROR: manual arithmetic check found
let result = if b > a { a.saturating_sub(b) } else { a - b };
let result = a.saturating_sub(b);
//~^ ERROR: manual arithmetic check found

// Should not warn!
Expand Down
16 changes: 8 additions & 8 deletions tests/ui/manual_arithmetic_check.stderr
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
error: manual arithmetic check found
--> tests/ui/manual_arithmetic_check.rs:9:44
--> tests/ui/manual_arithmetic_check.rs:9:18
|
LL | let result = if a > b { a - b } else { 0 };
| ^ help: replace it with: `a.saturating_sub(b)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`
|
= note: `-D clippy::implicit-saturating-sub` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]`

error: manual arithmetic check found
--> tests/ui/manual_arithmetic_check.rs:11:44
--> tests/ui/manual_arithmetic_check.rs:11:18
|
LL | let result = if b < a { a - b } else { 0 };
| ^ help: replace it with: `a.saturating_sub(b)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`

error: manual arithmetic check found
--> tests/ui/manual_arithmetic_check.rs:14:29
--> tests/ui/manual_arithmetic_check.rs:14:18
|
LL | let result = if a < b { 0 } else { a - b };
| ^ help: replace it with: `a.saturating_sub(b)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`

error: manual arithmetic check found
--> tests/ui/manual_arithmetic_check.rs:16:29
--> tests/ui/manual_arithmetic_check.rs:16:18
|
LL | let result = if b > a { 0 } else { a - b };
| ^ help: replace it with: `a.saturating_sub(b)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`

error: aborting due to 4 previous errors

0 comments on commit 2b562de

Please sign in to comment.