Skip to content

Commit 0de3f36

Browse files
authored
Merge pull request #2849 from mikerite/issue_2741
Fix #2741
2 parents 3626d86 + 4827bdc commit 0de3f36

File tree

4 files changed

+42
-20
lines changed

4 files changed

+42
-20
lines changed

clippy_lints/src/consts.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,21 +122,32 @@ impl Hash for Constant {
122122
}
123123
}
124124

125-
impl PartialOrd for Constant {
126-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
127-
match (self, other) {
125+
impl Constant {
126+
pub fn partial_cmp(tcx: TyCtxt, cmp_type: &ty::TypeVariants, left: &Self, right: &Self) -> Option<Ordering> {
127+
match (left, right) {
128128
(&Constant::Str(ref ls), &Constant::Str(ref rs)) => Some(ls.cmp(rs)),
129129
(&Constant::Char(ref l), &Constant::Char(ref r)) => Some(l.cmp(r)),
130-
(&Constant::Int(l), &Constant::Int(r)) => Some(l.cmp(&r)),
130+
(&Constant::Int(l), &Constant::Int(r)) => {
131+
if let ty::TyInt(int_ty) = *cmp_type {
132+
Some(sext(tcx, l, int_ty).cmp(&sext(tcx, r, int_ty)))
133+
} else {
134+
Some(l.cmp(&r))
135+
}
136+
},
131137
(&Constant::F64(l), &Constant::F64(r)) => l.partial_cmp(&r),
132138
(&Constant::F32(l), &Constant::F32(r)) => l.partial_cmp(&r),
133139
(&Constant::Bool(ref l), &Constant::Bool(ref r)) => Some(l.cmp(r)),
134-
(&Constant::Tuple(ref l), &Constant::Tuple(ref r)) | (&Constant::Vec(ref l), &Constant::Vec(ref r)) => {
135-
l.partial_cmp(r)
136-
},
137-
(&Constant::Repeat(ref lv, ref ls), &Constant::Repeat(ref rv, ref rs)) => match lv.partial_cmp(rv) {
138-
Some(Equal) => Some(ls.cmp(rs)),
139-
x => x,
140+
(&Constant::Tuple(ref l), &Constant::Tuple(ref r)) | (&Constant::Vec(ref l), &Constant::Vec(ref r)) => l
141+
.iter()
142+
.zip(r.iter())
143+
.map(|(li, ri)| Constant::partial_cmp(tcx, cmp_type, li, ri))
144+
.find(|r| r.map_or(true, |o| o != Ordering::Equal))
145+
.unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
146+
(&Constant::Repeat(ref lv, ref ls), &Constant::Repeat(ref rv, ref rs)) => {
147+
match Constant::partial_cmp(tcx, cmp_type, lv, rv) {
148+
Some(Equal) => Some(ls.cmp(rs)),
149+
x => x,
150+
}
140151
},
141152
_ => None, // TODO: Are there any useful inter-type orderings?
142153
}

clippy_lints/src/minmax.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::consts::{constant_simple, Constant};
2-
use rustc::lint::*;
3-
use rustc::hir::*;
4-
use std::cmp::{Ordering, PartialOrd};
52
use crate::utils::{match_def_path, opt_def_id, paths, span_lint};
3+
use rustc::hir::*;
4+
use rustc::lint::*;
5+
use std::cmp::Ordering;
66

77
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
88
/// used to clamp values, but switched so that the result is constant.
@@ -36,14 +36,22 @@ impl LintPass for MinMaxPass {
3636
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MinMaxPass {
3737
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
3838
if let Some((outer_max, outer_c, oe)) = min_max(cx, expr) {
39-
if let Some((inner_max, inner_c, _)) = min_max(cx, oe) {
39+
if let Some((inner_max, inner_c, ie)) = min_max(cx, oe) {
4040
if outer_max == inner_max {
4141
return;
4242
}
43-
match (outer_max, outer_c.partial_cmp(&inner_c)) {
43+
match (
44+
outer_max,
45+
Constant::partial_cmp(cx.tcx, &cx.tables.expr_ty(ie).sty, &outer_c, &inner_c),
46+
) {
4447
(_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (),
4548
_ => {
46-
span_lint(cx, MIN_MAX, expr.span, "this min/max combination leads to constant result");
49+
span_lint(
50+
cx,
51+
MIN_MAX,
52+
expr.span,
53+
"this min/max combination leads to constant result",
54+
);
4755
},
4856
}
4957
}

tests/ui/min_max.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ fn main() {
2323

2424
min(1, max(LARGE, x)); // no error, we don't lookup consts here
2525

26+
let y = 2isize;
27+
min(max(y, -1), 3);
28+
2629
let s;
2730
s = "Hello";
2831

tests/ui/min_max.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ error: this min/max combination leads to constant result
3131
| ^^^^^^^^^^^^^^^^^^^^^^^
3232

3333
error: this min/max combination leads to constant result
34-
--> $DIR/min_max.rs:29:5
34+
--> $DIR/min_max.rs:32:5
3535
|
36-
29 | min("Apple", max("Zoo", s));
36+
32 | min("Apple", max("Zoo", s));
3737
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
3838

3939
error: this min/max combination leads to constant result
40-
--> $DIR/min_max.rs:30:5
40+
--> $DIR/min_max.rs:33:5
4141
|
42-
30 | max(min(s, "Apple"), "Zoo");
42+
33 | max(min(s, "Apple"), "Zoo");
4343
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
4444

4545
error: aborting due to 7 previous errors

0 commit comments

Comments
 (0)