From 6984d2bc09b790e762ca4e82f9070dc0fe65c515 Mon Sep 17 00:00:00 2001 From: llogiq Date: Wed, 26 Aug 2015 14:26:43 +0200 Subject: [PATCH] added helpful links to lints that have wiki entries --- src/approx_const.rs | 16 ++++++--- src/attrs.rs | 8 +++-- src/bit_mask.rs | 68 ++++++++++++++++++++++++------------- src/misc.rs | 14 +++++--- src/returns.rs | 2 +- src/shadow.rs | 26 +++++++++----- src/strings.rs | 17 ++++++---- src/types.rs | 82 ++++++++++++++++++++++++++++----------------- 8 files changed, 150 insertions(+), 83 deletions(-) diff --git a/src/approx_const.rs b/src/approx_const.rs index 3e0ba4eb669..0ec2f94cab8 100644 --- a/src/approx_const.rs +++ b/src/approx_const.rs @@ -3,7 +3,7 @@ use syntax::ast::*; 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, @@ -40,7 +40,8 @@ fn check_lit(cx: &Context, lit: &Lit, span: Span) { 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}"), _ => () } } @@ -49,13 +50,18 @@ fn check_known_consts(cx: &Context, span: Span, str: &str, module: &str) { if let Ok(value) = str.parse::() { 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 } diff --git a/src/attrs.rs b/src/attrs.rs index ad021f28a4d..a9ee9402e28 100644 --- a/src/attrs.rs +++ b/src/attrs.rs @@ -4,7 +4,7 @@ use rustc::lint::*; 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" } @@ -98,10 +98,12 @@ fn check_attrs(cx: &Context, info: Option<&ExpnInfo>, ident: &Ident, 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"); } } } diff --git a/src/bit_mask.rs b/src/bit_mask.rs index 6537fcf4c1a..6817dd3d97b 100644 --- a/src/bit_mask.rs +++ b/src/bit_mask.rs @@ -5,7 +5,7 @@ use syntax::ast::*; 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, @@ -100,38 +100,50 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_, 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, "|"); }, @@ -141,19 +153,25 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_, }, 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, "|"); }, @@ -167,17 +185,21 @@ 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) { 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"); } } diff --git a/src/misc.rs b/src/misc.rs index 2290af38bb5..d3d99e93b0b 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -6,7 +6,7 @@ use syntax::codemap::{Span, Spanned}; 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, @@ -65,8 +65,10 @@ impl LintPass for CmpNan { 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"); }); } @@ -124,9 +126,11 @@ impl LintPass for Precedence { 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"); } } } diff --git a/src/returns.rs b/src/returns.rs index 889688cb0c7..e4b14c22115 100644 --- a/src/returns.rs +++ b/src/returns.rs @@ -60,7 +60,7 @@ impl ReturnPass { 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, ".."))) } diff --git a/src/shadow.rs b/src/shadow.rs index fb840fd3258..717c06a4c14 100644 --- a/src/shadow.rs +++ b/src/shadow.rs @@ -6,7 +6,7 @@ use syntax::visit::FnKind; 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`"); @@ -114,26 +114,34 @@ fn lint_shadow(cx: &Context, name: Name, span: Span, lspan: Span, init: &Option) where T: Deref { 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"); } } diff --git a/src/strings.rs b/src/strings.rs index d03f4d53c60..8e10cfaa72c 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -8,7 +8,7 @@ use syntax::ast::*; 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! { @@ -45,16 +45,19 @@ impl LintPass for StringAdd { } } } - //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") } } } diff --git a/src/types.rs b/src/types.rs index 7479a65b6ee..700666d0542 100644 --- a/src/types.rs +++ b/src/types.rs @@ -32,14 +32,17 @@ impl LintPass for TypePass { span_help_and_lint( cx, BOX_VEC, ast_ty.span, "you seem to be trying to use `Box>`. Did you mean to use `Vec`?", - "`Vec` is already on the heap, `Box>` makes an extra allocation"); + "`Vec` is already on the heap, `Box>` 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"); } } } @@ -141,13 +144,15 @@ fn span_precision_loss_lint(cx: &Context, expr: &Expr, cast_from: &ty::TyS, cast 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 { @@ -181,22 +186,26 @@ fn check_truncation_and_wrapping(cx: &Context, expr: &Expr, cast_from: &ty::TyS, ), }; 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"); } } @@ -221,24 +230,37 @@ impl LintPass for CastPass { } }, (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"); } } }