Merge pull request #1520 from Manishearth/rustup

rustup and compile-fail -> ui test move
This commit is contained in:
Martin Carton 2017-02-08 21:07:19 +01:00 committed by GitHub
commit 37a0e52a1e
303 changed files with 15013 additions and 2999 deletions

View File

@ -1,6 +1,10 @@
# Change Log
All notable changes to this project will be documented in this file.
## 0.0.114 — 2017-02-08
* Rustup to rustc 1.17.0-nightly (c49d10207 2017-02-07)
* Tests are now ui tests (testing the exact output of rustc)
## 0.0.113 — 2017-02-04
* Rustup to *rustc 1.16.0-nightly (eedaa94e3 2017-02-02)*
* New lint: [`large_enum_variant`]

View File

@ -40,6 +40,11 @@ contains some questionable code itself! Also before making a pull request, pleas
`util/update_lints.py`, which will update `lib.rs` and `README.md` with the lint declarations. Our
travis build actually checks for this.
Clippy uses UI tests. UI tests check that the output of the compiler is exactly as expected.
Of course there's little sense in writing the output yourself or copying it around.
Therefore you can simply run `tests/ui/update-all-references.sh` and check whether
the output looks as you expect with `git diff`. Commit all `*.stderr` files, too.
Also please document your lint with a doc comment akin to the following:
```rust
/// **What it does:** Checks for ... (describe what the lint matches).

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.0.113"
version = "0.0.114"
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",
"Andre Bogus <bogusandre@gmail.com>",
@ -30,7 +30,7 @@ test = false
[dependencies]
# begin automatic update
clippy_lints = { version = "0.0.113", path = "clippy_lints" }
clippy_lints = { version = "0.0.114", path = "clippy_lints" }
# end automatic update
cargo_metadata = "0.1.1"

View File

@ -180,7 +180,7 @@ transparently:
## Lints
There are 185 lints included in this crate:
There are 186 lints included in this crate:
name | default | triggers on
-----------------------------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
[package]
name = "clippy_lints"
# begin automatic update
version = "0.0.113"
version = "0.0.114"
# end automatic update
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",

View File

@ -158,7 +158,7 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref
TypeVariants::TyFnPtr(..) => {
return;
},
TypeVariants::TyTuple(tys) if tys.len() > 12 => {
TypeVariants::TyTuple(tys, _) if tys.len() > 12 => {
return;
},
_ => (),

View File

@ -197,7 +197,7 @@ fn check_let_unit(cx: &LateContext, decl: &Decl) {
if let DeclLocal(ref local) = decl.node {
let bindtype = &cx.tables.pat_ty(&local.pat).sty;
match *bindtype {
ty::TyTuple(slice) if slice.is_empty() => {
ty::TyTuple(slice, _) if slice.is_empty() => {
if in_external_macro(cx, decl.span) || in_macro(cx, local.pat.span) {
return;
}
@ -268,7 +268,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
if op.is_comparison() {
let sty = &cx.tables.expr_ty(left).sty;
match *sty {
ty::TyTuple(slice) if slice.is_empty() => {
ty::TyTuple(slice, _) if slice.is_empty() => {
let result = match op {
BiEq | BiLe | BiGe => "true",
_ => "false",

View File

@ -1,93 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(absurd_extreme_comparisons)]
#![allow(unused, eq_op, no_effect, unnecessary_operation)]
fn main() {
const Z: u32 = 0;
let u: u32 = 42;
u <= 0;
//~^ ERROR this comparison involving the minimum or maximum element for this type contains a
//~| HELP using u == 0 instead
u <= Z;
//~^ ERROR this comparison involving
//~| HELP using u == Z instead
u < Z;
//~^ ERROR this comparison involving
//~| HELP comparison is always false
Z >= u;
//~^ ERROR this comparison involving
//~| HELP using Z == u instead
Z > u;
//~^ ERROR this comparison involving
//~| HELP comparison is always false
u > std::u32::MAX;
//~^ ERROR this comparison involving
//~| HELP comparison is always false
u >= std::u32::MAX;
//~^ ERROR this comparison involving
//~| HELP using u == std::u32::MAX instead
std::u32::MAX < u;
//~^ ERROR this comparison involving
//~| HELP comparison is always false
std::u32::MAX <= u;
//~^ ERROR this comparison involving
//~| HELP using std::u32::MAX == u instead
1-1 > u;
//~^ ERROR this comparison involving
//~| HELP because 1-1 is the minimum value for this type, this comparison is always false
u >= !0;
//~^ ERROR this comparison involving
//~| HELP consider using u == !0 instead
u <= 12 - 2*6;
//~^ ERROR this comparison involving
//~| HELP consider using u == 12 - 2*6 instead
let i: i8 = 0;
i < -127 - 1;
//~^ ERROR this comparison involving
//~| HELP comparison is always false
std::i8::MAX >= i;
//~^ ERROR this comparison involving
//~| HELP comparison is always true
3-7 < std::i32::MIN;
//~^ ERROR this comparison involving
//~| HELP comparison is always false
let b = false;
b >= true;
//~^ ERROR this comparison involving
//~| HELP using b == true instead
false > b;
//~^ ERROR this comparison involving
//~| HELP comparison is always false
u > 0; // ok
// this is handled by unit_cmp
() < {}; //~WARNING <-comparison of unit values detected.
}
use std::cmp::{Ordering, PartialEq, PartialOrd};
#[derive(PartialEq, PartialOrd)]
pub struct U(u64);
impl PartialEq<u32> for U {
fn eq(&self, other: &u32) -> bool {
self.eq(&U(*other as u64))
}
}
impl PartialOrd<u32> for U {
fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
self.partial_cmp(&U(*other as u64))
}
}
pub fn foo(val: U) -> bool {
val > std::u32::MAX
}

View File

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

View File

@ -1,30 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(integer_arithmetic, float_arithmetic)]
#![allow(unused, shadow_reuse, shadow_unrelated, no_effect, unnecessary_operation)]
fn main() {
let i = 1i32;
1 + i; //~ERROR integer arithmetic detected
i * 2; //~ERROR integer arithmetic detected
1 % //~ERROR integer arithmetic detected
i / 2; // no error, this is part of the expression in the preceding line
i - 2 + 2 - i; //~ERROR integer arithmetic detected
-i; //~ERROR integer arithmetic detected
i & 1; // no wrapping
i | 1;
i ^ 1;
i >> 1;
i << 1;
let f = 1.0f32;
f * 2.0; //~ERROR floating-point arithmetic detected
1.0 + f; //~ERROR floating-point arithmetic detected
f * 2.0; //~ERROR floating-point arithmetic detected
f / 2.0; //~ERROR floating-point arithmetic detected
f - 2.0 * 4.2; //~ERROR floating-point arithmetic detected
-f; //~ERROR floating-point arithmetic detected
}

View File

@ -1,45 +0,0 @@
#![feature(inclusive_range_syntax, plugin)]
#![plugin(clippy)]
#![deny(indexing_slicing)]
#![deny(out_of_bounds_indexing)]
#![allow(no_effect, unnecessary_operation)]
fn main() {
let x = [1,2,3,4];
x[0];
x[3];
x[4]; //~ERROR: const index is out of bounds
x[1 << 3]; //~ERROR: const index is out of bounds
&x[1..5]; //~ERROR: range is out of bounds
&x[0..3];
&x[0...4]; //~ERROR: range is out of bounds
&x[...4]; //~ERROR: range is out of bounds
&x[..];
&x[1..];
&x[4..];
&x[5..]; //~ERROR: range is out of bounds
&x[..4];
&x[..5]; //~ERROR: range is out of bounds
let y = &x;
y[0]; //~ERROR: indexing may panic
&y[1..2]; //~ERROR: slicing may panic
&y[..];
&y[0...4]; //~ERROR: slicing may panic
&y[...4]; //~ERROR: slicing may panic
let empty: [i8; 0] = [];
empty[0]; //~ERROR: const index is out of bounds
&empty[1..5]; //~ERROR: range is out of bounds
&empty[0...4]; //~ERROR: range is out of bounds
&empty[...4]; //~ERROR: range is out of bounds
&empty[..];
&empty[0..];
&empty[0..0];
&empty[0...0]; //~ERROR: range is out of bounds
&empty[...0]; //~ERROR: range is out of bounds
&empty[..0];
&empty[1..]; //~ERROR: range is out of bounds
&empty[..4]; //~ERROR: range is out of bounds
}

View File

@ -1,85 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(assign_ops)]
#[allow(unused_assignments)]
fn main() {
let mut i = 1i32;
i += 2; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i + 2
i += 2 + 17; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i + 2 + 17
i -= 6; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i - 6
i -= 2 - 1;
//~^ ERROR assign operation detected
//~| HELP replace it with
//~| SUGGESTION i = i - (2 - 1)
i *= 5; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i * 5
i *= 1+5; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i * (1+5)
i /= 32; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i / 32
i /= 32 | 5; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i / (32 | 5)
i /= 32 / 5; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i / (32 / 5)
i %= 42; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i % 42
i >>= i; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i >> i
i <<= 9 + 6 - 7; //~ ERROR assign operation detected
//~^ HELP replace it with
//~| SUGGESTION i = i << (9 + 6 - 7)
i += 1 << 5;
//~^ ERROR assign operation detected
//~| HELP replace it with
//~| SUGGESTION i = i + (1 << 5)
}
#[allow(dead_code, unused_assignments)]
#[deny(assign_op_pattern)]
fn bla() {
let mut a = 5;
a = a + 1; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a += 1
a = 1 + a; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a += 1
a = a - 1; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a -= 1
a = a * 99; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a *= 99
a = 42 * a; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a *= 42
a = a / 2; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a /= 2
a = a % 5; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a %= 5
a = a & 1; //~ ERROR manual implementation of an assign operation
//~^ HELP replace it with
//~| SUGGESTION a &= 1
a = 1 - a;
a = 5 / a;
a = 42 % a;
a = 6 << a;
let mut s = String::new();
s = s + "bla";
}

View File

@ -1,57 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[allow(unused_assignments)]
#[deny(misrefactored_assign_op)]
fn main() {
let mut a = 5;
a += a + 1; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a += 1
a += 1 + a; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a += 1
a -= a - 1; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a -= 1
a *= a * 99; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a *= 99
a *= 42 * a; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a *= 42
a /= a / 2; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a /= 2
a %= a % 5; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a %= 5
a &= a & 1; //~ ERROR variable appears on both sides of an assignment operation
//~^ HELP replace it with
//~| SUGGESTION a &= 1
a -= 1 - a;
a /= 5 / a;
a %= 42 % a;
a <<= 6 << a;
}
// check that we don't lint on op assign impls, because that's just the way to impl them
use std::ops::{Mul, MulAssign};
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Wrap(i64);
impl Mul<i64> for Wrap {
type Output = Self;
fn mul(self, rhs: i64) -> Self {
Wrap(self.0 * rhs)
}
}
impl MulAssign<i64> for Wrap {
fn mul_assign(&mut self, rhs: i64) {
*self = *self * rhs
}
}

View File

@ -1,26 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(dead_code)]
#![allow(single_match)]
#![allow(unused_variables, similar_names)]
#![deny(blacklisted_name)]
fn test(foo: ()) {} //~ERROR use of a blacklisted/placeholder name `foo`
fn main() {
let foo = 42; //~ERROR use of a blacklisted/placeholder name `foo`
let bar = 42; //~ERROR use of a blacklisted/placeholder name `bar`
let baz = 42; //~ERROR use of a blacklisted/placeholder name `baz`
let barb = 42;
let barbaric = 42;
match (42, Some(1337), Some(0)) {
(foo, Some(bar), baz @ Some(_)) => (),
//~^ ERROR use of a blacklisted/placeholder name `foo`
//~| ERROR use of a blacklisted/placeholder name `bar`
//~| ERROR use of a blacklisted/placeholder name `baz`
_ => (),
}
}

View File

@ -1,23 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(bool_comparison)]
fn main() {
let x = true;
if x == true { "yes" } else { "no" };
//~^ ERROR equality checks against true are unnecessary
//~| HELP try simplifying it as shown:
//~| SUGGESTION if x { "yes" } else { "no" };
if x == false { "yes" } else { "no" };
//~^ ERROR equality checks against false can be replaced by a negation
//~| HELP try simplifying it as shown:
//~| SUGGESTION if !x { "yes" } else { "no" };
if true == x { "yes" } else { "no" };
//~^ ERROR equality checks against true are unnecessary
//~| HELP try simplifying it as shown:
//~| SUGGESTION if x { "yes" } else { "no" };
if false == x { "yes" } else { "no" };
//~^ ERROR equality checks against false can be replaced by a negation
//~| HELP try simplifying it as shown:
//~| SUGGESTION if !x { "yes" } else { "no" };
}

View File

@ -1,90 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(nonminimal_bool, logic_bug)]
#[allow(unused, many_single_char_names)]
fn main() {
let a: bool = unimplemented!();
let b: bool = unimplemented!();
let c: bool = unimplemented!();
let d: bool = unimplemented!();
let e: bool = unimplemented!();
let _ = a && b || a; //~ ERROR this boolean expression contains a logic bug
//~| HELP this expression can be optimized out
//~| HELP it would look like the following
//~| SUGGESTION let _ = a;
let _ = !(a && b);
let _ = !true; //~ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = false;
let _ = !false; //~ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = true;
let _ = !!a; //~ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = a;
let _ = false && a; //~ ERROR this boolean expression contains a logic bug
//~| HELP this expression can be optimized out
//~| HELP it would look like the following
//~| SUGGESTION let _ = false;
let _ = false || a; //~ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = a;
// don't lint on cfgs
let _ = cfg!(you_shall_not_not_pass) && a;
let _ = a || !b || !c || !d || !e;
let _ = !(a && b || c);
let _ = !(!a && b); //~ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = !b || a;
}
#[allow(unused, many_single_char_names)]
fn equality_stuff() {
let a: i32 = unimplemented!();
let b: i32 = unimplemented!();
let c: i32 = unimplemented!();
let d: i32 = unimplemented!();
let e: i32 = unimplemented!();
let _ = a == b && a != b;
//~^ ERROR this boolean expression contains a logic bug
//~| HELP this expression can be optimized out
//~| HELP it would look like the following
//~| SUGGESTION let _ = false;
let _ = a == b && c == 5 && a == b;
//~^ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = a == b && c == 5;
//~| HELP try
//~| SUGGESTION let _ = !(c != 5 || a != b);
let _ = a == b && c == 5 && b == a;
//~^ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = a == b && c == 5;
//~| HELP try
//~| SUGGESTION let _ = !(c != 5 || a != b);
let _ = a < b && a >= b;
//~^ ERROR this boolean expression contains a logic bug
//~| HELP this expression can be optimized out
//~| HELP it would look like the following
//~| SUGGESTION let _ = false;
let _ = a > b && a <= b;
//~^ ERROR this boolean expression contains a logic bug
//~| HELP this expression can be optimized out
//~| HELP it would look like the following
//~| SUGGESTION let _ = false;
let _ = a > b && a == b;
let _ = a != b || !(a != b || c == d);
//~^ ERROR this boolean expression can be simplified
//~| HELP try
//~| SUGGESTION let _ = c != d || a != b;
//~| HELP try
//~| SUGGESTION let _ = !(a == b && c == d);
}

View File

@ -1,64 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap)]
#[allow(no_effect, unnecessary_operation)]
fn main() {
// Test cast_precision_loss
1i32 as f32; //~ERROR casting i32 to f32 causes a loss of precision (i32 is 32 bits wide, but f32's mantissa is only 23 bits wide)
1i64 as f32; //~ERROR casting i64 to f32 causes a loss of precision (i64 is 64 bits wide, but f32's mantissa is only 23 bits wide)
1i64 as f64; //~ERROR casting i64 to f64 causes a loss of precision (i64 is 64 bits wide, but f64's mantissa is only 52 bits wide)
1u32 as f32; //~ERROR casting u32 to f32 causes a loss of precision (u32 is 32 bits wide, but f32's mantissa is only 23 bits wide)
1u64 as f32; //~ERROR casting u64 to f32 causes a loss of precision (u64 is 64 bits wide, but f32's mantissa is only 23 bits wide)
1u64 as f64; //~ERROR casting u64 to f64 causes a loss of precision (u64 is 64 bits wide, but f64's mantissa is only 52 bits wide)
1i32 as f64; // Should not trigger the lint
1u32 as f64; // Should not trigger the lint
// Test cast_possible_truncation
1f32 as i32; //~ERROR casting f32 to i32 may truncate the value
1f32 as u32; //~ERROR casting f32 to u32 may truncate the value
//~^ERROR casting f32 to u32 may lose the sign of the value
1f64 as f32; //~ERROR casting f64 to f32 may truncate the value
1i32 as i8; //~ERROR casting i32 to i8 may truncate the value
1i32 as u8; //~ERROR casting i32 to u8 may truncate the value
//~^ERROR casting i32 to u8 may lose the sign of the value
1f64 as isize; //~ERROR casting f64 to isize may truncate the value
1f64 as usize; //~ERROR casting f64 to usize may truncate the value
//~^ERROR casting f64 to usize may lose the sign of the value
// Test cast_possible_wrap
1u8 as i8; //~ERROR casting u8 to i8 may wrap around the value
1u16 as i16; //~ERROR casting u16 to i16 may wrap around the value
1u32 as i32; //~ERROR casting u32 to i32 may wrap around the value
1u64 as i64; //~ERROR casting u64 to i64 may wrap around the value
1usize as isize; //~ERROR casting usize to isize may wrap around the value
// Test cast_sign_loss
1i32 as u32; //~ERROR casting i32 to u32 may lose the sign of the value
1isize as usize; //~ERROR casting isize to usize may lose the sign of the value
// Extra checks for *size
// Casting from *size
1isize as i8; //~ERROR casting isize to i8 may truncate the value
1isize as f64; //~ERROR casting isize to f64 causes a loss of precision on targets with 64-bit wide pointers (isize is 64 bits wide, but f64's mantissa is only 52 bits wide)
1usize as f64; //~ERROR casting usize to f64 causes a loss of precision on targets with 64-bit wide pointers (usize is 64 bits wide, but f64's mantissa is only 52 bits wide)
1isize as f32; //~ERROR casting isize to f32 causes a loss of precision (isize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
1usize as f32; //~ERROR casting usize to f32 causes a loss of precision (usize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
1isize as i32; //~ERROR casting isize to i32 may truncate the value on targets with 64-bit wide pointers
1isize as u32; //~ERROR casting isize to u32 may lose the sign of the value
//~^ERROR casting isize to u32 may truncate the value on targets with 64-bit wide pointers
1usize as u32; //~ERROR casting usize to u32 may truncate the value on targets with 64-bit wide pointers
1usize as i32; //~ERROR casting usize to i32 may truncate the value on targets with 64-bit wide pointers
//~^ERROR casting usize to i32 may wrap around the value on targets with 32-bit wide pointers
// Casting to *size
1i64 as isize; //~ERROR casting i64 to isize may truncate the value on targets with 32-bit wide pointers
1i64 as usize; //~ERROR casting i64 to usize may truncate the value on targets with 32-bit wide pointers
//~^ERROR casting i64 to usize may lose the sign of the value
1u64 as isize; //~ERROR casting u64 to isize may truncate the value on targets with 32-bit wide pointers
//~^ERROR casting u64 to isize may wrap around the value on targets with 64-bit wide pointers
1u64 as usize; //~ERROR casting u64 to usize may truncate the value on targets with 32-bit wide pointers
1u32 as isize; //~ERROR casting u32 to isize may wrap around the value on targets with 32-bit wide pointers
1u32 as usize; // Should not trigger any lint
1i32 as isize; // Neither should this
1i32 as usize; //~ERROR casting i32 to usize may lose the sign of the value
}

View File

@ -1,22 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(cmp_nan)]
#[allow(float_cmp, no_effect, unnecessary_operation)]
fn main() {
let x = 5f32;
x == std::f32::NAN; //~ERROR doomed comparison with NAN
x != std::f32::NAN; //~ERROR doomed comparison with NAN
x < std::f32::NAN; //~ERROR doomed comparison with NAN
x > std::f32::NAN; //~ERROR doomed comparison with NAN
x <= std::f32::NAN; //~ERROR doomed comparison with NAN
x >= std::f32::NAN; //~ERROR doomed comparison with NAN
let y = 0f64;
y == std::f64::NAN; //~ERROR doomed comparison with NAN
y != std::f64::NAN; //~ERROR doomed comparison with NAN
y < std::f64::NAN; //~ERROR doomed comparison with NAN
y > std::f64::NAN; //~ERROR doomed comparison with NAN
y <= std::f64::NAN; //~ERROR doomed comparison with NAN
y >= std::f64::NAN; //~ERROR doomed comparison with NAN
}

View File

@ -1,27 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(cmp_owned)]
#[allow(unnecessary_operation)]
fn main() {
fn with_to_string(x : &str) {
x != "foo".to_string();
//~^ ERROR this creates an owned instance just for comparison. Consider using `x != "foo"` to compare without allocation
"foo".to_string() != x;
//~^ ERROR this creates an owned instance just for comparison. Consider using `"foo" != x` to compare without allocation
}
let x = "oh";
with_to_string(x);
x != "foo".to_owned(); //~ERROR this creates an owned instance
// removed String::from_str(..), as it has finally been removed in 1.4.0
// as of 2015-08-14
x != String::from("foo"); //~ERROR this creates an owned instance
42.to_string() == "42";
}

View File

@ -1,44 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy)]
#![allow(unused)]
#![feature(associated_consts, associated_type_defaults)]
type Alias = Vec<Vec<Box<(u32, u32, u32, u32)>>>; // no warning here
const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); //~ERROR very complex type
static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); //~ERROR very complex type
struct S {
f: Vec<Vec<Box<(u32, u32, u32, u32)>>>, //~ERROR very complex type
}
struct TS(Vec<Vec<Box<(u32, u32, u32, u32)>>>); //~ERROR very complex type
enum E {
Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>), //~ERROR very complex type
Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> }, //~ERROR very complex type
}
impl S {
const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); //~ERROR very complex type
fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { } //~ERROR very complex type
}
trait T {
const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>; //~ERROR very complex type
type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>; //~ERROR very complex type
fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>); //~ERROR very complex type
fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { } //~ERROR very complex type
}
fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> { vec![] } //~ERROR very complex type
fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { } //~ERROR very complex type
fn test3() {
let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![]; //~ERROR very complex type
}
fn main() {
}

View File

@ -1,26 +0,0 @@
#![feature(plugin)]
#![plugin(clippy(conf_file="./tests/auxiliary/conf_french_blacklisted_name.toml"))]
#![allow(dead_code)]
#![allow(single_match)]
#![allow(unused_variables)]
#![deny(blacklisted_name)]
fn test(toto: ()) {} //~ERROR use of a blacklisted/placeholder name `toto`
fn main() {
let toto = 42; //~ERROR use of a blacklisted/placeholder name `toto`
let tata = 42; //~ERROR use of a blacklisted/placeholder name `tata`
let titi = 42; //~ERROR use of a blacklisted/placeholder name `titi`
let tatab = 42;
let tatatataic = 42;
match (42, Some(1337), Some(0)) {
(toto, Some(tata), titi @ Some(_)) => (),
//~^ ERROR use of a blacklisted/placeholder name `toto`
//~| ERROR use of a blacklisted/placeholder name `tata`
//~| ERROR use of a blacklisted/placeholder name `titi`
_ => (),
}
}

View File

@ -1,60 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(drop_ref, forget_ref)]
#![allow(toplevel_ref_arg, similar_names)]
use std::mem::{drop, forget};
struct SomeStruct;
fn main() {
drop(&SomeStruct); //~ERROR call to `std::mem::drop` with a reference argument
forget(&SomeStruct); //~ERROR call to `std::mem::forget` with a reference argument
let mut owned1 = SomeStruct;
drop(&owned1); //~ERROR call to `std::mem::drop` with a reference argument
drop(&&owned1); //~ERROR call to `std::mem::drop` with a reference argument
drop(&mut owned1); //~ERROR call to `std::mem::drop` with a reference argument
drop(owned1); //OK
let mut owned2 = SomeStruct;
forget(&owned2); //~ERROR call to `std::mem::forget` with a reference argument
forget(&&owned2); //~ERROR call to `std::mem::forget` with a reference argument
forget(&mut owned2); //~ERROR call to `std::mem::forget` with a reference argument
forget(owned2); //OK
let reference1 = &SomeStruct;
drop(reference1); //~ERROR call to `std::mem::drop` with a reference argument
forget(&*reference1); //~ERROR call to `std::mem::forget` with a reference argument
let reference2 = &mut SomeStruct;
drop(reference2); //~ERROR call to `std::mem::drop` with a reference argument
let reference3 = &mut SomeStruct;
forget(reference3); //~ERROR call to `std::mem::forget` with a reference argument
let ref reference4 = SomeStruct;
drop(reference4); //~ERROR call to `std::mem::drop` with a reference argument
forget(reference4); //~ERROR call to `std::mem::forget` with a reference argument
}
#[allow(dead_code)]
fn test_generic_fn_drop<T>(val: T) {
drop(&val); //~ERROR call to `std::mem::drop` with a reference argument
drop(val); //OK
}
#[allow(dead_code)]
fn test_generic_fn_forget<T>(val: T) {
forget(&val); //~ERROR call to `std::mem::forget` with a reference argument
forget(val); //OK
}
#[allow(dead_code)]
fn test_similarly_named_function() {
fn drop<T>(_val: T) {}
drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name
std::mem::drop(&SomeStruct); //~ERROR call to `std::mem::drop` with a reference argument
fn forget<T>(_val: T) {}
forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name
std::mem::forget(&SomeStruct); //~ERROR call to `std::mem::forget` with a reference argument
}

View File

@ -1,11 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(dead_code)]
#![deny(empty_enum)]
enum Empty {} //~ ERROR enum with no variants
//~^ HELP consider using the uninhabited type `!` or a wrapper around it
fn main() {
}

View File

@ -1,54 +0,0 @@
// ignore-x86
#![feature(plugin, associated_consts)]
#![plugin(clippy)]
#![deny(clippy)]
#![allow(unused)]
#[repr(usize)]
enum NonPortable {
X = 0x1_0000_0000, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
Y = 0,
Z = 0x7FFF_FFFF,
A = 0xFFFF_FFFF,
}
enum NonPortableNoHint {
X = 0x1_0000_0000, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
Y = 0,
Z = 0x7FFF_FFFF,
A = 0xFFFF_FFFF, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
}
#[repr(isize)]
enum NonPortableSigned {
X = -1,
Y = 0x7FFF_FFFF,
Z = 0xFFFF_FFFF, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
A = 0x1_0000_0000, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
B = std::i32::MIN as isize,
C = (std::i32::MIN as isize) - 1, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
}
enum NonPortableSignedNoHint {
X = -1,
Y = 0x7FFF_FFFF,
Z = 0xFFFF_FFFF, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
A = 0x1_0000_0000, //~ ERROR: Clike enum variant discriminant is not portable to 32-bit targets
}
/*
FIXME: uncomment once https://github.com/rust-lang/rust/issues/31910 is fixed
#[repr(usize)]
enum NonPortable2<T: Trait> {
X = Trait::Number,
Y = 0,
}
trait Trait {
const Number: usize = 0x1_0000_0000;
}
*/
fn main() {
}

View File

@ -1,62 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(eq_op)]
#[allow(identity_op, double_parens)]
#[allow(no_effect, unused_variables, unnecessary_operation, short_circuit_statement)]
#[deny(nonminimal_bool)]
fn main() {
// simple values and comparisons
1 == 1; //~ERROR equal expressions
"no" == "no"; //~ERROR equal expressions
// even though I agree that no means no ;-)
false != false; //~ERROR equal expressions
1.5 < 1.5; //~ERROR equal expressions
1u64 >= 1u64; //~ERROR equal expressions
// casts, methods, parentheses
(1 as u64) & (1 as u64); //~ERROR equal expressions
1 ^ ((((((1)))))); //~ERROR equal expressions
// unary and binary operators
(-(2) < -(2)); //~ERROR equal expressions
((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
//~^ ERROR equal expressions as operands to `==`
//~^^ ERROR equal expressions as operands to `&`
//~^^^ ERROR equal expressions as operands to `&`
(1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; //~ERROR equal expressions
// various other things
([1] != [1]); //~ERROR equal expressions
((1, 2) != (1, 2)); //~ERROR equal expressions
vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros
// const folding
1 + 1 == 2; //~ERROR equal expressions
1 - 1 == 0; //~ERROR equal expressions as operands to `==`
//~^ ERROR equal expressions as operands to `-`
1 - 1; //~ERROR equal expressions
1 / 1; //~ERROR equal expressions
true && true; //~ERROR equal expressions
//~|ERROR this boolean expression can be simplified
true || true; //~ERROR equal expressions
//~|ERROR this boolean expression can be simplified
let a: u32 = 0;
let b: u32 = 0;
a == b && b == a; //~ERROR equal expressions
//~|ERROR this boolean expression can be simplified
a != b && b != a; //~ERROR equal expressions
//~|ERROR this boolean expression can be simplified
a < b && b > a; //~ERROR equal expressions
//~|ERROR this boolean expression can be simplified
a <= b && b >= a; //~ERROR equal expressions
//~|ERROR this boolean expression can be simplified
let mut a = vec![1];
a == a; //~ERROR equal expressions
2*a.len() == 2*a.len(); // ok, functions
a.pop() == a.pop(); // ok, functions
}

View File

@ -1,53 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy)]
#![deny(if_let_redundant_pattern_matching)]
fn main() {
if let Ok(_) = Ok::<i32, i32>(42) {}
//~^ERROR redundant pattern matching, consider using `is_ok()`
//~| HELP try this
//~| SUGGESTION if Ok::<i32, i32>(42).is_ok() {
if let Err(_) = Err::<i32, i32>(42) {
//~^ERROR redundant pattern matching, consider using `is_err()`
//~| HELP try this
//~| SUGGESTION if Err::<i32, i32>(42).is_err() {
}
if let None = None::<()> {
//~^ERROR redundant pattern matching, consider using `is_none()`
//~| HELP try this
//~| SUGGESTION if None::<()>.is_none() {
}
if let Some(_) = Some(42) {
//~^ERROR redundant pattern matching, consider using `is_some()`
//~| HELP try this
//~| SUGGESTION if Some(42).is_some() {
}
if Ok::<i32, i32>(42).is_ok() {
}
if Err::<i32, i32>(42).is_err() {
}
if None::<i32>.is_none() {
}
if Some(42).is_some() {
}
if let Ok(x) = Ok::<i32,i32>(42) {
println!("{}", x);
}
}

View File

@ -1,35 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(invalid_upcast_comparisons)]
#![allow(unused, eq_op, no_effect, unnecessary_operation)]
fn main() {
let zero: u32 = 0;
let u8_max: u8 = 255;
(u8_max as u32) > 300; //~ERROR because of the numeric bounds on `u8_max` prior to casting, this expression is always false
(u8_max as u32) > 20;
(zero as i32) < -5; //~ERROR because of the numeric bounds on `zero` prior to casting, this expression is always false
(zero as i32) < 10;
-5 < (zero as i32); //~ERROR because of the numeric bounds on `zero` prior to casting, this expression is always true
0 <= (zero as i32); //~ERROR because of the numeric bounds on `zero` prior to casting, this expression is always true
0 < (zero as i32);
-5 > (zero as i32); //~ERROR because of the numeric bounds on `zero` prior to casting, this expression is always false
-5 >= (u8_max as i32); //~ERROR because of the numeric bounds on `u8_max` prior to casting, this expression is always false
1337 == (u8_max as i32); //~ERROR because of the numeric bounds on `u8_max` prior to casting, this expression is always false
-5 == (zero as i32); //~ERROR because of the numeric bounds on `zero` prior to casting, this expression is always false
-5 != (u8_max as i32); //~ERROR because of the numeric bounds on `u8_max` prior to casting, this expression is always true
// Those are Ok:
42 == (u8_max as i32);
42 != (u8_max as i32);
42 > (u8_max as i32);
(u8_max as i32) == 42;
(u8_max as i32) != 42;
(u8_max as i32) > 42;
(u8_max as i32) < 42;
}

View File

@ -1,53 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(dead_code)]
#![allow(unused_variables)]
#![deny(large_enum_variant)]
enum LargeEnum {
A(i32),
B([i32; 8000]), //~ ERROR large enum variant found
//~^ HELP consider boxing the large fields to reduce the total size of the enum
//~| SUGGESTION Box<[i32; 8000]>
}
enum GenericEnum<T> {
A(i32),
B([i32; 8000]), //~ ERROR large enum variant found
//~^ HELP consider boxing the large fields to reduce the total size of the enum
//~| SUGGESTION Box<[i32; 8000]>
C([T; 8000]),
D(T, [i32; 8000]), //~ ERROR large enum variant found
//~^ HELP consider boxing the large fields to reduce the total size of the enum
}
trait SomeTrait {
type Item;
}
enum LargeEnumGeneric<A: SomeTrait> {
Var(A::Item), // regression test, this used to ICE
}
enum AnotherLargeEnum {
VariantOk(i32, u32),
ContainingLargeEnum(LargeEnum), //~ ERROR large enum variant found
//~^ HELP consider boxing the large fields to reduce the total size of the enum
//~| SUGGESTION Box<LargeEnum>
ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), //~ ERROR large enum variant found
//~^ HELP consider boxing the large fields to reduce the total size of the enum
VoidVariant,
StructLikeLittle { x: i32, y: i32 },
StructLikeLarge { x: [i32; 8000], y: i32 }, //~ ERROR large enum variant found
//~^ HELP consider boxing the large fields to reduce the total size of the enum
StructLikeLarge2 { //~ ERROR large enum variant found
x:
[i32; 8000] //~ SUGGESTION Box<[i32; 8000]>
//~^ HELP consider boxing the large fields to reduce the total size of the enum
},
}
fn main() {
}

View File

@ -1,38 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(mixed_case_hex_literals)]
#![deny(unseparated_literal_suffix)]
#![deny(zero_prefixed_literal)]
#![allow(dead_code)]
fn main() {
let ok1 = 0xABCD;
let ok3 = 0xab_cd;
let ok4 = 0xab_cd_i32;
let ok5 = 0xAB_CD_u32;
let ok5 = 0xAB_CD_isize;
let fail1 = 0xabCD; //~ERROR inconsistent casing in hexadecimal literal
let fail2 = 0xabCD_u32; //~ERROR inconsistent casing in hexadecimal literal
let fail2 = 0xabCD_isize; //~ERROR inconsistent casing in hexadecimal literal
let ok6 = 1234_i32;
let ok7 = 1234_f32;
let ok8 = 1234_isize;
let fail3 = 1234i32; //~ERROR integer type suffix should be separated
let fail4 = 1234u32; //~ERROR integer type suffix should be separated
let fail5 = 1234isize; //~ERROR integer type suffix should be separated
let fail6 = 1234usize; //~ERROR integer type suffix should be separated
let fail7 = 1.5f32; //~ERROR float type suffix should be separated
let ok9 = 0;
let ok10 = 0_i64;
let fail8 = 0123;
//~^ERROR decimal constant
//~|HELP remove the `0`
//~|SUGGESTION = 123;
//~|HELP use `0o`
//~|SUGGESTION = 0o123;
let ok11 = 0o123;
let ok12 = 0b101010;
}

View File

@ -15,21 +15,19 @@ use std::iter::FromIterator;
struct T;
impl T {
fn add(self, other: T) -> T { self } //~ERROR defining a method called `add`
fn drop(&mut self) { } //~ERROR defining a method called `drop`
fn add(self, other: T) -> T { self }
fn drop(&mut self) { }
fn sub(&self, other: T) -> &T { self } // no error, self is a ref
fn div(self) -> T { self } // no error, different #arguments
fn rem(self, other: T) { } // no error, wrong return type
fn into_u32(self) -> u32 { 0 } // fine
fn into_u16(&self) -> u16 { 0 } //~ERROR methods called `into_*` usually take self by value
fn into_u16(&self) -> u16 { 0 }
fn to_something(self) -> u32 { 0 } //~ERROR methods called `to_*` usually take self by reference
fn to_something(self) -> u32 { 0 }
fn new(self) {}
//~^ ERROR methods called `new` usually take no self
//~| ERROR methods called `new` usually return `Self`
}
struct Lt<'a> {
@ -96,15 +94,15 @@ fn option_methods() {
// Check OPTION_MAP_UNWRAP_OR
// single line case
let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or(a)`
//~| NOTE replace `map(|x| x + 1).unwrap_or(0)`
let _ = opt.map(|x| x + 1)
.unwrap_or(0); // should lint even though this call is on a separate line
// multi line cases
let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or(a)`
let _ = opt.map(|x| {
x + 1
}
).unwrap_or(0);
let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or(a)`
let _ = opt.map(|x| x + 1)
.unwrap_or({
0
});
@ -113,15 +111,15 @@ fn option_methods() {
// Check OPTION_MAP_UNWRAP_OR_ELSE
// single line case
let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or_else(g)`
//~| NOTE replace `map(|x| x + 1).unwrap_or_else(|| 0)`
let _ = opt.map(|x| x + 1)
.unwrap_or_else(|| 0); // should lint even though this call is on a separate line
// multi line cases
let _ = opt.map(|x| { //~ ERROR called `map(f).unwrap_or_else(g)`
let _ = opt.map(|x| {
x + 1
}
).unwrap_or_else(|| 0);
let _ = opt.map(|x| x + 1) //~ ERROR called `map(f).unwrap_or_else(g)`
let _ = opt.map(|x| x + 1)
.unwrap_or_else(||
0
);
@ -194,11 +192,11 @@ fn filter_next() {
// check single-line case
let _ = v.iter().filter(|&x| *x < 0).next();
//~^ ERROR called `filter(p).next()` on an `Iterator`.
//~| NOTE replace `filter(|&x| *x < 0).next()`
// check multi-line case
let _ = v.iter().filter(|&x| { //~ERROR called `filter(p).next()` on an `Iterator`.
let _ = v.iter().filter(|&x| {
*x < 0
}
).next();
@ -214,33 +212,33 @@ fn search_is_some() {
// check `find().is_some()`, single-line
let _ = v.iter().find(|&x| *x < 0).is_some();
//~^ ERROR called `is_some()` after searching
//~| NOTE replace `find(|&x| *x < 0).is_some()`
// check `find().is_some()`, multi-line
let _ = v.iter().find(|&x| { //~ERROR called `is_some()` after searching
let _ = v.iter().find(|&x| {
*x < 0
}
).is_some();
// check `position().is_some()`, single-line
let _ = v.iter().position(|&x| x < 0).is_some();
//~^ ERROR called `is_some()` after searching
//~| NOTE replace `position(|&x| x < 0).is_some()`
// check `position().is_some()`, multi-line
let _ = v.iter().position(|&x| { //~ERROR called `is_some()` after searching
let _ = v.iter().position(|&x| {
x < 0
}
).is_some();
// check `rposition().is_some()`, single-line
let _ = v.iter().rposition(|&x| x < 0).is_some();
//~^ ERROR called `is_some()` after searching
//~| NOTE replace `rposition(|&x| x < 0).is_some()`
// check `rposition().is_some()`, multi-line
let _ = v.iter().rposition(|&x| { //~ERROR called `is_some()` after searching
let _ = v.iter().rposition(|&x| {
x < 0
}
).is_some();
@ -276,75 +274,75 @@ fn or_fun_call() {
let with_constructor = Some(vec![1]);
with_constructor.unwrap_or(make());
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION with_constructor.unwrap_or_else(make)
let with_new = Some(vec![1]);
with_new.unwrap_or(Vec::new());
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION with_new.unwrap_or_default();
let with_const_args = Some(vec![1]);
with_const_args.unwrap_or(Vec::with_capacity(12));
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION with_const_args.unwrap_or_else(|| Vec::with_capacity(12));
let with_err : Result<_, ()> = Ok(vec![1]);
with_err.unwrap_or(make());
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION with_err.unwrap_or_else(|_| make());
let with_err_args : Result<_, ()> = Ok(vec![1]);
with_err_args.unwrap_or(Vec::with_capacity(12));
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION with_err_args.unwrap_or_else(|_| Vec::with_capacity(12));
let with_default_trait = Some(1);
with_default_trait.unwrap_or(Default::default());
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION with_default_trait.unwrap_or_default();
let with_default_type = Some(1);
with_default_type.unwrap_or(u64::default());
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION with_default_type.unwrap_or_default();
let with_vec = Some(vec![1]);
with_vec.unwrap_or(vec![]);
//~^ERROR use of `unwrap_or`
//~|HELP try this
// FIXME #944: ~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);
let without_default = Some(Foo);
without_default.unwrap_or(Foo::new());
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION without_default.unwrap_or_else(Foo::new);
let mut map = HashMap::<u64, String>::new();
map.entry(42).or_insert(String::new());
//~^ERROR use of `or_insert` followed by a function call
//~|HELP try this
//~|SUGGESTION map.entry(42).or_insert_with(String::new);
let mut btree = BTreeMap::<u64, String>::new();
btree.entry(42).or_insert(String::new());
//~^ERROR use of `or_insert` followed by a function call
//~|HELP try this
//~|SUGGESTION btree.entry(42).or_insert_with(String::new);
let stringy = Some(String::from(""));
let _ = stringy.unwrap_or("".to_owned());
//~^ERROR use of `unwrap_or`
//~|HELP try this
//~|SUGGESTION stringy.unwrap_or_else(|| "".to_owned());
}
/// Checks implementation of `ITER_NTH` lint
@ -356,27 +354,27 @@ fn iter_nth() {
{
// Make sure we lint `.iter()` for relevant types
let bad_vec = some_vec.iter().nth(3);
//~^ERROR called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more readable
let bad_slice = &some_vec[..].iter().nth(3);
//~^ERROR called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
let bad_boxed_slice = boxed_slice.iter().nth(3);
//~^ERROR called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
let bad_vec_deque = some_vec_deque.iter().nth(3);
//~^ERROR called `.iter().nth()` on a VecDeque. Calling `.get()` is both faster and more readable
}
{
// Make sure we lint `.iter_mut()` for relevant types
let bad_vec = some_vec.iter_mut().nth(3);
//~^ERROR called `.iter_mut().nth()` on a Vec. Calling `.get_mut()` is both faster and more readable
}
{
let bad_slice = &some_vec[..].iter_mut().nth(3);
//~^ERROR called `.iter_mut().nth()` on a slice. Calling `.get_mut()` is both faster and more readable
}
{
let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
//~^ERROR called `.iter_mut().nth()` on a VecDeque. Calling `.get_mut()` is both faster and more readable
}
// Make sure we don't lint for non-relevant types
@ -390,16 +388,16 @@ fn iter_skip_next() {
let mut some_vec = vec![0, 1, 2, 3];
let _ = some_vec.iter().skip(42).next();
//~^ERROR called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
let _ = some_vec.iter().cycle().skip(42).next();
//~^ERROR called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
let _ = (1..10).skip(10).next();
//~^ERROR called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
let _ = &some_vec[..].iter().skip(3).next();
//~^ERROR called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
let foo = IteratorFalsePositives { foo : 0 };
let _ = foo.skip(42).next();
@ -427,50 +425,50 @@ fn get_unwrap() {
{ // Test `get().unwrap()`
let _ = boxed_slice.get(1).unwrap();
//~^ERROR called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION boxed_slice[1]
let _ = some_slice.get(0).unwrap();
//~^ERROR called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION some_slice[0]
let _ = some_vec.get(0).unwrap();
//~^ERROR called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION some_vec[0]
let _ = some_vecdeque.get(0).unwrap();
//~^ERROR called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION some_vecdeque[0]
let _ = some_hashmap.get(&1).unwrap();
//~^ERROR called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION some_hashmap[&1]
let _ = some_btreemap.get(&1).unwrap();
//~^ERROR called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION some_btreemap[&1]
let _ = false_positive.get(0).unwrap();
}
{ // Test `get_mut().unwrap()`
*boxed_slice.get_mut(0).unwrap() = 1;
//~^ERROR called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION &mut boxed_slice[0]
*some_slice.get_mut(0).unwrap() = 1;
//~^ERROR called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION &mut some_slice[0]
*some_vec.get_mut(0).unwrap() = 1;
//~^ERROR called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION &mut some_vec[0]
*some_vecdeque.get_mut(0).unwrap() = 1;
//~^ERROR called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
//~|HELP try this
//~|SUGGESTION &mut some_vecdeque[0]
// Check false positives
*some_hashmap.get_mut(&1).unwrap() = 'b';
@ -485,24 +483,24 @@ fn main() {
use std::io;
let opt = Some(0);
let _ = opt.unwrap(); //~ERROR used unwrap() on an Option
let _ = opt.unwrap();
let res: Result<i32, ()> = Ok(0);
let _ = res.unwrap(); //~ERROR used unwrap() on a Result
let _ = res.unwrap();
res.ok().expect("disaster!"); //~ERROR called `ok().expect()`
res.ok().expect("disaster!");
// the following should not warn, since `expect` isn't implemented unless
// the error type implements `Debug`
let res2: Result<i32, MyError> = Ok(0);
res2.ok().expect("oh noes!");
let res3: Result<u32, MyErrorWithParam<u8>>= Ok(0);
res3.ok().expect("whoof"); //~ERROR called `ok().expect()`
res3.ok().expect("whoof");
let res4: Result<u32, io::Error> = Ok(0);
res4.ok().expect("argh"); //~ERROR called `ok().expect()`
res4.ok().expect("argh");
let res5: io::Result<u32> = Ok(0);
res5.ok().expect("oops"); //~ERROR called `ok().expect()`
res5.ok().expect("oops");
let res6: Result<u32, &str> = Ok(0);
res6.ok().expect("meh"); //~ERROR called `ok().expect()`
res6.ok().expect("meh");
}
struct MyError(()); // doesn't implement Debug
@ -515,14 +513,14 @@ struct MyErrorWithParam<T> {
#[allow(unnecessary_operation)]
fn starts_with() {
"".chars().next() == Some(' ');
//~^ ERROR starts_with
//~| HELP like this
//~| SUGGESTION "".starts_with(' ')
Some(' ') != "".chars().next();
//~^ ERROR starts_with
//~| HELP like this
//~| SUGGESTION !"".starts_with(' ')
}
fn str_extend_chars() {
@ -532,21 +530,21 @@ fn str_extend_chars() {
s.push_str(abc);
s.extend(abc.chars());
//~^ERROR calling `.extend(_.chars())`
//~|HELP try this
//~|SUGGESTION s.push_str(abc)
s.push_str("abc");
s.extend("abc".chars());
//~^ERROR calling `.extend(_.chars())`
//~|HELP try this
//~|SUGGESTION s.push_str("abc")
s.push_str(&def);
s.extend(def.chars());
//~^ERROR calling `.extend(_.chars())`
//~|HELP try this
//~|SUGGESTION s.push_str(&def)
s.extend(abc.chars().skip(1));
s.extend("abc".chars().skip(1));
@ -557,40 +555,40 @@ fn str_extend_chars() {
}
fn clone_on_copy() {
42.clone(); //~ERROR using `clone` on a `Copy` type
//~| HELP try removing the `clone` call
//~| SUGGESTION 42
42.clone();
vec![1].clone(); // ok, not a Copy type
Some(vec![1]).clone(); // ok, not a Copy type
(&42).clone(); //~ERROR using `clone` on a `Copy` type
//~| HELP try dereferencing it
//~| SUGGESTION *(&42)
(&42).clone();
}
fn clone_on_copy_generic<T: Copy>(t: T) {
t.clone(); //~ERROR using `clone` on a `Copy` type
//~| HELP try removing the `clone` call
//~| SUGGESTION t
Some(t).clone(); //~ERROR using `clone` on a `Copy` type
//~| HELP try removing the `clone` call
//~| SUGGESTION Some(t)
t.clone();
Some(t).clone();
}
fn clone_on_double_ref() {
let x = vec![1];
let y = &&x;
let z: &Vec<_> = y.clone(); //~ERROR using `clone` on a double
//~| HELP try dereferencing it
//~| SUGGESTION let z: &Vec<_> = (*y).clone();
let z: &Vec<_> = y.clone();
println!("{:p} {:p}",*y, z);
}
fn single_char_pattern() {
let x = "foo";
x.split("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.split('x');
x.split("xx");
@ -612,69 +610,69 @@ fn single_char_pattern() {
x.split("❤️");
x.contains("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.contains('x');
x.starts_with("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.starts_with('x');
x.ends_with("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.ends_with('x');
x.find("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.find('x');
x.rfind("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.rfind('x');
x.rsplit("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.rsplit('x');
x.split_terminator("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.split_terminator('x');
x.rsplit_terminator("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.rsplit_terminator('x');
x.splitn(0, "x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.splitn(0, 'x');
x.rsplitn(0, "x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.rsplitn(0, 'x');
x.matches("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.matches('x');
x.rmatches("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.rmatches('x');
x.match_indices("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.match_indices('x');
x.rmatch_indices("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.rmatch_indices('x');
x.trim_left_matches("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.trim_left_matches('x');
x.trim_right_matches("x");
//~^ ERROR single-character string constant used as pattern
//~| HELP try using a char instead:
//~| SUGGESTION x.trim_right_matches('x');
let h = HashSet::<String>::new();
h.contains("X"); // should not warn
@ -685,7 +683,7 @@ fn temporary_cstring() {
use std::ffi::CString;
CString::new("foo").unwrap().as_ptr();
//~^ ERROR you are getting the inner pointer of a temporary `CString`
//~| NOTE that pointer will be invalid outside this expression
//~| HELP assign the `CString` to a variable to extend its lifetime
}

View File

@ -1,33 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy)]
use std::cmp::{min, max};
use std::cmp::min as my_min;
use std::cmp::max as my_max;
const LARGE : usize = 3;
fn main() {
let x;
x = 2usize;
min(1, max(3, x)); //~ERROR this min/max combination leads to constant result
min(max(3, x), 1); //~ERROR this min/max combination leads to constant result
max(min(x, 1), 3); //~ERROR this min/max combination leads to constant result
max(3, min(x, 1)); //~ERROR this min/max combination leads to constant result
my_max(3, my_min(x, 1)); //~ERROR this min/max combination leads to constant result
min(3, max(1, x)); // ok, could be 1, 2 or 3 depending on x
min(1, max(LARGE, x)); // no error, we don't lookup consts here
let s;
s = "Hello";
min("Apple", max("Zoo", s)); //~ERROR this min/max combination leads to constant result
max(min(s, "Apple"), "Zoo"); //~ERROR this min/max combination leads to constant result
max("Apple", min(s, "Zoo")); // ok
}

View File

@ -1,64 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(unused, no_effect, unnecessary_operation)]
#![deny(mut_mut)]
//#![plugin(regex_macros)]
//extern crate regex;
fn fun(x : &mut &mut u32) -> bool { //~ERROR generally you want to avoid `&mut &mut
**x > 0
}
fn less_fun(x : *mut *mut u32) {
let y = x;
}
macro_rules! mut_ptr {
($p:expr) => { &mut $p }
//~^ ERROR generally you want to avoid `&mut &mut
}
#[allow(unused_mut, unused_variables)]
fn main() {
let mut x = &mut &mut 1u32; //~ERROR generally you want to avoid `&mut &mut
{
let mut y = &mut x; //~ERROR this expression mutably borrows a mutable reference
}
if fun(x) {
let y : &mut &mut u32 = &mut &mut 2;
//~^ ERROR generally you want to avoid `&mut &mut
//~| ERROR generally you want to avoid `&mut &mut
//~| ERROR generally you want to avoid `&mut &mut
**y + **x;
}
if fun(x) {
let y : &mut &mut &mut u32 = &mut &mut &mut 2;
//~^ ERROR generally you want to avoid `&mut &mut
//~| ERROR generally you want to avoid `&mut &mut
//~| ERROR generally you want to avoid `&mut &mut
//~| ERROR generally you want to avoid `&mut &mut
//~| ERROR generally you want to avoid `&mut &mut
//~| ERROR generally you want to avoid `&mut &mut
***y + **x;
}
let mut z = mut_ptr!(&mut 3u32);
//~^ NOTE in this expansion of mut_ptr!
}
fn issue939() {
let array = [5, 6, 7, 8, 9];
let mut args = array.iter().skip(2);
for &arg in &mut args {
println!("{}", arg);
}
let args = &mut args;
for arg in args {
println!(":{}", arg);
}
}

