Merge branch 'pr-149'

This commit is contained in:
Manish Goregaokar 2015-08-13 13:00:29 +05:30
commit 8dfa02938d
26 changed files with 139 additions and 137 deletions

View File

@ -53,7 +53,7 @@ fn check_known_consts(cx: &Context, span: Span, str: &str, module: &str) {
for &(constant, name) in KNOWN_CONSTS { for &(constant, name) in KNOWN_CONSTS {
if within_epsilon(constant, value) { if within_epsilon(constant, value) {
span_lint(cx, APPROX_CONSTANT, span, &format!( span_lint(cx, APPROX_CONSTANT, span, &format!(
"approximate value of `{}::{}` found. Consider using it directly.", module, &name)); "approximate value of `{}::{}` found. Consider using it directly", module, &name));
} }
} }
} }

View File

@ -51,7 +51,7 @@ impl LintPass for EtaPass {
} }
} }
span_lint(cx, REDUNDANT_CLOSURE, expr.span, span_lint(cx, REDUNDANT_CLOSURE, expr.span,
&format!("redundant closure found. Consider using `{}` in its place.", &format!("redundant closure found. Consider using `{}` in its place",
expr_to_string(caller))[..]) expr_to_string(caller))[..])
} }
} }

View File

@ -49,7 +49,7 @@ impl LintPass for IdentityOp {
fn check(cx: &Context, e: &Expr, m: i8, span: Span, arg: Span) { fn check(cx: &Context, e: &Expr, m: i8, span: Span, arg: Span) {
if have_lit(cx, e, m) { if have_lit(cx, e, m) {
span_lint(cx, IDENTITY_OP, span, &format!( span_lint(cx, IDENTITY_OP, span, &format!(
"the operation is ineffective. Consider reducing it to `{}`.", "the operation is ineffective. Consider reducing it to `{}`",
snippet(cx, arg, ".."))); snippet(cx, arg, "..")));
} }
} }

View File

@ -59,7 +59,7 @@ fn check_trait_items(cx: &Context, item: &Item, trait_items: &[P<TraitItem>]) {
if is_named_self(i, "len") { if is_named_self(i, "len") {
span_lint(cx, LEN_WITHOUT_IS_EMPTY, i.span, span_lint(cx, LEN_WITHOUT_IS_EMPTY, i.span,
&format!("trait `{}` has a `.len(_: &Self)` method, but no \ &format!("trait `{}` has a `.len(_: &Self)` method, but no \
`.is_empty(_: &Self)` method. Consider adding one.", `.is_empty(_: &Self)` method. Consider adding one",
item.ident.name)); item.ident.name));
} }
}; };
@ -79,7 +79,7 @@ fn check_impl_items(cx: &Context, item: &Item, impl_items: &[P<ImplItem>]) {
span_lint(cx, LEN_WITHOUT_IS_EMPTY, span_lint(cx, LEN_WITHOUT_IS_EMPTY,
Span{ lo: s.lo, hi: s.lo, expn_id: s.expn_id }, Span{ lo: s.lo, hi: s.lo, expn_id: s.expn_id },
&format!("item `{}` has a `.len(_: &Self)` method, but no \ &format!("item `{}` has a `.len(_: &Self)` method, but no \
`.is_empty(_: &Self)` method. Consider adding one.", `.is_empty(_: &Self)` method. Consider adding one",
item.ident.name)); item.ident.name));
return; return;
} }

View File

@ -30,12 +30,12 @@ impl LintPass for MethodsPass {
span_lint(cx, OPTION_UNWRAP_USED, expr.span, span_lint(cx, OPTION_UNWRAP_USED, expr.span,
"used unwrap() on an Option value. If you don't want \ "used unwrap() on an Option value. If you don't want \
to handle the None case gracefully, consider using to handle the None case gracefully, consider using
expect() to provide a better panic message."); expect() to provide a better panic message");
} }
else if match_def_path(cx, did.did, &["core", "result", "Result"]) { else if match_def_path(cx, did.did, &["core", "result", "Result"]) {
span_lint(cx, RESULT_UNWRAP_USED, expr.span, span_lint(cx, RESULT_UNWRAP_USED, expr.span,
"used unwrap() on a Result value. Graceful handling \ "used unwrap() on a Result value. Graceful handling \
of Err values is preferred."); of Err values is preferred");
} }
} }
} }

