Skip to content

Commit 1165176

Browse files
authored
Rollup merge of #4842 - timbodeit:comparison-chain-false-positive-4827, r=flip1995
[comparison_chain] #4827 Check `core::cmp::Ord` is implemented Only emit `comparison_chain` lint, if `cmp` is actually available on the type being compared. Don't emit lint in cases where only `PartialOrd` is implemented. I haven't yet fully understood [Adjustments](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/adjustment/struct.Adjustment.html). I would appreciate, if someone could double check whether my usage of [expr_ty](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.TypeckTables.html#method.expr_ty) in `clippy_lints/src/comparison_chain.rs:91` is correct or if there are cases where using [expr_ty_adjusted](https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.TypeckTables.html#method.expr_ty_adjusted) would lead to a different result when used with `utils::implements_trait`. --- fixes #4827 changelog: [comparison_chain] Check `core::cmp::Ord` is implemented
2 parents 6686892 + fff9a8e commit 1165176

File tree

3 files changed

+113
-2
lines changed

3 files changed

+113
-2
lines changed

clippy_lints/src/comparison_chain.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::utils::{if_sequence, parent_node_is_if_expr, span_help_and_lint, SpanlessEq};
1+
use crate::utils::{
2+
get_trait_def_id, if_sequence, implements_trait, parent_node_is_if_expr, paths, span_help_and_lint, SpanlessEq,
3+
};
24
use rustc::hir::*;
35
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
46
use rustc::{declare_lint_pass, declare_tool_lint};
@@ -84,6 +86,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ComparisonChain {
8486
{
8587
return;
8688
}
89+
90+
// Check that the type being compared implements `core::cmp::Ord`
91+
let ty = cx.tables.expr_ty(lhs1);
92+
let is_ord = get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]));
93+
94+
if !is_ord {
95+
return;
96+
}
8797
} else {
8898
// We only care about comparison chains
8999
return;

tests/ui/comparison_chain.rs

+61
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,65 @@ fn f(x: u8, y: u8, z: u8) {
7676
}
7777
}
7878

79+
#[allow(clippy::float_cmp)]
80+
fn g(x: f64, y: f64, z: f64) {
81+
// Ignored: f64 doesn't implement Ord
82+
if x > y {
83+
a()
84+
} else if x < y {
85+
b()
86+
}
87+
88+
// Ignored: f64 doesn't implement Ord
89+
if x > y {
90+
a()
91+
} else if x < y {
92+
b()
93+
} else {
94+
c()
95+
}
96+
97+
// Ignored: f64 doesn't implement Ord
98+
if x > y {
99+
a()
100+
} else if y > x {
101+
b()
102+
} else {
103+
c()
104+
}
105+
106+
// Ignored: f64 doesn't implement Ord
107+
if x > 1.0 {
108+
a()
109+
} else if x < 1.0 {
110+
b()
111+
} else if x == 1.0 {
112+
c()
113+
}
114+
}
115+
116+
fn h<T: Ord>(x: T, y: T, z: T) {
117+
if x > y {
118+
a()
119+
} else if x < y {
120+
b()
121+
}
122+
123+
if x > y {
124+
a()
125+
} else if x < y {
126+
b()
127+
} else {
128+
c()
129+
}
130+
131+
if x > y {
132+
a()
133+
} else if y > x {
134+
b()
135+
} else {
136+
c()
137+
}
138+
}
139+
79140
fn main() {}

tests/ui/comparison_chain.stderr

+41-1
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,45 @@ LL | | }
5353
|
5454
= help: Consider rewriting the `if` chain to use `cmp` and `match`.
5555

56-
error: aborting due to 4 previous errors
56+
error: `if` chain can be rewritten with `match`
57+
--> $DIR/comparison_chain.rs:117:5
58+
|
59+
LL | / if x > y {
60+
LL | | a()
61+
LL | | } else if x < y {
62+
LL | | b()
63+
LL | | }
64+
| |_____^
65+
|
66+
= help: Consider rewriting the `if` chain to use `cmp` and `match`.
67+
68+
error: `if` chain can be rewritten with `match`
69+
--> $DIR/comparison_chain.rs:123:5
70+
|
71+
LL | / if x > y {
72+
LL | | a()
73+
LL | | } else if x < y {
74+
LL | | b()
75+
LL | | } else {
76+
LL | | c()
77+
LL | | }
78+
| |_____^
79+
|
80+
= help: Consider rewriting the `if` chain to use `cmp` and `match`.
81+
82+
error: `if` chain can be rewritten with `match`
83+
--> $DIR/comparison_chain.rs:131:5
84+
|
85+
LL | / if x > y {
86+
LL | | a()
87+
LL | | } else if y > x {
88+
LL | | b()
89+
LL | | } else {
90+
LL | | c()
91+
LL | | }
92+
| |_____^
93+
|
94+
= help: Consider rewriting the `if` chain to use `cmp` and `match`.
95+
96+
error: aborting due to 7 previous errors
5797

0 commit comments

Comments
 (0)