fix nightly breakage

This commit is contained in:
Oliver 'ker' Schneider 2016-02-12 18:35:44 +01:00
parent d305bca25b
commit 3f34b65747
23 changed files with 201 additions and 259 deletions

View file

@ -24,7 +24,7 @@ regex-syntax = "0.2.2"
[dev-dependencies] [dev-dependencies]
compiletest_rs = "0.0.11" compiletest_rs = "0.0.11"
regex = "0.1.47" regex = "0.1.47"
regex_macros = "0.1.27" regex_macros = "0.1.28"
lazy_static = "0.1.15" lazy_static = "0.1.15"
rustc-serialize = "0.3" rustc-serialize = "0.3"

View file

@ -2,7 +2,7 @@ use rustc::lint::*;
use rustc_front::hir::*; use rustc_front::hir::*;
use std::f64::consts as f64; use std::f64::consts as f64;
use utils::span_lint; use utils::span_lint;
use syntax::ast::{Lit, Lit_, FloatTy}; use syntax::ast::{Lit, LitKind, FloatTy};
/// **What it does:** This lint checks for floating point literals that approximate constants which are defined in [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) or [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), respectively, suggesting to use the predefined constant. /// **What it does:** This lint checks for floating point literals that approximate constants which are defined in [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) or [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), respectively, suggesting to use the predefined constant.
/// ///
@ -55,9 +55,9 @@ impl LateLintPass for ApproxConstant {
fn check_lit(cx: &LateContext, lit: &Lit, e: &Expr) { fn check_lit(cx: &LateContext, lit: &Lit, e: &Expr) {
match lit.node { match lit.node {
Lit_::LitFloat(ref s, FloatTy::TyF32) => check_known_consts(cx, e, s, "f32"), LitKind::Float(ref s, FloatTy::F32) => check_known_consts(cx, e, s, "f32"),
Lit_::LitFloat(ref s, FloatTy::TyF64) => check_known_consts(cx, e, s, "f64"), LitKind::Float(ref s, FloatTy::F64) => check_known_consts(cx, e, s, "f64"),
Lit_::LitFloatUnsuffixed(ref s) => check_known_consts(cx, e, s, "f{32, 64}"), LitKind::FloatUnsuffixed(ref s) => check_known_consts(cx, e, s, "f{32, 64}"),
_ => (), _ => (),
} }
} }

View file

@ -6,7 +6,7 @@ use reexport::*;
use semver::Version; use semver::Version;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::attr::*; use syntax::attr::*;
use syntax::ast::{Attribute, Lit, Lit_, MetaList, MetaWord, MetaNameValue}; use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind};
use utils::{in_macro, match_path, span_lint, BEGIN_UNWIND}; use utils::{in_macro, match_path, span_lint, BEGIN_UNWIND};
/// **What it does:** This lint checks for items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics. /// **What it does:** This lint checks for items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics.
@ -54,12 +54,12 @@ impl LintPass for AttrPass {
impl LateLintPass for AttrPass { impl LateLintPass for AttrPass {
fn check_attribute(&mut self, cx: &LateContext, attr: &Attribute) { fn check_attribute(&mut self, cx: &LateContext, attr: &Attribute) {
if let MetaList(ref name, ref items) = attr.node.value.node { if let MetaItemKind::List(ref name, ref items) = attr.node.value.node {
if items.is_empty() || name != &"deprecated" { if items.is_empty() || name != &"deprecated" {
return; return;
} }
for ref item in items { for ref item in items {
if let MetaNameValue(ref name, ref lit) = item.node { if let MetaItemKind::NameValue(ref name, ref lit) = item.node {
if name == &"since" { if name == &"since" {
check_semver(cx, item.span, lit); check_semver(cx, item.span, lit);
} }
@ -144,11 +144,11 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) {
} }
for attr in attrs { for attr in attrs {
if let MetaList(ref inline, ref values) = attr.node.value.node { if let MetaItemKind::List(ref inline, ref values) = attr.node.value.node {
if values.len() != 1 || inline != &"inline" { if values.len() != 1 || inline != &"inline" {
continue; continue;
} }
if let MetaWord(ref always) = values[0].node { if let MetaItemKind::Word(ref always) = values[0].node {
if always != &"always" { if always != &"always" {
continue; continue;
} }
@ -163,7 +163,7 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) {
} }
fn check_semver(cx: &LateContext, span: Span, lit: &Lit) { fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
if let Lit_::LitStr(ref is, _) = lit.node { if let LitKind::Str(ref is, _) = lit.node {
if Version::parse(&*is).is_ok() { if Version::parse(&*is).is_ok() {
return; return;
} }

View file

@ -4,7 +4,7 @@ use rustc::middle::def::{Def, PathResolution};
use rustc_front::hir::*; use rustc_front::hir::*;
use rustc_front::util::is_comparison_binop; use rustc_front::util::is_comparison_binop;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ast::Lit_; use syntax::ast::LitKind;
use utils::span_lint; use utils::span_lint;
@ -254,7 +254,7 @@ fn check_ineffective_gt(cx: &LateContext, span: Span, m: u64, c: u64, op: &str)
fn fetch_int_literal(cx: &LateContext, lit: &Expr) -> Option<u64> { fn fetch_int_literal(cx: &LateContext, lit: &Expr) -> Option<u64> {
match lit.node { match lit.node {
ExprLit(ref lit_ptr) => { ExprLit(ref lit_ptr) => {
if let Lit_::LitInt(value, _) = lit_ptr.node { if let LitKind::Int(value, _) = lit_ptr.node {
Some(value) //TODO: Handle sign Some(value) //TODO: Handle sign
} else { } else {
None None

View file

@ -11,10 +11,9 @@ use std::cmp::Ordering::{self, Greater, Less, Equal};
use std::rc::Rc; use std::rc::Rc;
use std::ops::Deref; use std::ops::Deref;
use syntax::ast::Lit_; use syntax::ast::LitKind;
use syntax::ast::LitIntType; use syntax::ast::LitIntType;
use syntax::ast::{UintTy, FloatTy, StrStyle}; use syntax::ast::{UintTy, FloatTy, StrStyle};
use syntax::ast::Sign::{self, Plus, Minus};
#[derive(PartialEq, Eq, Debug, Copy, Clone)] #[derive(PartialEq, Eq, Debug, Copy, Clone)]
@ -27,12 +26,18 @@ pub enum FloatWidth {
impl From<FloatTy> for FloatWidth { impl From<FloatTy> for FloatWidth {
fn from(ty: FloatTy) -> FloatWidth { fn from(ty: FloatTy) -> FloatWidth {
match ty { match ty {
FloatTy::TyF32 => FloatWidth::Fw32, FloatTy::F32 => FloatWidth::Fw32,
FloatTy::TyF64 => FloatWidth::Fw64, FloatTy::F64 => FloatWidth::Fw64,
} }
} }
} }
#[derive(Copy, Eq, Debug, Clone, PartialEq)]
pub enum Sign {
Plus,
Minus,
}
/// a Lit_-like enum to fold constant `Expr`s into /// a Lit_-like enum to fold constant `Expr`s into
#[derive(Eq, Debug, Clone)] #[derive(Eq, Debug, Clone)]
pub enum Constant { pub enum Constant {
@ -44,8 +49,8 @@ pub enum Constant {
Byte(u8), Byte(u8),
/// a single char 'a' /// a single char 'a'
Char(char), Char(char),
/// an integer /// an integer, third argument is whether the value is negated
Int(u64, LitIntType), Int(u64, LitIntType, Sign),
/// a float with given type /// a float with given type
Float(String, FloatWidth), Float(String, FloatWidth),
/// true or false /// true or false
@ -65,7 +70,7 @@ impl Constant {
/// ///
/// if the constant could not be converted to u64 losslessly /// if the constant could not be converted to u64 losslessly
fn as_u64(&self) -> u64 { fn as_u64(&self) -> u64 {
if let Constant::Int(val, _) = *self { if let Constant::Int(val, _, _) = *self {
val // TODO we may want to check the sign if any val // TODO we may want to check the sign if any
} else { } else {
panic!("Could not convert a {:?} to u64", self); panic!("Could not convert a {:?} to u64", self);
@ -78,13 +83,8 @@ impl Constant {
match *self { match *self {
Constant::Byte(b) => Some(b as f64), Constant::Byte(b) => Some(b as f64),
Constant::Float(ref s, _) => s.parse().ok(), Constant::Float(ref s, _) => s.parse().ok(),
Constant::Int(i, ty) => { Constant::Int(i, _, Sign::Minus) => Some(-(i as f64)),
Some(if is_negative(ty) { Constant::Int(i, _, Sign::Plus) => Some(i as f64),
-(i as f64)
} else {
i as f64
})
}
_ => None, _ => None,
} }
} }
@ -97,8 +97,9 @@ impl PartialEq for Constant {
(&Constant::Binary(ref l), &Constant::Binary(ref r)) => l == r, (&Constant::Binary(ref l), &Constant::Binary(ref r)) => l == r,
(&Constant::Byte(l), &Constant::Byte(r)) => l == r, (&Constant::Byte(l), &Constant::Byte(r)) => l == r,
(&Constant::Char(l), &Constant::Char(r)) => l == r, (&Constant::Char(l), &Constant::Char(r)) => l == r,
(&Constant::Int(lv, lty), &Constant::Int(rv, rty)) => { (&Constant::Int(0, _, _), &Constant::Int(0, _, _)) => true,
lv == rv && (is_negative(lty) & (lv != 0)) == (is_negative(rty) & (rv != 0)) (&Constant::Int(lv, _, lneg), &Constant::Int(rv, _, rneg)) => {
lv == rv && lneg == rneg
} }
(&Constant::Float(ref ls, lw), &Constant::Float(ref rs, rw)) => { (&Constant::Float(ref ls, lw), &Constant::Float(ref rs, rw)) => {
use self::FloatWidth::*; use self::FloatWidth::*;
@ -135,14 +136,11 @@ impl PartialOrd for Constant {
} }
(&Constant::Byte(ref l), &Constant::Byte(ref r)) => Some(l.cmp(r)), (&Constant::Byte(ref l), &Constant::Byte(ref r)) => Some(l.cmp(r)),
(&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(ref lv, lty), &Constant::Int(ref rv, rty)) => { (&Constant::Int(0, _, _), &Constant::Int(0, _, _)) => Some(Equal),
Some(match (is_negative(lty) && *lv != 0, is_negative(rty) && *rv != 0) { (&Constant::Int(ref lv, _, Sign::Plus), &Constant::Int(ref rv, _, Sign::Plus)) => Some(lv.cmp(rv)),
(true, true) => rv.cmp(lv), (&Constant::Int(ref lv, _, Sign::Minus), &Constant::Int(ref rv, _, Sign::Minus)) => Some(rv.cmp(lv)),
(false, false) => lv.cmp(rv), (&Constant::Int(_, _, Sign::Minus), &Constant::Int(_, _, Sign::Plus)) => Some(Less),
(true, false) => Less, (&Constant::Int(_, _, Sign::Plus), &Constant::Int(_, _, Sign::Minus)) => Some(Greater),
(false, true) => Greater,
})
}
(&Constant::Float(ref ls, lw), &Constant::Float(ref rs, rw)) => { (&Constant::Float(ref ls, lw), &Constant::Float(ref rs, rw)) => {
use self::FloatWidth::*; use self::FloatWidth::*;
if match (lw, rw) { if match (lw, rw) {
@ -171,16 +169,16 @@ impl PartialOrd for Constant {
} }
} }
fn lit_to_constant(lit: &Lit_) -> Constant { fn lit_to_constant(lit: &LitKind) -> Constant {
match *lit { match *lit {
Lit_::LitStr(ref is, style) => Constant::Str(is.to_string(), style), LitKind::Str(ref is, style) => Constant::Str(is.to_string(), style),
Lit_::LitByte(b) => Constant::Byte(b), LitKind::Byte(b) => Constant::Byte(b),
Lit_::LitByteStr(ref s) => Constant::Binary(s.clone()), LitKind::ByteStr(ref s) => Constant::Binary(s.clone()),
Lit_::LitChar(c) => Constant::Char(c), LitKind::Char(c) => Constant::Char(c),
Lit_::LitInt(value, ty) => Constant::Int(value, ty), LitKind::Int(value, ty) => Constant::Int(value, ty, Sign::Plus),
Lit_::LitFloat(ref is, ty) => Constant::Float(is.to_string(), ty.into()), LitKind::Float(ref is, ty) => Constant::Float(is.to_string(), ty.into()),
Lit_::LitFloatUnsuffixed(ref is) => Constant::Float(is.to_string(), FloatWidth::FwAny), LitKind::FloatUnsuffixed(ref is) => Constant::Float(is.to_string(), FloatWidth::FwAny),
Lit_::LitBool(b) => Constant::Bool(b), LitKind::Bool(b) => Constant::Bool(b),
} }
} }
@ -189,21 +187,21 @@ fn constant_not(o: Constant) -> Option<Constant> {
use self::Constant::*; use self::Constant::*;
match o { match o {
Bool(b) => Some(Bool(!b)), Bool(b) => Some(Bool(!b)),
Int(::std::u64::MAX, SignedIntLit(_, Plus)) => None, Int(::std::u64::MAX, LitIntType::Signed(_), Sign::Plus) => None,
Int(value, SignedIntLit(ity, Plus)) => Some(Int(value + 1, SignedIntLit(ity, Minus))), Int(value, LitIntType::Signed(ity), Sign::Plus) => Some(Int(value + 1, LitIntType::Signed(ity), Sign::Minus)),
Int(0, SignedIntLit(ity, Minus)) => Some(Int(1, SignedIntLit(ity, Minus))), Int(0, LitIntType::Signed(ity), Sign::Minus) => Some(Int(1, LitIntType::Signed(ity), Sign::Minus)),
Int(value, SignedIntLit(ity, Minus)) => Some(Int(value - 1, SignedIntLit(ity, Plus))), Int(value, LitIntType::Signed(ity), Sign::Minus) => Some(Int(value - 1, LitIntType::Signed(ity), Sign::Plus)),
Int(value, UnsignedIntLit(ity)) => { Int(value, LitIntType::Unsigned(ity), Sign::Plus) => {
let mask = match ity { let mask = match ity {
UintTy::TyU8 => ::std::u8::MAX as u64, UintTy::U8 => ::std::u8::MAX as u64,
UintTy::TyU16 => ::std::u16::MAX as u64, UintTy::U16 => ::std::u16::MAX as u64,
UintTy::TyU32 => ::std::u32::MAX as u64, UintTy::U32 => ::std::u32::MAX as u64,
UintTy::TyU64 => ::std::u64::MAX, UintTy::U64 => ::std::u64::MAX,
UintTy::TyUs => { UintTy::Us => {
return None; return None;
} // refuse to guess } // refuse to guess
}; };
Some(Int(!value & mask, UnsignedIntLit(ity))) Some(Int(!value & mask, LitIntType::Unsigned(ity), Sign::Plus))
}, },
_ => None, _ => None,
} }
@ -213,8 +211,8 @@ fn constant_negate(o: Constant) -> Option<Constant> {
use syntax::ast::LitIntType::*; use syntax::ast::LitIntType::*;
use self::Constant::*; use self::Constant::*;
match o { match o {
Int(value, SignedIntLit(ity, sign)) => Some(Int(value, SignedIntLit(ity, neg_sign(sign)))), Int(value, LitIntType::Signed(ity), sign) => Some(Int(value, LitIntType::Signed(ity), neg_sign(sign))),
Int(value, UnsuffixedIntLit(sign)) => Some(Int(value, UnsuffixedIntLit(neg_sign(sign)))), Int(value, LitIntType::Unsuffixed, sign) => Some(Int(value, LitIntType::Unsuffixed, neg_sign(sign))),
Float(is, ty) => Some(Float(neg_float_str(is), ty)), Float(is, ty) => Some(Float(neg_float_str(is), ty)),
_ => None, _ => None,
} }
@ -235,78 +233,32 @@ fn neg_float_str(s: String) -> String {
} }
} }
/// is the given LitIntType negative? fn unify_int_type(l: LitIntType, r: LitIntType) -> Option<LitIntType> {
///
/// Examples
///
/// ```
/// assert!(is_negative(UnsuffixedIntLit(Minus)));
/// ```
pub fn is_negative(ty: LitIntType) -> bool {
match ty {
LitIntType::SignedIntLit(_, sign) | LitIntType::UnsuffixedIntLit(sign) => sign == Minus,
LitIntType::UnsignedIntLit(_) => false,
}
}
fn unify_int_type(l: LitIntType, r: LitIntType, s: Sign) -> Option<LitIntType> {
use syntax::ast::LitIntType::*; use syntax::ast::LitIntType::*;
match (l, r) { match (l, r) {
(SignedIntLit(lty, _), SignedIntLit(rty, _)) => { (Signed(lty), Signed(rty)) => {
if lty == rty { if lty == rty {
Some(SignedIntLit(lty, s)) Some(LitIntType::Signed(lty))
} else { } else {
None None
} }
} }
(UnsignedIntLit(lty), UnsignedIntLit(rty)) => { (Unsigned(lty), Unsigned(rty)) => {
if s == Plus && lty == rty { if lty == rty {
Some(UnsignedIntLit(lty)) Some(LitIntType::Unsigned(lty))
} else {
None
}
}
(UnsuffixedIntLit(_), UnsuffixedIntLit(_)) => Some(UnsuffixedIntLit(s)),
(SignedIntLit(lty, _), UnsuffixedIntLit(_)) => Some(SignedIntLit(lty, s)),
(UnsignedIntLit(lty), UnsuffixedIntLit(rs)) => {
if rs == Plus {
Some(UnsignedIntLit(lty))
} else {
None
}
}
(UnsuffixedIntLit(_), SignedIntLit(rty, _)) => Some(SignedIntLit(rty, s)),
(UnsuffixedIntLit(ls), UnsignedIntLit(rty)) => {
if ls == Plus {
Some(UnsignedIntLit(rty))
} else { } else {
None None
} }
} }
(Unsuffixed, Unsuffixed) => Some(Unsuffixed),
(Signed(lty), Unsuffixed) => Some(Signed(lty)),
(Unsigned(lty), Unsuffixed) => Some(Unsigned(lty)),
(Unsuffixed, Signed(rty)) => Some(Signed(rty)),
(Unsuffixed, Unsigned(rty)) => Some(Unsigned(rty)),
_ => None, _ => None,
} }
} }
fn add_neg_int(pos: u64, pty: LitIntType, neg: u64, nty: LitIntType) -> Option<Constant> {
if neg > pos {
unify_int_type(nty, pty, Minus).map(|ty| Constant::Int(neg - pos, ty))
} else {
unify_int_type(nty, pty, Plus).map(|ty| Constant::Int(pos - neg, ty))
}
}
fn sub_int(l: u64, lty: LitIntType, r: u64, rty: LitIntType, neg: bool) -> Option<Constant> {
unify_int_type(lty,
rty,
if neg {
Minus
} else {
Plus
})
.and_then(|ty| l.checked_sub(r).map(|v| Constant::Int(v, ty)))
}
pub fn constant(lcx: &LateContext, e: &Expr) -> Option<(Constant, bool)> { pub fn constant(lcx: &LateContext, e: &Expr) -> Option<(Constant, bool)> {
let mut cx = ConstEvalLateContext { let mut cx = ConstEvalLateContext {
lcx: Some(lcx), lcx: Some(lcx),
@ -412,23 +364,9 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
self.binop_apply(left, right, |l, r| { self.binop_apply(left, right, |l, r| {
match (l, r) { match (l, r) {
(Constant::Byte(l8), Constant::Byte(r8)) => l8.checked_add(r8).map(Constant::Byte), (Constant::Byte(l8), Constant::Byte(r8)) => l8.checked_add(r8).map(Constant::Byte),
(Constant::Int(l64, lty), Constant::Int(r64, rty)) => { (Constant::Int(l64, lty, lsign), Constant::Int(r64, rty, rsign)) => {
let (ln, rn) = (is_negative(lty), is_negative(rty)); add_ints(l64, r64, lty, rty, lsign, rsign)
if ln == rn { },
unify_int_type(lty,
rty,
if ln {
Minus
} else {
Plus
})
.and_then(|ty| l64.checked_add(r64).map(|v| Constant::Int(v, ty)))
} else if ln {
add_neg_int(r64, rty, l64, lty)
} else {
add_neg_int(l64, lty, r64, rty)
}
}
// TODO: float (would need bignum library?) // TODO: float (would need bignum library?)
_ => None, _ => None,
} }
@ -444,20 +382,9 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
Some(Constant::Byte(l8 - r8)) Some(Constant::Byte(l8 - r8))
} }
} }
(Constant::Int(l64, lty), Constant::Int(r64, rty)) => { (Constant::Int(l64, lty, lsign), Constant::Int(r64, rty, rsign)) => {
match (is_negative(lty), is_negative(rty)) { add_ints(l64, r64, lty, rty, lsign, neg_sign(rsign))
(false, false) => sub_int(l64, lty, r64, rty, r64 > l64), },
(true, true) => sub_int(l64, lty, r64, rty, l64 > r64),
(true, false) => {
unify_int_type(lty, rty, Minus)
.and_then(|ty| l64.checked_add(r64).map(|v| Constant::Int(v, ty)))
}
(false, true) => {
unify_int_type(lty, rty, Plus)
.and_then(|ty| l64.checked_add(r64).map(|v| Constant::Int(v, ty)))
}
}
}
_ => None, _ => None,
} }
}) })
@ -487,16 +414,10 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
{ {
self.binop_apply(left, right, |l, r| { self.binop_apply(left, right, |l, r| {
match (l, r) { match (l, r) {
(Constant::Int(l64, lty), Constant::Int(r64, rty)) => { (Constant::Int(l64, lty, lsign), Constant::Int(r64, rty, rsign)) => {
f(l64, r64).and_then(|value| { f(l64, r64).and_then(|value| {
unify_int_type(lty, let sign = if lsign == rsign { Sign::Plus } else { Sign::Minus };
rty, unify_int_type(lty, rty).map(|ty| Constant::Int(value, ty, sign))
if is_negative(lty) == is_negative(rty) {
Plus
} else {
Minus
})
.map(|ty| Constant::Int(value, ty))
}) })
} }
_ => None, _ => None,
@ -511,8 +432,12 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
match (l, r) { match (l, r) {
(Constant::Bool(l), Constant::Bool(r)) => Some(Constant::Bool(f(l as u64, r as u64) != 0)), (Constant::Bool(l), Constant::Bool(r)) => Some(Constant::Bool(f(l as u64, r as u64) != 0)),
(Constant::Byte(l8), Constant::Byte(r8)) => Some(Constant::Byte(f(l8 as u64, r8 as u64) as u8)), (Constant::Byte(l8), Constant::Byte(r8)) => Some(Constant::Byte(f(l8 as u64, r8 as u64) as u8)),
(Constant::Int(l, lty), Constant::Int(r, rty)) => { (Constant::Int(l, lty, lsign), Constant::Int(r, rty, rsign)) => {
unify_int_type(lty, rty, Plus).map(|ty| Constant::Int(f(l, r), ty)) if lsign == Sign::Plus && rsign == Sign::Plus {
unify_int_type(lty, rty).map(|ty| Constant::Int(f(l, r), ty, Sign::Plus))
} else {
None
}
} }
_ => None, _ => None,
} }
@ -555,3 +480,21 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
}) })
} }
} }
fn add_ints(l64: u64, r64: u64, lty: LitIntType, rty: LitIntType, lsign: Sign, rsign: Sign) -> Option<Constant> {
let ty = if let Some(ty) = unify_int_type(lty, rty) { ty } else { return None; };
match (lsign, rsign) {
(Sign::Plus, Sign::Plus) => l64.checked_add(r64).map(|v| Constant::Int(v, ty, Sign::Plus)),
(Sign::Plus, Sign::Minus) => if r64 > l64 {
Some(Constant::Int(r64 - l64, ty, Sign::Minus))
} else {
Some(Constant::Int(l64 - r64, ty, Sign::Plus))
},
(Sign::Minus, Sign::Minus) => l64.checked_add(r64).map(|v| Constant::Int(v, ty, Sign::Minus)),
(Sign::Minus, Sign::Plus) => if l64 > r64 {
Some(Constant::Int(l64 - r64, ty, Sign::Minus))
} else {
Some(Constant::Int(r64 - l64, ty, Sign::Plus))
},
}
}

View file

@ -2,7 +2,7 @@ use rustc::lint::*;
use rustc::middle::ty::fast_reject::simplify_type; use rustc::middle::ty::fast_reject::simplify_type;
use rustc::middle::ty; use rustc::middle::ty;
use rustc_front::hir::*; use rustc_front::hir::*;
use syntax::ast::{Attribute, MetaItem_}; use syntax::ast::{Attribute, MetaItemKind};
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{CLONE_TRAIT_PATH, HASH_PATH}; use utils::{CLONE_TRAIT_PATH, HASH_PATH};
use utils::{match_path, span_lint_and_then}; use utils::{match_path, span_lint_and_then};
@ -170,7 +170,7 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref:
/// Checks for the `#[automatically_derived]` attribute all `#[derive]`d implementations have. /// Checks for the `#[automatically_derived]` attribute all `#[derive]`d implementations have.
fn is_automatically_derived(attr: &Attribute) -> bool { fn is_automatically_derived(attr: &Attribute) -> bool {
if let MetaItem_::MetaWord(ref word) = attr.node.value.node { if let MetaItemKind::Word(ref word) = attr.node.value.node {
word == &"automatically_derived" word == &"automatically_derived"
} else { } else {
false false

View file

@ -41,7 +41,7 @@ fn partial_rmatch(left: &str, right: &str) -> usize {
impl EarlyLintPass for EnumVariantNames { impl EarlyLintPass for EnumVariantNames {
fn check_item(&mut self, cx: &EarlyContext, item: &Item) { fn check_item(&mut self, cx: &EarlyContext, item: &Item) {
if let ItemEnum(ref def, _) = item.node { if let ItemKind::Enum(ref def, _) = item.node {
if def.variants.len() < 2 { if def.variants.len() < 2 {
return; return;
} }

View file

@ -2,7 +2,7 @@ use rustc::lint::*;
use rustc_front::hir::*; use rustc_front::hir::*;
use syntax::codemap::Span; use syntax::codemap::Span;
use consts::{constant_simple, is_negative, Constant}; use consts::{constant_simple, Constant, Sign};
use utils::{span_lint, snippet, in_macro}; use utils::{span_lint, snippet, in_macro};
/// **What it does:** This lint checks for identity operations, e.g. `x + 0`. /// **What it does:** This lint checks for identity operations, e.g. `x + 0`.
@ -55,11 +55,11 @@ impl LateLintPass for IdentityOp {
fn check(cx: &LateContext, e: &Expr, m: i8, span: Span, arg: Span) { fn check(cx: &LateContext, e: &Expr, m: i8, span: Span, arg: Span) {
if let Some(Constant::Int(v, ty)) = constant_simple(e) { if let Some(Constant::Int(v, _, sign)) = constant_simple(e) {
if match m { if match m {
0 => v == 0, 0 => v == 0,
-1 => is_negative(ty) && v == 1, -1 => sign == Sign::Minus && v == 1,
1 => !is_negative(ty) && v == 1, 1 => sign == Sign::Plus && v == 1,
_ => unreachable!(), _ => unreachable!(),
} { } {
span_lint(cx, span_lint(cx,

View file

@ -47,15 +47,15 @@ impl EarlyLintPass for ItemsAfterStatemets {
} }
let mut stmts = item.stmts.iter().map(|stmt| &stmt.node); let mut stmts = item.stmts.iter().map(|stmt| &stmt.node);
// skip initial items // skip initial items
while let Some(&StmtDecl(ref decl, _)) = stmts.next() { while let Some(&StmtKind::Decl(ref decl, _)) = stmts.next() {
if let DeclLocal(_) = decl.node { if let DeclKind::Local(_) = decl.node {
break; break;
} }
} }
// lint on all further items // lint on all further items
for stmt in stmts { for stmt in stmts {
if let StmtDecl(ref decl, _) = *stmt { if let StmtKind::Decl(ref decl, _) = *stmt {
if let DeclItem(ref it) = decl.node { if let DeclKind::Item(ref it) = decl.node {
if in_macro(cx, it.span) { if in_macro(cx, it.span) {
return; return;
} }

View file

@ -6,7 +6,7 @@ use syntax::codemap::{Span, Spanned};
use rustc::middle::def_id::DefId; use rustc::middle::def_id::DefId;
use rustc::middle::ty::{self, MethodTraitItemId, ImplOrTraitItemId}; use rustc::middle::ty::{self, MethodTraitItemId, ImplOrTraitItemId};
use syntax::ast::{Lit, Lit_}; use syntax::ast::{Lit, LitKind};
use utils::{get_item_name, snippet, span_lint, walk_ptrs_ty}; use utils::{get_item_name, snippet, span_lint, walk_ptrs_ty};
@ -151,7 +151,7 @@ fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str)
} }
fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[P<Expr>], lit: &Lit, op: &str) { fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[P<Expr>], lit: &Lit, op: &str) {
if let Spanned{node: Lit_::LitInt(0, _), ..} = *lit { if let Spanned{node: LitKind::Int(0, _), ..} = *lit {
if name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) { if name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
span_lint(cx, span_lint(cx,
LEN_ZERO, LEN_ZERO,

View file

@ -5,7 +5,7 @@ use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
use rustc::middle::ty; use rustc::middle::ty;
use rustc_front::hir::*; use rustc_front::hir::*;
use std::cmp::Ordering; use std::cmp::Ordering;
use syntax::ast::Lit_::LitBool; use syntax::ast::LitKind;
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{COW_PATH, OPTION_PATH, RESULT_PATH}; use utils::{COW_PATH, OPTION_PATH, RESULT_PATH};
@ -238,8 +238,8 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
let exprs = if let PatLit(ref arm_bool) = arms[0].pats[0].node { let exprs = if let PatLit(ref arm_bool) = arms[0].pats[0].node {
if let ExprLit(ref lit) = arm_bool.node { if let ExprLit(ref lit) = arm_bool.node {
match lit.node { match lit.node {
LitBool(true) => Some((&*arms[0].body, &*arms[1].body)), LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
LitBool(false) => Some((&*arms[1].body, &*arms[0].body)), LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
_ => None, _ => None,
} }
} else { } else {

View file

@ -56,8 +56,8 @@ impl LateLintPass for MutexAtomic {
behaviour and not the internal type, consider using Mutex<()>.", behaviour and not the internal type, consider using Mutex<()>.",
atomic_name); atomic_name);
match *mutex_param { match *mutex_param {
ty::TyUint(t) if t != ast::TyUs => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), ty::TyUint(t) if t != ast::UintTy::Us => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
ty::TyInt(t) if t != ast::TyIs => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), ty::TyInt(t) if t != ast::IntTy::Is => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
_ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg), _ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
}; };
} }

View file

@ -5,7 +5,7 @@
use rustc::lint::*; use rustc::lint::*;
use rustc_front::hir::*; use rustc_front::hir::*;
use syntax::ast::Lit_; use syntax::ast::LitKind;
use syntax::codemap::Spanned; use syntax::codemap::Spanned;
use utils::{span_lint, span_lint_and_then, snippet}; use utils::{span_lint, span_lint_and_then, snippet};
@ -164,7 +164,7 @@ fn fetch_bool_expr(expr: &Expr) -> Option<bool> {
match expr.node { match expr.node {
ExprBlock(ref block) => fetch_bool_block(block), ExprBlock(ref block) => fetch_bool_block(block),
ExprLit(ref lit_ptr) => { ExprLit(ref lit_ptr) => {
if let Lit_::LitBool(value) = lit_ptr.node { if let LitKind::Bool(value) = lit_ptr.node {
Some(value) Some(value)
} else { } else {
None None

View file

@ -2,7 +2,7 @@ use rustc::lint::*;
use rustc_front::hir::{Expr, ExprMethodCall, ExprLit}; use rustc_front::hir::{Expr, ExprMethodCall, ExprLit};
use utils::{walk_ptrs_ty_depth, match_type, span_lint, OPEN_OPTIONS_PATH}; use utils::{walk_ptrs_ty_depth, match_type, span_lint, OPEN_OPTIONS_PATH};
use syntax::codemap::{Span, Spanned}; use syntax::codemap::{Span, Spanned};
use syntax::ast::Lit_::LitBool; use syntax::ast::LitKind;
/// **What it does:** This lint checks for duplicate open options as well as combinations that make no sense. /// **What it does:** This lint checks for duplicate open options as well as combinations that make no sense.
/// ///
@ -65,7 +65,7 @@ fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOp
let argument_option = match arguments[1].node { let argument_option = match arguments[1].node {
ExprLit(ref span) => { ExprLit(ref span) => {
if let Spanned {node: LitBool(lit), ..} = **span { if let Spanned {node: LitKind::Bool(lit), ..} = **span {
if lit { if lit {
Argument::True Argument::True
} else { } else {

View file

@ -1,6 +1,6 @@
use rustc::lint::*; use rustc::lint::*;
use rustc_front::hir::*; use rustc_front::hir::*;
use syntax::ast::Lit_::LitStr; use syntax::ast::LitKind;
use utils::{span_lint, in_external_macro, match_path, BEGIN_UNWIND}; use utils::{span_lint, in_external_macro, match_path, BEGIN_UNWIND};
@ -37,7 +37,7 @@ impl LateLintPass for PanicPass {
let ExprPath(None, ref path) = fun.node, let ExprPath(None, ref path) = fun.node,
match_path(path, &BEGIN_UNWIND), match_path(path, &BEGIN_UNWIND),
let ExprLit(ref lit) = params[0].node, let ExprLit(ref lit) = params[0].node,
let LitStr(ref string, _) = lit.node, let LitKind::Str(ref string, _) = lit.node,
string.contains('{'), string.contains('{'),
let Some(sp) = cx.sess().codemap() let Some(sp) = cx.sess().codemap()
.with_expn_info(expr.span.expn_id, .with_expn_info(expr.span.expn_id,

View file

@ -32,7 +32,7 @@ impl LintPass for Precedence {
impl EarlyLintPass for Precedence { impl EarlyLintPass for Precedence {
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
if let ExprBinary(Spanned { node: op, ..}, ref left, ref right) = expr.node { if let ExprKind::Binary(Spanned { node: op, ..}, ref left, ref right) = expr.node {
if !is_bit_op(op) { if !is_bit_op(op) {
return; return;
} }
@ -71,12 +71,12 @@ impl EarlyLintPass for Precedence {
} }
} }
if let ExprUnary(UnNeg, ref rhs) = expr.node { if let ExprKind::Unary(UnOp::Neg, ref rhs) = expr.node {
if let ExprMethodCall(_, _, ref args) = rhs.node { if let ExprKind::MethodCall(_, _, ref args) = rhs.node {
if let Some(slf) = args.first() { if let Some(slf) = args.first() {
if let ExprLit(ref lit) = slf.node { if let ExprKind::Lit(ref lit) = slf.node {
match lit.node { match lit.node {
LitInt(..) | LitFloat(..) | LitFloatUnsuffixed(..) => { LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => {
span_lint(cx, span_lint(cx,
PRECEDENCE, PRECEDENCE,
expr.span, expr.span,
@ -95,21 +95,23 @@ impl EarlyLintPass for Precedence {
fn is_arith_expr(expr: &Expr) -> bool { fn is_arith_expr(expr: &Expr) -> bool {
match expr.node { match expr.node {
ExprBinary(Spanned { node: op, ..}, _, _) => is_arith_op(op), ExprKind::Binary(Spanned { node: op, ..}, _, _) => is_arith_op(op),
_ => false, _ => false,
} }
} }
fn is_bit_op(op: BinOp_) -> bool { fn is_bit_op(op: BinOpKind) -> bool {
use syntax::ast::BinOpKind::*;
match op { match op {
BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr => true, BitXor | BitAnd | BitOr | Shl | Shr => true,
_ => false, _ => false,
} }
} }
fn is_arith_op(op: BinOp_) -> bool { fn is_arith_op(op: BinOpKind) -> bool {
use syntax::ast::BinOpKind::*;
match op { match op {
BiAdd | BiSub | BiMul | BiDiv | BiRem => true, Add | Sub | Mul | Div | Rem => true,
_ => false, _ => false,
} }
} }

View file

@ -1,7 +1,7 @@
use regex_syntax; use regex_syntax;
use std::error::Error; use std::error::Error;
use std::collections::HashSet; use std::collections::HashSet;
use syntax::ast::Lit_::LitStr; use syntax::ast::LitKind;
use syntax::codemap::{Span, BytePos}; use syntax::codemap::{Span, BytePos};
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use rustc_front::hir::*; use rustc_front::hir::*;
@ -75,7 +75,7 @@ impl LateLintPass for RegexPass {
match_path(path, &REGEX_NEW_PATH) && args.len() == 1 match_path(path, &REGEX_NEW_PATH) && args.len() == 1
], { ], {
if let ExprLit(ref lit) = args[0].node { if let ExprLit(ref lit) = args[0].node {
if let LitStr(ref r, _) = lit.node { if let LitKind::Str(ref r, _) = lit.node {
match regex_syntax::Expr::parse(r) { match regex_syntax::Expr::parse(r) {
Ok(r) => { Ok(r) => {
if let Some(repl) = is_trivial_regex(&r) { if let Some(repl) = is_trivial_regex(&r) {

View file

@ -40,8 +40,8 @@ impl ReturnPass {
if let Some(ref expr) = block.expr { if let Some(ref expr) = block.expr {
self.check_final_expr(cx, expr); self.check_final_expr(cx, expr);
} else if let Some(stmt) = block.stmts.last() { } else if let Some(stmt) = block.stmts.last() {
if let StmtSemi(ref expr, _) = stmt.node { if let StmtKind::Semi(ref expr, _) = stmt.node {
if let ExprRet(Some(ref inner)) = expr.node { if let ExprKind::Ret(Some(ref inner)) = expr.node {
self.emit_return_lint(cx, (stmt.span, inner.span)); self.emit_return_lint(cx, (stmt.span, inner.span));
} }
} }
@ -52,22 +52,22 @@ impl ReturnPass {
fn check_final_expr(&mut self, cx: &EarlyContext, expr: &Expr) { fn check_final_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
match expr.node { match expr.node {
// simple return is always "bad" // simple return is always "bad"
ExprRet(Some(ref inner)) => { ExprKind::Ret(Some(ref inner)) => {
self.emit_return_lint(cx, (expr.span, inner.span)); self.emit_return_lint(cx, (expr.span, inner.span));
} }
// a whole block? check it! // a whole block? check it!
ExprBlock(ref block) => { ExprKind::Block(ref block) => {
self.check_block_return(cx, block); self.check_block_return(cx, block);
} }
// an if/if let expr, check both exprs // an if/if let expr, check both exprs
// note, if without else is going to be a type checking error anyways // note, if without else is going to be a type checking error anyways
// (except for unit type functions) so we don't match it // (except for unit type functions) so we don't match it
ExprIf(_, ref ifblock, Some(ref elsexpr)) => { ExprKind::If(_, ref ifblock, Some(ref elsexpr)) => {
self.check_block_return(cx, ifblock); self.check_block_return(cx, ifblock);
self.check_final_expr(cx, elsexpr); self.check_final_expr(cx, elsexpr);
} }
// a match expr, check all arms // a match expr, check all arms
ExprMatch(_, ref arms) => { ExprKind::Match(_, ref arms) => {
for arm in arms { for arm in arms {
self.check_final_expr(cx, &arm.body); self.check_final_expr(cx, &arm.body);
} }
@ -94,11 +94,11 @@ impl ReturnPass {
[ [
let Some(stmt) = block.stmts.last(), let Some(stmt) = block.stmts.last(),
let Some(ref retexpr) = block.expr, let Some(ref retexpr) = block.expr,
let StmtDecl(ref decl, _) = stmt.node, let StmtKind::Decl(ref decl, _) = stmt.node,
let DeclLocal(ref local) = decl.node, let DeclKind::Local(ref local) = decl.node,
let Some(ref initexpr) = local.init, let Some(ref initexpr) = local.init,
let PatIdent(_, Spanned { node: id, .. }, _) = local.pat.node, let PatIdent(_, Spanned { node: id, .. }, _) = local.pat.node,
let ExprPath(_, ref path) = retexpr.node, let ExprKind::Path(_, ref path) = retexpr.node,
match_path_ast(path, &[&id.name.as_str()]) match_path_ast(path, &[&id.name.as_str()])
], { ], {
self.emit_let_lint(cx, retexpr.span, initexpr.span); self.emit_let_lint(cx, retexpr.span, initexpr.span);

View file

@ -133,13 +133,13 @@ impl LintPass for StringLitAsBytes {
impl LateLintPass for StringLitAsBytes { impl LateLintPass for StringLitAsBytes {
fn check_expr(&mut self, cx: &LateContext, e: &Expr) { fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use syntax::ast::Lit_::LitStr; use syntax::ast::LitKind;
use utils::{snippet, in_macro}; use utils::{snippet, in_macro};
if let ExprMethodCall(ref name, _, ref args) = e.node { if let ExprMethodCall(ref name, _, ref args) = e.node {
if name.node.as_str() == "as_bytes" { if name.node.as_str() == "as_bytes" {
if let ExprLit(ref lit) = args[0].node { if let ExprLit(ref lit) = args[0].node {
if let LitStr(ref lit_content, _) = lit.node { if let LitKind::Str(ref lit_content, _) = lit.node {
if lit_content.chars().all(|c| c.is_ascii()) && !in_macro(cx, e.span) { if lit_content.chars().all(|c| c.is_ascii()) && !in_macro(cx, e.span) {
let msg = format!("calling `as_bytes()` on a string literal. \ let msg = format!("calling `as_bytes()` on a string literal. \
Consider using a byte string literal instead: \ Consider using a byte string literal instead: \

View file

@ -235,7 +235,7 @@ fn int_ty_to_nbits(typ: &ty::TyS) -> usize {
fn is_isize_or_usize(typ: &ty::TyS) -> bool { fn is_isize_or_usize(typ: &ty::TyS) -> bool {
match typ.sty { match typ.sty {
ty::TyInt(IntTy::TyIs) | ty::TyUint(UintTy::TyUs) => true, ty::TyInt(IntTy::Is) | ty::TyUint(UintTy::Us) => true,
_ => false, _ => false,
} }
} }
@ -360,7 +360,7 @@ impl LateLintPass for CastPass {
match (cast_from.is_integral(), cast_to.is_integral()) { match (cast_from.is_integral(), cast_to.is_integral()) {
(true, false) => { (true, false) => {
let from_nbits = int_ty_to_nbits(cast_from); let from_nbits = int_ty_to_nbits(cast_from);
let to_nbits = if let ty::TyFloat(FloatTy::TyF32) = cast_to.sty { let to_nbits = if let ty::TyFloat(FloatTy::F32) = cast_to.sty {
32 32
} else { } else {
64 64
@ -391,7 +391,7 @@ impl LateLintPass for CastPass {
check_truncation_and_wrapping(cx, expr, cast_from, cast_to); check_truncation_and_wrapping(cx, expr, cast_from, cast_to);
} }
(false, false) => { (false, false) => {
if let (&ty::TyFloat(FloatTy::TyF64), &ty::TyFloat(FloatTy::TyF32)) = (&cast_from.sty, &cast_to.sty) { if let (&ty::TyFloat(FloatTy::F64), &ty::TyFloat(FloatTy::F32)) = (&cast_from.sty, &cast_to.sty) {
span_lint(cx, span_lint(cx,
CAST_POSSIBLE_TRUNCATION, CAST_POSSIBLE_TRUNCATION,
expr.span, expr.span,
@ -560,12 +560,12 @@ impl LintPass for CharLitAsU8 {
impl LateLintPass for CharLitAsU8 { impl LateLintPass for CharLitAsU8 {
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
use syntax::ast::{Lit_, UintTy}; use syntax::ast::{LitKind, UintTy};
if let ExprCast(ref e, _) = expr.node { if let ExprCast(ref e, _) = expr.node {
if let ExprLit(ref l) = e.node { if let ExprLit(ref l) = e.node {
if let Lit_::LitChar(_) = l.node { if let LitKind::Char(_) = l.node {
if ty::TyUint(UintTy::TyU8) == cx.tcx.expr_ty(expr).sty && !in_macro(cx, expr.span) { if ty::TyUint(UintTy::U8) == cx.tcx.expr_ty(expr).sty && !in_macro(cx, expr.span) {
let msg = "casting character literal to u8. `char`s \ let msg = "casting character literal to u8. `char`s \
are 4 bytes wide in rust, so casting to u8 \ are 4 bytes wide in rust, so casting to u8 \
truncates them"; truncates them";
@ -676,31 +676,31 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeEx
let which = match (ty, cv) { let which = match (ty, cv) {
(&ty::TyBool, Bool(false)) => Minimum, (&ty::TyBool, Bool(false)) => Minimum,
(&ty::TyInt(IntTy::TyIs), Int(x)) if x == ::std::isize::MIN as i64 => Minimum, (&ty::TyInt(IntTy::Is), Int(x)) if x == ::std::isize::MIN as i64 => Minimum,
(&ty::TyInt(IntTy::TyI8), Int(x)) if x == ::std::i8::MIN as i64 => Minimum, (&ty::TyInt(IntTy::I8), Int(x)) if x == ::std::i8::MIN as i64 => Minimum,
(&ty::TyInt(IntTy::TyI16), Int(x)) if x == ::std::i16::MIN as i64 => Minimum, (&ty::TyInt(IntTy::I16), Int(x)) if x == ::std::i16::MIN as i64 => Minimum,
(&ty::TyInt(IntTy::TyI32), Int(x)) if x == ::std::i32::MIN as i64 => Minimum, (&ty::TyInt(IntTy::I32), Int(x)) if x == ::std::i32::MIN as i64 => Minimum,
(&ty::TyInt(IntTy::TyI64), Int(x)) if x == ::std::i64::MIN as i64 => Minimum, (&ty::TyInt(IntTy::I64), Int(x)) if x == ::std::i64::MIN as i64 => Minimum,
(&ty::TyUint(UintTy::TyUs), Uint(x)) if x == ::std::usize::MIN as u64 => Minimum, (&ty::TyUint(UintTy::Us), Uint(x)) if x == ::std::usize::MIN as u64 => Minimum,
(&ty::TyUint(UintTy::TyU8), Uint(x)) if x == ::std::u8::MIN as u64 => Minimum, (&ty::TyUint(UintTy::U8), Uint(x)) if x == ::std::u8::MIN as u64 => Minimum,
(&ty::TyUint(UintTy::TyU16), Uint(x)) if x == ::std::u16::MIN as u64 => Minimum, (&ty::TyUint(UintTy::U16), Uint(x)) if x == ::std::u16::MIN as u64 => Minimum,
(&ty::TyUint(UintTy::TyU32), Uint(x)) if x == ::std::u32::MIN as u64 => Minimum, (&ty::TyUint(UintTy::U32), Uint(x)) if x == ::std::u32::MIN as u64 => Minimum,
(&ty::TyUint(UintTy::TyU64), Uint(x)) if x == ::std::u64::MIN as u64 => Minimum, (&ty::TyUint(UintTy::U64), Uint(x)) if x == ::std::u64::MIN as u64 => Minimum,
(&ty::TyBool, Bool(true)) => Maximum, (&ty::TyBool, Bool(true)) => Maximum,
(&ty::TyInt(IntTy::TyIs), Int(x)) if x == ::std::isize::MAX as i64 => Maximum, (&ty::TyInt(IntTy::Is), Int(x)) if x == ::std::isize::MAX as i64 => Maximum,
(&ty::TyInt(IntTy::TyI8), Int(x)) if x == ::std::i8::MAX as i64 => Maximum, (&ty::TyInt(IntTy::I8), Int(x)) if x == ::std::i8::MAX as i64 => Maximum,
(&ty::TyInt(IntTy::TyI16), Int(x)) if x == ::std::i16::MAX as i64 => Maximum, (&ty::TyInt(IntTy::I16), Int(x)) if x == ::std::i16::MAX as i64 => Maximum,
(&ty::TyInt(IntTy::TyI32), Int(x)) if x == ::std::i32::MAX as i64 => Maximum, (&ty::TyInt(IntTy::I32), Int(x)) if x == ::std::i32::MAX as i64 => Maximum,
(&ty::TyInt(IntTy::TyI64), Int(x)) if x == ::std::i64::MAX as i64 => Maximum, (&ty::TyInt(IntTy::I64), Int(x)) if x == ::std::i64::MAX as i64 => Maximum,
(&ty::TyUint(UintTy::TyUs), Uint(x)) if x == ::std::usize::MAX as u64 => Maximum, (&ty::TyUint(UintTy::Us), Uint(x)) if x == ::std::usize::MAX as u64 => Maximum,
(&ty::TyUint(UintTy::TyU8), Uint(x)) if x == ::std::u8::MAX as u64 => Maximum, (&ty::TyUint(UintTy::U8), Uint(x)) if x == ::std::u8::MAX as u64 => Maximum,
(&ty::TyUint(UintTy::TyU16), Uint(x)) if x == ::std::u16::MAX as u64 => Maximum, (&ty::TyUint(UintTy::U16), Uint(x)) if x == ::std::u16::MAX as u64 => Maximum,
(&ty::TyUint(UintTy::TyU32), Uint(x)) if x == ::std::u32::MAX as u64 => Maximum, (&ty::TyUint(UintTy::U32), Uint(x)) if x == ::std::u32::MAX as u64 => Maximum,
(&ty::TyUint(UintTy::TyU64), Uint(x)) if x == ::std::u64::MAX as u64 => Maximum, (&ty::TyUint(UintTy::U64), Uint(x)) if x == ::std::u64::MAX as u64 => Maximum,
_ => return None, _ => return None,
}; };

View file

@ -2,7 +2,7 @@ use rustc::lint::*;
use rustc_front::hir::*; use rustc_front::hir::*;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ast::Lit_; use syntax::ast::LitKind;
use unicode_normalization::UnicodeNormalization; use unicode_normalization::UnicodeNormalization;
@ -59,7 +59,7 @@ impl LintPass for Unicode {
impl LateLintPass for Unicode { impl LateLintPass for Unicode {
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
if let ExprLit(ref lit) = expr.node { if let ExprLit(ref lit) = expr.node {
if let Lit_::LitStr(_, _) = lit.node { if let LitKind::Str(_, _) = lit.node {
check_str(cx, lit.span) check_str(cx, lit.span)
} }
} }

View file

@ -10,8 +10,7 @@ use std::borrow::Cow;
use std::mem; use std::mem;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::str::FromStr; use std::str::FromStr;
use syntax::ast::Lit_; use syntax::ast::{LitKind, self};
use syntax::ast;
use syntax::codemap::{ExpnInfo, Span, ExpnFormat}; use syntax::codemap::{ExpnInfo, Span, ExpnFormat};
use syntax::errors::DiagnosticBuilder; use syntax::errors::DiagnosticBuilder;
use syntax::ptr::P; use syntax::ptr::P;
@ -531,7 +530,7 @@ pub fn walk_ptrs_ty_depth(ty: ty::Ty) -> (ty::Ty, usize) {
pub fn is_integer_literal(expr: &Expr, value: u64) -> bool { pub fn is_integer_literal(expr: &Expr, value: u64) -> bool {
// FIXME: use constant folding // FIXME: use constant folding
if let ExprLit(ref spanned) = expr.node { if let ExprLit(ref spanned) = expr.node {
if let Lit_::LitInt(v, _) = spanned.node { if let LitKind::Int(v, _) = spanned.node {
return v == value; return v == value;
} }
} }
@ -575,9 +574,9 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
if attr.is_sugared_doc { if attr.is_sugared_doc {
continue; continue;
} }
if let ast::MetaNameValue(ref key, ref value) = attr.value.node { if let ast::MetaItemKind::NameValue(ref key, ref value) = attr.value.node {
if *key == name { if *key == name {
if let Lit_::LitStr(ref s, _) = value.node { if let LitKind::Str(ref s, _) = value.node {
if let Ok(value) = FromStr::from_str(s) { if let Ok(value) = FromStr::from_str(s) {
f(value) f(value)
} else { } else {

View file

@ -11,13 +11,11 @@ use syntax::parse::token::InternedString;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::codemap::{Spanned, COMMAND_LINE_SP}; use syntax::codemap::{Spanned, COMMAND_LINE_SP};
use syntax::ast::Lit_::*; use syntax::ast::LitKind;
use syntax::ast::Lit_; use syntax::ast::LitIntType;
use syntax::ast::LitIntType::*; use syntax::ast::StrStyle;
use syntax::ast::StrStyle::*;
use syntax::ast::Sign::*;
use clippy::consts::{constant_simple, Constant}; use clippy::consts::{constant_simple, Constant, Sign};
fn spanned<T>(t: T) -> Spanned<T> { fn spanned<T>(t: T) -> Spanned<T> {
Spanned{ node: t, span: COMMAND_LINE_SP } Spanned{ node: t, span: COMMAND_LINE_SP }
@ -32,7 +30,7 @@ fn expr(n: Expr_) -> Expr {
} }
} }
fn lit(l: Lit_) -> Expr { fn lit(l: LitKind) -> Expr {
expr(ExprLit(P(spanned(l)))) expr(ExprLit(P(spanned(l))))
} }
@ -46,26 +44,26 @@ fn check(expect: Constant, expr: &Expr) {
const TRUE : Constant = Constant::Bool(true); const TRUE : Constant = Constant::Bool(true);
const FALSE : Constant = Constant::Bool(false); const FALSE : Constant = Constant::Bool(false);
const ZERO : Constant = Constant::Int(0, UnsuffixedIntLit(Plus)); const ZERO : Constant = Constant::Int(0, LitIntType::Unsuffixed, Sign::Plus);
const ONE : Constant = Constant::Int(1, UnsuffixedIntLit(Plus)); const ONE : Constant = Constant::Int(1, LitIntType::Unsuffixed, Sign::Plus);
const TWO : Constant = Constant::Int(2, UnsuffixedIntLit(Plus)); const TWO : Constant = Constant::Int(2, LitIntType::Unsuffixed, Sign::Plus);
#[test] #[test]
fn test_lit() { fn test_lit() {
check(TRUE, &lit(LitBool(true))); check(TRUE, &lit(LitKind::Bool(true)));
check(FALSE, &lit(LitBool(false))); check(FALSE, &lit(LitKind::Bool(false)));
check(ZERO, &lit(LitInt(0, UnsuffixedIntLit(Plus)))); check(ZERO, &lit(LitKind::Int(0, LitIntType::Unsuffixed)));
check(Constant::Str("cool!".into(), CookedStr), &lit(LitStr( check(Constant::Str("cool!".into(), StrStyle::Cooked), &lit(LitKind::Str(
InternedString::new("cool!"), CookedStr))); InternedString::new("cool!"), StrStyle::Cooked)));
} }
#[test] #[test]
fn test_ops() { fn test_ops() {
check(TRUE, &binop(BiOr, lit(LitBool(false)), lit(LitBool(true)))); check(TRUE, &binop(BiOr, lit(LitKind::Bool(false)), lit(LitKind::Bool(true))));
check(FALSE, &binop(BiAnd, lit(LitBool(false)), lit(LitBool(true)))); check(FALSE, &binop(BiAnd, lit(LitKind::Bool(false)), lit(LitKind::Bool(true))));
let litzero = lit(LitInt(0, UnsuffixedIntLit(Plus))); let litzero = lit(LitKind::Int(0, LitIntType::Unsuffixed));
let litone = lit(LitInt(1, UnsuffixedIntLit(Plus))); let litone = lit(LitKind::Int(1, LitIntType::Unsuffixed));
check(TRUE, &binop(BiEq, litzero.clone(), litzero.clone())); check(TRUE, &binop(BiEq, litzero.clone(), litzero.clone()));
check(TRUE, &binop(BiGe, litzero.clone(), litzero.clone())); check(TRUE, &binop(BiGe, litzero.clone(), litzero.clone()));
check(TRUE, &binop(BiLe, litzero.clone(), litzero.clone())); check(TRUE, &binop(BiLe, litzero.clone(), litzero.clone()));