View File

@ -1,18 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy)]
#![deny(mutex_integer)]
fn main() {
use std::sync::Mutex;
Mutex::new(true); //~ERROR Consider using an AtomicBool instead of a Mutex here.
Mutex::new(5usize); //~ERROR Consider using an AtomicUsize instead of a Mutex here.
Mutex::new(9isize); //~ERROR Consider using an AtomicIsize instead of a Mutex here.
let mut x = 4u32;
Mutex::new(&x as *const u32); //~ERROR Consider using an AtomicPtr instead of a Mutex here.
Mutex::new(&mut x as *mut u32); //~ERROR Consider using an AtomicPtr instead of a Mutex here.
Mutex::new(0u32); //~ERROR Consider using an AtomicUsize instead of a Mutex here.
Mutex::new(0i32); //~ERROR Consider using an AtomicIsize instead of a Mutex here.
Mutex::new(0f32); // there are no float atomics, so this should not lint
}

View File

@ -1,74 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(needless_bool)]
#[allow(if_same_then_else)]
fn main() {
let x = true;
let y = false;
if x { true } else { true }; //~ERROR this if-then-else expression will always return true
if x { false } else { false }; //~ERROR this if-then-else expression will always return false
if x { true } else { false };
//~^ ERROR this if-then-else expression returns a bool literal
//~| HELP you can reduce it to
//~| SUGGESTION x
if x { false } else { true };
//~^ ERROR this if-then-else expression returns a bool literal
//~| HELP you can reduce it to
//~| SUGGESTION !x
if x && y { false } else { true };
//~^ ERROR this if-then-else expression returns a bool literal
//~| HELP you can reduce it to
//~| SUGGESTION !(x && y)
if x { x } else { false }; // would also be questionable, but we don't catch this yet
bool_ret(x);
bool_ret2(x);
bool_ret3(x);
bool_ret5(x, x);
bool_ret4(x);
bool_ret6(x, x);
}
#[allow(if_same_then_else, needless_return)]
fn bool_ret(x: bool) -> bool {
if x { return true } else { return true };
//~^ ERROR this if-then-else expression will always return true
}
#[allow(if_same_then_else, needless_return)]
fn bool_ret2(x: bool) -> bool {
if x { return false } else { return false };
//~^ ERROR this if-then-else expression will always return false
}
#[allow(needless_return)]
fn bool_ret3(x: bool) -> bool {
if x { return true } else { return false };
//~^ ERROR this if-then-else expression returns a bool literal
//~| HELP you can reduce it to
//~| SUGGESTION return x
}
#[allow(needless_return)]
fn bool_ret5(x: bool, y: bool) -> bool {
if x && y { return true } else { return false };
//~^ ERROR this if-then-else expression returns a bool literal
//~| HELP you can reduce it to
//~| SUGGESTION return x && y
}
#[allow(needless_return)]
fn bool_ret4(x: bool) -> bool {
if x { return false } else { return true };
//~^ ERROR this if-then-else expression returns a bool literal
//~| HELP you can reduce it to
//~| SUGGESTION return !x
}
#[allow(needless_return)]
fn bool_ret6(x: bool, y: bool) -> bool {
if x && y { return false } else { return true };
//~^ ERROR this if-then-else expression returns a bool literal
//~| HELP you can reduce it to
//~| SUGGESTION return !(x && y)
}

