Skip to content

Commit 78f7e37

Browse files
author
Evan Typanski
committed
Fix manual_range_contains with equal precedence
1 parent 050cdd6 commit 78f7e37

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

clippy_lints/src/ranges.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
194194
},
195195
ExprKind::Binary(ref op, l, r) => {
196196
if meets_msrv(self.msrv, msrvs::RANGE_CONTAINS) {
197-
check_possible_range_contains(cx, op.node, l, r, expr);
197+
check_possible_range_contains(cx, op.node, l, r, expr, expr.span);
198198
}
199199
},
200200
_ => {},
@@ -213,12 +213,12 @@ fn check_possible_range_contains(
213213
left: &Expr<'_>,
214214
right: &Expr<'_>,
215215
expr: &Expr<'_>,
216+
span: Span,
216217
) {
217218
if in_constant(cx, expr.hir_id) {
218219
return;
219220
}
220221

221-
let span = expr.span;
222222
let combine_and = match op {
223223
BinOpKind::And | BinOpKind::BitAnd => true,
224224
BinOpKind::Or | BinOpKind::BitOr => false,
@@ -294,6 +294,15 @@ fn check_possible_range_contains(
294294
);
295295
}
296296
}
297+
298+
// If the LHS is the same operator, we have to recurse to get the "real" RHS, since they have
299+
// the same operator precedence.
300+
if let ExprKind::Binary(ref lhs_op, _left, new_lhs) = left.kind {
301+
if op == lhs_op.node {
302+
let new_span = Span::new(new_lhs.span.lo(), right.span.hi(), expr.span.ctxt(), expr.span.parent());
303+
check_possible_range_contains(cx, op, new_lhs, right, expr, new_span);
304+
}
305+
}
297306
}
298307

299308
struct RangeBounds<'a> {

tests/ui/range_contains.fixed

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ fn main() {
4949
x >= 10 && x <= -10;
5050
(-3. ..=3.).contains(&y);
5151
y >= 3. && y <= -3.;
52+
53+
// Fix #8745
54+
let z = 42;
55+
(0..=10).contains(&x) && (0..=10).contains(&z);
56+
!(0..10).contains(&x) || !(0..10).contains(&z);
5257
}
5358

5459
// Fix #6373

tests/ui/range_contains.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ fn main() {
4949
x >= 10 && x <= -10;
5050
y >= -3. && y <= 3.;
5151
y >= 3. && y <= -3.;
52+
53+
// Fix #8745
54+
let z = 42;
55+
(x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
56+
(x < 0) || (x >= 10) || (z < 0) || (z >= 10);
5257
}
5358

5459
// Fix #6373

tests/ui/range_contains.stderr

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,29 @@ error: manual `RangeInclusive::contains` implementation
9696
LL | y >= -3. && y <= 3.;
9797
| ^^^^^^^^^^^^^^^^^^^ help: use: `(-3. ..=3.).contains(&y)`
9898

99-
error: aborting due to 16 previous errors
99+
error: manual `RangeInclusive::contains` implementation
100+
--> $DIR/range_contains.rs:55:30
101+
|
102+
LL | (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
103+
| ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&z)`
104+
105+
error: manual `RangeInclusive::contains` implementation
106+
--> $DIR/range_contains.rs:55:5
107+
|
108+
LL | (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);
109+
| ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&x)`
110+
111+
error: manual `!Range::contains` implementation
112+
--> $DIR/range_contains.rs:56:29
113+
|
114+
LL | (x < 0) || (x >= 10) || (z < 0) || (z >= 10);
115+
| ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&z)`
116+
117+
error: manual `!Range::contains` implementation
118+
--> $DIR/range_contains.rs:56:5
119+
|
120+
LL | (x < 0) || (x >= 10) || (z < 0) || (z >= 10);
121+
| ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&x)`
122+
123+
error: aborting due to 20 previous errors
100124

0 commit comments

Comments
 (0)