Replace Constant::partial_cmp
This commit is contained in:
@@ -122,21 +122,32 @@ impl Hash for Constant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for Constant {
|
impl Constant {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
pub fn partial_cmp(tcx: TyCtxt, cmp_type: &ty::TypeVariants, left: &Self, right: &Self) -> Option<Ordering> {
|
||||||
match (self, other) {
|
match (left, right) {
|
||||||
(&Constant::Str(ref ls), &Constant::Str(ref rs)) => Some(ls.cmp(rs)),
|
(&Constant::Str(ref ls), &Constant::Str(ref rs)) => Some(ls.cmp(rs)),
|
||||||
(&Constant::Char(ref l), &Constant::Char(ref r)) => Some(l.cmp(r)),
|
(&Constant::Char(ref l), &Constant::Char(ref r)) => Some(l.cmp(r)),
|
||||||
(&Constant::Int(l), &Constant::Int(r)) => Some(l.cmp(&r)),
|
(&Constant::Int(l), &Constant::Int(r)) => {
|
||||||
|
if let ty::TyInt(int_ty) = *cmp_type {
|
||||||
|
Some(sext(tcx, l, int_ty).cmp(&sext(tcx, r, int_ty)))
|
||||||
|
} else {
|
||||||
|
Some(l.cmp(&r))
|
||||||
|
}
|
||||||
|
},
|
||||||
(&Constant::F64(l), &Constant::F64(r)) => l.partial_cmp(&r),
|
(&Constant::F64(l), &Constant::F64(r)) => l.partial_cmp(&r),
|
||||||
(&Constant::F32(l), &Constant::F32(r)) => l.partial_cmp(&r),
|
(&Constant::F32(l), &Constant::F32(r)) => l.partial_cmp(&r),
|
||||||
(&Constant::Bool(ref l), &Constant::Bool(ref r)) => Some(l.cmp(r)),
|
(&Constant::Bool(ref l), &Constant::Bool(ref r)) => Some(l.cmp(r)),
|
||||||
(&Constant::Tuple(ref l), &Constant::Tuple(ref r)) | (&Constant::Vec(ref l), &Constant::Vec(ref r)) => {
|
(&Constant::Tuple(ref l), &Constant::Tuple(ref r)) | (&Constant::Vec(ref l), &Constant::Vec(ref r)) => l
|
||||||
l.partial_cmp(r)
|
.iter()
|
||||||
},
|
.zip(r.iter())
|
||||||
(&Constant::Repeat(ref lv, ref ls), &Constant::Repeat(ref rv, ref rs)) => match lv.partial_cmp(rv) {
|
.map(|(li, ri)| Constant::partial_cmp(tcx, cmp_type, li, ri))
|
||||||
Some(Equal) => Some(ls.cmp(rs)),
|
.find(|r| r.map_or(true, |o| o != Ordering::Equal))
|
||||||
x => x,
|
.unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
|
||||||
|
(&Constant::Repeat(ref lv, ref ls), &Constant::Repeat(ref rv, ref rs)) => {
|
||||||
|
match Constant::partial_cmp(tcx, cmp_type, lv, rv) {
|
||||||
|
Some(Equal) => Some(ls.cmp(rs)),
|
||||||
|
x => x,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => None, // TODO: Are there any useful inter-type orderings?
|
_ => None, // TODO: Are there any useful inter-type orderings?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
use crate::consts::{constant_simple, Constant};
|
use crate::consts::{constant_simple, Constant};
|
||||||
use crate::utils::{match_def_path, opt_def_id, paths, sext, span_lint};
|
use crate::utils::{match_def_path, opt_def_id, paths, span_lint};
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty::{self, TyCtxt};
|
use std::cmp::Ordering;
|
||||||
use std::cmp::{Ordering, PartialOrd};
|
|
||||||
|
|
||||||
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
|
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
|
||||||
/// used to clamp values, but switched so that the result is constant.
|
/// used to clamp values, but switched so that the result is constant.
|
||||||
@@ -43,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MinMaxPass {
|
|||||||
}
|
}
|
||||||
match (
|
match (
|
||||||
outer_max,
|
outer_max,
|
||||||
const_partial_cmp(cx.tcx, &outer_c, &inner_c, &cx.tables.expr_ty(ie).sty),
|
Constant::partial_cmp(cx.tcx, &cx.tables.expr_ty(ie).sty, &outer_c, &inner_c),
|
||||||
) {
|
) {
|
||||||
(_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (),
|
(_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (),
|
||||||
_ => {
|
_ => {
|
||||||
@@ -60,20 +59,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MinMaxPass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constant::partial_cmp incorrectly orders signed integers
|
|
||||||
fn const_partial_cmp(tcx: TyCtxt, a: &Constant, b: &Constant, expr_ty: &ty::TypeVariants) -> Option<Ordering> {
|
|
||||||
match *expr_ty {
|
|
||||||
ty::TyInt(int_ty) => {
|
|
||||||
if let (&Constant::Int(a), &Constant::Int(b)) = (a, b) {
|
|
||||||
Some(sext(tcx, a, int_ty).cmp(&sext(tcx, b, int_ty)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => a.partial_cmp(&b),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
enum MinMax {
|
enum MinMax {
|
||||||
Min,
|
Min,
|
||||||
|
|||||||
Reference in New Issue
Block a user