View File

@ -1,73 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(needless_return)]
fn test_end_of_fn() -> bool {
if true {
// no error!
return true;
}
return true;
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION true
}
fn test_no_semicolon() -> bool {
return true
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION true
}
fn test_if_block() -> bool {
if true {
return true;
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION true
} else {
return false;
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION false
}
}
fn test_match(x: bool) -> bool {
match x {
true => return false,
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION false
false => {
return true;
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION true
}
}
}
fn test_closure() {
let _ = || {
return true;
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION true
};
let _ = || return true;
//~^ ERROR unneeded return statement
//~| HELP remove `return` as shown
//~| SUGGESTION true
}
fn main() {
let _ = test_end_of_fn();
let _ = test_no_semicolon();
let _ = test_if_block();
let _ = test_match(true);
test_closure();
}

View File

@ -1,122 +0,0 @@
#![feature(plugin, box_syntax, inclusive_range_syntax)]
#![plugin(clippy)]
#![deny(no_effect, unnecessary_operation)]
#![allow(dead_code)]
#![allow(path_statements)]
#![allow(deref_addrof)]
#![feature(untagged_unions)]
struct Unit;
struct Tuple(i32);
struct Struct {
field: i32
}
enum Enum {
Tuple(i32),
Struct { field: i32 },
}
union Union {
a: u8,
b: f64,
}
fn get_number() -> i32 { 0 }
fn get_struct() -> Struct { Struct { field: 0 } }
unsafe fn unsafe_fn() -> i32 { 0 }
fn main() {
let s = get_struct();
let s2 = get_struct();
0; //~ERROR statement with no effect
s2; //~ERROR statement with no effect
Unit; //~ERROR statement with no effect
Tuple(0); //~ERROR statement with no effect
Struct { field: 0 }; //~ERROR statement with no effect
Struct { ..s }; //~ERROR statement with no effect
Union { a: 0 }; //~ERROR statement with no effect
Enum::Tuple(0); //~ERROR statement with no effect
Enum::Struct { field: 0 }; //~ERROR statement with no effect
5 + 6; //~ERROR statement with no effect
*&42; //~ERROR statement with no effect
&6; //~ERROR statement with no effect
(5, 6, 7); //~ERROR statement with no effect
box 42; //~ERROR statement with no effect
..; //~ERROR statement with no effect
5..; //~ERROR statement with no effect
..5; //~ERROR statement with no effect
5..6; //~ERROR statement with no effect
5...6; //~ERROR statement with no effect
[42, 55]; //~ERROR statement with no effect
[42, 55][1]; //~ERROR statement with no effect
(42, 55).1; //~ERROR statement with no effect
[42; 55]; //~ERROR statement with no effect
[42; 55][13]; //~ERROR statement with no effect
let mut x = 0;
|| x += 5; //~ERROR statement with no effect
// Do not warn
get_number();
unsafe { unsafe_fn() };
Tuple(get_number()); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
Struct { field: get_number() }; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
Struct { ..get_struct() }; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_struct();
Enum::Tuple(get_number()); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
Enum::Struct { field: get_number() }; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
5 + get_number(); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION 5;get_number();
*&get_number(); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
&get_number(); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
(5, 6, get_number()); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION 5;6;get_number();
box get_number(); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
get_number()..; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
..get_number(); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
5..get_number(); //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION 5;get_number();
[42, get_number()]; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION 42;get_number();
[42, 55][get_number() as usize]; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION [42, 55];get_number() as usize;
(42, get_number()).1; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION 42;get_number();
[get_number(); 55]; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
[42; 55][get_number() as usize]; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION [42; 55];get_number() as usize;
{get_number()}; //~ERROR statement can be reduced
//~^HELP replace it with
//~|SUGGESTION get_number();
}

