mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-14 00:47:16 +00:00
fix nightly breakage
This commit is contained in:
parent
d305bca25b
commit
3f34b65747
23 changed files with 201 additions and 259 deletions
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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}"),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/attrs.rs
12
src/attrs.rs
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
233
src/consts.rs
233
src/consts.rs
|
@ -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))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, ®EX_NEW_PATH) && args.len() == 1
|
match_path(path, ®EX_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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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: \
|
||||||
|
|
52
src/types.rs
52
src/types.rs
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
Loading…
Reference in a new issue