use syntax::codemap::Span;
use std::f64::consts as f64;
-use utils::span_lint;
+use utils::span_help_and_lint;
declare_lint! {
pub APPROX_CONSTANT,
match lit.node {
LitFloat(ref str, TyF32) => check_known_consts(cx, span, str, "f32"),
LitFloat(ref str, TyF64) => check_known_consts(cx, span, str, "f64"),
- LitFloatUnsuffixed(ref str) => check_known_consts(cx, span, str, "f{32, 64}"),
+ LitFloatUnsuffixed(ref str) =>
+ check_known_consts(cx, span, str, "f{32, 64}"),
_ => ()
}
}
if let Ok(value) = str.parse::<f64>() {
for &(constant, name) in KNOWN_CONSTS {
if within_epsilon(constant, value) {
- span_lint(cx, APPROX_CONSTANT, span, &format!(
- "approximate value of `{}::{}` found. Consider using it directly", module, &name));
+ span_help_and_lint(cx, APPROX_CONSTANT, span, &format!(
+ "approximate value of `{}::{}` found. \
+ 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 {
- f64::abs(value - target) < f64::abs((if target > value { target } else { value })) / EPSILON_DIVISOR
+ f64::abs(value - target) < f64::abs(if target > value {
+ target
+ } else { value }) / EPSILON_DIVISOR
}
use syntax::ast::*;
use syntax::codemap::ExpnInfo;
-use utils::{in_macro, match_path, span_lint};
+use utils::{in_macro, match_path, span_help_and_lint};
declare_lint! { pub INLINE_ALWAYS, Warn,
"`#[inline(always)]` is a bad idea in most cases" }
if values.len() != 1 || inline != &"inline" { continue; }
if let MetaWord(ref always) = values[0].node {
if always != &"always" { continue; }
- span_lint(cx, INLINE_ALWAYS, attr.span, &format!(
+ span_help_and_lint(cx, INLINE_ALWAYS, attr.span, &format!(
"you have declared `#[inline(always)]` on `{}`. This \
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");
}
}
}
use syntax::ast_util::is_comparison_binop;
use syntax::codemap::Span;
-use utils::span_lint;
+use utils::span_help_and_lint;
declare_lint! {
pub BAD_BIT_MASK,
BiEq | BiNe => match bit_op {
BiBitAnd => if mask_value & cmp_value != mask_value {
if cmp_value != 0 {
- span_lint(cx, BAD_BIT_MASK, *span, &format!(
+ span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
"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 {
if mask_value == 0 {
- span_lint(cx, BAD_BIT_MASK, *span,
- &format!("&-masking with zero"));
+ span_help_and_lint(cx, BAD_BIT_MASK, *span,
+ "&-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 {
- span_lint(cx, BAD_BIT_MASK, *span, &format!(
+ span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
"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 {
BiBitAnd => if mask_value < cmp_value {
- span_lint(cx, BAD_BIT_MASK, *span, &format!(
+ span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
"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 {
if mask_value == 0 {
- span_lint(cx, BAD_BIT_MASK, *span,
- &format!("&-masking with zero"));
+ span_help_and_lint(cx, BAD_BIT_MASK, *span,
+ "&-masking with zero",
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#bad_bit_mask");
}
},
BiBitOr => if mask_value >= cmp_value {
- span_lint(cx, BAD_BIT_MASK, *span, &format!(
+ span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
"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 {
check_ineffective_lt(cx, *span, mask_value, cmp_value, "|");
},
},
BiLe | BiGt => match bit_op {
BiBitAnd => if mask_value <= cmp_value {
- span_lint(cx, BAD_BIT_MASK, *span, &format!(
+ span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
"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 {
if mask_value == 0 {
- span_lint(cx, BAD_BIT_MASK, *span,
- &format!("&-masking with zero"));
+ span_help_and_lint(cx, BAD_BIT_MASK, *span,
+ "&-masking with zero",
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#bad_bit_mask");
}
},
BiBitOr => if mask_value > cmp_value {
- span_lint(cx, BAD_BIT_MASK, *span, &format!(
+ span_help_and_lint(cx, BAD_BIT_MASK, *span, &format!(
"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 {
check_ineffective_gt(cx, *span, mask_value, cmp_value, "|");
},
fn check_ineffective_lt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
if c.is_power_of_two() && m < c {
- span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
+ span_help_and_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
"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) {
if (c + 1).is_power_of_two() && m <= c {
- span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
+ span_help_and_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
"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");
}
}
use syntax::visit::FnKind;
use rustc::middle::ty;
-use utils::{match_path, snippet, span_lint, walk_ptrs_ty};
+use utils::{match_path, snippet, span_lint, span_help_and_lint, walk_ptrs_ty};
use consts::constant;
declare_lint!(pub TOPLEVEL_REF_ARG, Warn,
fn check_nan(cx: &Context, path: &Path, span: Span) {
path.segments.last().map(|seg| if seg.identifier.name == "NAN" {
- span_lint(cx, CMP_NAN, span,
- "doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead");
+ span_help_and_lint(cx, CMP_NAN, span,
+ "doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead",
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#cmp_nan");
});
}
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
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)) {
- span_lint(cx, PRECEDENCE, expr.span,
+ span_help_and_lint(cx, PRECEDENCE, expr.span,
"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");
}
}
}
fn emit_return_lint(&mut self, cx: &Context, spans: (Span, Span)) {
span_lint(cx, NEEDLESS_RETURN, spans.0, &format!(
"unneeded return statement. Consider using `{}` \
- without the trailing semicolon",
+ without the return and trailing semicolon",
snippet(cx, spans.1, "..")))
}
use rustc::lint::{Context, LintArray, LintPass};
use rustc::middle::def::Def::{DefVariant, DefStruct};
-use utils::{in_external_macro, snippet, span_lint};
+use utils::{in_external_macro, snippet, span_help_and_lint};
declare_lint!(pub SHADOW_SAME, Allow,
"rebinding a name to itself, e.g. `let mut x = &mut x`");
&Option<T>) where T: Deref<Target=Expr> {
if let &Some(ref expr) = init {
if is_self_shadow(name, expr) {
- span_lint(cx, SHADOW_SAME, span, &format!(
+ span_help_and_lint(cx, SHADOW_SAME, span, &format!(
"{} is shadowed by itself in {}",
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 {
if contains_self(name, expr) {
- span_lint(cx, SHADOW_REUSE, span, &format!(
+ span_help_and_lint(cx, SHADOW_REUSE, span, &format!(
"{} is shadowed by {} which reuses the original value",
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 {
- span_lint(cx, SHADOW_UNRELATED, span, &format!(
+ span_help_and_lint(cx, SHADOW_UNRELATED, span, &format!(
"{} is shadowed by {} in this declaration",
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 {
- span_lint(cx, SHADOW_UNRELATED, span, &format!(
- "{} is shadowed in this declaration", snippet(cx, lspan, "_")));
+ span_help_and_lint(cx, SHADOW_UNRELATED, span, &format!(
+ "{} is shadowed in this declaration", snippet(cx, lspan, "_")),
+ "for further information see \
+ https://github.com/Manishearth/rust-clippy/wiki#shadow_unrelated");
}
}
use syntax::codemap::Spanned;
use eq_op::is_exp_equal;
-use utils::{match_type, span_lint, walk_ptrs_ty, get_parent_expr};
+use utils::{match_type, span_help_and_lint, walk_ptrs_ty, get_parent_expr};
use utils::STRING_PATH;
declare_lint! {
}
}
}
- //TODO check for duplicates
- span_lint(cx, STRING_ADD, e.span,
- "you added something to a string. \
- Consider using `String::push_str()` instead")
+ span_help_and_lint(cx, STRING_ADD, e.span,
+ "you added something to a string. \
+ 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 {
if is_string(cx, target) && is_add(cx, src, target) {
- span_lint(cx, STRING_ADD_ASSIGN, e.span,
+ span_help_and_lint(cx, STRING_ADD_ASSIGN, e.span,
"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")
}
}
}
span_help_and_lint(
cx, BOX_VEC, ast_ty.span,
"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) {
span_help_and_lint(
cx, LINKEDLIST, ast_ty.span,
"I see you're using a LinkedList! Perhaps you meant some other data structure?",
- "a RingBuf might work");
+ "a RingBuf might work; for further information see \
+ https://github.com/Manishearth/rust-clippy/wiki#ineffective_bit_mask");
}
}
}
let from_nbits_str = if arch_dependent {"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()};
- span_lint(cx, CAST_PRECISION_LOSS, expr.span,
- &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)",
- cast_from, if cast_to_f64 {"f64"} else {"f32"},
- if arch_dependent {arch_dependent_str} else {""},
- from_nbits_str,
- mantissa_nbits));
+ span_help_and_lint(cx, CAST_PRECISION_LOSS, expr.span,
+ &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)",
+ cast_from, if cast_to_f64 {"f64"} else {"f32"},
+ if arch_dependent {arch_dependent_str} else {""},
+ from_nbits_str,
+ mantissa_nbits),
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#cast_precision_loss");
}
enum ArchSuffix {
),
};
if span_truncation {
- span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
- &format!("casting {} to {} may truncate the value{}",
- cast_from, cast_to,
- match suffix_truncation {
- ArchSuffix::_32 => arch_32_suffix,
- ArchSuffix::_64 => arch_64_suffix,
- ArchSuffix::None => "" }));
+ span_help_and_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
+ &format!("casting {} to {} may truncate the value{}",
+ cast_from, cast_to,
+ match suffix_truncation {
+ ArchSuffix::_32 => arch_32_suffix,
+ ArchSuffix::_64 => arch_64_suffix,
+ ArchSuffix::None => "" }),
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#cast_possible_truncation");
}
if span_wrap {
- span_lint(cx, CAST_POSSIBLE_WRAP, expr.span,
- &format!("casting {} to {} may wrap around the value{}",
- cast_from, cast_to,
- match suffix_wrap {
- ArchSuffix::_32 => arch_32_suffix,
- ArchSuffix::_64 => arch_64_suffix,
- ArchSuffix::None => "" }));
+ span_help_and_lint(cx, CAST_POSSIBLE_WRAP, expr.span,
+ &format!("casting {} to {} may wrap around the value{}",
+ cast_from, cast_to,
+ match suffix_wrap {
+ ArchSuffix::_32 => arch_32_suffix,
+ ArchSuffix::_64 => arch_64_suffix,
+ ArchSuffix::None => "" }),
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#cast_possible_wrap");
}
}
}
},
(false, true) => {
- span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
- &format!("casting {} to {} may truncate the value", cast_from, cast_to));
+ span_help_and_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span,
+ &format!("casting {} to {} may truncate the value",
+ cast_from, cast_to),
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#cast_possible_truncation");
if !cast_to.is_signed() {
- span_lint(cx, CAST_SIGN_LOSS, expr.span,
- &format!("casting {} to {} may lose the sign of the value", cast_from, cast_to));
+ span_help_and_lint(cx, CAST_SIGN_LOSS, expr.span,
+ &format!("casting {} to {} may lose the sign of the value",
+ cast_from, cast_to),
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#cast_sign_loss");
}
},
(true, true) => {
if cast_from.is_signed() && !cast_to.is_signed() {
- span_lint(cx, CAST_SIGN_LOSS, expr.span,
- &format!("casting {} to {} may lose the sign of the value", cast_from, cast_to));
+ span_help_and_lint(cx, CAST_SIGN_LOSS, expr.span,
+ &format!("casting {} to {} may lose the sign of the value",
+ 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);
}
(false, false) => {
if let (&ty::TyFloat(ast::TyF64),
&ty::TyFloat(ast::TyF32)) = (&cast_from.sty, &cast_to.sty) {
- span_lint(cx, CAST_POSSIBLE_TRUNCATION, expr.span, "casting f64 to f32 may truncate the value");
+ span_help_and_lint(cx, CAST_POSSIBLE_TRUNCATION,
+ expr.span,
+ "casting f64 to f32 may truncate the value",
+ "for further information see https://github.com/\
+ Manishearth/rust-clippy/wiki#cast_possible_truncation");
}
}
}