View File

@ -1,17 +1,17 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy,similar_names)]
//~^ NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
//~| NOTE: lint level defined here
#![allow(unused)]
@ -24,12 +24,12 @@ fn main() {
let specter: i32;
let spectre: i32;
let apple: i32; //~ NOTE: existing binding defined here
//~^ NOTE: existing binding defined here
let bpple: i32; //~ ERROR: name is too similar
//~| HELP: separate the discriminating character by an underscore like: `b_pple`
let cpple: i32; //~ ERROR: name is too similar
//~| HELP: separate the discriminating character by an underscore like: `c_pple`
let apple: i32;
let bpple: i32;
let cpple: i32;
let a_bar: i32;
let b_bar: i32;
@ -52,13 +52,13 @@ fn main() {
let blubrhs: i32;
let blublhs: i32;
let blubx: i32; //~ NOTE: existing binding defined here
let bluby: i32; //~ ERROR: name is too similar
//~| HELP: separate the discriminating character by an underscore like: `blub_y`
let blubx: i32;
let bluby: i32;
let cake: i32; //~ NOTE: existing binding defined here
let cake: i32;
let cakes: i32;
let coke: i32; //~ ERROR: name is too similar
let coke: i32;
match 5 {
cheese @ 1 => {},
@ -74,14 +74,14 @@ fn main() {
let ipv6: i32;
let abcd1: i32;
let abdc2: i32;
let xyz1abc: i32; //~ NOTE: existing binding defined here
let xyz1abc: i32;
let xyz2abc: i32;
let xyzeabc: i32; //~ ERROR: name is too similar
let xyzeabc: i32;
let parser: i32; //~ NOTE: existing binding defined here
let parser: i32;
let parsed: i32;
let parsee: i32; //~ ERROR: name is too similar
//~| HELP: separate the discriminating character by an underscore like: `parse_e`
let parsee: i32;
let setter: i32;
let getter: i32;
@ -93,8 +93,8 @@ fn main() {
fn foo() {
let Foo { apple, bpple } = unimplemented!();
let Foo { apple: spring, //~NOTE existing binding defined here
bpple: sprang } = unimplemented!(); //~ ERROR: name is too similar
let Foo { apple: spring,
bpple: sprang } = unimplemented!();
}
#[derive(Clone, Debug)]
@ -128,15 +128,19 @@ fn bla() {
let blar: i32;
}
{
let e: i32; //~ ERROR: 5th binding whose name is just one char
let e: i32;
}
{
let e: i32; //~ ERROR: 5th binding whose name is just one char
let f: i32; //~ ERROR: 6th binding whose name is just one char
let e: i32;
let f: i32;
}
match 5 {
1 => println!(""),
e => panic!(), //~ ERROR: 5th binding whose name is just one char
e => panic!(),
}
match 5 {
1 => println!(""),

View File

@ -1,61 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(many_single_char_names)]
#![deny(overflow_check_conditional)]
fn main() {
let a: u32 = 1;
let b: u32 = 2;
let c: u32 = 3;
if a + b < a { //~ERROR You are trying to use classic C overflow conditions that will fail in Rust.
}
if a > a + b { //~ERROR You are trying to use classic C overflow conditions that will fail in Rust.
}
if a + b < b { //~ERROR You are trying to use classic C overflow conditions that will fail in Rust.
}
if b > a + b { //~ERROR You are trying to use classic C overflow conditions that will fail in Rust.
}
if a - b > b { //~ERROR You are trying to use classic C underflow conditions that will fail in Rust.
}
if b < a - b { //~ERROR You are trying to use classic C underflow conditions that will fail in Rust.
}
if a - b > a { //~ERROR You are trying to use classic C underflow conditions that will fail in Rust.
}
if a < a - b { //~ERROR You are trying to use classic C underflow conditions that will fail in Rust.
}
if a + b < c {
}
if c > a + b {
}
if a - b < c {
}
if c > a - b {
}
let i = 1.1;
let j = 2.2;
if i + j < i {
}
if i - j < i {
}
if i > i + j {
}
if i - j < i {
}
}

View File

@ -1,44 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(precedence)]
#[allow(identity_op)]
#[allow(eq_op)]
fn main() {
1 << 2 + 3;
//~^ ERROR operator precedence can trip
//~| SUGGESTION 1 << (2 + 3)
1 + 2 << 3;
//~^ERROR operator precedence can trip
//~| SUGGESTION (1 + 2) << 3
4 >> 1 + 1;
//~^ERROR operator precedence can trip
//~| SUGGESTION 4 >> (1 + 1)
1 + 3 >> 2;
//~^ERROR operator precedence can trip
//~| SUGGESTION (1 + 3) >> 2
1 ^ 1 - 1;
//~^ERROR operator precedence can trip
//~| SUGGESTION 1 ^ (1 - 1)
3 | 2 - 1;
//~^ERROR operator precedence can trip
//~| SUGGESTION 3 | (2 - 1)
3 & 5 - 2;
//~^ERROR operator precedence can trip
//~| SUGGESTION 3 & (5 - 2)
-1i32.abs();
//~^ERROR unary minus has lower precedence
//~| SUGGESTION -(1i32.abs())
-1f32.abs();
//~^ERROR unary minus has lower precedence
//~| SUGGESTION -(1f32.abs())
// These should not trigger an error
let _ = (-1i32).abs();
let _ = (-1f32).abs();
let _ = -(1i32).abs();
let _ = -(1f32).abs();
let _ = -(1i32.abs());
let _ = -(1f32.abs());
}

View File

@ -1,20 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(print_with_newline)]
fn main() {
print!("Hello\n"); //~ERROR using `print!()` with a format string
print!("Hello {}\n", "world"); //~ERROR using `print!()` with a format string
print!("Hello {} {}\n\n", "world", "#2"); //~ERROR using `print!()` with a format string
print!("{}\n", 1265); //~ERROR using `print!()` with a format string
// these are all fine
print!("");
print!("Hello");
println!("Hello");
println!("Hello\n");
println!("Hello {}\n", "world");
print!("Issue\n{}", 1265);
print!("{}", 1265);
print!("\n{}", 1275);
}

View File

@ -1,25 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(redundant_closure_call)]
fn main() {
let a = (|| 42)();
//~^ ERROR Try not to call a closure in the expression where it is declared.
//~| HELP Try doing something like:
//~| SUGGESTION let a = 42;
let mut i = 1;
let k = (|m| m+1)(i); //~ERROR Try not to call a closure in the expression where it is declared.
k = (|a,b| a*b)(1,5); //~ERROR Try not to call a closure in the expression where it is declared.
let closure = || 32;
i = closure(); //~ERROR Closure called just once immediately after it was declared
let closure = |i| i+1;
i = closure(3); //~ERROR Closure called just once immediately after it was declared
i = closure(4);
}

View File

@ -1,88 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
fn get_number() -> usize {
10
}
fn get_reference(n : &usize) -> &usize {
n
}
#[allow(many_single_char_names, double_parens)]
#[allow(unused_variables)]
#[deny(deref_addrof)]
fn main() {
let a = 10;
let aref = &a;
let b = *&a;
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = a;
let b = *&get_number();
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = get_number();
let b = *get_reference(&a);
let bytes : Vec<usize> = vec![1, 2, 3, 4];
let b = *&bytes[1..2][0];
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = bytes[1..2][0];
//This produces a suggestion of 'let b = (a);' which
//will trigger the 'unused_parens' lint
let b = *&(a);
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = (a)
let b = *(&a);
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = a;
let b = *((&a));
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = a
let b = *&&a;
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = &a;
let b = **&aref;
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = *aref;
//This produces a suggestion of 'let b = *&a;' which
//will trigger the 'deref_addrof' lint again
let b = **&&a;
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let b = *&a;
{
let mut x = 10;
let y = *&mut x;
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let y = x;
}
{
//This produces a suggestion of 'let y = *&mut x' which
//will trigger the 'deref_addrof' lint again
let mut x = 10;
let y = **&mut &mut x;
//~^ERROR immediately dereferencing a reference
//~|HELP try this
//~|SUGGESTION let y = *&mut x;
}
}

View File

@ -1,27 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(short_circuit_statement)]
fn main() {
f() && g();
//~^ ERROR boolean short circuit operator
//~| HELP replace it with
//~| SUGGESTION if f() { g(); }
f() || g();
//~^ ERROR boolean short circuit operator
//~| HELP replace it with
//~| SUGGESTION if !f() { g(); }
1 == 2 || g();
//~^ ERROR boolean short circuit operator
//~| HELP replace it with
//~| SUGGESTION if !(1 == 2) { g(); }
}
fn f() -> bool {
true
}
fn g() -> bool {
false
}

View File

@ -7,11 +7,11 @@ fn add_only() { // ignores assignment distinction
let mut x = "".to_owned();
for _ in 1..3 {
x = x + "."; //~ERROR you added something to a string.
x = x + ".";
}
let y = "".to_owned();
let z = y + "..."; //~ERROR you added something to a string.
let z = y + "...";
assert_eq!(&x, &z);
}
@ -21,7 +21,7 @@ fn add_assign_only() {
let mut x = "".to_owned();
for _ in 1..3 {
x = x + "."; //~ERROR you assigned the result of adding something to this string.
x = x + ".";
}
let y = "".to_owned();
@ -35,11 +35,11 @@ fn both() {
let mut x = "".to_owned();
for _ in 1..3 {
x = x + "."; //~ERROR you assigned the result of adding something to this string.
x = x + ".";
}
let y = "".to_owned();
let z = y + "..."; //~ERROR you added something to a string.
let z = y + "...";
assert_eq!(&x, &z);
}
@ -48,9 +48,9 @@ fn both() {
#[deny(string_lit_as_bytes)]
fn str_lit_as_bytes() {
let bs = "hello there".as_bytes();
//~^ERROR calling `as_bytes()`
//~|HELP byte string literal
//~|SUGGESTION b"hello there"
// no warning, because this cannot be written as a byte string literal:
let ubs = "".as_bytes();
@ -66,8 +66,8 @@ fn main() {
// the add is only caught for `String`
let mut x = 1;
; x = x + 1;
//~^ WARN assign_op_pattern
//~| HELP replace
//~| SUGGESTION ; x += 1;
assert_eq!(2, x);
}

View File

@ -1,14 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(stutter)]
#![allow(dead_code)]
mod foo {
pub fn foo() {}
pub fn foo_bar() {} //~ ERROR: item name starts with its containing module's name
pub fn bar_foo() {} //~ ERROR: item name ends with its containing module's name
pub struct FooCake {} //~ ERROR: item name starts with its containing module's name
pub enum CakeFoo {} //~ ERROR: item name ends with its containing module's name
}
fn main() {}

View File

@ -11,9 +11,9 @@ fn array() {
let temp = foo[0];
foo[0] = foo[1];
foo[1] = temp;
//~^^^ ERROR this looks like you are swapping elements of `foo` manually
//~| HELP try
//~| SUGGESTION foo.swap(0, 1);
foo.swap(0, 1);
}
@ -23,9 +23,9 @@ fn slice() {
let temp = foo[0];
foo[0] = foo[1];
foo[1] = temp;
//~^^^ ERROR this looks like you are swapping elements of `foo` manually
//~| HELP try
//~| SUGGESTION foo.swap(0, 1);
foo.swap(0, 1);
}
@ -35,9 +35,9 @@ fn vec() {
let temp = foo[0];
foo[0] = foo[1];
foo[1] = temp;
//~^^^ ERROR this looks like you are swapping elements of `foo` manually
//~| HELP try
//~| SUGGESTION foo.swap(0, 1);
foo.swap(0, 1);
}
@ -52,33 +52,33 @@ fn main() {
a = b;
b = a;
//~^^ ERROR this looks like you are trying to swap `a` and `b`
//~| HELP try
//~| SUGGESTION std::mem::swap(&mut a, &mut b);
//~| NOTE or maybe you should use `std::mem::replace`?
; let t = a;
a = b;
b = t;
//~^^^ ERROR this looks like you are swapping `a` and `b` manually
//~| HELP try
//~| SUGGESTION ; std::mem::swap(&mut a, &mut b);
//~| NOTE or maybe you should use `std::mem::replace`?
let mut c = Foo(42);
c.0 = a;
a = c.0;
//~^^ ERROR this looks like you are trying to swap `c.0` and `a`
//~| HELP try
//~| SUGGESTION std::mem::swap(&mut c.0, &mut a);
//~| NOTE or maybe you should use `std::mem::replace`?
; let t = c.0;
c.0 = a;
a = t;
//~^^^ ERROR this looks like you are swapping `c.0` and `a` manually
//~| HELP try
//~| SUGGESTION ; std::mem::swap(&mut c.0, &mut a);
//~| NOTE or maybe you should use `std::mem::replace`?
}

View File

@ -1,40 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy)]
#![allow(unused)]
fn the_answer(ref mut x: u8) { //~ ERROR `ref` directly on a function argument is ignored
*x = 42;
}
fn main() {
let mut x = 0;
the_answer(x);
// Closures should not warn
let y = |ref x| { println!("{:?}", x) };
y(1u8);
let ref x = 1;
//~^ ERROR `ref` on an entire `let` pattern is discouraged
//~| HELP try
//~| SUGGESTION let x = &1;
let ref y: (&_, u8) = (&1, 2);
//~^ ERROR `ref` on an entire `let` pattern is discouraged
//~| HELP try
//~| SUGGESTION let y: &(&_, u8) = &(&1, 2);
let ref z = 1 + 2;
//~^ ERROR `ref` on an entire `let` pattern is discouraged
//~| HELP try
//~| SUGGESTION let z = &(1 + 2);
let ref mut z = 1 + 2;
//~^ ERROR `ref` on an entire `let` pattern is discouraged
//~| HELP try
//~| SUGGESTION let z = &mut (1 + 2);
let (ref x, _) = (1,2); // okay, not top level
println!("The answer is {}.", x);
}

View File

@ -1,60 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(wrong_self_convention)]
#![deny(wrong_pub_self_convention)]
#![allow(dead_code)]
fn main() {}
#[derive(Clone, Copy)]
struct Foo;
impl Foo {
fn as_i32(self) {}
fn as_u32(&self) {}
fn into_i32(self) {}
fn is_i32(self) {}
fn is_u32(&self) {}
fn to_i32(self) {}
fn from_i32(self) {} //~ERROR: methods called `from_*` usually take no self
pub fn as_i64(self) {}
pub fn into_i64(self) {}
pub fn is_i64(self) {}
pub fn to_i64(self) {}
pub fn from_i64(self) {} //~ERROR: methods called `from_*` usually take no self
// check whether the lint can be allowed at the function level
#[allow(wrong_self_convention)]
pub fn from_cake(self) {}
}
struct Bar;
impl Bar {
fn as_i32(self) {} //~ERROR: methods called `as_*` usually take self by reference
fn as_u32(&self) {}
fn into_i32(&self) {} //~ERROR: methods called `into_*` usually take self by value
fn into_u32(self) {}
fn is_i32(self) {} //~ERROR: methods called `is_*` usually take self by reference
fn is_u32(&self) {}
fn to_i32(self) {} //~ERROR: methods called `to_*` usually take self by reference
fn to_u32(&self) {}
fn from_i32(self) {} //~ERROR: methods called `from_*` usually take no self
pub fn as_i64(self) {} //~ERROR: methods called `as_*` usually take self by reference
pub fn into_i64(&self) {} //~ERROR: methods called `into_*` usually take self by value
pub fn is_i64(self) {} //~ERROR: methods called `is_*` usually take self by reference
pub fn to_i64(self) {} //~ERROR: methods called `to_*` usually take self by reference
pub fn from_i64(self) {} //~ERROR: methods called `from_*` usually take no self
// test for false positives
fn as_(self) {}
fn into_(&self) {}
fn is_(self) {}
fn to_(self) {}
fn from_(self) {}
}