View File

@ -129,7 +129,8 @@ impl LintPass for FloatCmp {
let op = cmp.node; let op = cmp.node;
if (op == BiEq || op == BiNe) && (is_float(cx, left) || is_float(cx, right)) { if (op == BiEq || op == BiNe) && (is_float(cx, left) || is_float(cx, right)) {
span_lint(cx, FLOAT_CMP, expr.span, &format!( span_lint(cx, FLOAT_CMP, expr.span, &format!(
"{}-comparison of f32 or f64 detected. Consider changing this to `abs({} - {}) < epsilon` for some suitable value of epsilon.", "{}-comparison of f32 or f64 detected. Consider changing this to \
`abs({} - {}) < epsilon` for some suitable value of epsilon",
binop_to_string(op), snippet(cx, left.span, ".."), binop_to_string(op), snippet(cx, left.span, ".."),
snippet(cx, right.span, ".."))); snippet(cx, right.span, "..")));
} }
@ -146,7 +147,7 @@ fn is_float(cx: &Context, expr: &Expr) -> bool {
} }
declare_lint!(pub PRECEDENCE, Warn, declare_lint!(pub PRECEDENCE, Warn,
"Warn on mixing bit ops with integer arithmetic without parenthesis"); "Warn on mixing bit ops with integer arithmetic without parentheses");
#[derive(Copy,Clone)] #[derive(Copy,Clone)]
pub struct Precedence; pub struct Precedence;
@ -160,7 +161,8 @@ impl LintPass for Precedence {
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_lint(cx, PRECEDENCE, expr.span, span_lint(cx, PRECEDENCE, expr.span,
"operator precedence can trip the unwary. Consider adding parenthesis to the subexpression."); "operator precedence can trip the unwary. Consider adding parentheses \
to the subexpression");
} }
} }
} }
@ -216,7 +218,7 @@ fn check_to_owned(cx: &Context, expr: &Expr, other_span: Span) {
name == "to_owned" && is_str_arg(cx, args) { name == "to_owned" && is_str_arg(cx, args) {
span_lint(cx, CMP_OWNED, expr.span, &format!( span_lint(cx, CMP_OWNED, expr.span, &format!(
"this creates an owned instance just for comparison. \ "this creates an owned instance just for comparison. \
Consider using `{}.as_slice()` to compare without allocation.", Consider using `{}.as_slice()` to compare without allocation",
snippet(cx, other_span, ".."))) snippet(cx, other_span, "..")))
} }
}, },
@ -226,7 +228,7 @@ fn check_to_owned(cx: &Context, expr: &Expr, other_span: Span) {
match_path(path, &["String", "from"]) { match_path(path, &["String", "from"]) {
span_lint(cx, CMP_OWNED, expr.span, &format!( span_lint(cx, CMP_OWNED, expr.span, &format!(
"this creates an owned instance just for comparison. \ "this creates an owned instance just for comparison. \
Consider using `{}.as_slice()` to compare without allocation.", Consider using `{}.as_slice()` to compare without allocation",
snippet(cx, other_span, ".."))) snippet(cx, other_span, "..")))
} }
} }

View File

@ -46,7 +46,7 @@ fn check_expr_expd(cx: &Context, expr: &Expr, info: Option<&ExpnInfo>) {
cx.tcx.expr_ty(e).sty { cx.tcx.expr_ty(e).sty {
span_lint(cx, MUT_MUT, expr.span, span_lint(cx, MUT_MUT, expr.span,
"this expression mutably borrows a mutable reference. \ "this expression mutably borrows a mutable reference. \
Consider reborrowing.") Consider reborrowing")
} }
}) })
}) })

View File

