Merge branch 'pr-704'

Conflicts:
	src/len_zero.rs
This commit is contained in:
Manish Goregaokar 2016-02-25 01:38:08 +05:30
commit f13b841282
46 changed files with 282 additions and 280 deletions

View File

@ -1,8 +1,8 @@
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.
///

View File

@ -1,12 +1,12 @@
//! 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.

View File

@ -3,8 +3,8 @@ use rustc::middle::const_eval::lookup_const_by_id;
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;

View File

@ -1,5 +1,5 @@
use rustc_front::hir::*;
use rustc::lint::{LateLintPass, LateContext, LintArray, LintPass};
use rustc_front::hir::*;
use rustc_front::intravisit::{Visitor, walk_expr};
use utils::*;

View File

@ -95,9 +95,7 @@ impl PartialEq for Constant {
(&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 dont compare them
@ -116,7 +114,9 @@ impl PartialEq for Constant {
}
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);
@ -144,7 +144,7 @@ impl Hash for Constant {
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) => {
@ -210,7 +210,9 @@ fn constant_not(o: Constant) -> Option<Constant> {
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) => {
@ -224,7 +226,7 @@ fn constant_not(o: Constant) -> Option<Constant> {
} // refuse to guess
};
Some(Int(!value & mask, LitIntType::Unsigned(ity), Sign::Plus))
},
}
_ => None,
}
}
@ -388,7 +390,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
(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,
}
@ -406,7 +408,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
}
(Constant::Int(l64, lty, lsign), Constant::Int(r64, rty, rsign)) => {
add_ints(l64, r64, lty, rty, lsign, neg_sign(rsign))
},
}
_ => None,
}
})
@ -438,7 +440,11 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
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))
})
}
@ -504,19 +510,28 @@ 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; };
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))
}
}
}
}

View File

@ -61,11 +61,7 @@ pub struct CopyAndPaste;
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]
}
}
@ -89,35 +85,43 @@ impl LateLintPass for CopyAndPaste {
/// 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");
}
}
@ -137,7 +141,12 @@ fn lint_match_arms(cx: &LateContext, expr: &Expr) {
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");
}
}
}
@ -155,8 +164,7 @@ fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) {
if let Some(ref else_expr) = *else_expr {
expr = else_expr;
}
else {
} else {
break;
}
}
@ -188,7 +196,7 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<Interned
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);
@ -210,7 +218,12 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<Interned
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(..) => (),
}
}
@ -219,36 +232,35 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<Interned
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]);
}
}
}

View File

@ -1,13 +1,13 @@
//! 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};

View File

@ -1,8 +1,7 @@
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};

View File

@ -1,13 +1,13 @@
//! 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
///

View File

@ -1,10 +1,9 @@
//! 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};
@ -95,7 +94,7 @@ impl EarlyLintPass for EnumVariantNames {
} else if !post.is_empty() {
("post", post)
} else {
return
return;
};
span_help_and_lint(cx,
ENUM_VARIANT_NAMES,

View File

@ -1,7 +1,6 @@
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,

View File

@ -1,13 +1,13 @@
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;

View File

@ -1,10 +1,8 @@
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;

View File

@ -1,8 +1,7 @@
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`.

View File

@ -1,8 +1,8 @@
//! 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

View File

@ -1,13 +1,10 @@
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, in_macro, snippet, span_lint, span_lint_and_then, 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.

View File

@ -1,11 +1,10 @@
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.

View File

@ -354,9 +354,9 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
// 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);
@ -441,8 +441,12 @@ fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) {
// who think that this will iterate from the larger value to the
// smaller value.
let (sup, eq) = match (start_idx, 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),
};
@ -518,26 +522,25 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
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, "_")));
}
}
@ -593,31 +596,29 @@ fn check_for_loop_over_map_kv(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Ex
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));
});
}
}
}
@ -635,7 +636,7 @@ fn pat_is_wild(pat: &PatKind, body: &Expr) -> bool {
};
walk_expr(&mut visitor, body);
!visitor.used
},
}
_ => false,
}
}
@ -650,7 +651,7 @@ impl<'a> Visitor<'a> for UsedVisitor {
if let ExprPath(None, ref path) = expr.node {
if path.segments.len() == 1 && path.segments[0].identifier == self.var {
self.used = true;
return
return;
}
}

View File

@ -1,8 +1,10 @@
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.
///

View File

@ -7,7 +7,6 @@ use rustc_front::hir::*;
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};
@ -139,20 +138,20 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
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);
}
}
}
@ -194,11 +193,11 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr:
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,

View File

@ -1,6 +1,7 @@
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::*;
@ -8,14 +9,12 @@ use std::borrow::Cow;
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;
@ -439,12 +438,10 @@ impl LateLintPass for MethodsPass {
if let Some(&ret_ty) = ret_ty {
ret_ty.walk().any(|t| t == ty)
}
else {
} else {
false
}
}
else {
} else {
false
};
@ -961,9 +958,9 @@ impl SelfKind {
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,
@ -973,10 +970,10 @@ impl SelfKind {
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,
}
}

View File

@ -1,11 +1,9 @@
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.
///
@ -36,7 +34,7 @@ impl LateLintPass for MinMaxPass {
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");
}
@ -58,9 +56,9 @@ fn min_max<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(MinMax, Constant, &'
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
}

View File

@ -1,15 +1,14 @@
use rustc::lint::*;
use syntax::ptr::P;
use rustc_front::hir::*;
use reexport::*;
use rustc::lint::*;
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 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};

View File

@ -1,11 +1,8 @@
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.

View File

@ -1,7 +1,6 @@
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.

View File

@ -1,8 +1,8 @@
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.
///

View File

@ -3,12 +3,10 @@
//! This lint is **warn** by default
use rustc::lint::{LintPass, LintArray, LateLintPass, LateContext};
use rustc_front::hir::Expr;
use syntax::ast;
use rustc::middle::ty;
use rustc::middle::subst::ParamSpace;
use rustc::middle::ty;
use rustc_front::hir::Expr;
use syntax::ast;
use utils::{span_lint, MUTEX_PATH, match_type};
/// **What it does:** This lint checks for usages of `Mutex<X>` where an atomic will do.

View File

@ -4,10 +4,8 @@
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.

View File

@ -4,7 +4,6 @@
use rustc::lint::*;
use rustc_front::hir::*;
use utils::span_lint;
use utils;

View File

@ -1,7 +1,6 @@
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.

View File

@ -1,10 +1,7 @@
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.
///

View File

@ -1,8 +1,8 @@
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.
///

View File

@ -1,7 +1,6 @@
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!`.

View File

@ -1,7 +1,6 @@
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:

View File

@ -1,6 +1,6 @@
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};