View File

@ -1,20 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[allow(unused_variables)]
#[deny(zero_divided_by_zero)]
fn main() {
let nan = 0.0 / 0.0; //~ERROR constant division of 0.0 with 0.0 will always result in NaN
//~^ equal expressions as operands to `/`
let f64_nan = 0.0 / 0.0f64; //~ERROR constant division of 0.0 with 0.0 will always result in NaN
//~^ equal expressions as operands to `/`
let other_f64_nan = 0.0f64 / 0.0; //~ERROR constant division of 0.0 with 0.0 will always result in NaN
//~^ equal expressions as operands to `/`
let one_more_f64_nan = 0.0f64/0.0f64; //~ERROR constant division of 0.0 with 0.0 will always result in NaN
//~^ equal expressions as operands to `/`
let zero = 0.0;
let other_zero = 0.0;
let other_nan = zero / other_zero; // fine - this lint doesn't propegate constants.
let not_nan = 2.0/0.0; // not an error: 2/0 = inf
let also_not_nan = 0.0/2.0; // not an error: 0/2 = 0
}

View File

@ -14,6 +14,7 @@ fn run_mode(dir: &'static str, mode: &'static str) {
}
config.mode = cfg_mode;
config.build_base = PathBuf::from("target/debug/test_build_base");
config.src_base = PathBuf::from(format!("tests/{}", dir));
compiletest::run_tests(&config);
@ -27,5 +28,5 @@ fn prepare_env() {
fn compile_test() {
prepare_env();
run_mode("run-pass", "run-pass");
run_mode("compile-fail", "compile-fail");
run_mode("ui", "ui");
}

View File

@ -2,11 +2,11 @@
#![plugin(clippy)]
#[warn(str_to_string)]
//~^WARNING: lint str_to_string has been removed: using `str::to_string`
#[warn(string_to_string)]
//~^WARNING: lint string_to_string has been removed: using `string::to_string`
#[warn(unstable_as_slice)]
//~^WARNING: lint unstable_as_slice has been removed: `Vec::as_slice` has been stabilized
#[warn(unstable_as_mut_slice)]
//~^WARNING: lint unstable_as_mut_slice has been removed: `Vec::as_mut_slice` has been stabilized
fn main() {}

View File

@ -0,0 +1,93 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(absurd_extreme_comparisons)]
#![allow(unused, eq_op, no_effect, unnecessary_operation)]
fn main() {
const Z: u32 = 0;
let u: u32 = 42;
u <= 0;
u <= Z;
u < Z;
Z >= u;
Z > u;
u > std::u32::MAX;
u >= std::u32::MAX;
std::u32::MAX < u;
std::u32::MAX <= u;
1-1 > u;
u >= !0;
u <= 12 - 2*6;
let i: i8 = 0;
i < -127 - 1;
std::i8::MAX >= i;
3-7 < std::i32::MIN;
let b = false;
b >= true;
false > b;
u > 0; // ok
// this is handled by unit_cmp
() < {};
}
use std::cmp::{Ordering, PartialEq, PartialOrd};
#[derive(PartialEq, PartialOrd)]
pub struct U(u64);
impl PartialEq<u32> for U {
fn eq(&self, other: &u32) -> bool {
self.eq(&U(*other as u64))
}
}
impl PartialOrd<u32> for U {
fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
self.partial_cmp(&U(*other as u64))
}
}
pub fn foo(val: U) -> bool {
val > std::u32::MAX
}

View File

@ -0,0 +1,151 @@
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:12:5
|
12 | u <= 0;
| ^^^^^^
|
note: lint level defined here
--> $DIR/absurd-extreme-comparisons.rs:4:9
|
4 | #![deny(absurd_extreme_comparisons)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: because 0 is the minimum value for this type, the case where the two sides are not equal never occurs, consider using u == 0 instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:15:5
|
15 | u <= Z;
| ^^^^^^
|
= help: because Z is the minimum value for this type, the case where the two sides are not equal never occurs, consider using u == Z instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:18:5
|
18 | u < Z;
| ^^^^^
|
= help: because Z is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:21:5
|
21 | Z >= u;
| ^^^^^^
|
= help: because Z is the minimum value for this type, the case where the two sides are not equal never occurs, consider using Z == u instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:24:5
|
24 | Z > u;
| ^^^^^
|
= help: because Z is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:27:5
|
27 | u > std::u32::MAX;
| ^^^^^^^^^^^^^^^^^
|
= help: because std::u32::MAX is the maximum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:30:5
|
30 | u >= std::u32::MAX;
| ^^^^^^^^^^^^^^^^^^
|
= help: because std::u32::MAX is the maximum value for this type, the case where the two sides are not equal never occurs, consider using u == std::u32::MAX instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:33:5
|
33 | std::u32::MAX < u;
| ^^^^^^^^^^^^^^^^^
|
= help: because std::u32::MAX is the maximum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:36:5
|
36 | std::u32::MAX <= u;
| ^^^^^^^^^^^^^^^^^^
|
= help: because std::u32::MAX is the maximum value for this type, the case where the two sides are not equal never occurs, consider using std::u32::MAX == u instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:40:5
|
40 | 1-1 > u;
| ^^^^^^^
|
= help: because 1-1 is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:43:5
|
43 | u >= !0;
| ^^^^^^^
|
= help: because !0 is the maximum value for this type, the case where the two sides are not equal never occurs, consider using u == !0 instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:46:5
|
46 | u <= 12 - 2*6;
| ^^^^^^^^^^^^^
|
= help: because 12 - 2*6 is the minimum value for this type, the case where the two sides are not equal never occurs, consider using u == 12 - 2*6 instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:51:5
|
51 | i < -127 - 1;
| ^^^^^^^^^^^^
|
= help: because -127 - 1 is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:54:5
|
54 | std::i8::MAX >= i;
| ^^^^^^^^^^^^^^^^^
|
= help: because std::i8::MAX is the maximum value for this type, this comparison is always true
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:57:5
|
57 | 3-7 < std::i32::MIN;
| ^^^^^^^^^^^^^^^^^^^
|
= help: because std::i32::MIN is the minimum value for this type, this comparison is always false
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:62:5
|
62 | b >= true;
| ^^^^^^^^^
|
= help: because true is the maximum value for this type, the case where the two sides are not equal never occurs, consider using b == true instead
error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false
--> $DIR/absurd-extreme-comparisons.rs:65:5
|
65 | false > b;
| ^^^^^^^^^
|
= help: because false is the minimum value for this type, this comparison is always false
warning: <-comparison of unit values detected. This will always be false
--> $DIR/absurd-extreme-comparisons.rs:72:5
|
72 | () < {};
| ^^^^^^^
|
= note: #[warn(unit_cmp)] on by default
error: aborting due to 17 previous errors

57
tests/ui/approx_const.rs Normal file
View File

@ -0,0 +1,57 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(approx_constant)]
#[allow(unused, shadow_unrelated, similar_names)]
fn main() {
let my_e = 2.7182;
let almost_e = 2.718;
let no_e = 2.71;
let my_1_frac_pi = 0.3183;
let no_1_frac_pi = 0.31;
let my_frac_1_sqrt_2 = 0.70710678;
let almost_frac_1_sqrt_2 = 0.70711;
let my_frac_1_sqrt_2 = 0.707;
let my_frac_2_pi = 0.63661977;
let no_frac_2_pi = 0.636;
let my_frac_2_sq_pi = 1.128379;
let no_frac_2_sq_pi = 1.128;
let my_frac_pi_2 = 1.57079632679;
let no_frac_pi_2 = 1.5705;
let my_frac_pi_3 = 1.04719755119;
let no_frac_pi_3 = 1.047;
let my_frac_pi_4 = 0.785398163397;
let no_frac_pi_4 = 0.785;
let my_frac_pi_6 = 0.523598775598;
let no_frac_pi_6 = 0.523;
let my_frac_pi_8 = 0.3926990816987;
let no_frac_pi_8 = 0.392;
let my_ln_10 = 2.302585092994046;
let no_ln_10 = 2.303;
let my_ln_2 = 0.6931471805599453;
let no_ln_2 = 0.693;
let my_log10_e = 0.43429448190325182;
let no_log10_e = 0.434;
let my_log2_e = 1.4426950408889634;
let no_log2_e = 1.442;
let my_pi = 3.1415;
let almost_pi = 3.14;
let no_pi = 3.15;
let my_sq2 = 1.4142;
let no_sq2 = 1.414;
}

View File