@ -37,7 +37,7 @@ impl LintPass for NeedlessBool {
"you can reduce your if statement to its predicate"); }, "you can reduce your if statement to its predicate"); },
(Option::Some(false), Option::Some(true)) => { (Option::Some(false), Option::Some(true)) => {
span_lint(cx, NEEDLESS_BOOL, e.span, span_lint(cx, NEEDLESS_BOOL, e.span,
"you can reduce your if statement to `!` + your predicate"); }, "you can reduce your if statement to `!` + its predicate"); },
(Option::Some(false), Option::Some(false)) => { (Option::Some(false), Option::Some(false)) => {
span_lint(cx, NEEDLESS_BOOL, e.span, span_lint(cx, NEEDLESS_BOOL, e.span,
"your if-then-else expression will always return false"); }, "your if-then-else expression will always return false"); },

View File

@ -61,9 +61,9 @@ fn check_ptr_subtype(cx: &Context, span: Span, ty: &Ty) {
&["String"]).map_or((), |_| { &["String"]).map_or((), |_| {
span_lint(cx, PTR_ARG, span, span_lint(cx, PTR_ARG, span,
"writing `&String` instead of `&str` involves a new object \ "writing `&String` instead of `&str` involves a new object \
where a slice will do. Consider changing the type to `&str`.") where a slice will do. Consider changing the type to `&str`")
}), |_| span_lint(cx, PTR_ARG, span, }), |_| span_lint(cx, PTR_ARG, span,
"writing `&Vec<_>` instead of \ "writing `&Vec<_>` instead of \
`&[_]` involves one more reference and cannot be used with \ `&[_]` involves one more reference and cannot be used with \
non-Vec-based slices. Consider changing the type to `&[...]`.")) non-Vec-based slices. Consider changing the type to `&[...]`"))
} }

View File

@ -30,7 +30,7 @@ impl LintPass for StringAdd {
if is_string(cx, target) && is_add(src, target) { if is_string(cx, target) && is_add(src, target) {
span_lint(cx, STRING_ADD_ASSIGN, e.span, span_lint(cx, STRING_ADD_ASSIGN, e.span,
"you assign the result of adding something to this string. \ "you assign the result of adding something to this string. \
Consider using `String::push_str()` instead.") Consider using `String::push_str()` instead")
} }
} }
} }

View File

@ -90,7 +90,7 @@ fn check_let_unit(cx: &Context, decl: &Decl, info: Option<&ExpnInfo>) {
let bindtype = &cx.tcx.pat_ty(&*local.pat).sty; let bindtype = &cx.tcx.pat_ty(&*local.pat).sty;
if *bindtype == ty::TyTuple(vec![]) { if *bindtype == ty::TyTuple(vec![]) {
span_lint(cx, LET_UNIT_VALUE, decl.span, &format!( span_lint(cx, LET_UNIT_VALUE, decl.span, &format!(
"this let-binding has unit value. Consider omitting `let {} =`.", "this let-binding has unit value. Consider omitting `let {} =`",
snippet(cx, local.pat.span, ".."))); snippet(cx, local.pat.span, "..")));
} }
} }

View File

@ -27,11 +27,11 @@ fn check_str(cx: &Context, string: &str, span: Span) {
for (i, c) in string.char_indices() { for (i, c) in string.char_indices() {
if c == '\u{200B}' { if c == '\u{200B}' {
str_pos_lint(cx, ZERO_WIDTH_SPACE, span, i, str_pos_lint(cx, ZERO_WIDTH_SPACE, span, i,
"zero-width space detected. Consider using `\\u{200B}`."); "zero-width space detected. Consider using `\\u{200B}`");
} }
if c as u32 > 0x7F { if c as u32 > 0x7F {
str_pos_lint(cx, NON_ASCII_LITERAL, span, i, &format!( str_pos_lint(cx, NON_ASCII_LITERAL, span, i, &format!(
"literal non-ASCII character detected. Consider using `\\u{{{:X}}}`.", c as u32)); "literal non-ASCII character detected. Consider using `\\u{{{:X}}}`", c as u32));
} }
} }
} }

View File

