Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book/src/lint_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next)
* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)
* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
* [`implicit_saturating_sub`](https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_sub)
* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
* [`inefficient_to_string`](https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string)
* [`io_other_error`](https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error)
Expand Down
1 change: 1 addition & 0 deletions clippy_config/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ define_Conf! {
filter_map_next,
from_over_into,
if_then_some_else_none,
implicit_saturating_sub,
index_refutable_slice,
inefficient_to_string,
io_other_error,
Expand Down
7 changes: 6 additions & 1 deletion clippy_lints/src/implicit_saturating_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
// Check if the conditional expression is a binary operation
&& let ExprKind::Binary(ref cond_op, cond_left, cond_right) = cond.kind
{
check_with_condition(cx, expr, cond_op.node, cond_left, cond_right, then);
check_with_condition(cx, expr, cond_op.node, cond_left, cond_right, then, self.msrv);
} else if let Some(higher::If {
cond,
then: if_block,
Expand Down Expand Up @@ -309,6 +309,7 @@ fn check_with_condition<'tcx>(
cond_left: &Expr<'tcx>,
cond_right: &Expr<'tcx>,
then: &Expr<'tcx>,
msrv: Msrv,
) {
// Ensure that the binary operator is >, !=, or <
if (BinOpKind::Ne == cond_op || BinOpKind::Gt == cond_op || BinOpKind::Lt == cond_op)
Expand Down Expand Up @@ -342,6 +343,10 @@ fn check_with_condition<'tcx>(
return;
}

if is_in_const_context(cx) && !msrv.meets(cx, msrvs::SATURATING_SUB_CONST) {
return;
}

// Get the variable name
let var_name = ares_path.segments[0].ident.name;
match cond_num_val.kind {
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/implicit_saturating_sub.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,23 @@ fn wrongly_unmangled_macros() {
let b = 20u64;
let _ = test_big!(a).saturating_sub(test_little!(b));
}

#[clippy::msrv = "1.46.0"]
pub const fn const_msrv_too_low(mut x: u32) -> u32 {
if x != 0 {
x -= 1;
}
x
}

#[clippy::msrv = "1.47.0"]
pub const fn const_msrv_ok(mut x: u32) -> u32 {
x = x.saturating_sub(1);
x
}

#[clippy::msrv = "1.46.0"]
pub fn nonconst_msrv_low(mut x: u32) -> u32 {
x = x.saturating_sub(1);
x
}
26 changes: 26 additions & 0 deletions tests/ui/implicit_saturating_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,29 @@ fn wrongly_unmangled_macros() {
0
};
}

#[clippy::msrv = "1.46.0"]
pub const fn const_msrv_too_low(mut x: u32) -> u32 {
if x != 0 {
x -= 1;
}
x
}

#[clippy::msrv = "1.47.0"]
pub const fn const_msrv_ok(mut x: u32) -> u32 {
if x != 0 {
//~^ implicit_saturating_sub
x -= 1;
}
x
}

#[clippy::msrv = "1.46.0"]
pub fn nonconst_msrv_low(mut x: u32) -> u32 {
if x != 0 {
//~^ implicit_saturating_sub
x -= 1;
}
x
}
20 changes: 19 additions & 1 deletion tests/ui/implicit_saturating_sub.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,23 @@ LL | | 0
LL | | };
| |_____^ help: replace it with: `test_big!(a).saturating_sub(test_little!(b))`

error: aborting due to 29 previous errors
error: implicitly performing saturating subtraction
--> tests/ui/implicit_saturating_sub.rs:371:5
|
LL | / if x != 0 {
LL | |
LL | | x -= 1;
LL | | }
| |_____^ help: try: `x = x.saturating_sub(1);`

error: implicitly performing saturating subtraction
--> tests/ui/implicit_saturating_sub.rs:380:5
|
LL | / if x != 0 {
LL | |
LL | | x -= 1;
LL | | }
| |_____^ help: try: `x = x.saturating_sub(1);`

error: aborting due to 31 previous errors

Loading