@ -0,0 +1,122 @@
error: approximate value of `f{32, 64}::consts::E` found. Consider using it directly
--> $DIR/approx_const.rs:7:16
|
7 | let my_e = 2.7182;
| ^^^^^^
|
note: lint level defined here
--> $DIR/approx_const.rs:4:8
|
4 | #[deny(approx_constant)]
| ^^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::E` found. Consider using it directly
--> $DIR/approx_const.rs:8:20
|
8 | let almost_e = 2.718;
| ^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_1_PI` found. Consider using it directly
--> $DIR/approx_const.rs:11:24
|
11 | let my_1_frac_pi = 0.3183;
| ^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found. Consider using it directly
--> $DIR/approx_const.rs:14:28
|
14 | let my_frac_1_sqrt_2 = 0.70710678;
| ^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found. Consider using it directly
--> $DIR/approx_const.rs:15:32
|
15 | let almost_frac_1_sqrt_2 = 0.70711;
| ^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_2_PI` found. Consider using it directly
--> $DIR/approx_const.rs:18:24
|
18 | let my_frac_2_pi = 0.63661977;
| ^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_2_SQRT_PI` found. Consider using it directly
--> $DIR/approx_const.rs:21:27
|
21 | let my_frac_2_sq_pi = 1.128379;
| ^^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_PI_2` found. Consider using it directly
--> $DIR/approx_const.rs:24:24
|
24 | let my_frac_pi_2 = 1.57079632679;
| ^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_PI_3` found. Consider using it directly
--> $DIR/approx_const.rs:27:24
|
27 | let my_frac_pi_3 = 1.04719755119;
| ^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_PI_4` found. Consider using it directly
--> $DIR/approx_const.rs:30:24
|
30 | let my_frac_pi_4 = 0.785398163397;
| ^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_PI_6` found. Consider using it directly
--> $DIR/approx_const.rs:33:24
|
33 | let my_frac_pi_6 = 0.523598775598;
| ^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::FRAC_PI_8` found. Consider using it directly
--> $DIR/approx_const.rs:36:24
|
36 | let my_frac_pi_8 = 0.3926990816987;
| ^^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::LN_10` found. Consider using it directly
--> $DIR/approx_const.rs:39:20
|
39 | let my_ln_10 = 2.302585092994046;
| ^^^^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::LN_2` found. Consider using it directly
--> $DIR/approx_const.rs:42:19
|
42 | let my_ln_2 = 0.6931471805599453;
| ^^^^^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::LOG10_E` found. Consider using it directly
--> $DIR/approx_const.rs:45:22
|
45 | let my_log10_e = 0.43429448190325182;
| ^^^^^^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::LOG2_E` found. Consider using it directly
--> $DIR/approx_const.rs:48:21
|
48 | let my_log2_e = 1.4426950408889634;
| ^^^^^^^^^^^^^^^^^^
error: approximate value of `f{32, 64}::consts::PI` found. Consider using it directly
--> $DIR/approx_const.rs:51:17
|
51 | let my_pi = 3.1415;
| ^^^^^^
error: approximate value of `f{32, 64}::consts::PI` found. Consider using it directly
--> $DIR/approx_const.rs:52:21
|
52 | let almost_pi = 3.14;
| ^^^^
error: approximate value of `f{32, 64}::consts::SQRT_2` found. Consider using it directly
--> $DIR/approx_const.rs:55:18
|
55 | let my_sq2 = 1.4142;
| ^^^^^^
error: aborting due to 19 previous errors

30
tests/ui/arithmetic.rs Normal file
View File

@ -0,0 +1,30 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(integer_arithmetic, float_arithmetic)]
#![allow(unused, shadow_reuse, shadow_unrelated, no_effect, unnecessary_operation)]
fn main() {
let i = 1i32;
1 + i;
i * 2;
1 %
i / 2; // no error, this is part of the expression in the preceding line
i - 2 + 2 - i;
-i;
i & 1; // no wrapping
i | 1;
i ^ 1;
i >> 1;
i << 1;
let f = 1.0f32;
f * 2.0;
1.0 + f;
f * 2.0;
f / 2.0;
f - 2.0 * 4.2;
-f;
}

View File

@ -0,0 +1,82 @@
error: integer arithmetic detected
--> $DIR/arithmetic.rs:8:5
|
8 | 1 + i;
| ^^^^^
|
note: lint level defined here
--> $DIR/arithmetic.rs:4:9
|
4 | #![deny(integer_arithmetic, float_arithmetic)]
| ^^^^^^^^^^^^^^^^^^
error: integer arithmetic detected
--> $DIR/arithmetic.rs:9:5
|
9 | i * 2;
| ^^^^^
error: integer arithmetic detected
--> $DIR/arithmetic.rs:10:5
|
10 | 1 %
| _____^ starting here...
11 | | i / 2; // no error, this is part of the expression in the preceding line
| |_________^ ...ending here
error: integer arithmetic detected
--> $DIR/arithmetic.rs:12:5
|
12 | i - 2 + 2 - i;
| ^^^^^^^^^^^^^
error: integer arithmetic detected
--> $DIR/arithmetic.rs:13:5
|
13 | -i;
| ^^
error: floating-point arithmetic detected
--> $DIR/arithmetic.rs:23:5
|
23 | f * 2.0;
| ^^^^^^^
|
note: lint level defined here
--> $DIR/arithmetic.rs:4:29
|
4 | #![deny(integer_arithmetic, float_arithmetic)]
| ^^^^^^^^^^^^^^^^
error: floating-point arithmetic detected
--> $DIR/arithmetic.rs:25:5
|
25 | 1.0 + f;
| ^^^^^^^
error: floating-point arithmetic detected
--> $DIR/arithmetic.rs:26:5
|
26 | f * 2.0;
| ^^^^^^^
error: floating-point arithmetic detected
--> $DIR/arithmetic.rs:27:5
|
27 | f / 2.0;
| ^^^^^^^
error: floating-point arithmetic detected
--> $DIR/arithmetic.rs:28:5
|
28 | f - 2.0 * 4.2;
| ^^^^^^^^^^^^^
error: floating-point arithmetic detected
--> $DIR/arithmetic.rs:29:5
|
29 | -f;
| ^^
error: aborting due to 11 previous errors

View File

@ -0,0 +1,45 @@
#![feature(inclusive_range_syntax, plugin)]
#![plugin(clippy)]
#![deny(indexing_slicing)]
#![deny(out_of_bounds_indexing)]
#![allow(no_effect, unnecessary_operation)]
fn main() {
let x = [1,2,3,4];
x[0];
x[3];
x[4];
x[1 << 3];
&x[1..5];
&x[0..3];
&x[0...4];
&x[...4];
&x[..];
&x[1..];
&x[4..];
&x[5..];
&x[..4];
&x[..5];
let y = &x;
y[0];
&y[1..2];
&y[..];
&y[0...4];
&y[...4];
let empty: [i8; 0] = [];
empty[0];
&empty[1..5];
&empty[0...4];
&empty[...4];
&empty[..];
&empty[0..];
&empty[0..0];
&empty[0...0];
&empty[...0];
&empty[..0];
&empty[1..];
&empty[..4];
}

View File

@ -0,0 +1,152 @@
error: const index is out of bounds
--> $DIR/array_indexing.rs:12:5
|
12 | x[4];
| ^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: const index is out of bounds
--> $DIR/array_indexing.rs:13:5
|
13 | x[1 << 3];
| ^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:14:6
|
14 | &x[1..5];
| ^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:16:6
|
16 | &x[0...4];
| ^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:17:6
|
17 | &x[...4];
| ^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:21:6
|
21 | &x[5..];
| ^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:23:6
|
23 | &x[..5];
| ^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: indexing may panic
--> $DIR/array_indexing.rs:26:5
|
26 | y[0];
| ^^^^
|
note: lint level defined here
--> $DIR/array_indexing.rs:4:9
|
4 | #![deny(indexing_slicing)]
| ^^^^^^^^^^^^^^^^
error: slicing may panic
--> $DIR/array_indexing.rs:27:6
|
27 | &y[1..2];
| ^^^^^^^
error: slicing may panic
--> $DIR/array_indexing.rs:29:6
|
29 | &y[0...4];
| ^^^^^^^^
error: slicing may panic
--> $DIR/array_indexing.rs:30:6
|
30 | &y[...4];
| ^^^^^^^
error: const index is out of bounds
--> $DIR/array_indexing.rs:33:5
|
33 | empty[0];
| ^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:34:6
|
34 | &empty[1..5];
| ^^^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:35:6
|
35 | &empty[0...4];
| ^^^^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:36:6
|
36 | &empty[...4];
| ^^^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:40:6
|
40 | &empty[0...0];
| ^^^^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:41:6
|
41 | &empty[...0];
| ^^^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:43:6
|
43 | &empty[1..];
| ^^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: range is out of bounds
--> $DIR/array_indexing.rs:44:6
|
44 | &empty[..4];
| ^^^^^^^^^^
|
= note: #[deny(out_of_bounds_indexing)] on by default
error: aborting due to 19 previous errors

85
tests/ui/assign_ops.rs Normal file
View File

@ -0,0 +1,85 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(assign_ops)]
#[allow(unused_assignments)]
fn main() {
let mut i = 1i32;
i += 2;
i += 2 + 17;
i -= 6;
i -= 2 - 1;
i *= 5;
i *= 1+5;
i /= 32;
i /= 32 | 5;
i /= 32 / 5;
i %= 42;
i >>= i;
i <<= 9 + 6 - 7;
i += 1 << 5;
}
#[allow(dead_code, unused_assignments)]
#[deny(assign_op_pattern)]
fn bla() {
let mut a = 5;
a = a + 1;
a = 1 + a;
a = a - 1;
a = a * 99;
a = 42 * a;
a = a / 2;
a = a % 5;
a = a & 1;
a = 1 - a;
a = 5 / a;
a = 42 % a;
a = 6 << a;
let mut s = String::new();
s = s + "bla";
}

201
tests/ui/assign_ops.stderr Normal file
View File

@ -0,0 +1,201 @@
error: assign operation detected
--> $DIR/assign_ops.rs:8:5
|
8 | i += 2;
| ^^^^^^
|
note: lint level defined here
--> $DIR/assign_ops.rs:4:8
|
4 | #[deny(assign_ops)]
| ^^^^^^^^^^
help: replace it with
| i = i + 2;
error: assign operation detected
--> $DIR/assign_ops.rs:11:5
|
11 | i += 2 + 17;
| ^^^^^^^^^^^
|
help: replace it with
| i = i + 2 + 17;
error: assign operation detected
--> $DIR/assign_ops.rs:14:5
|
14 | i -= 6;
| ^^^^^^
|
help: replace it with
| i = i - 6;
error: assign operation detected
--> $DIR/assign_ops.rs:17:5
|
17 | i -= 2 - 1;
| ^^^^^^^^^^
|
help: replace it with
| i = i - (2 - 1);
error: assign operation detected
--> $DIR/assign_ops.rs:21:5
|
21 | i *= 5;
| ^^^^^^
|
help: replace it with
| i = i * 5;
error: assign operation detected
--> $DIR/assign_ops.rs:24:5
|
24 | i *= 1+5;
| ^^^^^^^^
|
help: replace it with
| i = i * (1+5);
error: assign operation detected
--> $DIR/assign_ops.rs:27:5
|
27 | i /= 32;
| ^^^^^^^
|
help: replace it with
| i = i / 32;
error: assign operation detected
--> $DIR/assign_ops.rs:30:5
|
30 | i /= 32 | 5;
| ^^^^^^^^^^^
|
help: replace it with
| i = i / (32 | 5);
error: assign operation detected
--> $DIR/assign_ops.rs:33:5
|
33 | i /= 32 / 5;
| ^^^^^^^^^^^
|
help: replace it with
| i = i / (32 / 5);
error: assign operation detected
--> $DIR/assign_ops.rs:36:5
|
36 | i %= 42;
| ^^^^^^^
|
help: replace it with
| i = i % 42;
error: assign operation detected
--> $DIR/assign_ops.rs:39:5
|
39 | i >>= i;
| ^^^^^^^
|
help: replace it with
| i = i >> i;
error: assign operation detected
--> $DIR/assign_ops.rs:42:5
|
42 | i <<= 9 + 6 - 7;
| ^^^^^^^^^^^^^^^
|
help: replace it with
| i = i << (9 + 6 - 7);
error: assign operation detected
--> $DIR/assign_ops.rs:45:5
|
45 | i += 1 << 5;
| ^^^^^^^^^^^
|
help: replace it with
| i = i + (1 << 5);
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:55:5
|
55 | a = a + 1;
| ^^^^^^^^^
|
note: lint level defined here
--> $DIR/assign_ops.rs:52:8
|
52 | #[deny(assign_op_pattern)]
| ^^^^^^^^^^^^^^^^^
help: replace it with
| a += 1;
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:58:5
|
58 | a = 1 + a;
| ^^^^^^^^^
|
help: replace it with
| a += 1;
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:61:5
|
61 | a = a - 1;
| ^^^^^^^^^
|
help: replace it with
| a -= 1;
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:64:5
|
64 | a = a * 99;
| ^^^^^^^^^^
|
help: replace it with
| a *= 99;
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:67:5
|
67 | a = 42 * a;
| ^^^^^^^^^^
|
help: replace it with
| a *= 42;
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:70:5
|
70 | a = a / 2;
| ^^^^^^^^^
|
help: replace it with
| a /= 2;
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:73:5
|
73 | a = a % 5;
| ^^^^^^^^^
|
help: replace it with
| a %= 5;
error: manual implementation of an assign operation
--> $DIR/assign_ops.rs:76:5
|
76 | a = a & 1;
| ^^^^^^^^^
|
help: replace it with
| a &= 1;
error: aborting due to 21 previous errors

57
tests/ui/assign_ops2.rs Normal file
View File

@ -0,0 +1,57 @@
#![feature(plugin)]
#![plugin(clippy)]
#[allow(unused_assignments)]
#[deny(misrefactored_assign_op)]
fn main() {
let mut a = 5;
a += a + 1;
a += 1 + a;
a -= a - 1;
a *= a * 99;
a *= 42 * a;
a /= a / 2;
a %= a % 5;
a &= a & 1;
a -= 1 - a;
a /= 5 / a;
a %= 42 % a;
a <<= 6 << a;
}
// check that we don't lint on op assign impls, because that's just the way to impl them
use std::ops::{Mul, MulAssign};
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Wrap(i64);
impl Mul<i64> for Wrap {
type Output = Self;
fn mul(self, rhs: i64) -> Self {
Wrap(self.0 * rhs)
}
}
impl MulAssign<i64> for Wrap {
fn mul_assign(&mut self, rhs: i64) {
*self = *self * rhs
}
}

View File

@ -0,0 +1,79 @@
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:8:5
|
8 | a += a + 1;
| ^^^^^^^^^^
|
note: lint level defined here
--> $DIR/assign_ops2.rs:5:8
|
5 | #[deny(misrefactored_assign_op)]
| ^^^^^^^^^^^^^^^^^^^^^^^
help: replace it with
| a += 1;
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:11:5
|
11 | a += 1 + a;
| ^^^^^^^^^^
|
help: replace it with
| a += 1;
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:14:5
|
14 | a -= a - 1;
| ^^^^^^^^^^
|
help: replace it with
| a -= 1;
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:17:5
|
17 | a *= a * 99;
| ^^^^^^^^^^^
|
help: replace it with
| a *= 99;
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:20:5
|
20 | a *= 42 * a;
| ^^^^^^^^^^^
|
help: replace it with
| a *= 42;
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:23:5
|
23 | a /= a / 2;
| ^^^^^^^^^^
|
help: replace it with
| a /= 2;
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:26:5
|
26 | a %= a % 5;
| ^^^^^^^^^^
|
help: replace it with
| a %= 5;
error: variable appears on both sides of an assignment operation
--> $DIR/assign_ops2.rs:29:5
|
29 | a &= a & 1;
| ^^^^^^^^^^
|
help: replace it with
| a &= 1;
error: aborting due to 8 previous errors

View File

@ -3,7 +3,7 @@
#![deny(inline_always, deprecated_semver)]
#[inline(always)] //~ERROR you have declared `#[inline(always)]` on `test_attr_lint`.
#[inline(always)]
fn test_attr_lint() {
assert!(true)
}
@ -24,10 +24,10 @@ fn empty_and_false_positive_stmt() {
unreachable!();
}
#[deprecated(since = "forever")] //~ERROR the since field must contain a semver-compliant version
#[deprecated(since = "forever")]
pub const SOME_CONST : u8 = 42;
#[deprecated(since = "1")] //~ERROR the since field must contain a semver-compliant version
#[deprecated(since = "1")]
pub const ANOTHER_CONST : u8 = 23;
#[deprecated(since = "0.1.1")]

32
tests/ui/attrs.stderr Normal file
View File

@ -0,0 +1,32 @@
error: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea
--> $DIR/attrs.rs:6:1
|
6 | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/attrs.rs:4:9
|
4 | #![deny(inline_always, deprecated_semver)]
| ^^^^^^^^^^^^^
error: the since field must contain a semver-compliant version
--> $DIR/attrs.rs:27:14
|
27 | #[deprecated(since = "forever")]
| ^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/attrs.rs:4:24
|
4 | #![deny(inline_always, deprecated_semver)]
| ^^^^^^^^^^^^^^^^^
error: the since field must contain a semver-compliant version
--> $DIR/attrs.rs:30:14
|
30 | #[deprecated(since = "1")]
| ^^^^^^^^^^^
error: aborting due to 3 previous errors

View File