@ -4,53 +4,53 @@
#[deny(approx_constant)] #[deny(approx_constant)]
#[allow(unused)] #[allow(unused)]
fn main() { fn main() {
let my_e = 2.7182; //~ERROR let my_e = 2.7182; //~ERROR approximate value of `f{32, 64}::E` found
let almost_e = 2.718; //~ERROR let almost_e = 2.718; //~ERROR approximate value of `f{32, 64}::E` found
let no_e = 2.71; let no_e = 2.71;
let my_1_frac_pi = 0.3183; //~ERROR let my_1_frac_pi = 0.3183; //~ERROR approximate value of `f{32, 64}::FRAC_1_PI` found
let no_1_frac_pi = 0.31; let no_1_frac_pi = 0.31;
let my_frac_1_sqrt_2 = 0.70710678; //~ERROR let my_frac_1_sqrt_2 = 0.70710678; //~ERROR approximate value of `f{32, 64}::FRAC_1_SQRT_2` found
let almost_frac_1_sqrt_2 = 0.70711; //~ERROR let almost_frac_1_sqrt_2 = 0.70711; //~ERROR approximate value of `f{32, 64}::FRAC_1_SQRT_2` found
let my_frac_1_sqrt_2 = 0.707; let my_frac_1_sqrt_2 = 0.707;
let my_frac_2_pi = 0.63661977; //~ERROR let my_frac_2_pi = 0.63661977; //~ERROR approximate value of `f{32, 64}::FRAC_2_PI` found
let no_frac_2_pi = 0.636; let no_frac_2_pi = 0.636;
let my_frac_2_sq_pi = 1.128379; //~ERROR let my_frac_2_sq_pi = 1.128379; //~ERROR approximate value of `f{32, 64}::FRAC_2_SQRT_PI` found
let no_frac_2_sq_pi = 1.128; let no_frac_2_sq_pi = 1.128;
let my_frac_2_pi = 1.57079632679; //~ERROR let my_frac_pi_2 = 1.57079632679; //~ERROR approximate value of `f{32, 64}::FRAC_PI_2` found
let no_frac_2_pi = 1.5705; let no_frac_pi_2 = 1.5705;
let my_frac_3_pi = 1.04719755119; //~ERROR let my_frac_pi_3 = 1.04719755119; //~ERROR approximate value of `f{32, 64}::FRAC_PI_3` found
let no_frac_3_pi = 1.047; let no_frac_pi_3 = 1.047;
let my_frac_4_pi = 0.785398163397; //~ERROR let my_frac_pi_4 = 0.785398163397; //~ERROR approximate value of `f{32, 64}::FRAC_PI_4` found
let no_frac_4_pi = 0.785; let no_frac_pi_4 = 0.785;
let my_frac_6_pi = 0.523598775598; //~ERROR let my_frac_pi_6 = 0.523598775598; //~ERROR approximate value of `f{32, 64}::FRAC_PI_6` found
let no_frac_6_pi = 0.523; let no_frac_pi_6 = 0.523;
let my_frac_8_pi = 0.3926990816987; //~ERROR let my_frac_pi_8 = 0.3926990816987; //~ERROR approximate value of `f{32, 64}::FRAC_PI_8` found
let no_frac_8_pi = 0.392; let no_frac_pi_8 = 0.392;
let my_ln_10 = 2.302585092994046; //~ERROR let my_ln_10 = 2.302585092994046; //~ERROR approximate value of `f{32, 64}::LN_10` found
let no_ln_10 = 2.303; let no_ln_10 = 2.303;
let my_ln_2 = 0.6931471805599453; //~ERROR let my_ln_2 = 0.6931471805599453; //~ERROR approximate value of `f{32, 64}::LN_2` found
let no_ln_2 = 0.693; let no_ln_2 = 0.693;
let my_log10_e = 0.43429448190325176; //~ERROR let my_log10_e = 0.43429448190325176; //~ERROR approximate value of `f{32, 64}::LOG10_E` found
let no_log10_e = 0.434; let no_log10_e = 0.434;
let my_log2_e = 1.4426950408889634; //~ERROR let my_log2_e = 1.4426950408889634; //~ERROR approximate value of `f{32, 64}::LOG2_E` found
let no_log2_e = 1.442; let no_log2_e = 1.442;
let my_pi = 3.1415; //~ERROR let my_pi = 3.1415; //~ERROR approximate value of `f{32, 64}::PI` found
let almost_pi = 3.141; let almost_pi = 3.141;
let my_sq2 = 1.4142; //~ERROR let my_sq2 = 1.4142; //~ERROR approximate value of `f{32, 64}::SQRT_2` found
let no_sq2 = 1.414; let no_sq2 = 1.414;
} }

