mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 09:44:08 +00:00
Merge pull request #247 from Manishearth/links
added the rest of the link help messages
This commit is contained in:
commit
2606f34bcb
@ -3,7 +3,7 @@ use syntax::ast::*;
|
|||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use std::f64::consts as f64;
|
use std::f64::consts as f64;
|
||||||
|
|
||||||
use utils::span_help_and_lint;
|
use utils::span_lint;
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub APPROX_CONSTANT,
|
pub APPROX_CONSTANT,
|
||||||
@ -40,7 +40,7 @@ fn check_lit(cx: &Context, lit: &Lit, span: Span) {
|
|||||||
match lit.node {
|
match lit.node {
|
||||||
LitFloat(ref str, TyF32) => check_known_consts(cx, span, str, "f32"),
|
LitFloat(ref str, TyF32) => check_known_consts(cx, span, str, "f32"),
|
||||||
LitFloat(ref str, TyF64) => check_known_consts(cx, span, str, "f64"),
|
LitFloat(ref str, TyF64) => check_known_consts(cx, span, str, "f64"),
|
||||||
LitFloatUnsuffixed(ref str) =>
|
LitFloatUnsuffixed(ref str) =>
|
||||||
check_known_consts(cx, span, str, "f{32, 64}"),
|
check_known_consts(cx, span, str, "f{32, 64}"),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
@ -50,18 +50,16 @@ fn check_known_consts(cx: &Context, span: Span, str: &str, module: &str) {
|
|||||||
if let Ok(value) = str.parse::<f64>() {
|
if let Ok(value) = str.parse::<f64>() {
|
||||||
for &(constant, name) in KNOWN_CONSTS {
|
for &(constant, name) in KNOWN_CONSTS {
|
||||||
if within_epsilon(constant, value) {
|
if within_epsilon(constant, value) {
|
||||||
span_help_and_lint(cx, APPROX_CONSTANT, span, &format!(
|
span_lint(cx, APPROX_CONSTANT, span, &format!(
|
||||||
"approximate value of `{}::{}` found. \
|
"approximate value of `{}::{}` found. \
|
||||||
Consider using it directly", module, &name),
|
Consider using it directly", module, &name));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#approx_constant");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn within_epsilon(target: f64, value: f64) -> bool {
|
fn within_epsilon(target: f64, value: f64) -> bool {
|
||||||
f64::abs(value - target) < f64::abs(if target > value {
|
f64::abs(value - target) < f64::abs(if target > value {
|
||||||
target
|
target
|
||||||
} else { value }) / EPSILON_DIVISOR
|
} else { value }) / EPSILON_DIVISOR
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use rustc::lint::*;
|
|||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::codemap::ExpnInfo;
|
use syntax::codemap::ExpnInfo;
|
||||||
|
|
||||||
use utils::{in_macro, match_path, span_help_and_lint};
|
use utils::{in_macro, match_path, span_lint};
|
||||||
|
|
||||||
declare_lint! { pub INLINE_ALWAYS, Warn,
|
declare_lint! { pub INLINE_ALWAYS, Warn,
|
||||||
"`#[inline(always)]` is a bad idea in most cases" }
|
"`#[inline(always)]` is a bad idea in most cases" }
|
||||||
@ -98,12 +98,10 @@ fn check_attrs(cx: &Context, info: Option<&ExpnInfo>, ident: &Ident,
|
|||||||
if values.len() != 1 || inline != &"inline" { continue; }
|
if values.len() != 1 || inline != &"inline" { continue; }
|
||||||
if let MetaWord(ref always) = values[0].node {
|
if let MetaWord(ref always) = values[0].node {
|
||||||
if always != &"always" { continue; }
|
if always != &"always" { continue; }
|
||||||
span_help_and_lint(cx, INLINE_ALWAYS, attr.span, &format!(
|
span_lint(cx, INLINE_ALWAYS, attr.span, &format!(
|
||||||
"you have declared `#[inline(always)]` on `{}`. This \
|
"you have declared `#[inline(always)]` on `{}`. This \
|
||||||
is usually a bad idea. Are you sure?",
|
is usually a bad idea. Are you sure?",
|
||||||
ident.name),
|
ident.name));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#inline_always");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use syntax::ast::*;
|
|||||||
use syntax::ast_util::is_comparison_binop;
|
use syntax::ast_util::is_comparison_binop;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
|
|
||||||
use utils::span_help_and_lint;
|
use utils::span_lint;
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub BAD_BIT_MASK,
|
pub BAD_BIT_MASK,
|
||||||
@ -100,50 +100,36 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_,
|
|||||||
BiEq | BiNe => match bit_op {
|
BiEq | BiNe => match bit_op {
|
||||||
BiBitAnd => if mask_value & cmp_value != mask_value {
|
BiBitAnd => if mask_value & cmp_value != mask_value {
|
||||||
if cmp_value != 0 {
|
if cmp_value != 0 {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
|
span_lint(cx, BAD_BIT_MASK, *span, &format!(
|
||||||
"incompatible bit mask: `_ & {}` can never be equal to `{}`",
|
"incompatible bit mask: `_ & {}` can never be equal to `{}`",
|
||||||
mask_value, cmp_value),
|
mask_value, cmp_value));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if mask_value == 0 {
|
if mask_value == 0 {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span,
|
span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero");
|
||||||
"&-masking with zero",
|
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BiBitOr => if mask_value | cmp_value != cmp_value {
|
BiBitOr => if mask_value | cmp_value != cmp_value {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
|
span_lint(cx, BAD_BIT_MASK, *span, &format!(
|
||||||
"incompatible bit mask: `_ | {}` can never be equal to `{}`",
|
"incompatible bit mask: `_ | {}` can never be equal to `{}`",
|
||||||
mask_value, cmp_value),
|
mask_value, cmp_value));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
},
|
},
|
||||||
BiLt | BiGe => match bit_op {
|
BiLt | BiGe => match bit_op {
|
||||||
BiBitAnd => if mask_value < cmp_value {
|
BiBitAnd => if mask_value < cmp_value {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
|
span_lint(cx, BAD_BIT_MASK, *span, &format!(
|
||||||
"incompatible bit mask: `_ & {}` will always be lower than `{}`",
|
"incompatible bit mask: `_ & {}` will always be lower than `{}`",
|
||||||
mask_value, cmp_value),
|
mask_value, cmp_value));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
} else {
|
} else {
|
||||||
if mask_value == 0 {
|
if mask_value == 0 {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span,
|
span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero");
|
||||||
"&-masking with zero",
|
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BiBitOr => if mask_value >= cmp_value {
|
BiBitOr => if mask_value >= cmp_value {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
|
span_lint(cx, BAD_BIT_MASK, *span, &format!(
|
||||||
"incompatible bit mask: `_ | {}` will never be lower than `{}`",
|
"incompatible bit mask: `_ | {}` will never be lower than `{}`",
|
||||||
mask_value, cmp_value),
|
mask_value, cmp_value));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
} else {
|
} else {
|
||||||
check_ineffective_lt(cx, *span, mask_value, cmp_value, "|");
|
check_ineffective_lt(cx, *span, mask_value, cmp_value, "|");
|
||||||
},
|
},
|
||||||
@ -153,25 +139,18 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_,
|
|||||||
},
|
},
|
||||||
BiLe | BiGt => match bit_op {
|
BiLe | BiGt => match bit_op {
|
||||||
BiBitAnd => if mask_value <= cmp_value {
|
BiBitAnd => if mask_value <= cmp_value {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
|
span_lint(cx, BAD_BIT_MASK, *span, &format!(
|
||||||
"incompatible bit mask: `_ & {}` will never be higher than `{}`",
|
"incompatible bit mask: `_ & {}` will never be higher than `{}`",
|
||||||
mask_value, cmp_value),
|
mask_value, cmp_value));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
} else {
|
} else {
|
||||||
if mask_value == 0 {
|
if mask_value == 0 {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span,
|
span_lint(cx, BAD_BIT_MASK, *span, "&-masking with zero");
|
||||||
"&-masking with zero",
|
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BiBitOr => if mask_value > cmp_value {
|
BiBitOr => if mask_value > cmp_value {
|
||||||
span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
|
span_lint(cx, BAD_BIT_MASK, *span, &format!(
|
||||||
"incompatible bit mask: `_ | {}` will always be higher than `{}`",
|
"incompatible bit mask: `_ | {}` will always be higher than `{}`",
|
||||||
mask_value, cmp_value),
|
mask_value, cmp_value));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#bad_bit_mask");
|
|
||||||
} else {
|
} else {
|
||||||
check_ineffective_gt(cx, *span, mask_value, cmp_value, "|");
|
check_ineffective_gt(cx, *span, mask_value, cmp_value, "|");
|
||||||
},
|
},
|
||||||
@ -185,21 +164,17 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_,
|
|||||||
|
|
||||||
fn check_ineffective_lt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
fn check_ineffective_lt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||||
if c.is_power_of_two() && m < c {
|
if c.is_power_of_two() && m < c {
|
||||||
span_help_and_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
||||||
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
||||||
op, m, c),
|
op, m, c));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#ineffective_bit_mask");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_ineffective_gt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
fn check_ineffective_gt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||||
if (c + 1).is_power_of_two() && m <= c {
|
if (c + 1).is_power_of_two() && m <= c {
|
||||||
span_help_and_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
||||||
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
||||||
op, m, c),
|
op, m, c));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#ineffective_bit_mask");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
src/misc.rs
14
src/misc.rs
@ -6,7 +6,7 @@ use syntax::codemap::{Span, Spanned};
|
|||||||
use syntax::visit::FnKind;
|
use syntax::visit::FnKind;
|
||||||
use rustc::middle::ty;
|
use rustc::middle::ty;
|
||||||
|
|
||||||
use utils::{match_path, snippet, span_lint, span_help_and_lint, walk_ptrs_ty};
|
use utils::{match_path, snippet, span_lint, walk_ptrs_ty};
|
||||||
use consts::constant;
|
use consts::constant;
|
||||||
|
|
||||||
declare_lint!(pub TOPLEVEL_REF_ARG, Warn,
|
declare_lint!(pub TOPLEVEL_REF_ARG, Warn,
|
||||||
@ -65,10 +65,8 @@ impl LintPass for CmpNan {
|
|||||||
|
|
||||||
fn check_nan(cx: &Context, path: &Path, span: Span) {
|
fn check_nan(cx: &Context, path: &Path, span: Span) {
|
||||||
path.segments.last().map(|seg| if seg.identifier.name == "NAN" {
|
path.segments.last().map(|seg| if seg.identifier.name == "NAN" {
|
||||||
span_help_and_lint(cx, CMP_NAN, span,
|
span_lint(cx, CMP_NAN, span,
|
||||||
"doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead",
|
"doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead");
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cmp_nan");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,11 +124,9 @@ impl LintPass for Precedence {
|
|||||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||||
if let ExprBinary(Spanned { node: op, ..}, ref left, ref right) = expr.node {
|
if let ExprBinary(Spanned { node: op, ..}, ref left, ref right) = expr.node {
|
||||||
if is_bit_op(op) && (is_arith_expr(left) || is_arith_expr(right)) {
|
if is_bit_op(op) && (is_arith_expr(left) || is_arith_expr(right)) {
|
||||||
span_help_and_lint(cx, PRECEDENCE, expr.span,
|
span_lint(cx, PRECEDENCE, expr.span,
|
||||||
"operator precedence can trip the unwary. Consider adding parentheses \
|
"operator precedence can trip the unwary. Consider adding parentheses \
|
||||||
to the subexpression",
|
to the subexpression");
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#precedence");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use syntax::visit::FnKind;
|
|||||||
use rustc::lint::{Context, LintArray, LintPass};
|
use rustc::lint::{Context, LintArray, LintPass};
|
||||||
use rustc::middle::def::Def::{DefVariant, DefStruct};
|
use rustc::middle::def::Def::{DefVariant, DefStruct};
|
||||||
|
|
||||||
use utils::{in_external_macro, snippet, span_help_and_lint};
|
use utils::{in_external_macro, snippet, span_lint};
|
||||||
|
|
||||||
declare_lint!(pub SHADOW_SAME, Allow,
|
declare_lint!(pub SHADOW_SAME, Allow,
|
||||||
"rebinding a name to itself, e.g. `let mut x = &mut x`");
|
"rebinding a name to itself, e.g. `let mut x = &mut x`");
|
||||||
@ -72,7 +72,7 @@ fn is_binding(cx: &Context, pat: &Pat) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat<T>(cx: &Context, pat: &Pat, init: &Option<T>, span: Span,
|
fn check_pat<T>(cx: &Context, pat: &Pat, init: &Option<T>, span: Span,
|
||||||
bindings: &mut Vec<Name>) where T: Deref<Target=Expr> {
|
bindings: &mut Vec<Name>) where T: Deref<Target=Expr> {
|
||||||
//TODO: match more stuff / destructuring
|
//TODO: match more stuff / destructuring
|
||||||
match pat.node {
|
match pat.node {
|
||||||
@ -94,7 +94,7 @@ fn check_pat<T>(cx: &Context, pat: &Pat, init: &Option<T>, span: Span,
|
|||||||
PatBox(ref inner) => {
|
PatBox(ref inner) => {
|
||||||
if let Some(ref initp) = *init {
|
if let Some(ref initp) = *init {
|
||||||
match initp.node {
|
match initp.node {
|
||||||
ExprBox(_, ref inner_init) =>
|
ExprBox(_, ref inner_init) =>
|
||||||
check_pat(cx, inner, &Some(&**inner_init), span, bindings),
|
check_pat(cx, inner, &Some(&**inner_init), span, bindings),
|
||||||
//TODO: ExprCall on Box::new
|
//TODO: ExprCall on Box::new
|
||||||
_ => check_pat(cx, inner, init, span, bindings),
|
_ => check_pat(cx, inner, init, span, bindings),
|
||||||
@ -110,38 +110,30 @@ fn check_pat<T>(cx: &Context, pat: &Pat, init: &Option<T>, span: Span,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
|
fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
|
||||||
&Option<T>) where T: Deref<Target=Expr> {
|
&Option<T>) where T: Deref<Target=Expr> {
|
||||||
if let &Some(ref expr) = init {
|
if let &Some(ref expr) = init {
|
||||||
if is_self_shadow(name, expr) {
|
if is_self_shadow(name, expr) {
|
||||||
span_help_and_lint(cx, SHADOW_SAME, span, &format!(
|
span_lint(cx, SHADOW_SAME, span, &format!(
|
||||||
"{} is shadowed by itself in {}",
|
"{} is shadowed by itself in {}",
|
||||||
snippet(cx, lspan, "_"),
|
snippet(cx, lspan, "_"),
|
||||||
snippet(cx, expr.span, "..")),
|
snippet(cx, expr.span, "..")));
|
||||||
"for further information see \
|
|
||||||
https://github.com/Manishearth/rust-clippy/wiki#shadow_same");
|
|
||||||
} else {
|
} else {
|
||||||
if contains_self(name, expr) {
|
if contains_self(name, expr) {
|
||||||
span_help_and_lint(cx, SHADOW_REUSE, span, &format!(
|
span_lint(cx, SHADOW_REUSE, span, &format!(
|
||||||
"{} is shadowed by {} which reuses the original value",
|
"{} is shadowed by {} which reuses the original value",
|
||||||
snippet(cx, lspan, "_"),
|
snippet(cx, lspan, "_"),
|
||||||
snippet(cx, expr.span, "..")),
|
snippet(cx, expr.span, "..")));
|
||||||
"for further information see https://\
|
|
||||||
github.com/Manishearth/rust-clippy/wiki#shadow_reuse");
|
|
||||||
} else {
|
} else {
|
||||||
span_help_and_lint(cx, SHADOW_UNRELATED, span, &format!(
|
span_lint(cx, SHADOW_UNRELATED, span, &format!(
|
||||||
"{} is shadowed by {} in this declaration",
|
"{} is shadowed by {} in this declaration",
|
||||||
snippet(cx, lspan, "_"),
|
snippet(cx, lspan, "_"),
|
||||||
snippet(cx, expr.span, "..")),
|
snippet(cx, expr.span, "..")));
|
||||||
"for further information see https://github.com\
|
|
||||||
/Manishearth/rust-clippy/wiki#shadow_unrelated");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
span_help_and_lint(cx, SHADOW_UNRELATED, span, &format!(
|
span_lint(cx, SHADOW_UNRELATED, span, &format!(
|
||||||
"{} is shadowed in this declaration", snippet(cx, lspan, "_")),
|
"{} is shadowed in this declaration", snippet(cx, lspan, "_")));
|
||||||
"for further information see \
|
|
||||||
https://github.com/Manishearth/rust-clippy/wiki#shadow_unrelated");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +210,7 @@ fn is_self_shadow(name: Name, expr: &Expr) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn path_eq_name(name: Name, path: &Path) -> bool {
|
fn path_eq_name(name: Name, path: &Path) -> bool {
|
||||||
!path.global && path.segments.len() == 1 &&
|
!path.global && path.segments.len() == 1 &&
|
||||||
path.segments[0].identifier.name == name
|
path.segments[0].identifier.name == name
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,8 +234,8 @@ fn contains_self(name: Name, expr: &Expr) -> bool {
|
|||||||
otherwise.as_ref().map_or(false, |ref e| contains_self(name, e)),
|
otherwise.as_ref().map_or(false, |ref e| contains_self(name, e)),
|
||||||
ExprWhile(ref e, ref block, _) =>
|
ExprWhile(ref e, ref block, _) =>
|
||||||
contains_self(name, e) || contains_block_self(name, block),
|
contains_self(name, e) || contains_block_self(name, block),
|
||||||
ExprMatch(ref e, ref arms, _) =>
|
ExprMatch(ref e, ref arms, _) =>
|
||||||
arms.iter().any(|ref arm| arm.pats.iter().any(|ref pat|
|
arms.iter().any(|ref arm| arm.pats.iter().any(|ref pat|
|
||||||
contains_pat_self(name, pat))) || contains_self(name, e),
|
contains_pat_self(name, pat))) || contains_self(name, e),
|
||||||
ExprPath(_, ref path) => path_eq_name(name, path),
|
ExprPath(_, ref path) => path_eq_name(name, path),
|
||||||
_ => false
|
_ => false
|
||||||
@ -274,7 +266,7 @@ fn contains_pat_self(name: Name, pat: &Pat) -> bool {
|
|||||||
match pat.node {
|
match pat.node {
|
||||||
PatIdent(_, ref ident, ref inner) => name == ident.node.name ||
|
PatIdent(_, ref ident, ref inner) => name == ident.node.name ||
|
||||||
inner.as_ref().map_or(false, |ref p| contains_pat_self(name, p)),
|
inner.as_ref().map_or(false, |ref p| contains_pat_self(name, p)),
|
||||||
PatEnum(_, ref opats) => opats.as_ref().map_or(false,
|
PatEnum(_, ref opats) => opats.as_ref().map_or(false,
|
||||||
|pats| pats.iter().any(|p| contains_pat_self(name, p))),
|
|pats| pats.iter().any(|p| contains_pat_self(name, p))),
|
||||||
PatQPath(_, ref path) => path_eq_name(name, path),
|
PatQPath(_, ref path) => path_eq_name(name, path),
|
||||||
PatStruct(_, ref fieldpats, _) => fieldpats.iter().any(
|
PatStruct(_, ref fieldpats, _) => fieldpats.iter().any(
|
||||||
@ -282,10 +274,10 @@ fn contains_pat_self(name: Name, pat: &Pat) -> bool {
|
|||||||
PatTup(ref ps) => ps.iter().any(|ref p| contains_pat_self(name, p)),
|
PatTup(ref ps) => ps.iter().any(|ref p| contains_pat_self(name, p)),
|
||||||
PatBox(ref p) |
|
PatBox(ref p) |
|
||||||
PatRegion(ref p, _) => contains_pat_self(name, p),
|
PatRegion(ref p, _) => contains_pat_self(name, p),
|
||||||
PatRange(ref from, ref until) =>
|
PatRange(ref from, ref until) =>
|
||||||
contains_self(name, from) || contains_self(name, until),
|
contains_self(name, from) || contains_self(name, until),
|
||||||
PatVec(ref pre, ref opt, ref post) =>
|
PatVec(ref pre, ref opt, ref post) =>
|
||||||
pre.iter().any(|ref p| contains_pat_self(name, p)) ||
|
pre.iter().any(|ref p| contains_pat_self(name, p)) ||
|
||||||
opt.as_ref().map_or(false, |ref p| contains_pat_self(name, p)) ||
|
opt.as_ref().map_or(false, |ref p| contains_pat_self(name, p)) ||
|
||||||
post.iter().any(|ref p| contains_pat_self(name, p)),
|
post.iter().any(|ref p| contains_pat_self(name, p)),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -8,7 +8,7 @@ use syntax::ast::*;
|
|||||||
use syntax::codemap::Spanned;
|
use syntax::codemap::Spanned;
|
||||||
|
|
||||||
use eq_op::is_exp_equal;
|
use eq_op::is_exp_equal;
|
||||||
use utils::{match_type, span_help_and_lint, walk_ptrs_ty, get_parent_expr};
|
use utils::{match_type, span_lint, walk_ptrs_ty, get_parent_expr};
|
||||||
use utils::STRING_PATH;
|
use utils::STRING_PATH;
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
@ -45,19 +45,15 @@ impl LintPass for StringAdd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span_help_and_lint(cx, STRING_ADD, e.span,
|
span_lint(cx, STRING_ADD, e.span,
|
||||||
"you added something to a string. \
|
"you added something to a string. \
|
||||||
Consider using `String::push_str()` instead",
|
Consider using `String::push_str()` instead")
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#string_add")
|
|
||||||
}
|
}
|
||||||
} else if let &ExprAssign(ref target, ref src) = &e.node {
|
} else if let &ExprAssign(ref target, ref src) = &e.node {
|
||||||
if is_string(cx, target) && is_add(cx, src, target) {
|
if is_string(cx, target) && is_add(cx, src, target) {
|
||||||
span_help_and_lint(cx, STRING_ADD_ASSIGN, e.span,
|
span_lint(cx, STRING_ADD_ASSIGN, e.span,
|
||||||
"you assigned the result of adding something to this string. \
|
"you assigned the result of adding something to this string. \
|
||||||
Consider using `String::push_str()` instead",
|
Consider using `String::push_str()` instead")
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#string_add_assign")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
58
src/types.rs
58
src/types.rs
@ -31,17 +31,14 @@ impl LintPass for TypePass {
|
|||||||
span_help_and_lint(
|
span_help_and_lint(
|
||||||
cx, BOX_VEC, ast_ty.span,
|
cx, BOX_VEC, ast_ty.span,
|
||||||
"you seem to be trying to use `Box<Vec<T>>`. Did you mean to use `Vec<T>`?",
|
"you seem to be trying to use `Box<Vec<T>>`. Did you mean to use `Vec<T>`?",
|
||||||
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation. \
|
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.");
|
||||||
for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#box_vec");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if match_type(cx, ty, &LL_PATH) {
|
else if match_type(cx, ty, &LL_PATH) {
|
||||||
span_help_and_lint(
|
span_help_and_lint(
|
||||||
cx, LINKEDLIST, ast_ty.span,
|
cx, LINKEDLIST, ast_ty.span,
|
||||||
"I see you're using a LinkedList! Perhaps you meant some other data structure?",
|
"I see you're using a LinkedList! Perhaps you meant some other data structure?",
|
||||||
"a RingBuf might work; for further information see \
|
"a RingBuf might work");
|
||||||
https://github.com/Manishearth/rust-clippy/wiki#ineffective_bit_mask");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,15 +138,12 @@ fn span_precision_loss_lint(cx: &Context, expr: &Expr, cast_from: &ty::TyS, cast
|
|||||||
let from_nbits_str = if arch_dependent {"64".to_owned()}
|
let from_nbits_str = if arch_dependent {"64".to_owned()}
|
||||||
else if is_isize_or_usize(cast_from) {"32 or 64".to_owned()}
|
else if is_isize_or_usize(cast_from) {"32 or 64".to_owned()}
|
||||||
else {int_ty_to_nbits(cast_from).to_string()};
|
else {int_ty_to_nbits(cast_from).to_string()};
|
||||||
span_help_and_lint(cx, CAST_PRECISION_LOSS, expr.span,
|
span_lint(cx, CAST_PRECISION_LOSS, expr.span,
|
||||||
&format!("casting {0} to {1} causes a loss of precision {2}\
|
&format!("casting {0} to {1} causes a loss of precision {2}\
|
||||||
({0} is {3} bits wide, but {1}'s mantissa is only {4} bits wide)",
|
({0} is {3} bits wide, but {1}'s mantissa is only {4} bits wide)",
|
||||||
cast_from, if cast_to_f64 {"f64"} else {"f32"},
|
cast_from, if cast_to_f64 {"f64"} else {"f32"},
|
||||||
if arch_dependent {arch_dependent_str} else {""},
|
if arch_dependent {arch_dependent_str} else {""},
|
||||||
from_nbits_str,
|
from_nbits_str, mantissa_nbits));
|
||||||
mantissa_nbits),
|
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cast_precision_loss");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ArchSuffix {
|
enum ArchSuffix {
|
||||||
@ -183,26 +177,22 @@ fn check_truncation_and_wrapping(cx: &Context, expr: &Expr, cast_from: &ty::TyS,
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
if span_truncation {
|
if span_truncation {
|
||||||
span_help_and_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
|
span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
|
||||||
&format!("casting {} to {} may truncate the value{}",
|
&format!("casting {} to {} may truncate the value{}",
|
||||||
cast_from, cast_to,
|
cast_from, cast_to,
|
||||||
match suffix_truncation {
|
match suffix_truncation {
|
||||||
ArchSuffix::_32 => arch_32_suffix,
|
ArchSuffix::_32 => arch_32_suffix,
|
||||||
ArchSuffix::_64 => arch_64_suffix,
|
ArchSuffix::_64 => arch_64_suffix,
|
||||||
ArchSuffix::None => "" }),
|
ArchSuffix::None => "" }));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cast_possible_truncation");
|
|
||||||
}
|
}
|
||||||
if span_wrap {
|
if span_wrap {
|
||||||
span_help_and_lint(cx, CAST_POSSIBLE_WRAP, expr.span,
|
span_lint(cx, CAST_POSSIBLE_WRAP, expr.span,
|
||||||
&format!("casting {} to {} may wrap around the value{}",
|
&format!("casting {} to {} may wrap around the value{}",
|
||||||
cast_from, cast_to,
|
cast_from, cast_to,
|
||||||
match suffix_wrap {
|
match suffix_wrap {
|
||||||
ArchSuffix::_32 => arch_32_suffix,
|
ArchSuffix::_32 => arch_32_suffix,
|
||||||
ArchSuffix::_64 => arch_64_suffix,
|
ArchSuffix::_64 => arch_64_suffix,
|
||||||
ArchSuffix::None => "" }),
|
ArchSuffix::None => "" }));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cast_possible_wrap");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,37 +217,29 @@ impl LintPass for CastPass {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
(false, true) => {
|
(false, true) => {
|
||||||
span_help_and_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
|
span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
|
||||||
&format!("casting {} to {} may truncate the value",
|
&format!("casting {} to {} may truncate the value",
|
||||||
cast_from, cast_to),
|
cast_from, cast_to));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cast_possible_truncation");
|
|
||||||
if !cast_to.is_signed() {
|
if !cast_to.is_signed() {
|
||||||
span_help_and_lint(cx, CAST_SIGN_LOSS, expr.span,
|
span_lint(cx, CAST_SIGN_LOSS, expr.span,
|
||||||
&format!("casting {} to {} may lose the sign of the value",
|
&format!("casting {} to {} may lose the sign of the value",
|
||||||
cast_from, cast_to),
|
cast_from, cast_to));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cast_sign_loss");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(true, true) => {
|
(true, true) => {
|
||||||
if cast_from.is_signed() && !cast_to.is_signed() {
|
if cast_from.is_signed() && !cast_to.is_signed() {
|
||||||
span_help_and_lint(cx, CAST_SIGN_LOSS, expr.span,
|
span_lint(cx, CAST_SIGN_LOSS, expr.span,
|
||||||
&format!("casting {} to {} may lose the sign of the value",
|
&format!("casting {} to {} may lose the sign of the value",
|
||||||
cast_from, cast_to),
|
cast_from, cast_to));
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cast_sign_loss");
|
|
||||||
}
|
}
|
||||||
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(ast::TyF64),
|
if let (&ty::TyFloat(ast::TyF64),
|
||||||
&ty::TyFloat(ast::TyF32)) = (&cast_from.sty, &cast_to.sty) {
|
&ty::TyFloat(ast::TyF32)) = (&cast_from.sty, &cast_to.sty) {
|
||||||
span_help_and_lint(cx, CAST_POSSIBLE_TRUNCATION,
|
span_lint(cx, CAST_POSSIBLE_TRUNCATION,
|
||||||
expr.span,
|
expr.span,
|
||||||
"casting f64 to f32 may truncate the value",
|
"casting f64 to f32 may truncate the value");
|
||||||
"for further information see https://github.com/\
|
|
||||||
Manishearth/rust-clippy/wiki#cast_possible_truncation");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
src/utils.rs
14
src/utils.rs
@ -141,6 +141,11 @@ pub fn get_parent_expr<'c>(cx: &'c Context, e: &Expr) -> Option<&'c Expr> {
|
|||||||
#[cfg(not(feature="structured_logging"))]
|
#[cfg(not(feature="structured_logging"))]
|
||||||
pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
|
pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
|
||||||
cx.span_lint(lint, sp, msg);
|
cx.span_lint(lint, sp, msg);
|
||||||
|
if cx.current_level(lint) != Level::Allow {
|
||||||
|
cx.sess().fileline_help(sp, &format!("for further information visit \
|
||||||
|
https://github.com/Manishearth/rust-clippy/wiki#{}",
|
||||||
|
lint.name_lower()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="structured_logging")]
|
#[cfg(feature="structured_logging")]
|
||||||
@ -149,13 +154,20 @@ pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
|
|||||||
// cx.sess().codemap() has all these nice functions for line/column/snippet details
|
// cx.sess().codemap() has all these nice functions for line/column/snippet details
|
||||||
// http://doc.rust-lang.org/syntax/codemap/struct.CodeMap.html#method.span_to_string
|
// http://doc.rust-lang.org/syntax/codemap/struct.CodeMap.html#method.span_to_string
|
||||||
cx.span_lint(lint, sp, msg);
|
cx.span_lint(lint, sp, msg);
|
||||||
|
if cx.current_level(lint) != Level::Allow {
|
||||||
|
cx.sess().fileline_help(sp, &format!("for further information visit \
|
||||||
|
https://github.com/Manishearth/rust-clippy/wiki#{}",
|
||||||
|
lint.name_lower()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span_help_and_lint(cx: &Context, lint: &'static Lint, span: Span,
|
pub fn span_help_and_lint(cx: &Context, lint: &'static Lint, span: Span,
|
||||||
msg: &str, help: &str) {
|
msg: &str, help: &str) {
|
||||||
span_lint(cx, lint, span, msg);
|
span_lint(cx, lint, span, msg);
|
||||||
if cx.current_level(lint) != Level::Allow {
|
if cx.current_level(lint) != Level::Allow {
|
||||||
cx.sess().fileline_help(span, help);
|
cx.sess().fileline_help(span, &format!("{}\nfor further information \
|
||||||
|
visit https://github.com/Manishearth/rust-clippy/wiki#{}",
|
||||||
|
help, lint.name_lower()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user