about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEvan Typanski <evan.typanski@microfocus.com>2022-05-24 11:50:12 -0400
committerEvan Typanski <evan.typanski@microfocus.com>2022-05-24 11:50:12 -0400
commit78f7e3745fe59db1e6309b1e42ea25df3317ee36 (patch)
tree5ce53d4900c03d360c5d1a6b1f1fe67acc9fee42
parent050cdd6689254db96b47ff86732e286839a67584 (diff)
downloadrust-78f7e3745fe59db1e6309b1e42ea25df3317ee36.tar.gz
rust-78f7e3745fe59db1e6309b1e42ea25df3317ee36.zip
Fix `manual_range_contains` with equal precedence
-rw-r--r--clippy_lints/src/ranges.rs13
-rw-r--r--tests/ui/range_contains.fixed5
-rw-r--r--tests/ui/range_contains.rs5
-rw-r--r--tests/ui/range_contains.stderr26
4 files changed, 46 insertions, 3 deletions
diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs
index a47dc26f603..416d6de55c8 100644
--- a/clippy_lints/src/ranges.rs
+++ b/clippy_lints/src/ranges.rs
@@ -194,7 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
             },
             ExprKind::Binary(ref op, l, r) => {
                 if meets_msrv(self.msrv, msrvs::RANGE_CONTAINS) {
-                    check_possible_range_contains(cx, op.node, l, r, expr);
+                    check_possible_range_contains(cx, op.node, l, r, expr, expr.span);
                 }
             },
             _ => {},
@@ -213,12 +213,12 @@ fn check_possible_range_contains(
     left: &Expr<'_>,
     right: &Expr<'_>,
     expr: &Expr<'_>,
+    span: Span,
 ) {
     if in_constant(cx, expr.hir_id) {
         return;
     }
 
-    let span = expr.span;
     let combine_and = match op {
         BinOpKind::And | BinOpKind::BitAnd => true,
         BinOpKind::Or | BinOpKind::BitOr => false,
@@ -294,6 +294,15 @@ fn check_possible_range_contains(
             );
         }
     }
+
+    // If the LHS is the same operator, we have to recurse to get the "real" RHS, since they have
+    // the same operator precedence.
+    if let ExprKind::Binary(ref lhs_op, _left, new_lhs) = left.kind {
+        if op == lhs_op.node {
+            let new_span = Span::new(new_lhs.span.lo(), right.span.hi(), expr.span.ctxt(), expr.span.parent());
+            check_possible_range_contains(cx, op, new_lhs, right, expr, new_span);
+        }
+    }
 }
 
 struct RangeBounds<'a> {
diff --git a/tests/ui/range_contains.fixed b/tests/ui/range_contains.fixed
index f4977199711..fd4dcf39f2f 100644
--- a/tests/ui/range_contains.fixed
+++ b/tests/ui/range_contains.fixed
@@ -49,6 +49,11 @@ fn main() {
     x >= 10 && x <= -10;
     (-3. ..=3.).contains(&y);
     y >= 3. && y <= -3.;
+
+    // Fix #8745
+    let z = 42;
+    (0..=10).contains(&x) && (0..=10).contains(&z);
+    !(0..10).contains(&x) || !(0..10).contains(&z);
 }
 
 // Fix #6373
diff --git a/tests/ui/range_contains.rs b/tests/ui/range_contains.rs
index 9e2180b0c99..b848e2e1671 100644
--- a/tests/ui/range_contains.rs
+++ b/tests/ui/range_contains.rs
@@ -49,6 +49,11 @@ fn main() {
     x >= 10 && x <= -10;
     y >= -3. && y <= 3.;
     y >= 3. && y <= -3.;
+
+    // Fix #8745
+    let z = 42;
+    (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
+    (x < 0) || (x >= 10) || (z < 0) || (z >= 10);
 }
 
 // Fix #6373
diff --git a/tests/ui/range_contains.stderr b/tests/ui/range_contains.stderr
index 1817ee1715d..936859db5a1 100644
--- a/tests/ui/range_contains.stderr
+++ b/tests/ui/range_contains.stderr
@@ -96,5 +96,29 @@ error: manual `RangeInclusive::contains` implementation
 LL |     y >= -3. && y <= 3.;
    |     ^^^^^^^^^^^^^^^^^^^ help: use: `(-3. ..=3.).contains(&y)`
 
-error: aborting due to 16 previous errors
+error: manual `RangeInclusive::contains` implementation
+  --> $DIR/range_contains.rs:55:30
+   |
+LL |     (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
+   |                              ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&z)`
+
+error: manual `RangeInclusive::contains` implementation
+  --> $DIR/range_contains.rs:55:5
+   |
+LL |     (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&x)`
+
+error: manual `!Range::contains` implementation
+  --> $DIR/range_contains.rs:56:29
+   |
+LL |     (x < 0) || (x >= 10) || (z < 0) || (z >= 10);
+   |                             ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&z)`
+
+error: manual `!Range::contains` implementation
+  --> $DIR/range_contains.rs:56:5
+   |
+LL |     (x < 0) || (x >= 10) || (z < 0) || (z >= 10);
+   |     ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&x)`
+
+error: aborting due to 20 previous errors