View File

@ -12,30 +12,30 @@ fn main() {
x & 0 == 0; //~ERROR &-masking with zero x & 0 == 0; //~ERROR &-masking with zero
x & 1 == 1; //ok, distinguishes bit 0 x & 1 == 1; //ok, distinguishes bit 0
x & 1 == 0; //ok, compared with zero x & 1 == 0; //ok, compared with zero
x & 2 == 1; //~ERROR x & 2 == 1; //~ERROR incompatible bit mask
x | 0 == 0; //ok, equals x == 0 (maybe warn?) x | 0 == 0; //ok, equals x == 0 (maybe warn?)
x | 1 == 3; //ok, equals x == 2 || x == 3 x | 1 == 3; //ok, equals x == 2 || x == 3
x | 3 == 3; //ok, equals x <= 3 x | 3 == 3; //ok, equals x <= 3
x | 3 == 2; //~ERROR x | 3 == 2; //~ERROR incompatible bit mask
x & 1 > 1; //~ERROR x & 1 > 1; //~ERROR incompatible bit mask
x & 2 > 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0 x & 2 > 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0
x & 2 < 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0 x & 2 < 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0
x | 1 > 1; // ok (if a bit silly), equals x > 1 x | 1 > 1; // ok (if a bit silly), equals x > 1
x | 2 > 1; //~ERROR x | 2 > 1; //~ERROR incompatible bit mask
x | 2 <= 2; // ok (if a bit silly), equals x <= 2 x | 2 <= 2; // ok (if a bit silly), equals x <= 2
// this also now works with constants // this also now works with constants
x & THREE_BITS == 8; //~ERROR x & THREE_BITS == 8; //~ERROR incompatible bit mask
x | EVEN_MORE_REDIRECTION < 7; //~ERROR x | EVEN_MORE_REDIRECTION < 7; //~ERROR incompatible bit mask
0 & x == 0; //~ERROR 0 & x == 0; //~ERROR &-masking with zero
1 | x > 1; 1 | x > 1;
// and should now also match uncommon usage // and should now also match uncommon usage
1 < 2 | x; //~ERROR 1 < 2 | x; //~ERROR incompatible bit mask
2 == 3 | x; //~ERROR 2 == 3 | x; //~ERROR incompatible bit mask
1 == x & 2; //~ERROR 1 == x & 2; //~ERROR incompatible bit mask
x | 1 > 2; // no error, because we allowed ineffective bit masks x | 1 > 2; // no error, because we allowed ineffective bit masks
ineffective(); ineffective();
@ -46,8 +46,8 @@ fn main() {
fn ineffective() { fn ineffective() {
let x = 5; let x = 5;
x | 1 > 2; //~ERROR x | 1 > 2; //~ERROR ineffective bit mask
x | 1 < 3; //~ERROR x | 1 < 3; //~ERROR ineffective bit mask
x | 1 <= 3; //~ERROR x | 1 <= 3; //~ERROR ineffective bit mask
x | 1 >= 2; //~ERROR x | 1 >= 2; //~ERROR ineffective bit mask
} }

View File

@ -5,18 +5,18 @@
#[allow(float_cmp)] #[allow(float_cmp)]
fn main() { fn main() {
let x = 5f32; let x = 5f32;
x == std::f32::NAN; //~ERROR x == std::f32::NAN; //~ERROR doomed comparison with NAN
x != std::f32::NAN; //~ERROR x != std::f32::NAN; //~ERROR doomed comparison with NAN
x < std::f32::NAN; //~ERROR x < std::f32::NAN; //~ERROR doomed comparison with NAN
x > std::f32::NAN; //~ERROR x > std::f32::NAN; //~ERROR doomed comparison with NAN
x <= std::f32::NAN; //~ERROR x <= std::f32::NAN; //~ERROR doomed comparison with NAN
x >= std::f32::NAN; //~ERROR x >= std::f32::NAN; //~ERROR doomed comparison with NAN
let y = 0f64; let y = 0f64;
y == std::f64::NAN; //~ERROR y == std::f64::NAN; //~ERROR doomed comparison with NAN
y != std::f64::NAN; //~ERROR y != std::f64::NAN; //~ERROR doomed comparison with NAN
y < std::f64::NAN; //~ERROR y < std::f64::NAN; //~ERROR doomed comparison with NAN
y > std::f64::NAN; //~ERROR y > std::f64::NAN; //~ERROR doomed comparison with NAN
y <= std::f64::NAN; //~ERROR y <= std::f64::NAN; //~ERROR doomed comparison with NAN
y >= std::f64::NAN; //~ERROR y >= std::f64::NAN; //~ERROR doomed comparison with NAN
} }

View File

@ -9,29 +9,29 @@ fn id<X>(x: X) -> X {
#[allow(identity_op)] #[allow(identity_op)]
fn main() { fn main() {
// simple values and comparisons // simple values and comparisons
1 == 1; //~ERROR 1 == 1; //~ERROR equal expressions
"no" == "no"; //~ERROR "no" == "no"; //~ERROR equal expressions
// even though I agree that no means no ;-) // even though I agree that no means no ;-)
false != false; //~ERROR false != false; //~ERROR equal expressions
1.5 < 1.5; //~ERROR 1.5 < 1.5; //~ERROR equal expressions
1u64 >= 1u64; //~ERROR 1u64 >= 1u64; //~ERROR equal expressions
// casts, methods, parenthesis // casts, methods, parenthesis
(1 as u64) & (1 as u64); //~ERROR (1 as u64) & (1 as u64); //~ERROR equal expressions
1 ^ ((((((1)))))); //~ERROR 1 ^ ((((((1)))))); //~ERROR equal expressions
id((1)) | id(1); //~ERROR id((1)) | id(1); //~ERROR equal expressions
// unary and binary operators // unary and binary operators
(-(2) < -(2)); //~ERROR (-(2) < -(2)); //~ERROR equal expressions
((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
//~^ ERROR //~^ ERROR equal expressions
//~^^ ERROR //~^^ ERROR equal expressions
//~^^^ ERROR //~^^^ ERROR equal expressions
(1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; //~ERROR (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; //~ERROR equal expressions
// various other things // various other things
([1] != [1]); //~ERROR ([1] != [1]); //~ERROR equal expressions
((1, 2) != (1, 2)); //~ERROR ((1, 2) != (1, 2)); //~ERROR equal expressions
[1].len() == [1].len(); //~ERROR [1].len() == [1].len(); //~ERROR equal expressions
vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros
} }

View File

@ -13,20 +13,20 @@ fn twice<T>(x : T) -> T where T : Add<T, Output = T>, T : Copy {
#[deny(float_cmp)] #[deny(float_cmp)]
#[allow(unused)] #[allow(unused)]
fn main() { fn main() {
ZERO == 0f32; //~ERROR ZERO == 0f32; //~ERROR ==-comparison of f32 or f64
ZERO == 0.0; //~ERROR ZERO == 0.0; //~ERROR ==-comparison of f32 or f64
ZERO + ZERO != 1.0; //~ERROR ZERO + ZERO != 1.0; //~ERROR !=-comparison of f32 or f64
ONE != 0.0; //~ERROR ONE != 0.0; //~ERROR
twice(ONE) != ONE; //~ERROR twice(ONE) != ONE; //~ERROR !=-comparison of f32 or f64
ONE as f64 != 0.0; //~ERROR ONE as f64 != 0.0; //~ERROR !=-comparison of f32 or f64
let x : f64 = 1.0; let x : f64 = 1.0;
x == 1.0; //~ERROR x == 1.0; //~ERROR ==-comparison of f32 or f64
x != 0f64; //~ERROR x != 0f64; //~ERROR !=-comparison of f32 or f64
twice(x) != twice(ONE as f64); //~ERROR twice(x) != twice(ONE as f64); //~ERROR !=-comparison of f32 or f64
x < 0.0; x < 0.0;
x > 0.0; x > 0.0;

View File

@ -9,16 +9,16 @@ const ZERO : i64 = 0;
fn main() { fn main() {
let x = 0; let x = 0;
x + 0; //~ERROR x + 0; //~ERROR the operation is ineffective
0 + x; //~ERROR 0 + x; //~ERROR the operation is ineffective
x - ZERO; //~ERROR x - ZERO; //~ERROR the operation is ineffective
x | (0); //~ERROR x | (0); //~ERROR the operation is ineffective
((ZERO)) | x; //~ERROR ((ZERO)) | x; //~ERROR the operation is ineffective
x * 1; //~ERROR x * 1; //~ERROR the operation is ineffective
1 * x; //~ERROR 1 * x; //~ERROR the operation is ineffective
x / ONE; //~ERROR x / ONE; //~ERROR the operation is ineffective
x & NEG_ONE; //~ERROR x & NEG_ONE; //~ERROR the operation is ineffective
-1 & x; //~ERROR -1 & x; //~ERROR the operation is ineffective
} }

View File

@ -6,7 +6,7 @@
fn test() -> i32 { fn test() -> i32 {
let _y = 0; // no warning let _y = 0; // no warning
let x = 5; //~NOTE let x = 5; //~NOTE
x //~ERROR: x //~ERROR returning the result of a let binding
} }
fn test_nowarn_1() -> i32 { fn test_nowarn_1() -> i32 {

View File

@ -8,6 +8,6 @@ fn main() {
let _y = 1; // this is fine let _y = 1; // this is fine
let _z = ((), 1); // this as well let _z = ((), 1); // this as well
if true { if true {
let _a = (); //~ERROR let _a = (); //~ERROR this let-binding has unit value
} }
} }

View File

@ -5,11 +5,11 @@
#[deny(str_to_string, string_to_string)] #[deny(str_to_string, string_to_string)]
fn main() { fn main() {
let opt = Some(0); let opt = Some(0);
let _ = opt.unwrap(); //~ERROR let _ = opt.unwrap(); //~ERROR used unwrap() on an Option
let res: Result<i32, ()> = Ok(0); let res: Result<i32, ()> = Ok(0);
let _ = res.unwrap(); //~ERROR let _ = res.unwrap(); //~ERROR used unwrap() on a Result
let string = "str".to_string(); //~ERROR let string = "str".to_string(); //~ERROR `str.to_owned()` is faster
let _again = string.to_string(); //~ERROR let _again = string.to_string(); //~ERROR `String.to_string()` is a no-op
} }

View File

@ -5,7 +5,7 @@
//extern crate regex; //extern crate regex;
#[deny(mut_mut)] #[deny(mut_mut)]
fn fun(x : &mut &mut u32) -> bool { //~ERROR fn fun(x : &mut &mut u32) -> bool { //~ERROR generally you want to avoid `&mut &mut
**x > 0 **x > 0
} }
@ -16,19 +16,19 @@ macro_rules! mut_ptr {
#[deny(mut_mut)] #[deny(mut_mut)]
#[allow(unused_mut, unused_variables)] #[allow(unused_mut, unused_variables)]
fn main() { fn main() {
let mut x = &mut &mut 1u32; //~ERROR let mut x = &mut &mut 1u32; //~ERROR generally you want to avoid `&mut &mut
{ {
let mut y = &mut x; //~ERROR let mut y = &mut x; //~ERROR this expression mutably borrows a mutable reference
} }
if fun(x) { if fun(x) {
let y : &mut &mut &mut u32 = &mut &mut &mut 2; let y : &mut &mut &mut u32 = &mut &mut &mut 2;
//~^ ERROR //~^ ERROR generally you want to avoid `&mut &mut
//~^^ ERROR //~^^ ERROR generally you want to avoid `&mut &mut
//~^^^ ERROR //~^^^ ERROR generally you want to avoid `&mut &mut
//~^^^^ ERROR //~^^^^ ERROR generally you want to avoid `&mut &mut
***y + **x; ***y + **x;
} }
let mut z = mut_ptr!(&mut 3u32); //~ERROR let mut z = mut_ptr!(&mut 3u32); //~ERROR generally you want to avoid `&mut &mut
} }

View File

@ -4,9 +4,9 @@
#[deny(needless_bool)] #[deny(needless_bool)]
fn main() { fn main() {
let x = true; let x = true;
if x { true } else { true }; //~ERROR if x { true } else { true }; //~ERROR your if-then-else expression will always return true
if x { false } else { false }; //~ERROR if x { false } else { false }; //~ERROR your if-then-else expression will always return false
if x { true } else { false }; //~ERROR if x { true } else { false }; //~ERROR you can reduce your if statement to its predicate
if x { false } else { true }; //~ERROR if x { false } else { true }; //~ERROR you can reduce your if statement to `!` + its predicate
if x { x } else { false }; // would also be questionable, but we don't catch this yet if x { x } else { false }; // would also be questionable, but we don't catch this yet
} }

View File

@ -8,35 +8,35 @@ fn test_end_of_fn() -> bool {
// no error! // no error!
return true; return true;
} }
return true; //~ERROR return true; //~ERROR unneeded return statement
} }
fn test_no_semicolon() -> bool { fn test_no_semicolon() -> bool {
return true //~ERROR return true //~ERROR unneeded return statement
} }
fn test_if_block() -> bool { fn test_if_block() -> bool {
if true { if true {
return true; //~ERROR return true; //~ERROR unneeded return statement
} else { } else {
return false; //~ERROR return false; //~ERROR unneeded return statement
} }
} }
fn test_match(x: bool) -> bool { fn test_match(x: bool) -> bool {
match x { match x {
true => { true => {
return false; //~ERROR return false; //~ERROR unneeded return statement
} }
false => { false => {
return true //~ERROR return true //~ERROR unneeded return statement
} }
} }
} }
fn test_closure() { fn test_closure() {
let _ = || { let _ = || {
return true; //~ERROR return true; //~ERROR unneeded return statement
}; };
} }

View File

@ -4,12 +4,12 @@
#[deny(precedence)] #[deny(precedence)]
#[allow(eq_op)] #[allow(eq_op)]
fn main() { fn main() {
format!("{} vs. {}", 1 << 2 + 3, (1 << 2) + 3); //~ERROR format!("{} vs. {}", 1 << 2 + 3, (1 << 2) + 3); //~ERROR operator precedence can trip
format!("{} vs. {}", 1 + 2 << 3, 1 + (2 << 3)); //~ERROR format!("{} vs. {}", 1 + 2 << 3, 1 + (2 << 3)); //~ERROR operator precedence can trip
format!("{} vs. {}", 4 >> 1 + 1, (4 >> 1) + 1); //~ERROR format!("{} vs. {}", 4 >> 1 + 1, (4 >> 1) + 1); //~ERROR operator precedence can trip
format!("{} vs. {}", 1 + 3 >> 2, 1 + (3 >> 2)); //~ERROR format!("{} vs. {}", 1 + 3 >> 2, 1 + (3 >> 2)); //~ERROR operator precedence can trip
format!("{} vs. {}", 1 ^ 1 - 1, (1 ^ 1) - 1); //~ERROR format!("{} vs. {}", 1 ^ 1 - 1, (1 ^ 1) - 1); //~ERROR operator precedence can trip
format!("{} vs. {}", 3 | 2 - 1, (3 | 2) - 1); //~ERROR format!("{} vs. {}", 3 | 2 - 1, (3 | 2) - 1); //~ERROR operator precedence can trip
format!("{} vs. {}", 3 & 5 - 2, (3 & 5) - 2); //~ERROR format!("{} vs. {}", 3 & 5 - 2, (3 & 5) - 2); //~ERROR operator precedence can trip
} }

View File

@ -3,13 +3,13 @@
#[deny(ptr_arg)] #[deny(ptr_arg)]
#[allow(unused)] #[allow(unused)]
fn do_vec(x: &Vec<i64>) { //~ERROR: writing `&Vec<_>` instead of `&[_]` fn do_vec(x: &Vec<i64>) { //~ERROR writing `&Vec<_>` instead of `&[_]`
//Nothing here //Nothing here
} }
#[deny(ptr_arg)] #[deny(ptr_arg)]
#[allow(unused)] #[allow(unused)]
fn do_str(x: &String) { //~ERROR fn do_str(x: &String) { //~ERROR writing `&String` instead of `&str`
//Nothing here either //Nothing here either
} }