about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-07-19 14:51:56 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2024-08-29 20:20:13 +0200
commitd20fc38f0a17561166fb57c83ff5660b3cd41392 (patch)
tree35616a50b15cbc536df28d8fc9a4d2e156296fcb
parent27c63433659773c70dca86a3d6f3b9bd7654c2c3 (diff)
downloadrust-d20fc38f0a17561166fb57c83ff5660b3cd41392.tar.gz
rust-d20fc38f0a17561166fb57c83ff5660b3cd41392.zip
Create new `inverted_saturating_sub` lint
-rw-r--r--CHANGELOG.md1
-rw-r--r--clippy_lints/src/declared_lints.rs1
-rw-r--r--clippy_lints/src/implicit_saturating_sub.rs34
-rw-r--r--tests/ui/manual_arithmetic_check-2.stderr3
-rw-r--r--tests/ui/manual_arithmetic_check.fixed2
-rw-r--r--tests/ui/manual_arithmetic_check.rs2
6 files changed, 37 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fddc2fd994e..0bef3552966 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5500,6 +5500,7 @@ Released 2018-09-13
 [`invalid_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_regex
 [`invalid_upcast_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_upcast_comparisons
 [`invalid_utf8_in_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_utf8_in_unchecked
+[`inverted_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#inverted_saturating_sub
 [`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters
 [`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix
 [`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
index 8754a4dff87..a6dd6ae7312 100644
--- a/clippy_lints/src/declared_lints.rs
+++ b/clippy_lints/src/declared_lints.rs
@@ -216,6 +216,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::implicit_return::IMPLICIT_RETURN_INFO,
     crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
     crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
+    crate::implicit_saturating_sub::INVERTED_SATURATING_SUB_INFO,
     crate::implied_bounds_in_impls::IMPLIED_BOUNDS_IN_IMPLS_INFO,
     crate::incompatible_msrv::INCOMPATIBLE_MSRV_INFO,
     crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs
index 453ff09bf4f..04c89062039 100644
--- a/clippy_lints/src/implicit_saturating_sub.rs
+++ b/clippy_lints/src/implicit_saturating_sub.rs
@@ -41,7 +41,37 @@ declare_clippy_lint! {
     "Perform saturating subtraction instead of implicitly checking lower bound of data type"
 }
 
-declare_lint_pass!(ImplicitSaturatingSub => [IMPLICIT_SATURATING_SUB]);
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for comparisons between integers, followed by subtracting the greater value from the
+    /// lower one.
+    ///
+    /// ### Why is this bad?
+    /// This could result in an underflow and is most likely not what the user wants. If this was
+    /// intended to be a saturated subtraction, consider using the `saturating_sub` method directly.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let a = 12u32;
+    /// let b = 13u32;
+    ///
+    /// let result = if a > b { b - a } else { 0 };
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// let a = 12u32;
+    /// let b = 13u32;
+    ///
+    /// let result = a.saturating_sub(b);
+    /// ```
+    #[clippy::version = "1.44.0"]
+    pub INVERTED_SATURATING_SUB,
+    correctness,
+    "Check if a variable is smaller than another one and still subtract from it even if smaller"
+}
+
+declare_lint_pass!(ImplicitSaturatingSub => [IMPLICIT_SATURATING_SUB, INVERTED_SATURATING_SUB]);
 
 impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
@@ -182,7 +212,7 @@ fn check_subtraction(
         {
             span_lint_and_then(
                 cx,
-                IMPLICIT_SATURATING_SUB,
+                INVERTED_SATURATING_SUB,
                 condition_span,
                 "inverted arithmetic check before subtraction",
                 |diag| {
diff --git a/tests/ui/manual_arithmetic_check-2.stderr b/tests/ui/manual_arithmetic_check-2.stderr
index d49e536ce3f..4121aa7464f 100644
--- a/tests/ui/manual_arithmetic_check-2.stderr
+++ b/tests/ui/manual_arithmetic_check-2.stderr
@@ -9,8 +9,7 @@ note: this subtraction underflows when `b < a`
    |
 LL |     let result = if a > b { b - a } else { 0 };
    |                             ^^^^^
-   = note: `-D clippy::implicit-saturating-sub` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]`
+   = note: `#[deny(clippy::inverted_saturating_sub)]` on by default
 
 error: inverted arithmetic check before subtraction
   --> tests/ui/manual_arithmetic_check-2.rs:11:23
diff --git a/tests/ui/manual_arithmetic_check.fixed b/tests/ui/manual_arithmetic_check.fixed
index 600fcd3765d..29ecbb9ad2a 100644
--- a/tests/ui/manual_arithmetic_check.fixed
+++ b/tests/ui/manual_arithmetic_check.fixed
@@ -1,4 +1,4 @@
-#![warn(clippy::implicit_saturating_sub)]
+#![warn(clippy::implicit_saturating_sub, clippy::inverted_saturating_sub)]
 #![allow(clippy::if_same_then_else)]
 
 fn main() {
diff --git a/tests/ui/manual_arithmetic_check.rs b/tests/ui/manual_arithmetic_check.rs
index 33f5adafe7e..69554c6b61c 100644
--- a/tests/ui/manual_arithmetic_check.rs
+++ b/tests/ui/manual_arithmetic_check.rs
@@ -1,4 +1,4 @@
-#![warn(clippy::implicit_saturating_sub)]
+#![warn(clippy::implicit_saturating_sub, clippy::inverted_saturating_sub)]
 #![allow(clippy::if_same_then_else)]
 
 fn main() {