diff --git a/src/array_indexing.rs b/src/array_indexing.rs
index 274491b7c..3c6acb932 100644
--- a/src/array_indexing.rs
+++ b/src/array_indexing.rs
@@ -3,6 +3,7 @@ use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
use rustc::middle::ty::TyArray;
use rustc_front::hir::*;
+use rustc_const_eval::ConstInt;
use syntax::ast::RangeLimits;
use utils;
@@ -62,11 +63,11 @@ impl LateLintPass for ArrayIndexing {
// Array with known size can be checked statically
let ty = cx.tcx.expr_ty(array);
if let TyArray(_, size) = ty.sty {
- let size = size as u64;
+ let size = ConstInt::Infer(size as u64);
// Index is a constant uint
let const_index = eval_const_expr_partial(cx.tcx, &index, ExprTypeChecked, None);
- if let Ok(ConstVal::Uint(const_index)) = const_index {
+ if let Ok(ConstVal::Integral(const_index)) = const_index {
if size <= const_index {
utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "const index is out of bounds");
}
@@ -115,24 +116,24 @@ impl LateLintPass for ArrayIndexing {
fn to_const_range(start: Option>,
end: Option >,
limits: RangeLimits,
- array_size: u64)
- -> Option<(u64, u64)> {
+ array_size: ConstInt)
+ -> Option<(ConstInt, ConstInt)> {
let start = match start {
- Some(Some(ConstVal::Uint(x))) => x,
+ Some(Some(ConstVal::Integral(x))) => x,
Some(_) => return None,
- None => 0,
+ None => ConstInt::Infer(0),
};
let end = match end {
- Some(Some(ConstVal::Uint(x))) => {
+ Some(Some(ConstVal::Integral(x))) => {
if limits == RangeLimits::Closed {
x
} else {
- x - 1
+ (x - ConstInt::Infer(1)).expect("x > 0")
}
}
Some(_) => return None,
- None => array_size - 1,
+ None => (array_size - ConstInt::Infer(1)).expect("array_size > 0"),
};
Some((start, end))
diff --git a/src/bit_mask.rs b/src/bit_mask.rs
index 0e09122bc..02d428e83 100644
--- a/src/bit_mask.rs
+++ b/src/bit_mask.rs
@@ -271,7 +271,7 @@ fn fetch_int_literal(cx: &LateContext, lit: &Expr) -> Option {
}
}
.and_then(|def_id| lookup_const_by_id(cx.tcx, def_id, None, None))
- .and_then(|l| fetch_int_literal(cx, l))
+ .and_then(|(l, _ty)| fetch_int_literal(cx, l))
}
_ => None,
}
diff --git a/src/consts.rs b/src/consts.rs
index 6dd5651e7..eae9747d6 100644
--- a/src/consts.rs
+++ b/src/consts.rs
@@ -347,7 +347,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
}
// separate if lets to avoid double borrowing the def_map
if let Some(id) = maybe_id {
- if let Some(const_expr) = lookup_const_by_id(lcx.tcx, id, None, None) {
+ if let Some((const_expr, _ty)) = lookup_const_by_id(lcx.tcx, id, None, None) {
let ret = self.expr(const_expr);
if ret.is_some() {
self.needed_resolution = true;
diff --git a/src/enum_clike.rs b/src/enum_clike.rs
index 7ee71f41f..85fa418f2 100644
--- a/src/enum_clike.rs
+++ b/src/enum_clike.rs
@@ -1,11 +1,9 @@
//! lint on C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`
use rustc::lint::*;
-use syntax::ast::{IntTy, UintTy};
use syntax::attr::*;
use rustc_front::hir::*;
use rustc::middle::const_eval::{ConstVal, EvalHint, eval_const_expr_partial};
-use rustc::middle::ty;
use utils::span_lint;
/// **What it does:** Lints on C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`.
@@ -35,12 +33,10 @@ impl LateLintPass for EnumClikeUnportableVariant {
for var in &def.variants {
let variant = &var.node;
if let Some(ref disr) = variant.disr_expr {
- let cv = eval_const_expr_partial(cx.tcx, &**disr, EvalHint::ExprTypeChecked, None);
- let bad = match (cv, &cx.tcx.expr_ty(&**disr).sty) {
- (Ok(ConstVal::Int(i)), &ty::TyInt(IntTy::Is)) => i as i32 as i64 != i,
- (Ok(ConstVal::Uint(i)), &ty::TyInt(IntTy::Is)) => i as i32 as u64 != i,
- (Ok(ConstVal::Int(i)), &ty::TyUint(UintTy::Us)) => (i < 0) || (i as u32 as i64 != i),
- (Ok(ConstVal::Uint(i)), &ty::TyUint(UintTy::Us)) => i as u32 as u64 != i,
+ use rustc_const_eval::*;
+ let bad = match eval_const_expr_partial(cx.tcx, &**disr, EvalHint::ExprTypeChecked, None) {
+ Ok(ConstVal::Integral(Usize(Us64(i)))) => i as u32 as u64 != i,
+ Ok(ConstVal::Integral(Isize(Is64(i)))) => i as i32 as i64 != i,
_ => false,
};
if bad {
diff --git a/src/loops.rs b/src/loops.rs
index 462ca7c49..7987c70d0 100644
--- a/src/loops.rs
+++ b/src/loops.rs
@@ -429,10 +429,7 @@ fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) {
// who think that this will iterate from the larger value to the
// smaller value.
let (sup, eq) = match (start_idx, end_idx) {
- (ConstVal::Int(start_idx), ConstVal::Int(end_idx)) => {
- (start_idx > end_idx, start_idx == end_idx)
- }
- (ConstVal::Uint(start_idx), ConstVal::Uint(end_idx)) => {
+ (ConstVal::Integral(start_idx), ConstVal::Integral(end_idx)) => {
(start_idx > end_idx, start_idx == end_idx)
}
_ => (false, false),
diff --git a/src/matches.rs b/src/matches.rs
index 4c60ea89b..a456a816f 100644
--- a/src/matches.rs
+++ b/src/matches.rs
@@ -1,9 +1,9 @@
use rustc::lint::*;
-use rustc::middle::const_eval::ConstVal::{Int, Uint};
use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
use rustc::middle::ty;
use rustc_front::hir::*;
+use rustc_const_eval::ConstInt;
use std::cmp::Ordering;
use syntax::ast::LitKind;
use syntax::codemap::Span;
@@ -288,19 +288,16 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
if arms.len() >= 2 && cx.tcx.expr_ty(ex).is_integral() {
let ranges = all_ranges(cx, arms);
- let overlap = match type_ranges(&ranges) {
- TypedRanges::IntRanges(ranges) => overlapping(&ranges).map(|(start, end)| (start.span, end.span)),
- TypedRanges::UintRanges(ranges) => overlapping(&ranges).map(|(start, end)| (start.span, end.span)),
- TypedRanges::None => None,
- };
-
- if let Some((start, end)) = overlap {
- span_note_and_lint(cx,
- MATCH_OVERLAPPING_ARM,
- start,
- "some ranges overlap",
- end,
- "overlaps with this");
+ let type_ranges = type_ranges(&ranges);
+ if !type_ranges.is_empty() {
+ if let Some((start, end)) = overlapping(&type_ranges) {
+ span_note_and_lint(cx,
+ MATCH_OVERLAPPING_ARM,
+ start.span,
+ "some ranges overlap",
+ end.span,
+ "overlaps with this");
+ }
}
}
}
@@ -370,51 +367,22 @@ pub struct SpannedRange {
pub node: (T, T),
}
-#[derive(Debug)]
-enum TypedRanges {
- IntRanges(Vec>),
- UintRanges(Vec>),
- None,
-}
+type TypedRanges = Vec>;
/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway and other types than
/// `Uint` and `Int` probably don't make sense.
fn type_ranges(ranges: &[SpannedRange]) -> TypedRanges {
- if ranges.is_empty() {
- TypedRanges::None
- } else {
- match ranges[0].node {
- (Int(_), Int(_)) => {
- TypedRanges::IntRanges(ranges.iter()
- .filter_map(|range| {
- if let (Int(start), Int(end)) = range.node {
- Some(SpannedRange {
- span: range.span,
- node: (start, end),
- })
- } else {
- None
- }
- })
- .collect())
- }
- (Uint(_), Uint(_)) => {
- TypedRanges::UintRanges(ranges.iter()
- .filter_map(|range| {
- if let (Uint(start), Uint(end)) = range.node {
- Some(SpannedRange {
- span: range.span,
- node: (start, end),
- })
- } else {
- None
- }
- })
- .collect())
- }
- _ => TypedRanges::None,
+ ranges.iter().filter_map(|range| {
+ if let (ConstVal::Integral(start), ConstVal::Integral(end)) = range.node {
+ Some(SpannedRange {
+ span: range.span,
+ node: (start, end),
+ })
+ } else {
+ None
}
- }
+ })
+ .collect()
}
fn is_unit_expr(expr: &Expr) -> bool {
diff --git a/src/types.rs b/src/types.rs
index e64bf0105..c5acbb41e 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -673,6 +673,7 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option(cx: &LateContext, expr: &'a Expr) -> Option Minimum,
+ (&ty::TyBool, Bool(false)) |
- (&ty::TyInt(IntTy::Is), Int(x)) if x == ::std::isize::MIN as i64 => Minimum,
- (&ty::TyInt(IntTy::I8), Int(x)) if x == ::std::i8::MIN as i64 => Minimum,
- (&ty::TyInt(IntTy::I16), Int(x)) if x == ::std::i16::MIN as i64 => Minimum,
- (&ty::TyInt(IntTy::I32), Int(x)) if x == ::std::i32::MIN as i64 => Minimum,
- (&ty::TyInt(IntTy::I64), Int(x)) if x == ::std::i64::MIN as i64 => Minimum,
+ (&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MIN)))) |
+ (&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MIN)))) |
+ (&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MIN))) |
+ (&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MIN))) |
+ (&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MIN))) |
+ (&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MIN))) |
- (&ty::TyUint(UintTy::Us), Uint(x)) if x == ::std::usize::MIN as u64 => Minimum,
- (&ty::TyUint(UintTy::U8), Uint(x)) if x == ::std::u8::MIN as u64 => Minimum,
- (&ty::TyUint(UintTy::U16), Uint(x)) if x == ::std::u16::MIN as u64 => Minimum,
- (&ty::TyUint(UintTy::U32), Uint(x)) if x == ::std::u32::MIN as u64 => Minimum,
- (&ty::TyUint(UintTy::U64), Uint(x)) if x == ::std::u64::MIN as u64 => Minimum,
+ (&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MIN)))) |
+ (&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MIN)))) |
+ (&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MIN))) |
+ (&ty::TyUint(UintTy::U16), Integral(U16(::std::u16::MIN))) |
+ (&ty::TyUint(UintTy::U32), Integral(U32(::std::u32::MIN))) |
+ (&ty::TyUint(UintTy::U64), Integral(U64(::std::u64::MIN))) => Minimum,
- (&ty::TyBool, Bool(true)) => Maximum,
+ (&ty::TyBool, Bool(true)) |
- (&ty::TyInt(IntTy::Is), Int(x)) if x == ::std::isize::MAX as i64 => Maximum,
- (&ty::TyInt(IntTy::I8), Int(x)) if x == ::std::i8::MAX as i64 => Maximum,
- (&ty::TyInt(IntTy::I16), Int(x)) if x == ::std::i16::MAX as i64 => Maximum,
- (&ty::TyInt(IntTy::I32), Int(x)) if x == ::std::i32::MAX as i64 => Maximum,
- (&ty::TyInt(IntTy::I64), Int(x)) if x == ::std::i64::MAX as i64 => Maximum,
+ (&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MAX)))) |
+ (&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MAX)))) |
+ (&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MAX))) |
+ (&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MAX))) |
+ (&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MAX))) |
+ (&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MAX))) |
- (&ty::TyUint(UintTy::Us), Uint(x)) if x == ::std::usize::MAX as u64 => Maximum,
- (&ty::TyUint(UintTy::U8), Uint(x)) if x == ::std::u8::MAX as u64 => Maximum,
- (&ty::TyUint(UintTy::U16), Uint(x)) if x == ::std::u16::MAX as u64 => Maximum,
- (&ty::TyUint(UintTy::U32), Uint(x)) if x == ::std::u32::MAX as u64 => Maximum,
- (&ty::TyUint(UintTy::U64), Uint(x)) if x == ::std::u64::MAX as u64 => Maximum,
+ (&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MAX)))) |
+ (&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MAX)))) |
+ (&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MAX))) |
+ (&ty::TyUint(UintTy::U16), Integral(U16(::std::u16::MAX))) |
+ (&ty::TyUint(UintTy::U32), Integral(U32(::std::u32::MAX))) |
+ (&ty::TyUint(UintTy::U64), Integral(U64(::std::u64::MAX))) => Maximum,
_ => return None,
};