@ -9,36 +9,36 @@ const EVEN_MORE_REDIRECTION : i64 = THREE_BITS;
fn main() {
let x = 5;
x & 0 == 0; //~ERROR &-masking with zero
x & 0 == 0;
x & 1 == 1; //ok, distinguishes bit 0
x & 1 == 0; //ok, compared with zero
x & 2 == 1; //~ERROR incompatible bit mask
x & 2 == 1;
x | 0 == 0; //ok, equals x == 0 (maybe warn?)
x | 1 == 3; //ok, equals x == 2 || x == 3
x | 3 == 3; //ok, equals x <= 3
x | 3 == 2; //~ERROR incompatible bit mask
x | 3 == 2;
x & 1 > 1; //~ERROR incompatible bit mask
x & 1 > 1;
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 | 2 > 1; //~ERROR incompatible bit mask
x | 2 > 1;
x | 2 <= 2; // ok (if a bit silly), equals x <= 2
x & 192 == 128; // ok, tests for bit 7 and not bit 6
x & 0xffc0 == 0xfe80; // ok
// this also now works with constants
x & THREE_BITS == 8; //~ERROR incompatible bit mask
x | EVEN_MORE_REDIRECTION < 7; //~ERROR incompatible bit mask
x & THREE_BITS == 8;
x | EVEN_MORE_REDIRECTION < 7;
0 & x == 0; //~ERROR &-masking with zero
0 & x == 0;
1 | x > 1;
// and should now also match uncommon usage
1 < 2 | x; //~ERROR incompatible bit mask
2 == 3 | x; //~ERROR incompatible bit mask
1 == x & 2; //~ERROR incompatible bit mask
1 < 2 | x;
2 == 3 | x;
1 == x & 2;
x | 1 > 2; // no error, because we allowed ineffective bit masks
ineffective();
@ -49,10 +49,10 @@ fn main() {
fn ineffective() {
let x = 5;
x | 1 > 3; //~ERROR ineffective bit mask
x | 1 < 4; //~ERROR ineffective bit mask
x | 1 <= 3; //~ERROR ineffective bit mask
x | 1 >= 8; //~ERROR ineffective bit mask
x | 1 > 3;
x | 1 < 4;
x | 1 <= 3;
x | 1 >= 8;
x | 1 > 2; // not an error (yet), better written as x >= 2
x | 1 >= 7; // not an error (yet), better written as x >= 6

104
tests/ui/bit_masks.stderr Normal file
View File

@ -0,0 +1,104 @@
error: &-masking with zero
--> $DIR/bit_masks.rs:12:5
|
12 | x & 0 == 0;
| ^^^^^^^^^^
|
note: lint level defined here
--> $DIR/bit_masks.rs:7:8
|
7 | #[deny(bad_bit_mask)]
| ^^^^^^^^^^^^
error: incompatible bit mask: `_ & 2` can never be equal to `1`
--> $DIR/bit_masks.rs:15:5
|
15 | x & 2 == 1;
| ^^^^^^^^^^
error: incompatible bit mask: `_ | 3` can never be equal to `2`
--> $DIR/bit_masks.rs:19:5
|
19 | x | 3 == 2;
| ^^^^^^^^^^
error: incompatible bit mask: `_ & 1` will never be higher than `1`
--> $DIR/bit_masks.rs:21:5
|
21 | x & 1 > 1;
| ^^^^^^^^^
error: incompatible bit mask: `_ | 2` will always be higher than `1`
--> $DIR/bit_masks.rs:25:5
|
25 | x | 2 > 1;
| ^^^^^^^^^
error: incompatible bit mask: `_ & 7` can never be equal to `8`
--> $DIR/bit_masks.rs:32:5
|
32 | x & THREE_BITS == 8;
| ^^^^^^^^^^^^^^^^^^^
error: incompatible bit mask: `_ | 7` will never be lower than `7`
--> $DIR/bit_masks.rs:33:5
|
33 | x | EVEN_MORE_REDIRECTION < 7;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: &-masking with zero
--> $DIR/bit_masks.rs:35:5
|
35 | 0 & x == 0;
| ^^^^^^^^^^
error: incompatible bit mask: `_ | 2` will always be higher than `1`
--> $DIR/bit_masks.rs:39:5
|
39 | 1 < 2 | x;
| ^^^^^^^^^
error: incompatible bit mask: `_ | 3` can never be equal to `2`
--> $DIR/bit_masks.rs:40:5
|
40 | 2 == 3 | x;
| ^^^^^^^^^^
error: incompatible bit mask: `_ & 2` can never be equal to `1`
--> $DIR/bit_masks.rs:41:5
|
41 | 1 == x & 2;
| ^^^^^^^^^^
error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly
--> $DIR/bit_masks.rs:52:5
|
52 | x | 1 > 3;
| ^^^^^^^^^
|
note: lint level defined here
--> $DIR/bit_masks.rs:47:8
|
47 | #[deny(ineffective_bit_mask)]
| ^^^^^^^^^^^^^^^^^^^^
error: ineffective bit mask: `x | 1` compared to `4`, is the same as x compared directly
--> $DIR/bit_masks.rs:53:5
|
53 | x | 1 < 4;
| ^^^^^^^^^
error: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly
--> $DIR/bit_masks.rs:54:5
|
54 | x | 1 <= 3;
| ^^^^^^^^^^
error: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared directly
--> $DIR/bit_masks.rs:55:5
|
55 | x | 1 >= 8;
| ^^^^^^^^^^
error: aborting due to 15 previous errors

View File

@ -0,0 +1,26 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(dead_code)]
#![allow(single_match)]
#![allow(unused_variables, similar_names)]
#![deny(blacklisted_name)]
fn test(foo: ()) {}
fn main() {
let foo = 42;
let bar = 42;
let baz = 42;
let barb = 42;
let barbaric = 42;
match (42, Some(1337), Some(0)) {
(foo, Some(bar), baz @ Some(_)) => (),
_ => (),
}
}

View File

@ -0,0 +1,50 @@
error: use of a blacklisted/placeholder name `foo`
--> $DIR/blacklisted_name.rs:9:9
|
9 | fn test(foo: ()) {}
| ^^^
|
note: lint level defined here
--> $DIR/blacklisted_name.rs:7:9
|
7 | #![deny(blacklisted_name)]
| ^^^^^^^^^^^^^^^^
error: use of a blacklisted/placeholder name `foo`
--> $DIR/blacklisted_name.rs:12:9
|
12 | let foo = 42;
| ^^^
error: use of a blacklisted/placeholder name `bar`
--> $DIR/blacklisted_name.rs:13:9
|
13 | let bar = 42;
| ^^^
error: use of a blacklisted/placeholder name `baz`
--> $DIR/blacklisted_name.rs:14:9
|
14 | let baz = 42;
| ^^^
error: use of a blacklisted/placeholder name `foo`
--> $DIR/blacklisted_name.rs:20:10
|
20 | (foo, Some(bar), baz @ Some(_)) => (),
| ^^^
error: use of a blacklisted/placeholder name `bar`
--> $DIR/blacklisted_name.rs:20:20
|
20 | (foo, Some(bar), baz @ Some(_)) => (),
| ^^^
error: use of a blacklisted/placeholder name `baz`
--> $DIR/blacklisted_name.rs:20:26
|
20 | (foo, Some(bar), baz @ Some(_)) => (),
| ^^^^^^^^^^^^^
error: aborting due to 7 previous errors

View File

@ -27,7 +27,7 @@ fn macro_if() {
}
fn condition_has_block() -> i32 {
if { //~ERROR in an 'if' condition, avoid complex blocks or closures with blocks;
if {
let x = 3;
x == 3
} {
@ -38,7 +38,7 @@ fn condition_has_block() -> i32 {
}
fn condition_has_block_with_single_expression() -> i32 {
if { true } { //~ERROR omit braces around single expression condition
if { true } {
6
} else {
10
@ -56,18 +56,18 @@ fn pred_test() {
// inside a closure that the condition is using. same principle applies. add some extra
// expressions to make sure linter isn't confused by them.
if v == 3 && sky == "blue" && predicate(|x| { let target = 3; x == target }, v) {
//~^ERROR in an 'if' condition, avoid complex blocks or closures with blocks;
}
if predicate(|x| { let target = 3; x == target }, v) {
//~^ERROR in an 'if' condition, avoid complex blocks or closures with blocks;
}
}
fn condition_is_normal() -> i32 {
let x = 3;
if true && x == 3 { //~ WARN this boolean expression can be simplified
if true && x == 3 {
6
} else {
10

View File

@ -0,0 +1,68 @@
error: in an 'if' condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a 'let'
--> $DIR/block_in_if_condition.rs:30:8
|
30 | if {
| ________^ starting here...
31 | | let x = 3;
32 | | x == 3
33 | | } {
| |_____^ ...ending here
|
note: lint level defined here
--> $DIR/block_in_if_condition.rs:5:9
|
5 | #![deny(block_in_if_condition_stmt)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: try
let res = {
let x = 3;
x == 3
};
if res {
6
} ...
error: omit braces around single expression condition
--> $DIR/block_in_if_condition.rs:41:8
|
41 | if { true } {
| ^^^^^^^^
|
note: lint level defined here
--> $DIR/block_in_if_condition.rs:4:9
|
4 | #![deny(block_in_if_condition_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: try
if true {
6
} ...
error: in an 'if' condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a 'let'
--> $DIR/block_in_if_condition.rs:58:49
|
58 | if v == 3 && sky == "blue" && predicate(|x| { let target = 3; x == target }, v) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: in an 'if' condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a 'let'
--> $DIR/block_in_if_condition.rs:62:22
|
62 | if predicate(|x| { let target = 3; x == target }, v) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: this boolean expression can be simplified
--> $DIR/block_in_if_condition.rs:70:8
|
70 | if true && x == 3 {
| ^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/block_in_if_condition.rs:7:9
|
7 | #![warn(nonminimal_bool)]
| ^^^^^^^^^^^^^^^
help: try
| if x == 3 {
error: aborting due to 4 previous errors

View File

@ -0,0 +1,23 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(bool_comparison)]
fn main() {
let x = true;
if x == true { "yes" } else { "no" };
if x == false { "yes" } else { "no" };
if true == x { "yes" } else { "no" };
if false == x { "yes" } else { "no" };
}

View File

@ -0,0 +1,43 @@
error: equality checks against true are unnecessary
--> $DIR/bool_comparison.rs:7:8
|
7 | if x == true { "yes" } else { "no" };
| ^^^^^^^^^
|
note: lint level defined here
--> $DIR/bool_comparison.rs:4:8
|
4 | #[deny(bool_comparison)]
| ^^^^^^^^^^^^^^^
help: try simplifying it as shown:
| if x { "yes" } else { "no" };
error: equality checks against false can be replaced by a negation
--> $DIR/bool_comparison.rs:11:8
|
11 | if x == false { "yes" } else { "no" };
| ^^^^^^^^^^
|
help: try simplifying it as shown:
| if !x { "yes" } else { "no" };
error: equality checks against true are unnecessary
--> $DIR/bool_comparison.rs:15:8
|
15 | if true == x { "yes" } else { "no" };
| ^^^^^^^^^
|
help: try simplifying it as shown:
| if x { "yes" } else { "no" };
error: equality checks against false can be replaced by a negation
--> $DIR/bool_comparison.rs:19:8
|
19 | if false == x { "yes" } else { "no" };
| ^^^^^^^^^^
|
help: try simplifying it as shown:
| if !x { "yes" } else { "no" };
error: aborting due to 4 previous errors

90
tests/ui/booleans.rs Normal file
View File

@ -0,0 +1,90 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(nonminimal_bool, logic_bug)]
#[allow(unused, many_single_char_names)]
fn main() {
let a: bool = unimplemented!();
let b: bool = unimplemented!();
let c: bool = unimplemented!();
let d: bool = unimplemented!();
let e: bool = unimplemented!();
let _ = a && b || a;
let _ = !(a && b);
let _ = !true;
let _ = !false;
let _ = !!a;
let _ = false && a;
let _ = false || a;
// don't lint on cfgs
let _ = cfg!(you_shall_not_not_pass) && a;
let _ = a || !b || !c || !d || !e;
let _ = !(a && b || c);
let _ = !(!a && b);
}
#[allow(unused, many_single_char_names)]
fn equality_stuff() {
let a: i32 = unimplemented!();
let b: i32 = unimplemented!();
let c: i32 = unimplemented!();
let d: i32 = unimplemented!();
let e: i32 = unimplemented!();
let _ = a == b && a != b;
let _ = a == b && c == 5 && a == b;
let _ = a == b && c == 5 && b == a;
let _ = a < b && a >= b;
let _ = a > b && a <= b;
let _ = a > b && a == b;
let _ = a != b || !(a != b || c == d);
}

160
tests/ui/booleans.stderr Normal file
View File

@ -0,0 +1,160 @@
error: this boolean expression contains a logic bug
--> $DIR/booleans.rs:12:13
|
12 | let _ = a && b || a;
| ^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/booleans.rs:3:26
|
3 | #![deny(nonminimal_bool, logic_bug)]
| ^^^^^^^^^
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/booleans.rs:12:18
|
12 | let _ = a && b || a;
| ^
help: it would look like the following
| let _ = a;
error: this boolean expression can be simplified
--> $DIR/booleans.rs:17:13
|
17 | let _ = !true;
| ^^^^^
|
note: lint level defined here
--> $DIR/booleans.rs:3:9
|
3 | #![deny(nonminimal_bool, logic_bug)]
| ^^^^^^^^^^^^^^^
help: try
| let _ = false;
error: this boolean expression can be simplified
--> $DIR/booleans.rs:20:13
|
20 | let _ = !false;
| ^^^^^^
|
help: try
| let _ = true;
error: this boolean expression can be simplified
--> $DIR/booleans.rs:23:13
|
23 | let _ = !!a;
| ^^^
|
help: try
| let _ = a;
error: this boolean expression contains a logic bug
--> $DIR/booleans.rs:27:13
|
27 | let _ = false && a;
| ^^^^^^^^^^
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/booleans.rs:27:22
|
27 | let _ = false && a;
| ^
help: it would look like the following
| let _ = false;
error: this boolean expression can be simplified
--> $DIR/booleans.rs:32:13
|
32 | let _ = false || a;
| ^^^^^^^^^^
|
help: try
| let _ = a;
error: this boolean expression can be simplified
--> $DIR/booleans.rs:43:13
|
43 | let _ = !(!a && b);
| ^^^^^^^^^^
|
help: try
| let _ = !b || a;
error: this boolean expression contains a logic bug
--> $DIR/booleans.rs:55:13
|
55 | let _ = a == b && a != b;
| ^^^^^^^^^^^^^^^^
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/booleans.rs:55:13
|
55 | let _ = a == b && a != b;
| ^^^^^^
help: it would look like the following
| let _ = false;
error: this boolean expression can be simplified
--> $DIR/booleans.rs:60:13
|
60 | let _ = a == b && c == 5 && a == b;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: try
| let _ = a == b && c == 5;
help: try
| let _ = !(c != 5 || a != b);
error: this boolean expression can be simplified
--> $DIR/booleans.rs:66:13
|
66 | let _ = a == b && c == 5 && b == a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: try
| let _ = a == b && c == 5;
help: try
| let _ = !(c != 5 || a != b);
error: this boolean expression contains a logic bug
--> $DIR/booleans.rs:72:13
|
72 | let _ = a < b && a >= b;
| ^^^^^^^^^^^^^^^
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/booleans.rs:72:13
|
72 | let _ = a < b && a >= b;
| ^^^^^
help: it would look like the following
| let _ = false;
error: this boolean expression contains a logic bug
--> $DIR/booleans.rs:77:13
|
77 | let _ = a > b && a <= b;
| ^^^^^^^^^^^^^^^
|
help: this expression can be optimized out by applying boolean operations to the outer expression
--> $DIR/booleans.rs:77:13
|
77 | let _ = a > b && a <= b;
| ^^^^^
help: it would look like the following
| let _ = false;
error: this boolean expression can be simplified
--> $DIR/booleans.rs:84:13
|
84 | let _ = a != b || !(a != b || c == d);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: try
| let _ = c != d || a != b;
help: try
| let _ = !(a == b && c == d);
error: aborting due to 13 previous errors

View File

@ -14,7 +14,7 @@ macro_rules! boxit {
fn test_macro() {
boxit!(Vec::new(), Vec<u8>);
}
pub fn test(foo: Box<Vec<bool>>) { //~ ERROR you seem to be trying to use `Box<Vec<T>>`
pub fn test(foo: Box<Vec<bool>>) {
println!("{:?}", foo.get(0))
}

16
tests/ui/box_vec.stderr Normal file
View File

@ -0,0 +1,16 @@
error: you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`
--> $DIR/box_vec.rs:17:18
|
17 | pub fn test(foo: Box<Vec<bool>>) {
| ^^^^^^^^^^^^^^
|
= note: #[deny(box_vec)] implied by #[deny(clippy)]
note: lint level defined here
--> $DIR/box_vec.rs:4:9
|
4 | #![deny(clippy)]
| ^^^^^^
= help: `Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.
error: aborting due to previous error

View File

@ -2,8 +2,8 @@
#![plugin(clippy)]
#![deny(builtin_type_shadow)]
fn foo<u32>(a: u32) -> u32 { //~ERROR shadows the built-in type `u32`
42 //~ERROR E0308
fn foo<u32>(a: u32) -> u32 {
42
// ^ rustc's type error
}

View File

@ -0,0 +1,23 @@
error: This generic shadows the built-in type `u32`
--> $DIR/builtin-type-shadow.rs:5:8
|
5 | fn foo<u32>(a: u32) -> u32 {
| ^^^
|
note: lint level defined here
--> $DIR/builtin-type-shadow.rs:3:9
|
3 | #![deny(builtin_type_shadow)]
| ^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/builtin-type-shadow.rs:6:5
|
6 | 42
| ^^ expected type parameter, found integral variable
|
= note: expected type `u32`
found type `{integer}`
error: aborting due to previous error

64
tests/ui/cast.rs Normal file
View File

@ -0,0 +1,64 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap)]
#[allow(no_effect, unnecessary_operation)]
fn main() {
// Test cast_precision_loss
1i32 as f32;
1i64 as f32;
1i64 as f64;
1u32 as f32;
1u64 as f32;
1u64 as f64;
1i32 as f64; // Should not trigger the lint
1u32 as f64; // Should not trigger the lint
// Test cast_possible_truncation
1f32 as i32;
1f32 as u32;
1f64 as f32;
1i32 as i8;
1i32 as u8;
1f64 as isize;
1f64 as usize;
// Test cast_possible_wrap
1u8 as i8;
1u16 as i16;
1u32 as i32;
1u64 as i64;
1usize as isize;
// Test cast_sign_loss
1i32 as u32;
1isize as usize;
// Extra checks for *size
// Casting from *size
1isize as i8;
1isize as f64;
1usize as f64;
1isize as f32;
1usize as f32;
1isize as i32;
1isize as u32;
1usize as u32;
1usize as i32;
// Casting to *size
1i64 as isize;
1i64 as usize;
1u64 as isize;
1u64 as usize;
1u32 as isize;
1u32 as usize; // Should not trigger any lint
1i32 as isize; // Neither should this
1i32 as usize;
}

278
tests/ui/cast.stderr Normal file
View File

@ -0,0 +1,278 @@
error: casting i32 to f32 causes a loss of precision (i32 is 32 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:8:5
|
8 | 1i32 as f32;
| ^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/cast.rs:4:8
|
4 | #[deny(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap)]
| ^^^^^^^^^^^^^^^^^^^
error: casting i64 to f32 causes a loss of precision (i64 is 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:9:5
|
9 | 1i64 as f32;
| ^^^^^^^^^^^
error: casting i64 to f64 causes a loss of precision (i64 is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast.rs:10:5
|
10 | 1i64 as f64;
| ^^^^^^^^^^^
error: casting u32 to f32 causes a loss of precision (u32 is 32 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:11:5
|
11 | 1u32 as f32;
| ^^^^^^^^^^^
error: casting u64 to f32 causes a loss of precision (u64 is 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:12:5
|
12 | 1u64 as f32;
| ^^^^^^^^^^^
error: casting u64 to f64 causes a loss of precision (u64 is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast.rs:13:5
|
13 | 1u64 as f64;
| ^^^^^^^^^^^
error: casting f32 to i32 may truncate the value
--> $DIR/cast.rs:18:5
|
18 | 1f32 as i32;
| ^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/cast.rs:4:29
|
4 | #[deny(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: casting f32 to u32 may truncate the value
--> $DIR/cast.rs:19:5
|
19 | 1f32 as u32;
| ^^^^^^^^^^^
error: casting f32 to u32 may lose the sign of the value
--> $DIR/cast.rs:19:5
|
19 | 1f32 as u32;
| ^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/cast.rs:4:55
|
4 | #[deny(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap)]
| ^^^^^^^^^^^^^^
error: casting f64 to f32 may truncate the value
--> $DIR/cast.rs:21:5
|
21 | 1f64 as f32;
| ^^^^^^^^^^^
error: casting i32 to i8 may truncate the value
--> $DIR/cast.rs:22:5
|
22 | 1i32 as i8;
| ^^^^^^^^^^
error: casting i32 to u8 may lose the sign of the value
--> $DIR/cast.rs:23:5
|
23 | 1i32 as u8;
| ^^^^^^^^^^
error: casting i32 to u8 may truncate the value
--> $DIR/cast.rs:23:5
|
23 | 1i32 as u8;
| ^^^^^^^^^^
error: casting f64 to isize may truncate the value
--> $DIR/cast.rs:25:5
|
25 | 1f64 as isize;
| ^^^^^^^^^^^^^
error: casting f64 to usize may truncate the value
--> $DIR/cast.rs:26:5
|
26 | 1f64 as usize;
| ^^^^^^^^^^^^^
error: casting f64 to usize may lose the sign of the value
--> $DIR/cast.rs:26:5
|
26 | 1f64 as usize;
| ^^^^^^^^^^^^^
error: casting u8 to i8 may wrap around the value
--> $DIR/cast.rs:30:5
|
30 | 1u8 as i8;
| ^^^^^^^^^
|
note: lint level defined here
--> $DIR/cast.rs:4:71
|
4 | #[deny(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap)]
| ^^^^^^^^^^^^^^^^^^
error: casting u16 to i16 may wrap around the value
--> $DIR/cast.rs:31:5
|
31 | 1u16 as i16;
| ^^^^^^^^^^^
error: casting u32 to i32 may wrap around the value
--> $DIR/cast.rs:32:5
|
32 | 1u32 as i32;
| ^^^^^^^^^^^
error: casting u64 to i64 may wrap around the value
--> $DIR/cast.rs:33:5
|
33 | 1u64 as i64;
| ^^^^^^^^^^^
error: casting usize to isize may wrap around the value
--> $DIR/cast.rs:34:5
|
34 | 1usize as isize;
| ^^^^^^^^^^^^^^^
error: casting i32 to u32 may lose the sign of the value
--> $DIR/cast.rs:37:5
|
37 | 1i32 as u32;
| ^^^^^^^^^^^
error: casting isize to usize may lose the sign of the value
--> $DIR/cast.rs:38:5
|
38 | 1isize as usize;
| ^^^^^^^^^^^^^^^
error: casting isize to i8 may truncate the value
--> $DIR/cast.rs:42:5
|
42 | 1isize as i8;
| ^^^^^^^^^^^^
error: casting isize to f64 causes a loss of precision on targets with 64-bit wide pointers (isize is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast.rs:43:5
|
43 | 1isize as f64;
| ^^^^^^^^^^^^^
error: casting usize to f64 causes a loss of precision on targets with 64-bit wide pointers (usize is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast.rs:44:5
|
44 | 1usize as f64;
| ^^^^^^^^^^^^^
error: casting isize to f32 causes a loss of precision (isize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:45:5
|
45 | 1isize as f32;
| ^^^^^^^^^^^^^
error: casting usize to f32 causes a loss of precision (usize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:46:5
|
46 | 1usize as f32;
| ^^^^^^^^^^^^^
error: casting isize to i32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:47:5
|
47 | 1isize as i32;
| ^^^^^^^^^^^^^
error: casting isize to u32 may lose the sign of the value
--> $DIR/cast.rs:48:5
|
48 | 1isize as u32;
| ^^^^^^^^^^^^^
error: casting isize to u32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:48:5
|
48 | 1isize as u32;
| ^^^^^^^^^^^^^
error: casting usize to u32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:50:5
|
50 | 1usize as u32;
| ^^^^^^^^^^^^^
error: casting usize to i32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:51:5
|
51 | 1usize as i32;
| ^^^^^^^^^^^^^
error: casting usize to i32 may wrap around the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:51:5
|
51 | 1usize as i32;
| ^^^^^^^^^^^^^
error: casting i64 to isize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:54:5
|
54 | 1i64 as isize;
| ^^^^^^^^^^^^^
error: casting i64 to usize may lose the sign of the value
--> $DIR/cast.rs:55:5
|
55 | 1i64 as usize;
| ^^^^^^^^^^^^^
error: casting i64 to usize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:55:5
|
55 | 1i64 as usize;
| ^^^^^^^^^^^^^
error: casting u64 to isize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:57:5
|
57 | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting u64 to isize may wrap around the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:57:5
|
57 | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting u64 to usize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:59:5
|
59 | 1u64 as usize;
| ^^^^^^^^^^^^^
error: casting u32 to isize may wrap around the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:60:5
|
60 | 1u32 as isize;
| ^^^^^^^^^^^^^
error: casting i32 to usize may lose the sign of the value
--> $DIR/cast.rs:63:5
|
63 | 1i32 as usize;
| ^^^^^^^^^^^^^
error: aborting due to 42 previous errors

View File

@ -4,5 +4,5 @@
#![deny(char_lit_as_u8)]
#![allow(unused_variables)]
fn main() {
let c = 'a' as u8; //~ERROR casting character literal
let c = 'a' as u8;
}

View File

@ -0,0 +1,16 @@
error: casting character literal to u8. `char`s are 4 bytes wide in rust, so casting to u8 truncates them
--> $DIR/char_lit_as_u8.rs:7:13
|
7 | let c = 'a' as u8;
| ^^^^^^^^^
|
note: lint level defined here
--> $DIR/char_lit_as_u8.rs:4:9
|
4 | #![deny(char_lit_as_u8)]
| ^^^^^^^^^^^^^^
= help: Consider using a byte literal instead:
b'a'
error: aborting due to previous error

22
tests/ui/cmp_nan.rs Normal file
View File

@ -0,0 +1,22 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(cmp_nan)]
#[allow(float_cmp, no_effect, unnecessary_operation)]
fn main() {
let x = 5f32;
x == std::f32::NAN;
x != std::f32::NAN;
x < std::f32::NAN;
x > std::f32::NAN;
x <= std::f32::NAN;
x >= std::f32::NAN;
let y = 0f64;
y == std::f64::NAN;
y != std::f64::NAN;
y < std::f64::NAN;
y > std::f64::NAN;
y <= std::f64::NAN;
y >= std::f64::NAN;
}

98
tests/ui/cmp_nan.stderr Normal file
View File

@ -0,0 +1,98 @@
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:8:5
|
8 | x == std::f32::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:9:5
|
9 | x != std::f32::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:10:5
|
10 | x < std::f32::NAN;
| ^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:11:5
|
11 | x > std::f32::NAN;
| ^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:12:5
|
12 | x <= std::f32::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:13:5
|
13 | x >= std::f32::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:16:5
|
16 | y == std::f64::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:17:5
|
17 | y != std::f64::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:18:5
|
18 | y < std::f64::NAN;
| ^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:19:5
|
19 | y > std::f64::NAN;
| ^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:20:5
|
20 | y <= std::f64::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
--> $DIR/cmp_nan.rs:21:5
|
21 | y >= std::f64::NAN;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[deny(cmp_nan)] on by default
error: aborting due to 12 previous errors

View File

@ -8,12 +8,12 @@ use std::ptr;
fn main() {
let x = 0;
let p : *const usize = &x;
if p == ptr::null() { //~ERROR: Comparing with null
if p == ptr::null() {
println!("This is surprising!");
}
let mut y = 0;
let mut m : *mut usize = &mut y;
if m == ptr::null_mut() { //~ERROR: Comparing with null
if m == ptr::null_mut() {
println!("This is surprising, too!");
}
}

20
tests/ui/cmp_null.stderr Normal file
View File

@ -0,0 +1,20 @@
error: Comparing with null is better expressed by the .is_null() method
--> $DIR/cmp_null.rs:11:8
|
11 | if p == ptr::null() {
| ^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/cmp_null.rs:3:9
|
3 | #![deny(cmp_null)]
| ^^^^^^^^
error: Comparing with null is better expressed by the .is_null() method
--> $DIR/cmp_null.rs:16:8
|
16 | if m == ptr::null_mut() {
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

27
tests/ui/cmp_owned.rs Normal file
View File

@ -0,0 +1,27 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(cmp_owned)]
#[allow(unnecessary_operation)]
fn main() {
fn with_to_string(x : &str) {
x != "foo".to_string();
"foo".to_string() != x;
}
let x = "oh";
with_to_string(x);
x != "foo".to_owned();
// removed String::from_str(..), as it has finally been removed in 1.4.0
// as of 2015-08-14
x != String::from("foo");
42.to_string() == "42";
}

32
tests/ui/cmp_owned.stderr Normal file
View File

@ -0,0 +1,32 @@
error: this creates an owned instance just for comparison. Consider using `x != "foo"` to compare without allocation
--> $DIR/cmp_owned.rs:8:14
|
8 | x != "foo".to_string();
| ^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/cmp_owned.rs:4:8
|
4 | #[deny(cmp_owned)]
| ^^^^^^^^^
error: this creates an owned instance just for comparison. Consider using `"foo" != x` to compare without allocation
--> $DIR/cmp_owned.rs:11:9
|
11 | "foo".to_string() != x;
| ^^^^^^^^^^^^^^^^^
error: this creates an owned instance just for comparison. Consider using `x != "foo"` to compare without allocation
--> $DIR/cmp_owned.rs:19:10
|
19 | x != "foo".to_owned();
| ^^^^^^^^^^^^^^^^
error: this creates an owned instance just for comparison. Consider using `x != "foo"` to compare without allocation
--> $DIR/cmp_owned.rs:24:10
|
24 | x != String::from("foo");
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors

View File

@ -6,54 +6,54 @@ fn main() {
let x = "hello";
let y = "world";
if x == "hello" {
//~^ ERROR this if statement can be collapsed
//~| HELP try
//~| SUGGESTION if x == "hello" && y == "world" {
if y == "world" {
println!("Hello world!");
}
}
if x == "hello" || x == "world" {
//~^ ERROR this if statement can be collapsed
//~| HELP try
//~| SUGGESTION if (x == "hello" || x == "world") && (y == "world" || y == "hello") {
if y == "world" || y == "hello" {
println!("Hello world!");
}
}
if x == "hello" && x == "world" {
//~^ ERROR this if statement can be collapsed
//~| HELP try
//~| SUGGESTION if x == "hello" && x == "world" && (y == "world" || y == "hello") {
if y == "world" || y == "hello" {
println!("Hello world!");
}
}
if x == "hello" || x == "world" {
//~^ ERROR this if statement can be collapsed
//~| HELP try
//~| SUGGESTION if (x == "hello" || x == "world") && y == "world" && y == "hello" {
if y == "world" && y == "hello" {
println!("Hello world!");
}
}
if x == "hello" && x == "world" {
//~^ ERROR this if statement can be collapsed
//~| HELP try
//~| SUGGESTION if x == "hello" && x == "world" && y == "world" && y == "hello" {
if y == "world" && y == "hello" {
println!("Hello world!");
}
}
if 42 == 1337 {
//~^ ERROR this if statement can be collapsed
//~| HELP try
//~| SUGGESTION if 42 == 1337 && 'a' != 'A' {
if 'a' != 'A' {
println!("world!")
}
@ -63,9 +63,9 @@ fn main() {
if x == "hello" {
print!("Hello ");
} else {
//~^ ERROR: this `else { if .. }`
//~| HELP try
//~| SUGGESTION } else if y == "world"
if y == "world" {
println!("world!")
}
@ -74,9 +74,9 @@ fn main() {
if x == "hello" {
print!("Hello ");
} else {
//~^ ERROR: this `else { if .. }`
//~| HELP try
//~| SUGGESTION } else if let Some(42)
if let Some(42) = Some(42) {
println!("world!")
}
@ -85,9 +85,9 @@ fn main() {
if x == "hello" {
print!("Hello ");
} else {
//~^ ERROR this `else { if .. }`
//~| HELP try
//~| SUGGESTION } else if y == "world"
if y == "world" {
println!("world")
}
@ -99,9 +99,9 @@ fn main() {
if x == "hello" {
print!("Hello ");
} else {
//~^ ERROR this `else { if .. }`
//~| HELP try
//~| SUGGESTION } else if let Some(42)
if let Some(42) = Some(42) {
println!("world")
}
@ -113,9 +113,9 @@ fn main() {
if let Some(42) = Some(42) {
print!("Hello ");
} else {
//~^ ERROR this `else { if .. }`
//~| HELP try
//~| SUGGESTION } else if let Some(42)
if let Some(42) = Some(42) {
println!("world")
}
@ -127,9 +127,9 @@ fn main() {
if let Some(42) = Some(42) {
print!("Hello ");
} else {
//~^ ERROR this `else { if .. }`
//~| HELP try
//~| SUGGESTION } else if x == "hello"
if x == "hello" {
println!("world")
}
@ -141,9 +141,9 @@ fn main() {
if let Some(42) = Some(42) {
print!("Hello ");
} else {
//~^ ERROR this `else { if .. }`
//~| HELP try
//~| SUGGESTION } else if let Some(42)
if let Some(42) = Some(42) {
println!("world")
}

View File

@ -0,0 +1,229 @@
error: this if statement can be collapsed
--> $DIR/collapsible_if.rs:8:5
|
8 | if x == "hello" {
| _____^ starting here...
9 | |
10 | |
11 | |
12 | | if y == "world" {
13 | | println!("Hello world!");
14 | | }
15 | | }
| |_____^ ...ending here
|
note: lint level defined here
--> $DIR/collapsible_if.rs:4:8
|
4 | #[deny(collapsible_if)]
| ^^^^^^^^^^^^^^
help: try
| if x == "hello" && y == "world" {
| println!("Hello world!");
| }
error: this if statement can be collapsed
--> $DIR/collapsible_if.rs:17:5
|
17 | if x == "hello" || x == "world" {
| _____^ starting here...
18 | |
19 | |
20 | |
21 | | if y == "world" || y == "hello" {
22 | | println!("Hello world!");
23 | | }
24 | | }
| |_____^ ...ending here
|
help: try
| if (x == "hello" || x == "world") && (y == "world" || y == "hello") {
| println!("Hello world!");
| }
error: this if statement can be collapsed
--> $DIR/collapsible_if.rs:26:5
|
26 | if x == "hello" && x == "world" {
| _____^ starting here...
27 | |
28 | |
29 | |
30 | | if y == "world" || y == "hello" {
31 | | println!("Hello world!");
32 | | }
33 | | }
| |_____^ ...ending here
|
help: try
| if x == "hello" && x == "world" && (y == "world" || y == "hello") {
| println!("Hello world!");
| }
error: this if statement can be collapsed
--> $DIR/collapsible_if.rs:35:5
|
35 | if x == "hello" || x == "world" {
| _____^ starting here...
36 | |
37 | |
38 | |
39 | | if y == "world" && y == "hello" {
40 | | println!("Hello world!");
41 | | }
42 | | }
| |_____^ ...ending here
|
help: try
| if (x == "hello" || x == "world") && y == "world" && y == "hello" {
| println!("Hello world!");
| }
error: this if statement can be collapsed
--> $DIR/collapsible_if.rs:44:5
|
44 | if x == "hello" && x == "world" {
| _____^ starting here...
45 | |
46 | |
47 | |
48 | | if y == "world" && y == "hello" {
49 | | println!("Hello world!");
50 | | }
51 | | }
| |_____^ ...ending here
|
help: try
| if x == "hello" && x == "world" && y == "world" && y == "hello" {
| println!("Hello world!");
| }
error: this if statement can be collapsed
--> $DIR/collapsible_if.rs:53:5
|
53 | if 42 == 1337 {
| _____^ starting here...
54 | |
55 | |
56 | |
57 | | if 'a' != 'A' {
58 | | println!("world!")
59 | | }
60 | | }
| |_____^ ...ending here
|
help: try
| if 42 == 1337 && 'a' != 'A' {
| println!("world!")
| }
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:65:12
|
65 | } else {
| ____________^ starting here...
66 | |
67 | |
68 | |
69 | | if y == "world" {
70 | | println!("world!")
71 | | }
72 | | }
| |_____^ ...ending here
|
help: try
| } else if y == "world" {
| println!("world!")
| }
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:76:12
|
76 | } else {
| ____________^ starting here...
77 | |
78 | |
79 | |
80 | | if let Some(42) = Some(42) {
81 | | println!("world!")
82 | | }
83 | | }
| |_____^ ...ending here
|
help: try
| } else if let Some(42) = Some(42) {
| println!("world!")
| }
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:87:12
|
87 | } else {
| ^
|
help: try
| } else if y == "world" {
| println!("world")
| }
| else {
| println!("!")
| }
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:101:12
|
101 | } else {
| ^
|
help: try
| } else if let Some(42) = Some(42) {
| println!("world")
| }
| else {
| println!("!")
| }
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:115:12
|
115 | } else {
| ^
|
help: try
| } else if let Some(42) = Some(42) {
| println!("world")
| }
| else {
| println!("!")
| }
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:129:12
|
129 | } else {
| ^
|
help: try
| } else if x == "hello" {
| println!("world")
| }
| else {
| println!("!")
| }
error: this `else { if .. }` block can be collapsed
--> $DIR/collapsible_if.rs:143:12
|
143 | } else {
| ^
|
help: try
| } else if let Some(42) = Some(42) {
| println!("world")
| }
| else {
| println!("!")
| }
error: aborting due to 13 previous errors

44
tests/ui/complex_types.rs Normal file
View File

@ -0,0 +1,44 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy)]
#![allow(unused)]
#![feature(associated_consts, associated_type_defaults)]
type Alias = Vec<Vec<Box<(u32, u32, u32, u32)>>>; // no warning here
const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
struct S {
f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,
}
struct TS(Vec<Vec<Box<(u32, u32, u32, u32)>>>);
enum E {
Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),
Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },
}
impl S {
const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { }
}
trait T {
const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;
type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);
fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { }
}
fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> { vec![] }
fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { }
fn test3() {
let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
}
fn main() {
}

View File

@ -0,0 +1,127 @@
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:9:12
|
9 | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
note: lint level defined here
--> $DIR/complex_types.rs:3:9
|
3 | #![deny(clippy)]
| ^^^^^^
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:10:12
|
10 | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:13:8
|
13 | f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:16:11
|
16 | struct TS(Vec<Vec<Box<(u32, u32, u32, u32)>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:19:11
|
19 | Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:20:17
|
20 | Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:24:14
|
24 | const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:25:30
|
25 | fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:29:14
|
29 | const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:30:14
|
30 | type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:31:25
|
31 | fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:32:29
|
32 | fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:35:15
|
35 | fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> { vec![] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:37:14
|
37 | fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: very complex type used. Consider factoring parts into `type` definitions
--> $DIR/complex_types.rs:40:13
|
40 | let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(type_complexity)] implied by #[deny(clippy)]
error: aborting due to 15 previous errors

View File

@ -0,0 +1,14 @@
error: `conf_file` must be a named value
--> $DIR/conf_bad_arg.rs:4:18
|
4 | #![plugin(clippy(conf_file))]
| ^^^^^^^^^
|
note: Clippy will use default configuration
--> $DIR/conf_bad_arg.rs:4:18
|
4 | #![plugin(clippy(conf_file))]
| ^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,4 @@
error: error reading Clippy's configuration file: No such file or directory (os error 2)
error: aborting due to previous error

View File

@ -0,0 +1,4 @@
error: error reading Clippy's configuration file: No such file or directory (os error 2)
error: aborting due to previous error

Some files were not shown because too many files have changed in this diff Show More