View File

@ -2,13 +2,12 @@
//!
//! 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.
///

View File

@ -1,13 +1,13 @@
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};
@ -54,7 +54,7 @@ declare_lint! {
#[derive(Clone, Default)]
pub struct RegexPass {
spans: HashSet<Span>,
last: Option<NodeId>
last: Option<NodeId>,
}
impl LintPass for RegexPass {
@ -86,10 +86,10 @@ impl LateLintPass 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;
}
}
@ -145,7 +145,7 @@ impl LateLintPass for RegexPass {
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 }
}
@ -153,7 +153,7 @@ fn str_span(base: Span, s: &str, c: usize) -> Span {
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,
}
}
@ -165,20 +165,21 @@ fn is_trivial_regex(s: &regex_syntax::Expr) -> Option<&'static str> {
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,
}
}

View File

@ -1,6 +1,5 @@
use rustc::lint::*;
use syntax::ast::*;
// use reexport::*;
use syntax::codemap::{Span, Spanned};
use syntax::visit::FnKind;

View File

@ -1,12 +1,10 @@
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.

View File

@ -6,10 +6,9 @@
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`!).
///

View File

@ -1,6 +1,5 @@
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;

View File

@ -1,13 +1,12 @@
use rustc::lint::*;
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::lint::*;
use rustc::middle::const_eval;
use rustc::middle::ty;
use rustc_front::hir::*;
use rustc_front::intravisit::{FnKind, Visitor, walk_ty};
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
@ -618,7 +617,7 @@ enum AbsurdComparisonResult {
}
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>;
@ -704,7 +703,10 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeEx
_ => return None,
};
Some(ExtremeExpr { which: which, expr: expr })
Some(ExtremeExpr {
which: which,
expr: expr,
})
}
impl LateLintPass for AbsurdExtremeComparisons {
@ -721,16 +723,20 @@ 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);

View File

@ -1,11 +1,8 @@
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.

View File

@ -19,11 +19,17 @@ pub struct SpanlessEq<'a, 'tcx: 'a> {
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.
@ -40,7 +46,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
}
}
(&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,
}
}
@ -48,7 +54,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
/// 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, its a big function, but mostly one big match with simples cases
@ -77,9 +83,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
(&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)
}
@ -267,7 +271,10 @@ pub struct SpanlessHash<'a, 'tcx: 'a> {
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 {
@ -389,7 +396,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
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);
@ -466,7 +473,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
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);
@ -491,7 +498,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
c.hash(&mut self.s);
self.hash_exprs(v);
},
}
ExprWhile(ref cond, ref b, l) => {
let c: fn(_, _, _) -> _ = ExprWhile;
c.hash(&mut self.s);

View File

@ -9,7 +9,7 @@ use std::borrow::Cow;
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;

View File

@ -1,8 +1,7 @@
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