use rustc::lint::*;
use rustc_front::hir::*;
use std::f64::consts as f64;
-use utils::span_lint;
use syntax::ast::{Lit, LitKind, FloatTy};
+use utils::span_lint;
/// **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.
///
//! checks for attributes
+use reexport::*;
use rustc::lint::*;
use rustc_front::hir::*;
-use reexport::*;
use semver::Version;
-use syntax::codemap::Span;
-use syntax::attr::*;
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind};
+use syntax::attr::*;
+use syntax::codemap::Span;
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.
use rustc::middle::def::{Def, PathResolution};
use rustc_front::hir::*;
use rustc_front::util::is_comparison_binop;
-use syntax::codemap::Span;
use syntax::ast::LitKind;
+use syntax::codemap::Span;
use utils::span_lint;
-use rustc_front::hir::*;
use rustc::lint::{LateLintPass, LateContext, LintArray, LintPass};
+use rustc_front::hir::*;
use rustc_front::intravisit::{Visitor, walk_expr};
use utils::*;
(&Constant::Byte(l), &Constant::Byte(r)) => l == r,
(&Constant::Char(l), &Constant::Char(r)) => l == r,
(&Constant::Int(0, _, _), &Constant::Int(0, _, _)) => true,
- (&Constant::Int(lv, _, lneg), &Constant::Int(rv, _, rneg)) => {
- lv == rv && lneg == rneg
- }
+ (&Constant::Int(lv, _, lneg), &Constant::Int(rv, _, rneg)) => lv == rv && lneg == rneg,
(&Constant::Float(ref ls, _), &Constant::Float(ref rs, _)) => {
// we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
// `Fw32 == Fw64` so don’t compare them
}
impl Hash for Constant {
- fn hash<H>(&self, state: &mut H) where H: Hasher {
+ fn hash<H>(&self, state: &mut H)
+ where H: Hasher
+ {
match *self {
Constant::Str(ref s, ref k) => {
s.hash(state);
Constant::Bool(b) => {
b.hash(state);
}
- Constant::Vec(ref v) | Constant::Tuple(ref v)=> {
+ Constant::Vec(ref v) | Constant::Tuple(ref v) => {
v.hash(state);
}
Constant::Repeat(ref c, l) => {
use self::Constant::*;
match o {
Bool(b) => Some(Bool(!b)),
- Int(value, LitIntType::Signed(ity), Sign::Plus) if value != ::std::u64::MAX => Some(Int(value + 1, LitIntType::Signed(ity), Sign::Minus)),
+ Int(value, LitIntType::Signed(ity), Sign::Plus) if value != ::std::u64::MAX => {
+ Some(Int(value + 1, LitIntType::Signed(ity), Sign::Minus))
+ }
Int(0, LitIntType::Signed(ity), Sign::Minus) => Some(Int(1, LitIntType::Signed(ity), Sign::Minus)),
Int(value, LitIntType::Signed(ity), Sign::Minus) => Some(Int(value - 1, LitIntType::Signed(ity), Sign::Plus)),
Int(value, LitIntType::Unsigned(ity), Sign::Plus) => {
} // refuse to guess
};
Some(Int(!value & mask, LitIntType::Unsigned(ity), Sign::Plus))
- },
+ }
_ => None,
}
}
(Constant::Byte(l8), Constant::Byte(r8)) => l8.checked_add(r8).map(Constant::Byte),
(Constant::Int(l64, lty, lsign), Constant::Int(r64, rty, rsign)) => {
add_ints(l64, r64, lty, rty, lsign, rsign)
- },
+ }
// TODO: float (would need bignum library?)
_ => None,
}
}
(Constant::Int(l64, lty, lsign), Constant::Int(r64, rty, rsign)) => {
add_ints(l64, r64, lty, rty, lsign, neg_sign(rsign))
- },
+ }
_ => None,
}
})
match (l, r) {
(Constant::Int(l64, lty, lsign), Constant::Int(r64, rty, rsign)) => {
f(l64, r64).and_then(|value| {
- let sign = if lsign == rsign { Sign::Plus } else { Sign::Minus };
+ let sign = if lsign == rsign {
+ Sign::Plus
+ } else {
+ Sign::Minus
+ };
unify_int_type(lty, rty).map(|ty| Constant::Int(value, ty, sign))
})
}
}
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; };
+ 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))
- },
+ (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))
+ }
+ }
}
}
impl LintPass for CopyAndPaste {
fn get_lints(&self) -> LintArray {
- lint_array![
- IFS_SAME_COND,
- IF_SAME_THEN_ELSE,
- MATCH_SAME_ARMS
- ]
+ lint_array![IFS_SAME_COND, IF_SAME_THEN_ELSE, MATCH_SAME_ARMS]
}
}
/// Implementation of `IF_SAME_THEN_ELSE`.
fn lint_same_then_else(cx: &LateContext, blocks: &[&Block]) {
- let hash : &Fn(&&Block) -> u64 = &|block| -> u64 {
+ let hash: &Fn(&&Block) -> u64 = &|block| -> u64 {
let mut h = SpanlessHash::new(cx);
h.hash_block(block);
h.finish()
};
- let eq : &Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool {
+ let eq: &Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool {
SpanlessEq::new(cx).eq_block(lhs, rhs)
};
if let Some((i, j)) = search_same(blocks, hash, eq) {
- span_note_and_lint(cx, IF_SAME_THEN_ELSE, j.span, "this `if` has identical blocks", i.span, "same as this");
+ span_note_and_lint(cx,
+ IF_SAME_THEN_ELSE,
+ j.span,
+ "this `if` has identical blocks",
+ i.span,
+ "same as this");
}
}
/// Implementation of `IFS_SAME_COND`.
fn lint_same_cond(cx: &LateContext, conds: &[&Expr]) {
- let hash : &Fn(&&Expr) -> u64 = &|expr| -> u64 {
+ let hash: &Fn(&&Expr) -> u64 = &|expr| -> u64 {
let mut h = SpanlessHash::new(cx);
h.hash_expr(expr);
h.finish()
};
- let eq : &Fn(&&Expr, &&Expr) -> bool = &|&lhs, &rhs| -> bool {
- SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, rhs)
- };
+ let eq: &Fn(&&Expr, &&Expr) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, rhs) };
if let Some((i, j)) = search_same(conds, hash, eq) {
- span_note_and_lint(cx, IFS_SAME_COND, j.span, "this `if` has the same condition as a previous if", i.span, "same as this");
+ span_note_and_lint(cx,
+ IFS_SAME_COND,
+ j.span,
+ "this `if` has the same condition as a previous if",
+ i.span,
+ "same as this");
}
}
if let ExprMatch(_, ref arms, MatchSource::Normal) = expr.node {
if let Some((i, j)) = search_same(&**arms, hash, eq) {
- span_note_and_lint(cx, MATCH_SAME_ARMS, j.body.span, "this `match` has identical arm bodies", i.body.span, "same as this");
+ span_note_and_lint(cx,
+ MATCH_SAME_ARMS,
+ j.body.span,
+ "this `match` has identical arm bodies",
+ i.body.span,
+ "same as this");
}
}
}
if let Some(ref else_expr) = *else_expr {
expr = else_expr;
- }
- else {
+ } else {
break;
}
}
if let Some(ref as_pat) = *as_pat {
bindings_impl(cx, as_pat, map);
}
- },
+ }
PatKind::Struct(_, ref fields, _) => {
for pat in fields {
bindings_impl(cx, &pat.node.pat, map);
bindings_impl(cx, pat, map);
}
}
- PatKind::TupleStruct(..) | PatKind::Lit(..) | PatKind::QPath(..) | PatKind::Range(..) | PatKind::Wild | PatKind::Path(..) => (),
+ PatKind::TupleStruct(..) |
+ PatKind::Lit(..) |
+ PatKind::QPath(..) |
+ PatKind::Range(..) |
+ PatKind::Wild |
+ PatKind::Path(..) => (),
}
}
result
}
-fn search_same<T, Hash, Eq>(exprs: &[T],
- hash: Hash,
- eq: Eq) -> Option<(&T, &T)>
-where Hash: Fn(&T) -> u64,
- Eq: Fn(&T, &T) -> bool {
+fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Option<(&T, &T)>
+ where Hash: Fn(&T) -> u64,
+ Eq: Fn(&T, &T) -> bool
+{
// common cases
if exprs.len() < 2 {
return None;
- }
- else if exprs.len() == 2 {
+ } else if exprs.len() == 2 {
return if eq(&exprs[0], &exprs[1]) {
Some((&exprs[0], &exprs[1]))
- }
- else {
+ } else {
None
- }
+ };
}
- let mut map : HashMap<_, Vec<&_>> = HashMap::with_capacity(exprs.len());
+ let mut map: HashMap<_, Vec<&_>> = HashMap::with_capacity(exprs.len());
for expr in exprs {
match map.entry(hash(expr)) {
Entry::Occupied(o) => {
for o in o.get() {
if eq(&o, expr) {
- return Some((&o, expr))
+ return Some((&o, expr));
}
}
}
- Entry::Vacant(v) => { v.insert(vec![expr]); }
+ Entry::Vacant(v) => {
+ v.insert(vec![expr]);
+ }
}
}
//! calculate cyclomatic complexity and warn about overly complex functions
use rustc::lint::*;
-use rustc_front::hir::*;
use rustc::middle::cfg::CFG;
use rustc::middle::ty;
-use syntax::codemap::Span;
-use syntax::attr::*;
-use syntax::ast::Attribute;
+use rustc_front::hir::*;
use rustc_front::intravisit::{Visitor, walk_expr};
+use syntax::ast::Attribute;
+use syntax::attr::*;
+use syntax::codemap::Span;
use utils::{in_macro, LimitStack, span_help_and_lint};
use rustc::lint::*;
-use rustc_front::hir::*;
use rustc::middle::ty;
+use rustc_front::hir::*;
use syntax::codemap::Span;
-
use utils::DROP_PATH;
use utils::{match_def_path, span_note_and_lint};
//! lint on `use`ing all variants of an enum
-use rustc::lint::{LateLintPass, LintPass, LateContext, LintArray, LintContext};
-use rustc_front::hir::*;
use rustc::front::map::Node::NodeItem;
use rustc::front::map::definitions::DefPathData;
+use rustc::lint::{LateLintPass, LintPass, LateContext, LintArray, LintContext};
use rustc::middle::ty::TyEnum;
-use utils::span_lint;
-use syntax::codemap::Span;
+use rustc_front::hir::*;
use syntax::ast::NodeId;
+use syntax::codemap::Span;
+use utils::span_lint;
/// **What it does:** Warns when `use`ing all variants of an enum
///
//! lint on enum variants that are prefixed or suffixed by the same characters
use rustc::lint::*;
-use syntax::attr::*;
use syntax::ast::*;
+use syntax::attr::*;
use syntax::parse::token::InternedString;
-
use utils::span_help_and_lint;
use utils::{camel_case_from, camel_case_until};
} else if !post.is_empty() {
("post", post)
} else {
- return
+ return;
};
span_help_and_lint(cx,
ENUM_VARIANT_NAMES,
use rustc::lint::*;
use rustc_front::hir::*;
use rustc_front::util as ast_util;
-
use utils::{SpanlessEq, span_lint};
/// **What it does:** This lint checks for equal operands to comparison, logical and bitwise,
-use rustc::lint::*;
use rustc::front::map::Node::{NodeExpr, NodeStmt};
-use rustc_front::hir::*;
-use rustc_front::intravisit as visit;
-use rustc::middle::ty;
-use rustc::middle::ty::adjustment::AutoAdjustment;
+use rustc::lint::*;
use rustc::middle::expr_use_visitor::*;
use rustc::middle::infer;
use rustc::middle::mem_categorization::{cmt, Categorization};
+use rustc::middle::ty::adjustment::AutoAdjustment;
+use rustc::middle::ty;
use rustc::util::nodemap::NodeSet;
+use rustc_front::hir::*;
+use rustc_front::intravisit as visit;
use syntax::ast::NodeId;
use syntax::codemap::Span;
use utils::span_lint;
use rustc::lint::*;
-use rustc_front::hir::*;
use rustc::middle::ty;
-
+use rustc_front::hir::*;
use utils::{snippet_opt, span_lint_and_then, is_adjusted};
-
#[allow(missing_copy_implementations)]
pub struct EtaPass;
+use consts::{constant_simple, Constant, Sign};
use rustc::lint::*;
use rustc_front::hir::*;
use syntax::codemap::Span;
-
-use consts::{constant_simple, Constant, Sign};
use utils::{span_lint, snippet, in_macro};
/// **What it does:** This lint checks for identity operations, e.g. `x + 0`.
//! lint when items are used after statements
use rustc::lint::*;
-use syntax::attr::*;
use syntax::ast::*;
+use syntax::attr::*;
use utils::in_macro;
/// **What it does:** This lints checks for items declared after some statement in a block
use rustc::lint::*;
-use rustc_front::hir::*;
-use syntax::ast::Name;
-use syntax::ptr::P;
-use syntax::codemap::{Span, Spanned};
use rustc::middle::def_id::DefId;
use rustc::middle::ty::{self, MethodTraitItemId, ImplOrTraitItemId};
-
-use syntax::ast::{Lit, LitKind};
-
+use rustc_front::hir::*;
+use syntax::ast::{Lit, LitKind, Name};
+use syntax::codemap::{Span, Spanned};
+use syntax::ptr::P;
use utils::{get_item_name, snippet, span_lint, walk_ptrs_ty};
/// **What it does:** This lint checks for getting the length of something via `.len()` just to compare to zero, and suggests using `.is_empty()` where applicable.
-use rustc_front::hir::*;
use reexport::*;
use rustc::lint::*;
-use syntax::codemap::Span;
-use rustc_front::intravisit::{Visitor, walk_ty, walk_ty_param_bound, walk_fn_decl, walk_generics};
use rustc::middle::def::Def;
+use rustc_front::hir::*;
+use rustc_front::intravisit::{Visitor, walk_ty, walk_ty_param_bound, walk_fn_decl, walk_generics};
use std::collections::{HashSet, HashMap};
-
+use syntax::codemap::Span;
use utils::{in_external_macro, span_lint};
/// **What it does:** This lint checks for lifetime annotations which can be removed by relying on lifetime elision.
// linting condition: we only indexed one variable
if visitor.indexed.len() == 1 {
let (indexed, indexed_extent) = visitor.indexed
- .into_iter()
- .next()
- .unwrap_or_else(|| unreachable!() /* len == 1 */);
+ .into_iter()
+ .next()
+ .unwrap_or_else(|| unreachable!() /* len == 1 */);
// ensure that the indexed variable was declared before the loop, see #601
let pat_extent = cx.tcx.region_maps.var_scope(pat.id);
// who think that this will iterate from the larger value to the
// smaller value.
let (sup, eq) = match (start_idx, stop_idx) {
- (ConstVal::Int(start_idx), ConstVal::Int(stop_idx)) => (start_idx > stop_idx, start_idx == stop_idx),
- (ConstVal::Uint(start_idx), ConstVal::Uint(stop_idx)) => (start_idx > stop_idx, start_idx == stop_idx),
+ (ConstVal::Int(start_idx), ConstVal::Int(stop_idx)) => {
+ (start_idx > stop_idx, start_idx == stop_idx)
+ }
+ (ConstVal::Uint(start_idx), ConstVal::Uint(stop_idx)) => {
+ (start_idx > stop_idx, start_idx == stop_idx)
+ }
_ => (false, false),
};
fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) {
let ty = cx.tcx.expr_ty(arg);
if match_type(cx, ty, &OPTION_PATH) {
- span_help_and_lint(
- cx,
- FOR_LOOP_OVER_OPTION,
- arg.span,
- &format!("for loop over `{0}`, which is an `Option`. This is more readably written as \
- an `if let` statement.", snippet(cx, arg.span, "_")),
- &format!("consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`",
- snippet(cx, pat.span, "_"), snippet(cx, arg.span, "_"))
- );
- }
- else if match_type(cx, ty, &RESULT_PATH) {
- span_help_and_lint(
- cx,
- FOR_LOOP_OVER_RESULT,
- arg.span,
- &format!("for loop over `{0}`, which is a `Result`. This is more readably written as \
- an `if let` statement.", snippet(cx, arg.span, "_")),
- &format!("consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`",
- snippet(cx, pat.span, "_"), snippet(cx, arg.span, "_"))
- );
+ span_help_and_lint(cx,
+ FOR_LOOP_OVER_OPTION,
+ arg.span,
+ &format!("for loop over `{0}`, which is an `Option`. This is more readably written as an \
+ `if let` statement.",
+ snippet(cx, arg.span, "_")),
+ &format!("consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`",
+ snippet(cx, pat.span, "_"),
+ snippet(cx, arg.span, "_")));
+ } else if match_type(cx, ty, &RESULT_PATH) {
+ span_help_and_lint(cx,
+ FOR_LOOP_OVER_RESULT,
+ arg.span,
+ &format!("for loop over `{0}`, which is a `Result`. This is more readably written as an \
+ `if let` statement.",
+ snippet(cx, arg.span, "_")),
+ &format!("consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`",
+ snippet(cx, pat.span, "_"),
+ snippet(cx, arg.span, "_")));
}
}
let (pat_span, kind) = match (&pat[0].node, &pat[1].node) {
(key, _) if pat_is_wild(key, body) => (&pat[1].span, "values"),
(_, value) if pat_is_wild(value, body) => (&pat[0].span, "keys"),
- _ => return
+ _ => return,
};
let ty = walk_ptrs_ty(cx.tcx.expr_ty(arg));
let arg_span = if let ExprAddrOf(_, ref expr) = arg.node {
expr.span
- }
- else {
+ } else {
arg.span
};
- if match_type(cx, ty, &HASHMAP_PATH) ||
- match_type(cx, ty, &BTREEMAP_PATH) {
+ if match_type(cx, ty, &HASHMAP_PATH) || match_type(cx, ty, &BTREEMAP_PATH) {
span_lint_and_then(cx,
- FOR_KV_MAP,
- expr.span,
- &format!("you seem to want to iterate on a map's {}", kind),
- |db| {
- db.span_suggestion(expr.span,
- "use the corresponding method",
- format!("for {} in {}.{}() {{...}}",
- snippet(cx, *pat_span, ".."),
- snippet(cx, arg_span, ".."),
- kind));
- });
+ FOR_KV_MAP,
+ expr.span,
+ &format!("you seem to want to iterate on a map's {}", kind),
+ |db| {
+ db.span_suggestion(expr.span,
+ "use the corresponding method",
+ format!("for {} in {}.{}() {{...}}",
+ snippet(cx, *pat_span, ".."),
+ snippet(cx, arg_span, ".."),
+ kind));
+ });
}
}
}
};
walk_expr(&mut visitor, body);
!visitor.used
- },
+ }
_ => false,
}
}
if let ExprPath(None, ref path) = expr.node {
if path.segments.len() == 1 && path.segments[0].identifier == self.var {
self.used = true;
- return
+ return;
}
}
use rustc::lint::*;
use rustc_front::hir::*;
use utils::{CLONE_PATH, OPTION_PATH};
-use utils::{is_adjusted, match_path, match_trait_method, match_type, snippet, span_help_and_lint};
-use utils::{walk_ptrs_ty, walk_ptrs_ty_depth};
+use utils::{
+ is_adjusted, match_path, match_trait_method, match_type, snippet, span_help_and_lint,
+ walk_ptrs_ty, walk_ptrs_ty_depth
+};
/// **What it does:** This lint checks for mapping clone() over an iterator.
///
use std::cmp::Ordering;
use syntax::ast::LitKind;
use syntax::codemap::Span;
-
use utils::{COW_PATH, OPTION_PATH, RESULT_PATH};
use utils::{match_type, snippet, span_lint, span_note_and_lint, span_lint_and_then, in_external_macro, expr_block};
if arms.len() == 2 &&
arms[0].pats.len() == 1 && arms[0].guard.is_none() &&
arms[1].pats.len() == 1 && arms[1].guard.is_none() {
- let els = if is_unit_expr(&arms[1].body) {
- None
- } else if let ExprBlock(_) = arms[1].body.node {
- // matches with blocks that contain statements are prettier as `if let + else`
- Some(&*arms[1].body)
- } else {
- // allow match arms with just expressions
- return;
- };
- let ty = cx.tcx.expr_ty(ex);
- if ty.sty != ty::TyBool || cx.current_level(MATCH_BOOL) == Allow {
- check_single_match_single_pattern(cx, ex, arms, expr, els);
- check_single_match_opt_like(cx, ex, arms, expr, ty, els);
- }
+ let els = if is_unit_expr(&arms[1].body) {
+ None
+ } else if let ExprBlock(_) = arms[1].body.node {
+ // matches with blocks that contain statements are prettier as `if let + else`
+ Some(&*arms[1].body)
+ } else {
+ // allow match arms with just expressions
+ return;
+ };
+ let ty = cx.tcx.expr_ty(ex);
+ if ty.sty != ty::TyBool || cx.current_level(MATCH_BOOL) == Allow {
+ check_single_match_single_pattern(cx, ex, arms, expr, els);
+ check_single_match_opt_like(cx, ex, arms, expr, ty, els);
+ }
}
}
let path = match arms[1].pats[0].node {
PatKind::TupleStruct(ref path, Some(ref inner)) => {
// contains any non wildcard patterns? e.g. Err(err)
- if inner.iter().any(|pat| if let PatKind::Wild = pat.node { false } else { true }) {
+ if inner.iter().any(|pat| pat.node != PatKind::Wild) {
return;
}
path.to_string()
- },
+ }
PatKind::TupleStruct(ref path, None) => path.to_string(),
PatKind::Ident(BindByValue(MutImmutable), ident, None) => ident.node.to_string(),
_ => return,
use rustc::lint::*;
-use rustc::middle::const_eval::{ConstVal, eval_const_expr_partial};
use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
+use rustc::middle::const_eval::{ConstVal, eval_const_expr_partial};
+use rustc::middle::cstore::CrateStore;
use rustc::middle::subst::{Subst, TypeSpace};
use rustc::middle::ty;
use rustc_front::hir::*;
use std::{fmt, iter};
use syntax::codemap::Span;
use syntax::ptr::P;
-
use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, match_path, match_trait_method,
match_type, method_chain_args, snippet, snippet_opt, span_lint, span_lint_and_then, span_note_and_lint,
walk_ptrs_ty, walk_ptrs_ty_depth};
use utils::{BTREEMAP_ENTRY_PATH, DEFAULT_TRAIT_PATH, HASHMAP_ENTRY_PATH, OPTION_PATH, RESULT_PATH, STRING_PATH,
- VEC_PATH,};
+ VEC_PATH};
use utils::MethodArgs;
-use rustc::middle::cstore::CrateStore;
#[derive(Clone)]
pub struct MethodsPass;
if let Some(&ret_ty) = ret_ty {
ret_ty.walk().any(|t| t == ty)
- }
- else {
+ } else {
false
}
- }
- else {
+ } else {
false
};
fn matches(&self, slf: &ExplicitSelf_, allow_value_for_ref: bool) -> bool {
match (self, slf) {
(&SelfKind::Value, &SelfValue(_)) |
- (&SelfKind::Ref, &SelfRegion(_, Mutability::MutImmutable, _)) |
- (&SelfKind::RefMut, &SelfRegion(_, Mutability::MutMutable, _)) |
- (&SelfKind::No, &SelfStatic) => true,
+ (&SelfKind::Ref, &SelfRegion(_, Mutability::MutImmutable, _)) |
+ (&SelfKind::RefMut, &SelfRegion(_, Mutability::MutMutable, _)) |
+ (&SelfKind::No, &SelfStatic) => true,
(&SelfKind::Ref, &SelfValue(_)) | (&SelfKind::RefMut, &SelfValue(_)) => allow_value_for_ref,
(_, &SelfExplicit(ref ty, _)) => self.matches_explicit_type(ty, allow_value_for_ref),
_ => false,
fn matches_explicit_type(&self, ty: &Ty, allow_value_for_ref: bool) -> bool {
match (self, &ty.node) {
(&SelfKind::Value, &TyPath(..)) |
- (&SelfKind::Ref, &TyRptr(_, MutTy { mutbl: Mutability::MutImmutable, .. })) |
- (&SelfKind::RefMut, &TyRptr(_, MutTy { mutbl: Mutability::MutMutable, .. })) => true,
+ (&SelfKind::Ref, &TyRptr(_, MutTy { mutbl: Mutability::MutImmutable, .. })) |
+ (&SelfKind::RefMut, &TyRptr(_, MutTy { mutbl: Mutability::MutMutable, .. })) => true,
(&SelfKind::Ref, &TyPath(..)) |
- (&SelfKind::RefMut, &TyPath(..)) => allow_value_for_ref,
+ (&SelfKind::RefMut, &TyPath(..)) => allow_value_for_ref,
_ => false,
}
}
+use consts::{Constant, constant_simple};
use rustc::lint::*;
use rustc_front::hir::*;
-use syntax::ptr::P;
use std::cmp::{PartialOrd, Ordering};
-
-use consts::{Constant, constant_simple};
+use syntax::ptr::P;
use utils::{match_def_path, span_lint};
-use self::MinMax::{Min, Max};
/// **What it does:** This lint checks for expressions where `std::cmp::min` and `max` are used to clamp values, but switched so that the result is constant.
///
return;
}
match (outer_max, outer_c.partial_cmp(&inner_c)) {
- (_, None) | (Max, Some(Ordering::Less)) | (Min, Some(Ordering::Greater)) => (),
+ (_, None) | (MinMax::Max, Some(Ordering::Less)) | (MinMax::Min, Some(Ordering::Greater)) => (),
_ => {
span_lint(cx, MIN_MAX, expr.span, "this min/max combination leads to constant result");
}
let def_id = cx.tcx.def_map.borrow()[&path.id].def_id();
if match_def_path(cx, def_id, &["core", "cmp", "min"]) {
- fetch_const(args, Min)
+ fetch_const(args, MinMax::Min)
} else if match_def_path(cx, def_id, &["core", "cmp", "max"]) {
- fetch_const(args, Max)
+ fetch_const(args, MinMax::Max)
} else {
None
}
+use reexport::*;
use rustc::lint::*;
-use syntax::ptr::P;
+use rustc::middle::const_eval::ConstVal::Float;
+use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
+use rustc::middle::const_eval::eval_const_expr_partial;
+use rustc::middle::ty;
use rustc_front::hir::*;
-use reexport::*;
+use rustc_front::intravisit::FnKind;
use rustc_front::util::{is_comparison_binop, binop_to_string};
use syntax::codemap::{Span, Spanned, ExpnFormat};
-use rustc_front::intravisit::FnKind;
-use rustc::middle::ty;
-use rustc::middle::const_eval::ConstVal::Float;
-use rustc::middle::const_eval::eval_const_expr_partial;
-use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
-
+use syntax::ptr::P;
use utils::{get_item_name, match_path, snippet, get_parent_expr, span_lint};
use utils::{span_lint_and_then, walk_ptrs_ty, is_integer_literal, implements_trait};
use rustc::lint::*;
-
use std::collections::HashMap;
-
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::visit::FnKind;
-
use utils::{span_lint, span_help_and_lint};
/// **What it does:** This lint checks for structure field patterns bound to wildcards.
use rustc::lint::*;
-use rustc_front::hir::*;
use rustc::middle::ty::{TypeAndMut, TyRef};
-
+use rustc_front::hir::*;
use utils::{in_external_macro, span_lint};
/// **What it does:** This lint checks for instances of `mut mut` references.
use rustc::lint::*;
-use rustc_front::hir::*;
-use utils::span_lint;
use rustc::middle::ty::{TypeAndMut, TypeVariants, MethodCall, TyS};
+use rustc_front::hir::*;
use syntax::ptr::P;
+use utils::span_lint;
/// **What it does:** This lint detects giving a mutable reference to a function that only requires an immutable reference.
///
//! This lint is **warn** by default
use rustc::lint::{LintPass, LintArray, LateLintPass, LateContext};
+use rustc::middle::subst::ParamSpace;
+use rustc::middle::ty;
use rustc_front::hir::Expr;
-
use syntax::ast;
-use rustc::middle::ty;
-use rustc::middle::subst::ParamSpace;
-
use utils::{span_lint, MUTEX_PATH, match_type};
/// **What it does:** This lint checks for usages of `Mutex<X>` where an atomic will do.
use rustc::lint::*;
use rustc_front::hir::*;
-
use syntax::ast::LitKind;
use syntax::codemap::Spanned;
-
use utils::{span_lint, span_lint_and_then, snippet};
/// **What it does:** This lint checks for expressions of the form `if c { true } else { false }` (or vice versa) and suggest using the condition directly.
use rustc::lint::*;
use rustc_front::hir::*;
-
use utils::span_lint;
use utils;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::middle::ty::TyStruct;
use rustc_front::hir::{Expr, ExprStruct};
-
use utils::span_lint;
/// **What it does:** This lint warns on needlessly including a base struct on update when all fields are changed anyway.
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::middle::def::Def;
-use rustc_front::hir::{Expr, Expr_};
-use rustc_front::hir::{Stmt, StmtSemi};
-
-use utils::in_macro;
-use utils::span_lint;
+use rustc_front::hir::{Expr, Expr_, Stmt, StmtSemi};
+use utils::{in_macro, span_lint};
/// **What it does:** This lint checks for statements which have no effect.
///
use rustc::lint::*;
use rustc_front::hir::{Expr, ExprMethodCall, ExprLit};
-use utils::{walk_ptrs_ty_depth, match_type, span_lint, OPEN_OPTIONS_PATH};
-use syntax::codemap::{Span, Spanned};
use syntax::ast::LitKind;
+use syntax::codemap::{Span, Spanned};
+use utils::{walk_ptrs_ty_depth, match_type, span_lint, OPEN_OPTIONS_PATH};
/// **What it does:** This lint checks for duplicate open options as well as combinations that make no sense.
///
use rustc::lint::*;
use rustc_front::hir::*;
use syntax::ast::LitKind;
-
use utils::{span_lint, in_external_macro, match_path, BEGIN_UNWIND};
/// **What it does:** This lint checks for missing parameters in `panic!`.
use rustc::lint::*;
-use syntax::codemap::Spanned;
use syntax::ast::*;
-
+use syntax::codemap::Spanned;
use utils::{span_lint, snippet};
/// **What it does:** This lint checks for operations where precedence may be unclear and suggests to add parentheses. Currently it catches the following:
+use rustc::front::map::Node::{NodeItem, NodeImplItem};
use rustc::lint::*;
use rustc_front::hir::*;
-use rustc::front::map::Node::{NodeItem, NodeImplItem};
use utils::{FMT_ARGUMENTV1_NEW_PATH, DEBUG_FMT_METHOD_PATH, IO_PRINT_PATH};
use utils::{is_expn_of, match_path, span_lint};
//!
//! This lint is **warn** by default
-use rustc::lint::*;
-use rustc_front::hir::*;
use rustc::front::map::NodeItem;
+use rustc::lint::*;
use rustc::middle::ty;
-
-use utils::{span_lint, match_type};
+use rustc_front::hir::*;
use utils::{STRING_PATH, VEC_PATH};
+use utils::{span_lint, match_type};
/// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless the references are mutable.
///
use regex_syntax;
-use std::error::Error;
+use rustc::lint::*;
+use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
+use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
+use rustc_front::hir::*;
use std::collections::HashSet;
+use std::error::Error;
use syntax::ast::{LitKind, NodeId};
use syntax::codemap::{Span, BytePos};
use syntax::parse::token::InternedString;
-use rustc_front::hir::*;
-use rustc::middle::const_eval::{eval_const_expr_partial, ConstVal};
-use rustc::middle::const_eval::EvalHint::ExprTypeChecked;
-use rustc::lint::*;
use utils::{is_expn_of, match_path, match_type, REGEX_NEW_PATH, span_lint, span_help_and_lint};
#[derive(Clone, Default)]
pub struct RegexPass {
spans: HashSet<Span>,
- last: Option<NodeId>
+ last: Option<NodeId>,
}
impl LintPass for RegexPass {
self.last = Some(block.id);
}}
}
-
+
fn check_block_post(&mut self, _: &LateContext, block: &Block) {
if self.last.map_or(false, |id| block.id == id) {
- self.last = None;
+ self.last = None;
}
}
fn str_span(base: Span, s: &str, c: usize) -> Span {
let lo = match s.char_indices().nth(c) {
Some((b, _)) => base.lo + BytePos(b as u32),
- _ => base.hi
+ _ => base.hi,
};
Span{ lo: lo, hi: lo, ..base }
}
fn const_str(cx: &LateContext, e: &Expr) -> Option<InternedString> {
match eval_const_expr_partial(cx.tcx, e, ExprTypeChecked, None) {
Ok(ConstVal::Str(r)) => Some(r),
- _ => None
+ _ => None,
}
}
Expr::Literal {..} => Some("consider using `str::contains`"),
Expr::Concat(ref exprs) => {
match exprs.len() {
- 2 => match (&exprs[0], &exprs[1]) {
- (&Expr::StartText, &Expr::EndText) => Some("consider using `str::is_empty`"),
- (&Expr::StartText, &Expr::Literal {..}) => Some("consider using `str::starts_with`"),
- (&Expr::Literal {..}, &Expr::EndText) => Some("consider using `str::ends_with`"),
- _ => None,
- },
+ 2 => {
+ match (&exprs[0], &exprs[1]) {
+ (&Expr::StartText, &Expr::EndText) => Some("consider using `str::is_empty`"),
+ (&Expr::StartText, &Expr::Literal {..}) => Some("consider using `str::starts_with`"),
+ (&Expr::Literal {..}, &Expr::EndText) => Some("consider using `str::ends_with`"),
+ _ => None,
+ }
+ }
3 => {
if let (&Expr::StartText, &Expr::Literal {..}, &Expr::EndText) = (&exprs[0], &exprs[1], &exprs[2]) {
Some("consider using `==` on `str`s")
- }
- else {
+ } else {
None
}
- },
+ }
_ => None,
}
}
use rustc::lint::*;
use syntax::ast::*;
-// use reexport::*;
use syntax::codemap::{Span, Spanned};
use syntax::visit::FnKind;
-use std::ops::Deref;
-use rustc_front::hir::*;
use reexport::*;
-use syntax::codemap::Span;
-use rustc_front::intravisit::{Visitor, FnKind};
-
use rustc::lint::*;
use rustc::middle::def::Def;
-
+use rustc_front::hir::*;
+use rustc_front::intravisit::{Visitor, FnKind};
+use std::ops::Deref;
+use syntax::codemap::Span;
use utils::{is_from_for_desugar, in_external_macro, snippet, span_lint, span_note_and_lint, DiagnosticWrapper};
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope, while just changing reference level or mutability.
use rustc::lint::*;
use rustc_front::hir::*;
use syntax::codemap::Spanned;
-
-use utils::{match_type, span_lint, walk_ptrs_ty, get_parent_expr};
-use utils::SpanlessEq;
use utils::STRING_PATH;
+use utils::SpanlessEq;
+use utils::{match_type, span_lint, walk_ptrs_ty, get_parent_expr};
/// **What it does:** This lint matches code of the form `x = x + y` (without `let`!).
///
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc_front::hir::{Expr, ExprAssign, ExprField, ExprStruct, ExprTup, ExprTupField};
-
use utils::is_adjusted;
use utils::span_lint;
+use reexport::*;
use rustc::lint::*;
+use rustc::middle::const_eval;
+use rustc::middle::ty;
use rustc_front::hir::*;
-use reexport::*;
-use rustc_front::util::{is_comparison_binop, binop_to_string};
-use syntax::codemap::Span;
use rustc_front::intravisit::{FnKind, Visitor, walk_ty};
-use rustc::middle::ty;
-use rustc::middle::const_eval;
+use rustc_front::util::{is_comparison_binop, binop_to_string};
use syntax::ast::{IntTy, UintTy, FloatTy};
-
+use syntax::codemap::Span;
use utils::*;
/// Handles all the linting of funky types
}
fn detect_absurd_comparison<'a>(cx: &LateContext, op: BinOp_, lhs: &'a Expr, rhs: &'a Expr)
- -> Option<(ExtremeExpr<'a>, AbsurdComparisonResult)> {
+ -> Option<(ExtremeExpr<'a>, AbsurdComparisonResult)> {
use types::ExtremeType::*;
use types::AbsurdComparisonResult::*;
type Extr<'a> = ExtremeExpr<'a>;
_ => return None,
};
- Some(ExtremeExpr { which: which, expr: expr })
+ Some(ExtremeExpr {
+ which: which,
+ expr: expr,
+ })
}
impl LateLintPass for AbsurdExtremeComparisons {
let conclusion = match result {
AlwaysFalse => "this comparison is always false".to_owned(),
AlwaysTrue => "this comparison is always true".to_owned(),
- InequalityImpossible =>
- format!("the case where the two sides are not equal never occurs, \
- consider using {} == {} instead",
+ InequalityImpossible => {
+ format!("the case where the two sides are not equal never occurs, consider using {} == {} \
+ instead",
snippet(cx, lhs.span, "lhs"),
- snippet(cx, rhs.span, "rhs")),
+ snippet(cx, rhs.span, "rhs"))
+ }
};
let help = format!("because {} is the {} value for this type, {}",
snippet(cx, culprit.expr.span, "x"),
- match culprit.which { Minimum => "minimum", Maximum => "maximum" },
+ match culprit.which {
+ Minimum => "minimum",
+ Maximum => "maximum",
+ },
conclusion);
span_help_and_lint(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, &help);
use rustc::lint::*;
use rustc_front::hir::*;
-use syntax::codemap::Span;
-
use syntax::ast::LitKind;
-
+use syntax::codemap::Span;
use unicode_normalization::UnicodeNormalization;
-
use utils::{snippet, span_help_and_lint};
/// **What it does:** This lint checks for the unicode zero-width space in the code.
impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self {
- SpanlessEq { cx: cx, ignore_fn: false }
+ SpanlessEq {
+ cx: cx,
+ ignore_fn: false,
+ }
}
pub fn ignore_fn(self) -> Self {
- SpanlessEq { cx: self.cx, ignore_fn: true }
+ SpanlessEq {
+ cx: self.cx,
+ ignore_fn: true,
+ }
}
/// Check whether two statements are the same.
}
}
(&StmtExpr(ref l, _), &StmtExpr(ref r, _)) |
- (&StmtSemi(ref l, _), &StmtSemi(ref r, _)) => self.eq_expr(l, r),
+ (&StmtSemi(ref l, _), &StmtSemi(ref r, _)) => self.eq_expr(l, r),
_ => false,
}
}
/// Check whether two blocks are the same.
pub fn eq_block(&self, left: &Block, right: &Block) -> bool {
over(&left.stmts, &right.stmts, |l, r| self.eq_stmt(l, r)) &&
- both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r))
+ both(&left.expr, &right.expr, |l, r| self.eq_expr(l, r))
}
// ok, it’s a big function, but mostly one big match with simples cases
(&ExprAssignOp(ref lo, ref ll, ref lr), &ExprAssignOp(ref ro, ref rl, ref rr)) => {
lo.node == ro.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
}
- (&ExprBlock(ref l), &ExprBlock(ref r)) => {
- self.eq_block(l, r)
- }
+ (&ExprBlock(ref l), &ExprBlock(ref r)) => self.eq_block(l, r),
(&ExprBinary(lop, ref ll, ref lr), &ExprBinary(rop, ref rl, ref rr)) => {
lop.node == rop.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
}
impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
pub fn new(cx: &'a LateContext<'a, 'tcx>) -> Self {
- SpanlessHash { cx: cx, s: SipHasher::new() }
+ SpanlessHash {
+ cx: cx,
+ s: SipHasher::new(),
+ }
}
pub fn finish(&self) -> u64 {
let c: fn(_) -> _ = ExprLit;
c.hash(&mut self.s);
l.hash(&mut self.s);
- },
+ }
ExprLoop(ref b, ref i) => {
let c: fn(_, _) -> _ = ExprLoop;
c.hash(&mut self.s);
let c: fn(_) -> _ = ExprTup;
c.hash(&mut self.s);
self.hash_exprs(tup);
- },
+ }
ExprTupField(ref le, li) => {
let c: fn(_, _) -> _ = ExprTupField;
c.hash(&mut self.s);
c.hash(&mut self.s);
self.hash_exprs(v);
- },
+ }
ExprWhile(ref cond, ref b, l) => {
let c: fn(_, _, _) -> _ = ExprWhile;
c.hash(&mut self.s);
use std::mem;
use std::ops::{Deref, DerefMut};
use std::str::FromStr;
-use syntax::ast::{LitKind, self};
+use syntax::ast::{self, LitKind};
use syntax::codemap::{ExpnInfo, Span, ExpnFormat};
use syntax::errors::DiagnosticBuilder;
use syntax::ptr::P;
+use consts::{Constant, constant_simple, FloatWidth};
use rustc::lint::*;
use rustc_front::hir::*;
-
use utils::span_help_and_lint;
-use consts::{Constant, constant_simple, FloatWidth};
/// `ZeroDivZeroPass` is a pass that checks for a binary expression that consists
/// `of 0.0/0.0`, which is always NaN. It is more clear to replace instances of