diff --git a/CHANGELOG.md b/CHANGELOG.md index 42df561a6e12..b72387f0d718 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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`] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8734242c6c01..d481cfe0fa90 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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). diff --git a/Cargo.toml b/Cargo.toml index e46d3363a0d1..a45a7edf0fe2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.0.113" +version = "0.0.114" authors = [ "Manish Goregaokar ", "Andre Bogus ", @@ -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" diff --git a/README.md b/README.md index bb4b596a049e..3f3ed135e0ce 100644 --- a/README.md +++ b/README.md @@ -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 -----------------------------------------------------------------------------------------------------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------- diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 8a81dc75e978..d7a95ba04dd4 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -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 ", diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index b2a8d26000d1..951dd51dec44 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -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; }, _ => (), diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index ccdcb94d212c..b1581127c325 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -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", diff --git a/tests/compile-fail/absurd-extreme-comparisons.rs b/tests/compile-fail/absurd-extreme-comparisons.rs deleted file mode 100644 index cf69473bbe5f..000000000000 --- a/tests/compile-fail/absurd-extreme-comparisons.rs +++ /dev/null @@ -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 for U { - fn eq(&self, other: &u32) -> bool { - self.eq(&U(*other as u64)) - } -} -impl PartialOrd for U { - fn partial_cmp(&self, other: &u32) -> Option { - self.partial_cmp(&U(*other as u64)) - } -} - -pub fn foo(val: U) -> bool { - val > std::u32::MAX -} diff --git a/tests/compile-fail/approx_const.rs b/tests/compile-fail/approx_const.rs deleted file mode 100644 index 2240c3799a3c..000000000000 --- a/tests/compile-fail/approx_const.rs +++ /dev/null @@ -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; -} diff --git a/tests/compile-fail/arithmetic.rs b/tests/compile-fail/arithmetic.rs deleted file mode 100644 index 5479c55e11e0..000000000000 --- a/tests/compile-fail/arithmetic.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/array_indexing.rs b/tests/compile-fail/array_indexing.rs deleted file mode 100644 index c69144fe2920..000000000000 --- a/tests/compile-fail/array_indexing.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/assign_ops.rs b/tests/compile-fail/assign_ops.rs deleted file mode 100644 index 2b69e110f43d..000000000000 --- a/tests/compile-fail/assign_ops.rs +++ /dev/null @@ -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"; -} diff --git a/tests/compile-fail/assign_ops2.rs b/tests/compile-fail/assign_ops2.rs deleted file mode 100644 index e8549c01bc93..000000000000 --- a/tests/compile-fail/assign_ops2.rs +++ /dev/null @@ -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 for Wrap { - type Output = Self; - - fn mul(self, rhs: i64) -> Self { - Wrap(self.0 * rhs) - } -} - -impl MulAssign for Wrap { - fn mul_assign(&mut self, rhs: i64) { - *self = *self * rhs - } -} diff --git a/tests/compile-fail/blacklisted_name.rs b/tests/compile-fail/blacklisted_name.rs deleted file mode 100644 index 1afcd94a0b1d..000000000000 --- a/tests/compile-fail/blacklisted_name.rs +++ /dev/null @@ -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` - _ => (), - } -} diff --git a/tests/compile-fail/bool_comparison.rs b/tests/compile-fail/bool_comparison.rs deleted file mode 100644 index 836759455197..000000000000 --- a/tests/compile-fail/bool_comparison.rs +++ /dev/null @@ -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" }; -} diff --git a/tests/compile-fail/booleans.rs b/tests/compile-fail/booleans.rs deleted file mode 100644 index 193edebf3c4f..000000000000 --- a/tests/compile-fail/booleans.rs +++ /dev/null @@ -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); -} diff --git a/tests/compile-fail/cast.rs b/tests/compile-fail/cast.rs deleted file mode 100644 index d0ea5f40789d..000000000000 --- a/tests/compile-fail/cast.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/cmp_nan.rs b/tests/compile-fail/cmp_nan.rs deleted file mode 100644 index 8d173665a242..000000000000 --- a/tests/compile-fail/cmp_nan.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/cmp_owned.rs b/tests/compile-fail/cmp_owned.rs deleted file mode 100644 index f7c7824e9d1c..000000000000 --- a/tests/compile-fail/cmp_owned.rs +++ /dev/null @@ -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"; -} diff --git a/tests/compile-fail/complex_types.rs b/tests/compile-fail/complex_types.rs deleted file mode 100644 index ad01e4fadd5f..000000000000 --- a/tests/compile-fail/complex_types.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![feature(plugin)] -#![plugin(clippy)] -#![deny(clippy)] -#![allow(unused)] -#![feature(associated_consts, associated_type_defaults)] - -type Alias = Vec>>; // 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>>, //~ERROR very complex type -} - -struct TS(Vec>>); //~ERROR very complex type - -enum E { - Tuple(Vec>>), //~ERROR very complex type - Struct { f: Vec>> }, //~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>>) { } //~ERROR very complex type -} - -trait T { - const A: Vec>>; //~ERROR very complex type - type B = Vec>>; //~ERROR very complex type - fn method(&self, p: Vec>>); //~ERROR very complex type - fn def_method(&self, p: Vec>>) { } //~ERROR very complex type -} - -fn test1() -> Vec>> { vec![] } //~ERROR very complex type - -fn test2(_x: Vec>>) { } //~ERROR very complex type - -fn test3() { - let _y: Vec>> = vec![]; //~ERROR very complex type -} - -fn main() { -} diff --git a/tests/compile-fail/conf_french_blacklisted_name.rs b/tests/compile-fail/conf_french_blacklisted_name.rs deleted file mode 100644 index 4c306a98b201..000000000000 --- a/tests/compile-fail/conf_french_blacklisted_name.rs +++ /dev/null @@ -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` - _ => (), - } -} diff --git a/tests/compile-fail/drop_forget_ref.rs b/tests/compile-fail/drop_forget_ref.rs deleted file mode 100644 index 55cfe63dac4c..000000000000 --- a/tests/compile-fail/drop_forget_ref.rs +++ /dev/null @@ -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(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(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(_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(_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 -} diff --git a/tests/compile-fail/empty_enum.rs b/tests/compile-fail/empty_enum.rs deleted file mode 100644 index ac9b314c00a6..000000000000 --- a/tests/compile-fail/empty_enum.rs +++ /dev/null @@ -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() { -} diff --git a/tests/compile-fail/enums_clike.rs b/tests/compile-fail/enums_clike.rs deleted file mode 100644 index c342bf8f332b..000000000000 --- a/tests/compile-fail/enums_clike.rs +++ /dev/null @@ -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 { - X = Trait::Number, - Y = 0, -} - -trait Trait { - const Number: usize = 0x1_0000_0000; -} -*/ - -fn main() { -} diff --git a/tests/compile-fail/eq_op.rs b/tests/compile-fail/eq_op.rs deleted file mode 100644 index c133f4227776..000000000000 --- a/tests/compile-fail/eq_op.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/if_let_redundant_pattern_matching.rs b/tests/compile-fail/if_let_redundant_pattern_matching.rs deleted file mode 100644 index 24a3864b0133..000000000000 --- a/tests/compile-fail/if_let_redundant_pattern_matching.rs +++ /dev/null @@ -1,53 +0,0 @@ -#![feature(plugin)] - -#![plugin(clippy)] -#![deny(clippy)] -#![deny(if_let_redundant_pattern_matching)] - - -fn main() { - if let Ok(_) = Ok::(42) {} - //~^ERROR redundant pattern matching, consider using `is_ok()` - //~| HELP try this - //~| SUGGESTION if Ok::(42).is_ok() { - - if let Err(_) = Err::(42) { - //~^ERROR redundant pattern matching, consider using `is_err()` - //~| HELP try this - //~| SUGGESTION if Err::(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::(42).is_ok() { - - } - - if Err::(42).is_err() { - - } - - if None::.is_none() { - - } - - if Some(42).is_some() { - - } - - if let Ok(x) = Ok::(42) { - println!("{}", x); - } -} - - diff --git a/tests/compile-fail/invalid_upcast_comparisons.rs b/tests/compile-fail/invalid_upcast_comparisons.rs deleted file mode 100644 index 9635f3afede9..000000000000 --- a/tests/compile-fail/invalid_upcast_comparisons.rs +++ /dev/null @@ -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; -} diff --git a/tests/compile-fail/large_enum_variant.rs b/tests/compile-fail/large_enum_variant.rs deleted file mode 100644 index 8d289a328324..000000000000 --- a/tests/compile-fail/large_enum_variant.rs +++ /dev/null @@ -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 { - 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 { - 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 - 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() { - -} diff --git a/tests/compile-fail/literals.rs b/tests/compile-fail/literals.rs deleted file mode 100644 index 6c8a27c2ed4a..000000000000 --- a/tests/compile-fail/literals.rs +++ /dev/null @@ -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; -} diff --git a/tests/compile-fail/methods.rs b/tests/compile-fail/methods.rs index 43a4386886d9..34a0773df27f 100644 --- a/tests/compile-fail/methods.rs +++ b/tests/compile-fail/methods.rs @@ -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::::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::::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 = 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 = Ok(0); res2.ok().expect("oh noes!"); let res3: Result>= Ok(0); - res3.ok().expect("whoof"); //~ERROR called `ok().expect()` + res3.ok().expect("whoof"); let res4: Result = Ok(0); - res4.ok().expect("argh"); //~ERROR called `ok().expect()` + res4.ok().expect("argh"); let res5: io::Result = Ok(0); - res5.ok().expect("oops"); //~ERROR called `ok().expect()` + res5.ok().expect("oops"); let res6: Result = 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 { #[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: 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::::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 + + + } diff --git a/tests/compile-fail/min_max.rs b/tests/compile-fail/min_max.rs deleted file mode 100644 index 9a6794afebf1..000000000000 --- a/tests/compile-fail/min_max.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/mut_mut.rs b/tests/compile-fail/mut_mut.rs deleted file mode 100644 index edcc6906f082..000000000000 --- a/tests/compile-fail/mut_mut.rs +++ /dev/null @@ -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); - } -} diff --git a/tests/compile-fail/mutex_atomic.rs b/tests/compile-fail/mutex_atomic.rs deleted file mode 100644 index 20a34ba5547c..000000000000 --- a/tests/compile-fail/mutex_atomic.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/needless_bool.rs b/tests/compile-fail/needless_bool.rs deleted file mode 100644 index fb81d44308a0..000000000000 --- a/tests/compile-fail/needless_bool.rs +++ /dev/null @@ -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) -} diff --git a/tests/compile-fail/needless_return.rs b/tests/compile-fail/needless_return.rs deleted file mode 100644 index 442a0b925cbf..000000000000 --- a/tests/compile-fail/needless_return.rs +++ /dev/null @@ -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(); -} diff --git a/tests/compile-fail/no_effect.rs b/tests/compile-fail/no_effect.rs deleted file mode 100644 index 30a66a715f20..000000000000 --- a/tests/compile-fail/no_effect.rs +++ /dev/null @@ -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(); -} diff --git a/tests/compile-fail/non_expressive_names.rs b/tests/compile-fail/non_expressive_names.rs index 212dc2a96d50..649a5ecb812d 100644 --- a/tests/compile-fail/non_expressive_names.rs +++ b/tests/compile-fail/non_expressive_names.rs @@ -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!(""), diff --git a/tests/compile-fail/overflow_check_conditional.rs b/tests/compile-fail/overflow_check_conditional.rs deleted file mode 100644 index 24310eb81dae..000000000000 --- a/tests/compile-fail/overflow_check_conditional.rs +++ /dev/null @@ -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 { - - } -} diff --git a/tests/compile-fail/precedence.rs b/tests/compile-fail/precedence.rs deleted file mode 100644 index 28cc9e643c04..000000000000 --- a/tests/compile-fail/precedence.rs +++ /dev/null @@ -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()); -} diff --git a/tests/compile-fail/print_with_newline.rs b/tests/compile-fail/print_with_newline.rs deleted file mode 100644 index 4c1ebd9fe503..000000000000 --- a/tests/compile-fail/print_with_newline.rs +++ /dev/null @@ -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); -} diff --git a/tests/compile-fail/redundant_closure_call.rs b/tests/compile-fail/redundant_closure_call.rs deleted file mode 100644 index 73830ecc9f16..000000000000 --- a/tests/compile-fail/redundant_closure_call.rs +++ /dev/null @@ -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); -} - diff --git a/tests/compile-fail/reference.rs b/tests/compile-fail/reference.rs deleted file mode 100644 index 789425e71fe4..000000000000 --- a/tests/compile-fail/reference.rs +++ /dev/null @@ -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 = 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; - } -} diff --git a/tests/compile-fail/short_circuit_statement.rs b/tests/compile-fail/short_circuit_statement.rs deleted file mode 100644 index 23dfc0ebcaf2..000000000000 --- a/tests/compile-fail/short_circuit_statement.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-fail/strings.rs b/tests/compile-fail/strings.rs index d08f8b891bc9..f893d99491be 100644 --- a/tests/compile-fail/strings.rs +++ b/tests/compile-fail/strings.rs @@ -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); } diff --git a/tests/compile-fail/stutter.rs b/tests/compile-fail/stutter.rs deleted file mode 100644 index 0c99859c10d8..000000000000 --- a/tests/compile-fail/stutter.rs +++ /dev/null @@ -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() {} diff --git a/tests/compile-fail/swap.rs b/tests/compile-fail/swap.rs index c8ff2b610d01..95478dda0d32 100644 --- a/tests/compile-fail/swap.rs +++ b/tests/compile-fail/swap.rs @@ -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`? + + + + } diff --git a/tests/compile-fail/toplevel_ref_arg.rs b/tests/compile-fail/toplevel_ref_arg.rs deleted file mode 100644 index 86459ea97961..000000000000 --- a/tests/compile-fail/toplevel_ref_arg.rs +++ /dev/null @@ -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); -} diff --git a/tests/compile-fail/wrong_self_convention.rs b/tests/compile-fail/wrong_self_convention.rs deleted file mode 100644 index d22648c0cdba..000000000000 --- a/tests/compile-fail/wrong_self_convention.rs +++ /dev/null @@ -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) {} -} diff --git a/tests/compile-fail/zero_div_zero.rs b/tests/compile-fail/zero_div_zero.rs deleted file mode 100644 index c422e83873b0..000000000000 --- a/tests/compile-fail/zero_div_zero.rs +++ /dev/null @@ -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 -} diff --git a/tests/compile-test.rs b/tests/compile-test.rs index deadd499192d..bb60934d443e 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -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"); } diff --git a/tests/run-pass/deprecated.rs b/tests/run-pass/deprecated.rs index 670b096ea639..e0c856e3d7cc 100644 --- a/tests/run-pass/deprecated.rs +++ b/tests/run-pass/deprecated.rs @@ -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() {} diff --git a/tests/ui/absurd-extreme-comparisons.rs b/tests/ui/absurd-extreme-comparisons.rs new file mode 100644 index 000000000000..495dd27bb2bc --- /dev/null +++ b/tests/ui/absurd-extreme-comparisons.rs @@ -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 for U { + fn eq(&self, other: &u32) -> bool { + self.eq(&U(*other as u64)) + } +} +impl PartialOrd for U { + fn partial_cmp(&self, other: &u32) -> Option { + self.partial_cmp(&U(*other as u64)) + } +} + +pub fn foo(val: U) -> bool { + val > std::u32::MAX +} diff --git a/tests/ui/absurd-extreme-comparisons.stderr b/tests/ui/absurd-extreme-comparisons.stderr new file mode 100644 index 000000000000..834bcf03fe1e --- /dev/null +++ b/tests/ui/absurd-extreme-comparisons.stderr @@ -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 + diff --git a/tests/ui/approx_const.rs b/tests/ui/approx_const.rs new file mode 100644 index 000000000000..2da762725b15 --- /dev/null +++ b/tests/ui/approx_const.rs @@ -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; +} diff --git a/tests/ui/approx_const.stderr b/tests/ui/approx_const.stderr new file mode 100644 index 000000000000..cc0408fb2d9e --- /dev/null +++ b/tests/ui/approx_const.stderr @@ -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 + diff --git a/tests/ui/arithmetic.rs b/tests/ui/arithmetic.rs new file mode 100644 index 000000000000..b4014cc480fc --- /dev/null +++ b/tests/ui/arithmetic.rs @@ -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; +} diff --git a/tests/ui/arithmetic.stderr b/tests/ui/arithmetic.stderr new file mode 100644 index 000000000000..4f68b50ccbbb --- /dev/null +++ b/tests/ui/arithmetic.stderr @@ -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 + diff --git a/tests/ui/array_indexing.rs b/tests/ui/array_indexing.rs new file mode 100644 index 000000000000..28b4c78b4448 --- /dev/null +++ b/tests/ui/array_indexing.rs @@ -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]; +} diff --git a/tests/ui/array_indexing.stderr b/tests/ui/array_indexing.stderr new file mode 100644 index 000000000000..0650866ccdb6 --- /dev/null +++ b/tests/ui/array_indexing.stderr @@ -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 + diff --git a/tests/ui/assign_ops.rs b/tests/ui/assign_ops.rs new file mode 100644 index 000000000000..78f9dc0d0344 --- /dev/null +++ b/tests/ui/assign_ops.rs @@ -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"; +} diff --git a/tests/ui/assign_ops.stderr b/tests/ui/assign_ops.stderr new file mode 100644 index 000000000000..8ce2ae375f36 --- /dev/null +++ b/tests/ui/assign_ops.stderr @@ -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 + diff --git a/tests/ui/assign_ops2.rs b/tests/ui/assign_ops2.rs new file mode 100644 index 000000000000..3071cce161cc --- /dev/null +++ b/tests/ui/assign_ops2.rs @@ -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 for Wrap { + type Output = Self; + + fn mul(self, rhs: i64) -> Self { + Wrap(self.0 * rhs) + } +} + +impl MulAssign for Wrap { + fn mul_assign(&mut self, rhs: i64) { + *self = *self * rhs + } +} diff --git a/tests/ui/assign_ops2.stderr b/tests/ui/assign_ops2.stderr new file mode 100644 index 000000000000..ded39d1efc74 --- /dev/null +++ b/tests/ui/assign_ops2.stderr @@ -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 + diff --git a/tests/compile-fail/attrs.rs b/tests/ui/attrs.rs similarity index 70% rename from tests/compile-fail/attrs.rs rename to tests/ui/attrs.rs index 314602b2b0bf..50dddb83847e 100644 --- a/tests/compile-fail/attrs.rs +++ b/tests/ui/attrs.rs @@ -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")] diff --git a/tests/ui/attrs.stderr b/tests/ui/attrs.stderr new file mode 100644 index 000000000000..4ea0c5eece01 --- /dev/null +++ b/tests/ui/attrs.stderr @@ -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 + diff --git a/tests/compile-fail/bit_masks.rs b/tests/ui/bit_masks.rs similarity index 64% rename from tests/compile-fail/bit_masks.rs rename to tests/ui/bit_masks.rs index 79772840c73d..e8f2e47b283c 100644 --- a/tests/compile-fail/bit_masks.rs +++ b/tests/ui/bit_masks.rs @@ -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 diff --git a/tests/ui/bit_masks.stderr b/tests/ui/bit_masks.stderr new file mode 100644 index 000000000000..cba88f2827bd --- /dev/null +++ b/tests/ui/bit_masks.stderr @@ -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 + diff --git a/tests/ui/blacklisted_name.rs b/tests/ui/blacklisted_name.rs new file mode 100644 index 000000000000..16b4240fac2d --- /dev/null +++ b/tests/ui/blacklisted_name.rs @@ -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(_)) => (), + + + + _ => (), + } +} diff --git a/tests/ui/blacklisted_name.stderr b/tests/ui/blacklisted_name.stderr new file mode 100644 index 000000000000..29e9da2270f6 --- /dev/null +++ b/tests/ui/blacklisted_name.stderr @@ -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 + diff --git a/tests/compile-fail/block_in_if_condition.rs b/tests/ui/block_in_if_condition.rs similarity index 79% rename from tests/compile-fail/block_in_if_condition.rs rename to tests/ui/block_in_if_condition.rs index 090c39abc926..feb28e377970 100644 --- a/tests/compile-fail/block_in_if_condition.rs +++ b/tests/ui/block_in_if_condition.rs @@ -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 diff --git a/tests/ui/block_in_if_condition.stderr b/tests/ui/block_in_if_condition.stderr new file mode 100644 index 000000000000..d3e869024a7d --- /dev/null +++ b/tests/ui/block_in_if_condition.stderr @@ -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 + diff --git a/tests/ui/bool_comparison.rs b/tests/ui/bool_comparison.rs new file mode 100644 index 000000000000..3991d04bd2cc --- /dev/null +++ b/tests/ui/bool_comparison.rs @@ -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" }; + + + +} diff --git a/tests/ui/bool_comparison.stderr b/tests/ui/bool_comparison.stderr new file mode 100644 index 000000000000..9da1c76d07e6 --- /dev/null +++ b/tests/ui/bool_comparison.stderr @@ -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 + diff --git a/tests/ui/booleans.rs b/tests/ui/booleans.rs new file mode 100644 index 000000000000..fc1791f7f553 --- /dev/null +++ b/tests/ui/booleans.rs @@ -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); + + + + + +} diff --git a/tests/ui/booleans.stderr b/tests/ui/booleans.stderr new file mode 100644 index 000000000000..54f6638b938c --- /dev/null +++ b/tests/ui/booleans.stderr @@ -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 + diff --git a/tests/compile-fail/box_vec.rs b/tests/ui/box_vec.rs similarity index 84% rename from tests/compile-fail/box_vec.rs rename to tests/ui/box_vec.rs index 071945a81b23..01f1b1d09497 100644 --- a/tests/compile-fail/box_vec.rs +++ b/tests/ui/box_vec.rs @@ -14,7 +14,7 @@ macro_rules! boxit { fn test_macro() { boxit!(Vec::new(), Vec); } -pub fn test(foo: Box>) { //~ ERROR you seem to be trying to use `Box>` +pub fn test(foo: Box>) { println!("{:?}", foo.get(0)) } diff --git a/tests/ui/box_vec.stderr b/tests/ui/box_vec.stderr new file mode 100644 index 000000000000..a7ccf1dcd85e --- /dev/null +++ b/tests/ui/box_vec.stderr @@ -0,0 +1,16 @@ +error: you seem to be trying to use `Box>`. Consider using just `Vec` + --> $DIR/box_vec.rs:17:18 + | +17 | pub fn test(foo: Box>) { + | ^^^^^^^^^^^^^^ + | + = note: #[deny(box_vec)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/box_vec.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + = help: `Vec` is already on the heap, `Box>` makes an extra allocation. + +error: aborting due to previous error + diff --git a/tests/compile-fail/builtin-type-shadow.rs b/tests/ui/builtin-type-shadow.rs similarity index 55% rename from tests/compile-fail/builtin-type-shadow.rs rename to tests/ui/builtin-type-shadow.rs index 172875a6b9aa..bcf8a8dec71e 100644 --- a/tests/compile-fail/builtin-type-shadow.rs +++ b/tests/ui/builtin-type-shadow.rs @@ -2,8 +2,8 @@ #![plugin(clippy)] #![deny(builtin_type_shadow)] -fn foo(a: u32) -> u32 { //~ERROR shadows the built-in type `u32` - 42 //~ERROR E0308 +fn foo(a: u32) -> u32 { + 42 // ^ rustc's type error } diff --git a/tests/ui/builtin-type-shadow.stderr b/tests/ui/builtin-type-shadow.stderr new file mode 100644 index 000000000000..98cbd436686d --- /dev/null +++ b/tests/ui/builtin-type-shadow.stderr @@ -0,0 +1,23 @@ +error: This generic shadows the built-in type `u32` + --> $DIR/builtin-type-shadow.rs:5:8 + | +5 | fn foo(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 + diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs new file mode 100644 index 000000000000..ca5106102e9c --- /dev/null +++ b/tests/ui/cast.rs @@ -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; +} diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr new file mode 100644 index 000000000000..f4d8ec21d8d9 --- /dev/null +++ b/tests/ui/cast.stderr @@ -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 + diff --git a/tests/compile-fail/char_lit_as_u8.rs b/tests/ui/char_lit_as_u8.rs similarity index 64% rename from tests/compile-fail/char_lit_as_u8.rs rename to tests/ui/char_lit_as_u8.rs index 4fca878c4daf..84f76fb0131e 100644 --- a/tests/compile-fail/char_lit_as_u8.rs +++ b/tests/ui/char_lit_as_u8.rs @@ -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; } diff --git a/tests/ui/char_lit_as_u8.stderr b/tests/ui/char_lit_as_u8.stderr new file mode 100644 index 000000000000..95550194a8d2 --- /dev/null +++ b/tests/ui/char_lit_as_u8.stderr @@ -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 + diff --git a/tests/ui/cmp_nan.rs b/tests/ui/cmp_nan.rs new file mode 100644 index 000000000000..53aaba61787b --- /dev/null +++ b/tests/ui/cmp_nan.rs @@ -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; +} diff --git a/tests/ui/cmp_nan.stderr b/tests/ui/cmp_nan.stderr new file mode 100644 index 000000000000..9015e2fd3b27 --- /dev/null +++ b/tests/ui/cmp_nan.stderr @@ -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 + diff --git a/tests/compile-fail/cmp_null.rs b/tests/ui/cmp_null.rs similarity index 72% rename from tests/compile-fail/cmp_null.rs rename to tests/ui/cmp_null.rs index a55ea6f5bca2..5449d2d31ac8 100644 --- a/tests/compile-fail/cmp_null.rs +++ b/tests/ui/cmp_null.rs @@ -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!"); } } diff --git a/tests/ui/cmp_null.stderr b/tests/ui/cmp_null.stderr new file mode 100644 index 000000000000..f98edeaca46b --- /dev/null +++ b/tests/ui/cmp_null.stderr @@ -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 + diff --git a/tests/ui/cmp_owned.rs b/tests/ui/cmp_owned.rs new file mode 100644 index 000000000000..30cd502a1057 --- /dev/null +++ b/tests/ui/cmp_owned.rs @@ -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"; +} diff --git a/tests/ui/cmp_owned.stderr b/tests/ui/cmp_owned.stderr new file mode 100644 index 000000000000..231e2752c813 --- /dev/null +++ b/tests/ui/cmp_owned.stderr @@ -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 + diff --git a/tests/compile-fail/collapsible_if.rs b/tests/ui/collapsible_if.rs similarity index 62% rename from tests/compile-fail/collapsible_if.rs rename to tests/ui/collapsible_if.rs index b23d6a6e4c18..6034bba848e0 100644 --- a/tests/compile-fail/collapsible_if.rs +++ b/tests/ui/collapsible_if.rs @@ -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") } diff --git a/tests/ui/collapsible_if.stderr b/tests/ui/collapsible_if.stderr new file mode 100644 index 000000000000..eeac9166ad27 --- /dev/null +++ b/tests/ui/collapsible_if.stderr @@ -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 + diff --git a/tests/ui/complex_types.rs b/tests/ui/complex_types.rs new file mode 100644 index 000000000000..ef5cd68972db --- /dev/null +++ b/tests/ui/complex_types.rs @@ -0,0 +1,44 @@ +#![feature(plugin)] +#![plugin(clippy)] +#![deny(clippy)] +#![allow(unused)] +#![feature(associated_consts, associated_type_defaults)] + +type Alias = Vec>>; // 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>>, +} + +struct TS(Vec>>); + +enum E { + Tuple(Vec>>), + Struct { f: Vec>> }, +} + +impl S { + const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0)))); + fn impl_method(&self, p: Vec>>) { } +} + +trait T { + const A: Vec>>; + type B = Vec>>; + fn method(&self, p: Vec>>); + fn def_method(&self, p: Vec>>) { } +} + +fn test1() -> Vec>> { vec![] } + +fn test2(_x: Vec>>) { } + +fn test3() { + let _y: Vec>> = vec![]; +} + +fn main() { +} diff --git a/tests/ui/complex_types.stderr b/tests/ui/complex_types.stderr new file mode 100644 index 000000000000..a2e7f9384d10 --- /dev/null +++ b/tests/ui/complex_types.stderr @@ -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>>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>> }, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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![] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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>>) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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![]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(type_complexity)] implied by #[deny(clippy)] + +error: aborting due to 15 previous errors + diff --git a/tests/compile-fail/conf_bad_arg.rs b/tests/ui/conf_bad_arg.rs similarity index 100% rename from tests/compile-fail/conf_bad_arg.rs rename to tests/ui/conf_bad_arg.rs diff --git a/tests/ui/conf_bad_arg.stderr b/tests/ui/conf_bad_arg.stderr new file mode 100644 index 000000000000..92b3c82d4583 --- /dev/null +++ b/tests/ui/conf_bad_arg.stderr @@ -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 + diff --git a/tests/compile-fail/conf_bad_toml.rs b/tests/ui/conf_bad_toml.rs similarity index 100% rename from tests/compile-fail/conf_bad_toml.rs rename to tests/ui/conf_bad_toml.rs diff --git a/tests/ui/conf_bad_toml.stderr b/tests/ui/conf_bad_toml.stderr new file mode 100644 index 000000000000..7920bd35589d --- /dev/null +++ b/tests/ui/conf_bad_toml.stderr @@ -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 + diff --git a/tests/compile-fail/conf_bad_toml.toml b/tests/ui/conf_bad_toml.toml similarity index 100% rename from tests/compile-fail/conf_bad_toml.toml rename to tests/ui/conf_bad_toml.toml diff --git a/tests/compile-fail/conf_bad_type.rs b/tests/ui/conf_bad_type.rs similarity index 100% rename from tests/compile-fail/conf_bad_type.rs rename to tests/ui/conf_bad_type.rs diff --git a/tests/ui/conf_bad_type.stderr b/tests/ui/conf_bad_type.stderr new file mode 100644 index 000000000000..7920bd35589d --- /dev/null +++ b/tests/ui/conf_bad_type.stderr @@ -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 + diff --git a/tests/compile-fail/conf_bad_type.toml b/tests/ui/conf_bad_type.toml similarity index 100% rename from tests/compile-fail/conf_bad_type.toml rename to tests/ui/conf_bad_type.toml diff --git a/tests/ui/conf_french_blacklisted_name.rs b/tests/ui/conf_french_blacklisted_name.rs new file mode 100644 index 000000000000..20cd6aba369a --- /dev/null +++ b/tests/ui/conf_french_blacklisted_name.rs @@ -0,0 +1,26 @@ +#![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: ()) {} + +fn main() { + let toto = 42; + let tata = 42; + let titi = 42; + + let tatab = 42; + let tatatataic = 42; + + match (42, Some(1337), Some(0)) { + (toto, Some(tata), titi @ Some(_)) => (), + + + + _ => (), + } +} diff --git a/tests/ui/conf_french_blacklisted_name.stderr b/tests/ui/conf_french_blacklisted_name.stderr new file mode 100644 index 000000000000..b750f4564f6d --- /dev/null +++ b/tests/ui/conf_french_blacklisted_name.stderr @@ -0,0 +1,50 @@ +error: use of a blacklisted/placeholder name `toto` + --> $DIR/conf_french_blacklisted_name.rs:9:9 + | +9 | fn test(toto: ()) {} + | ^^^^ + | +note: lint level defined here + --> $DIR/conf_french_blacklisted_name.rs:7:9 + | +7 | #![deny(blacklisted_name)] + | ^^^^^^^^^^^^^^^^ + +error: use of a blacklisted/placeholder name `toto` + --> $DIR/conf_french_blacklisted_name.rs:12:9 + | +12 | let toto = 42; + | ^^^^ + +error: use of a blacklisted/placeholder name `tata` + --> $DIR/conf_french_blacklisted_name.rs:13:9 + | +13 | let tata = 42; + | ^^^^ + +error: use of a blacklisted/placeholder name `titi` + --> $DIR/conf_french_blacklisted_name.rs:14:9 + | +14 | let titi = 42; + | ^^^^ + +error: use of a blacklisted/placeholder name `toto` + --> $DIR/conf_french_blacklisted_name.rs:20:10 + | +20 | (toto, Some(tata), titi @ Some(_)) => (), + | ^^^^ + +error: use of a blacklisted/placeholder name `tata` + --> $DIR/conf_french_blacklisted_name.rs:20:21 + | +20 | (toto, Some(tata), titi @ Some(_)) => (), + | ^^^^ + +error: use of a blacklisted/placeholder name `titi` + --> $DIR/conf_french_blacklisted_name.rs:20:28 + | +20 | (toto, Some(tata), titi @ Some(_)) => (), + | ^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/tests/compile-fail/conf_non_existant.rs b/tests/ui/conf_non_existant.rs similarity index 100% rename from tests/compile-fail/conf_non_existant.rs rename to tests/ui/conf_non_existant.rs diff --git a/tests/ui/conf_non_existant.stderr b/tests/ui/conf_non_existant.stderr new file mode 100644 index 000000000000..7920bd35589d --- /dev/null +++ b/tests/ui/conf_non_existant.stderr @@ -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 + diff --git a/tests/compile-fail/conf_path_non_string.rs b/tests/ui/conf_path_non_string.rs similarity index 67% rename from tests/compile-fail/conf_path_non_string.rs rename to tests/ui/conf_path_non_string.rs index f26f581f5c01..ba78ccce7159 100644 --- a/tests/compile-fail/conf_path_non_string.rs +++ b/tests/ui/conf_path_non_string.rs @@ -1,6 +1,6 @@ #![feature(attr_literals)] #![feature(plugin)] #![plugin(clippy(conf_file=42))] -//~^ ERROR `conf_file` value must be a string + fn main() {} diff --git a/tests/ui/conf_path_non_string.stderr b/tests/ui/conf_path_non_string.stderr new file mode 100644 index 000000000000..3bf53f10cce4 --- /dev/null +++ b/tests/ui/conf_path_non_string.stderr @@ -0,0 +1,14 @@ +error: `conf_file` value must be a string + --> $DIR/conf_path_non_string.rs:3:28 + | +3 | #![plugin(clippy(conf_file=42))] + | ^^ + | +note: Clippy will use default configuration + --> $DIR/conf_path_non_string.rs:3:28 + | +3 | #![plugin(clippy(conf_file=42))] + | ^^ + +error: aborting due to previous error + diff --git a/tests/compile-fail/conf_unknown_key.rs b/tests/ui/conf_unknown_key.rs similarity index 100% rename from tests/compile-fail/conf_unknown_key.rs rename to tests/ui/conf_unknown_key.rs diff --git a/tests/ui/conf_unknown_key.stderr b/tests/ui/conf_unknown_key.stderr new file mode 100644 index 000000000000..536950fec31e --- /dev/null +++ b/tests/ui/conf_unknown_key.stderr @@ -0,0 +1,4 @@ +error: error reading Clippy's configuration file: unknown key `foobar` + +error: aborting due to previous error + diff --git a/tests/compile-fail/copies.rs b/tests/ui/copies.rs similarity index 72% rename from tests/compile-fail/copies.rs rename to tests/ui/copies.rs index 9b1e1ec801ec..15c149141767 100644 --- a/tests/compile-fail/copies.rs +++ b/tests/ui/copies.rs @@ -28,7 +28,7 @@ pub enum Abc { #[deny(match_same_arms)] fn if_same_then_else() -> Result<&'static str, ()> { if true { - //~^NOTE same as this + Foo { bar: 42 }; 0..10; ..; @@ -37,7 +37,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { 0...10; foo(); } - else { //~ERROR this `if` has identical blocks + else { Foo { bar: 42 }; 0..10; ..; @@ -78,8 +78,8 @@ fn if_same_then_else() -> Result<&'static str, ()> { let _ = match 42 { 42 => { - //~^ NOTE same as this - //~| NOTE removing + + foo(); let mut a = 42 + [23].len() as i32; if true { @@ -88,7 +88,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { a = -31-a; a } - _ => { //~ERROR this `match` has identical arm bodies + _ => { foo(); let mut a = 42 + [23].len() as i32; if true { @@ -101,10 +101,10 @@ fn if_same_then_else() -> Result<&'static str, ()> { let _ = match Abc::A { Abc::A => 0, - //~^ NOTE same as this - //~| NOTE removing + + Abc::B => 1, - _ => 0, //~ERROR this `match` has identical arm bodies + _ => 0, }; if true { @@ -112,15 +112,15 @@ fn if_same_then_else() -> Result<&'static str, ()> { } let _ = if true { - //~^NOTE same as this + 42 } - else { //~ERROR this `if` has identical blocks + else { 42 }; if true { - //~^NOTE same as this + for _ in &[42] { let foo: &Option<_> = &Some::(42); if true { @@ -130,7 +130,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { } } } - else { //~ERROR this `if` has identical blocks + else { for _ in &[42] { let foo: &Option<_> = &Some::(42); if true { @@ -142,7 +142,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { } if true { - //~^NOTE same as this + let bar = if true { 42 } @@ -153,7 +153,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { while foo() { break; } bar + 1; } - else { //~ERROR this `if` has identical blocks + else { let bar = if true { 42 } @@ -166,7 +166,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { } if true { - //~^NOTE same as this + let _ = match 42 { 42 => 1, a if a > 0 => 2, @@ -177,7 +177,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { else if false { foo(); } - else if foo() { //~ERROR this `if` has identical blocks + else if foo() { let _ = match 42 { 42 => 1, a if a > 0 => 2, @@ -187,18 +187,18 @@ fn if_same_then_else() -> Result<&'static str, ()> { } if true { - //~^NOTE same as this + if let Some(a) = Some(42) {} } - else { //~ERROR this `if` has identical blocks + else { if let Some(a) = Some(42) {} } if true { - //~^NOTE same as this + if let (1, .., 3) = (1, 2, 3) {} } - else { //~ERROR this `if` has identical blocks + else { if let (1, .., 3) = (1, 2, 3) {} } @@ -253,17 +253,17 @@ fn if_same_then_else() -> Result<&'static str, ()> { let _ = match 42 { 42 => foo(), - //~^NOTE same as this - //~|NOTE `42 | 51` - 51 => foo(), //~ERROR this `match` has identical arm bodies + + + 51 => foo(), _ => true, }; let _ = match Some(42) { Some(_) => 24, - //~^NOTE same as this - //~|NOTE `Some(_) | None` - None => 24, //~ERROR this `match` has identical arm bodies + + + None => 24, }; let _ = match Some(42) { @@ -285,39 +285,39 @@ fn if_same_then_else() -> Result<&'static str, ()> { match (Some(42), Some(42)) { (Some(a), None) => bar(a), - //~^NOTE same as this - //~|NOTE `(Some(a), None) | (None, Some(a))` - (None, Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies + + + (None, Some(a)) => bar(a), _ => (), } match (Some(42), Some(42)) { (Some(a), ..) => bar(a), - //~^NOTE same as this - //~|NOTE `(Some(a), ..) | (.., Some(a))` - (.., Some(a)) => bar(a), //~ERROR this `match` has identical arm bodies + + + (.., Some(a)) => bar(a), _ => (), } match (1, 2, 3) { (1, .., 3) => 42, - //~^NOTE same as this - //~|NOTE `(1, .., 3) | (.., 3)` - (.., 3) => 42, //~ERROR this `match` has identical arm bodies + + + (.., 3) => 42, _ => 0, }; let _ = if true { - //~^NOTE same as this + 0.0 - } else { //~ERROR this `if` has identical blocks + } else { 0.0 }; let _ = if true { - //~^NOTE same as this + -0.0 - } else { //~ERROR this `if` has identical blocks + } else { -0.0 }; @@ -336,9 +336,9 @@ fn if_same_then_else() -> Result<&'static str, ()> { // Same NaNs let _ = if true { - //~^NOTE same as this + std::f32::NAN - } else { //~ERROR this `if` has identical blocks + } else { std::f32::NAN }; @@ -354,15 +354,15 @@ fn if_same_then_else() -> Result<&'static str, ()> { } if true { - //~^NOTE same as this + try!(Ok("foo")); } - else { //~ERROR this `if` has identical blocks + else { try!(Ok("foo")); } if true { - //~^NOTE same as this + let foo = ""; return Ok(&foo[0..]); } @@ -370,7 +370,7 @@ fn if_same_then_else() -> Result<&'static str, ()> { let foo = "bar"; return Ok(&foo[0..]); } - else { //~ERROR this `if` has identical blocks + else { let foo = ""; return Ok(&foo[0..]); } @@ -383,23 +383,23 @@ fn ifs_same_cond() { let b = false; if b { - //~^NOTE same as this + } - else if b { //~ERROR this `if` has the same condition as a previous if + else if b { } if a == 1 { - //~^NOTE same as this + } - else if a == 1 { //~ERROR this `if` has the same condition as a previous if + else if a == 1 { } if 2*a == 1 { - //~^NOTE same as this + } else if 2*a == 2 { } - else if 2*a == 1 { //~ERROR this `if` has the same condition as a previous if + else if 2*a == 1 { } else if a == 1 { } diff --git a/tests/ui/copies.stderr b/tests/ui/copies.stderr new file mode 100644 index 000000000000..7f5cfe070bf1 --- /dev/null +++ b/tests/ui/copies.stderr @@ -0,0 +1,409 @@ +error: this `if` has identical blocks + --> $DIR/copies.rs:40:10 + | +40 | else { + | __________^ starting here... +41 | | Foo { bar: 42 }; +42 | | 0..10; +43 | | ..; +44 | | 0..; +45 | | ..10; +46 | | 0...10; +47 | | foo(); +48 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/copies.rs:27:8 + | +27 | #[deny(if_same_then_else)] + | ^^^^^^^^^^^^^^^^^ +note: same as this + --> $DIR/copies.rs:30:13 + | +30 | if true { + | ^ + +error: this `match` has identical arm bodies + --> $DIR/copies.rs:91:14 + | +91 | _ => { + | ______________^ starting here... +92 | | foo(); +93 | | let mut a = 42 + [23].len() as i32; +94 | | if true { +95 | | a += 7; +96 | | } +97 | | a = -31-a; +98 | | a +99 | | } + | |_________^ ...ending here + | +note: lint level defined here + --> $DIR/copies.rs:28:8 + | +28 | #[deny(match_same_arms)] + | ^^^^^^^^^^^^^^^ +note: same as this + --> $DIR/copies.rs:80:15 + | +80 | 42 => { + | ^ +note: `42` has the same arm body as the `_` wildcard, consider removing it` + --> $DIR/copies.rs:80:15 + | +80 | 42 => { + | ^ + +error: this `match` has identical arm bodies + --> $DIR/copies.rs:107:14 + | +107 | _ => 0, + | ^ + | +note: same as this + --> $DIR/copies.rs:103:19 + | +103 | Abc::A => 0, + | ^ +note: `Abc::A` has the same arm body as the `_` wildcard, consider removing it` + --> $DIR/copies.rs:103:19 + | +103 | Abc::A => 0, + | ^ + +error: this `if` has identical blocks + --> $DIR/copies.rs:118:10 + | +118 | else { + | __________^ starting here... +119 | | 42 +120 | | }; + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:114:21 + | +114 | let _ = if true { + | _____________________^ starting here... +115 | | +116 | | 42 +117 | | } + | |_____^ ...ending here + +error: this `if` has identical blocks + --> $DIR/copies.rs:133:10 + | +133 | else { + | ^ + | +note: same as this + --> $DIR/copies.rs:122:13 + | +122 | if true { + | ^ + +error: this `if` has identical blocks + --> $DIR/copies.rs:156:10 + | +156 | else { + | ^ + | +note: same as this + --> $DIR/copies.rs:144:13 + | +144 | if true { + | ^ + +error: this `if` has identical blocks + --> $DIR/copies.rs:180:19 + | +180 | else if foo() { + | ___________________^ starting here... +181 | | let _ = match 42 { +182 | | 42 => 1, +183 | | a if a > 0 => 2, +184 | | 10...15 => 3, +185 | | _ => 4, +186 | | }; +187 | | } + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:168:13 + | +168 | if true { + | _____________^ starting here... +169 | | +170 | | let _ = match 42 { +171 | | 42 => 1, +172 | | a if a > 0 => 2, +173 | | 10...15 => 3, +174 | | _ => 4, +175 | | }; +176 | | } + | |_____^ ...ending here + +error: this `if` has identical blocks + --> $DIR/copies.rs:193:10 + | +193 | else { + | __________^ starting here... +194 | | if let Some(a) = Some(42) {} +195 | | } + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:189:13 + | +189 | if true { + | _____________^ starting here... +190 | | +191 | | if let Some(a) = Some(42) {} +192 | | } + | |_____^ ...ending here + +error: this `if` has identical blocks + --> $DIR/copies.rs:201:10 + | +201 | else { + | __________^ starting here... +202 | | if let (1, .., 3) = (1, 2, 3) {} +203 | | } + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:197:13 + | +197 | if true { + | _____________^ starting here... +198 | | +199 | | if let (1, .., 3) = (1, 2, 3) {} +200 | | } + | |_____^ ...ending here + +error: this `match` has identical arm bodies + --> $DIR/copies.rs:258:15 + | +258 | 51 => foo(), + | ^^^^^ + | +note: same as this + --> $DIR/copies.rs:255:15 + | +255 | 42 => foo(), + | ^^^^^ +note: consider refactoring into `42 | 51` + --> $DIR/copies.rs:255:15 + | +255 | 42 => foo(), + | ^^^^^ + +error: this `match` has identical arm bodies + --> $DIR/copies.rs:266:17 + | +266 | None => 24, + | ^^ + | +note: same as this + --> $DIR/copies.rs:263:20 + | +263 | Some(_) => 24, + | ^^ +note: consider refactoring into `Some(_) | None` + --> $DIR/copies.rs:263:20 + | +263 | Some(_) => 24, + | ^^ + +error: this `match` has identical arm bodies + --> $DIR/copies.rs:290:28 + | +290 | (None, Some(a)) => bar(a), + | ^^^^^^ + | +note: same as this + --> $DIR/copies.rs:287:28 + | +287 | (Some(a), None) => bar(a), + | ^^^^^^ +note: consider refactoring into `(Some(a), None) | (None, Some(a))` + --> $DIR/copies.rs:287:28 + | +287 | (Some(a), None) => bar(a), + | ^^^^^^ + +error: this `match` has identical arm bodies + --> $DIR/copies.rs:298:26 + | +298 | (.., Some(a)) => bar(a), + | ^^^^^^ + | +note: same as this + --> $DIR/copies.rs:295:26 + | +295 | (Some(a), ..) => bar(a), + | ^^^^^^ +note: consider refactoring into `(Some(a), ..) | (.., Some(a))` + --> $DIR/copies.rs:295:26 + | +295 | (Some(a), ..) => bar(a), + | ^^^^^^ + +error: this `match` has identical arm bodies + --> $DIR/copies.rs:306:20 + | +306 | (.., 3) => 42, + | ^^ + | +note: same as this + --> $DIR/copies.rs:303:23 + | +303 | (1, .., 3) => 42, + | ^^ +note: consider refactoring into `(1, .., 3) | (.., 3)` + --> $DIR/copies.rs:303:23 + | +303 | (1, .., 3) => 42, + | ^^ + +error: this `if` has identical blocks + --> $DIR/copies.rs:313:12 + | +313 | } else { + | ____________^ starting here... +314 | | 0.0 +315 | | }; + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:310:21 + | +310 | let _ = if true { + | _____________________^ starting here... +311 | | +312 | | 0.0 +313 | | } else { + | |_____^ ...ending here + +error: this `if` has identical blocks + --> $DIR/copies.rs:320:12 + | +320 | } else { + | ____________^ starting here... +321 | | -0.0 +322 | | }; + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:317:21 + | +317 | let _ = if true { + | _____________________^ starting here... +318 | | +319 | | -0.0 +320 | | } else { + | |_____^ ...ending here + +error: this `if` has identical blocks + --> $DIR/copies.rs:341:12 + | +341 | } else { + | ____________^ starting here... +342 | | std::f32::NAN +343 | | }; + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:338:21 + | +338 | let _ = if true { + | _____________________^ starting here... +339 | | +340 | | std::f32::NAN +341 | | } else { + | |_____^ ...ending here + +error: this `if` has identical blocks + --> $DIR/copies.rs:360:10 + | +360 | else { + | __________^ starting here... +361 | | try!(Ok("foo")); +362 | | } + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:356:13 + | +356 | if true { + | _____________^ starting here... +357 | | +358 | | try!(Ok("foo")); +359 | | } + | |_____^ ...ending here + +error: this `if` has identical blocks + --> $DIR/copies.rs:373:10 + | +373 | else { + | __________^ starting here... +374 | | let foo = ""; +375 | | return Ok(&foo[0..]); +376 | | } + | |_____^ ...ending here + | +note: same as this + --> $DIR/copies.rs:364:13 + | +364 | if true { + | _____________^ starting here... +365 | | +366 | | let foo = ""; +367 | | return Ok(&foo[0..]); +368 | | } + | |_____^ ...ending here + +error: this `if` has the same condition as a previous if + --> $DIR/copies.rs:388:13 + | +388 | else if b { + | ^ + | +note: lint level defined here + --> $DIR/copies.rs:379:8 + | +379 | #[deny(ifs_same_cond)] + | ^^^^^^^^^^^^^ +note: same as this + --> $DIR/copies.rs:385:8 + | +385 | if b { + | ^ + +error: this `if` has the same condition as a previous if + --> $DIR/copies.rs:394:13 + | +394 | else if a == 1 { + | ^^^^^^ + | +note: same as this + --> $DIR/copies.rs:391:8 + | +391 | if a == 1 { + | ^^^^^^ + +error: this `if` has the same condition as a previous if + --> $DIR/copies.rs:402:13 + | +402 | else if 2*a == 1 { + | ^^^^^^^^ + | +note: same as this + --> $DIR/copies.rs:397:8 + | +397 | if 2*a == 1 { + | ^^^^^^^^ + +error: aborting due to 22 previous errors + diff --git a/tests/compile-fail/cyclomatic_complexity.rs b/tests/ui/cyclomatic_complexity.rs similarity index 82% rename from tests/compile-fail/cyclomatic_complexity.rs rename to tests/ui/cyclomatic_complexity.rs index 30bbcc6cb278..0b02c937be6a 100644 --- a/tests/compile-fail/cyclomatic_complexity.rs +++ b/tests/ui/cyclomatic_complexity.rs @@ -4,7 +4,7 @@ #![deny(cyclomatic_complexity)] #![allow(unused)] -fn main() { //~ERROR the function has a cyclomatic complexity of 28 +fn main() { if true { println!("a"); } @@ -89,7 +89,7 @@ fn main() { //~ERROR the function has a cyclomatic complexity of 28 } #[cyclomatic_complexity = "0"] -fn kaboom() { //~ ERROR: the function has a cyclomatic complexity of 7 +fn kaboom() { let n = 0; 'a: for i in 0..20 { 'b: for j in i..20 { @@ -135,18 +135,18 @@ fn bloo() { } #[cyclomatic_complexity = "0"] -fn lots_of_short_circuits() -> bool { //~ ERROR: the function has a cyclomatic complexity of 1 +fn lots_of_short_circuits() -> bool { true && false && true && false && true && false && true } #[cyclomatic_complexity = "0"] -fn lots_of_short_circuits2() -> bool { //~ ERROR: the function has a cyclomatic complexity of 1 +fn lots_of_short_circuits2() -> bool { true || false || true || false || true || false || true } #[cyclomatic_complexity = "0"] -fn baa() { //~ ERROR: the function has a cyclomatic complexity of 2 - let x = || match 99 { //~ ERROR: the function has a cyclomatic complexity of 2 +fn baa() { + let x = || match 99 { 0 => 0, 1 => 1, 2 => 2, @@ -163,7 +163,7 @@ fn baa() { //~ ERROR: the function has a cyclomatic complexity of 2 } #[cyclomatic_complexity = "0"] -fn bar() { //~ ERROR: the function has a cyclomatic complexity of 2 +fn bar() { match 99 { 0 => println!("hi"), _ => println!("bye"), @@ -182,7 +182,7 @@ fn dont_warn_on_tests() { } #[cyclomatic_complexity = "0"] -fn barr() { //~ ERROR: the function has a cyclomatic complexity of 2 +fn barr() { match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -192,7 +192,7 @@ fn barr() { //~ ERROR: the function has a cyclomatic complexity of 2 } #[cyclomatic_complexity = "0"] -fn barr2() { //~ ERROR: the function has a cyclomatic complexity of 3 +fn barr2() { match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -208,7 +208,7 @@ fn barr2() { //~ ERROR: the function has a cyclomatic complexity of 3 } #[cyclomatic_complexity = "0"] -fn barrr() { //~ ERROR: the function has a cyclomatic complexity of 2 +fn barrr() { match 99 { 0 => println!("hi"), 1 => panic!("bla"), @@ -218,7 +218,7 @@ fn barrr() { //~ ERROR: the function has a cyclomatic complexity of 2 } #[cyclomatic_complexity = "0"] -fn barrr2() { //~ ERROR: the function has a cyclomatic complexity of 3 +fn barrr2() { match 99 { 0 => println!("hi"), 1 => panic!("bla"), @@ -234,7 +234,7 @@ fn barrr2() { //~ ERROR: the function has a cyclomatic complexity of 3 } #[cyclomatic_complexity = "0"] -fn barrrr() { //~ ERROR: the function has a cyclomatic complexity of 2 +fn barrrr() { match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -244,7 +244,7 @@ fn barrrr() { //~ ERROR: the function has a cyclomatic complexity of 2 } #[cyclomatic_complexity = "0"] -fn barrrr2() { //~ ERROR: the function has a cyclomatic complexity of 3 +fn barrrr2() { match 99 { 0 => println!("hi"), 1 => println!("bla"), @@ -260,7 +260,7 @@ fn barrrr2() { //~ ERROR: the function has a cyclomatic complexity of 3 } #[cyclomatic_complexity = "0"] -fn cake() { //~ ERROR: the function has a cyclomatic complexity of 2 +fn cake() { if 4 == 5 { println!("yea"); } else { @@ -271,7 +271,7 @@ fn cake() { //~ ERROR: the function has a cyclomatic complexity of 2 #[cyclomatic_complexity = "0"] -pub fn read_file(input_path: &str) -> String { //~ ERROR: the function has a cyclomatic complexity of 4 +pub fn read_file(input_path: &str) -> String { use std::fs::File; use std::io::{Read, Write}; use std::path::Path; @@ -302,7 +302,7 @@ pub fn read_file(input_path: &str) -> String { //~ ERROR: the function has a cyc enum Void {} #[cyclomatic_complexity = "0"] -fn void(void: Void) { //~ ERROR: the function has a cyclomatic complexity of 1 +fn void(void: Void) { if true { match void { } @@ -316,7 +316,7 @@ fn mcarton_sees_all() { } #[cyclomatic_complexity = "0"] -fn try() -> Result { //~ ERROR: cyclomatic complexity of 1 +fn try() -> Result { match 5 { 5 => Ok(5), _ => return Err("bla"), @@ -324,7 +324,7 @@ fn try() -> Result { //~ ERROR: cyclomatic complexity of 1 } #[cyclomatic_complexity = "0"] -fn try_again() -> Result { //~ ERROR: cyclomatic complexity of 1 +fn try_again() -> Result { let _ = try!(Ok(42)); let _ = try!(Ok(43)); let _ = try!(Ok(44)); @@ -340,7 +340,7 @@ fn try_again() -> Result { //~ ERROR: cyclomatic complexity o } #[cyclomatic_complexity = "0"] -fn early() -> Result { //~ ERROR: cyclomatic complexity of 1 +fn early() -> Result { return Ok(5); return Ok(5); return Ok(5); @@ -353,7 +353,7 @@ fn early() -> Result { //~ ERROR: cyclomatic complexity of 1 } #[cyclomatic_complexity = "0"] -fn early_ret() -> i32 { //~ ERROR: cyclomatic complexity of 8 +fn early_ret() -> i32 { let a = if true { 42 } else { return 0; }; let a = if a < 99 { 42 } else { return 0; }; let a = if a < 99 { 42 } else { return 0; }; diff --git a/tests/ui/cyclomatic_complexity.stderr b/tests/ui/cyclomatic_complexity.stderr new file mode 100644 index 000000000000..70eb05e8db6f --- /dev/null +++ b/tests/ui/cyclomatic_complexity.stderr @@ -0,0 +1,232 @@ +error: the function has a cyclomatic complexity of 28 + --> $DIR/cyclomatic_complexity.rs:7:1 + | +7 | fn main() { + | ^ + | +note: lint level defined here + --> $DIR/cyclomatic_complexity.rs:4:9 + | +4 | #![deny(cyclomatic_complexity)] + | ^^^^^^^^^^^^^^^^^^^^^ + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 7 + --> $DIR/cyclomatic_complexity.rs:92:1 + | +92 | fn kaboom() { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 1 + --> $DIR/cyclomatic_complexity.rs:138:1 + | +138 | fn lots_of_short_circuits() -> bool { + | _^ starting here... +139 | | true && false && true && false && true && false && true +140 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 1 + --> $DIR/cyclomatic_complexity.rs:143:1 + | +143 | fn lots_of_short_circuits2() -> bool { + | _^ starting here... +144 | | true || false || true || false || true || false || true +145 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 2 + --> $DIR/cyclomatic_complexity.rs:148:1 + | +148 | fn baa() { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 2 + --> $DIR/cyclomatic_complexity.rs:149:13 + | +149 | let x = || match 99 { + | _____________^ starting here... +150 | | 0 => 0, +151 | | 1 => 1, +152 | | 2 => 2, +153 | | 4 => 4, +154 | | 6 => 6, +155 | | 9 => 9, +156 | | _ => 42, +157 | | }; + | |_____^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 2 + --> $DIR/cyclomatic_complexity.rs:166:1 + | +166 | fn bar() { + | _^ starting here... +167 | | match 99 { +168 | | 0 => println!("hi"), +169 | | _ => println!("bye"), +170 | | } +171 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 2 + --> $DIR/cyclomatic_complexity.rs:185:1 + | +185 | fn barr() { + | _^ starting here... +186 | | match 99 { +187 | | 0 => println!("hi"), +188 | | 1 => println!("bla"), +189 | | 2 | 3 => println!("blub"), +190 | | _ => println!("bye"), +191 | | } +192 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 3 + --> $DIR/cyclomatic_complexity.rs:195:1 + | +195 | fn barr2() { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 2 + --> $DIR/cyclomatic_complexity.rs:211:1 + | +211 | fn barrr() { + | _^ starting here... +212 | | match 99 { +213 | | 0 => println!("hi"), +214 | | 1 => panic!("bla"), +215 | | 2 | 3 => println!("blub"), +216 | | _ => println!("bye"), +217 | | } +218 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 3 + --> $DIR/cyclomatic_complexity.rs:221:1 + | +221 | fn barrr2() { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 2 + --> $DIR/cyclomatic_complexity.rs:237:1 + | +237 | fn barrrr() { + | _^ starting here... +238 | | match 99 { +239 | | 0 => println!("hi"), +240 | | 1 => println!("bla"), +241 | | 2 | 3 => panic!("blub"), +242 | | _ => println!("bye"), +243 | | } +244 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 3 + --> $DIR/cyclomatic_complexity.rs:247:1 + | +247 | fn barrrr2() { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 2 + --> $DIR/cyclomatic_complexity.rs:263:1 + | +263 | fn cake() { + | _^ starting here... +264 | | if 4 == 5 { +265 | | println!("yea"); +266 | | } else { +267 | | panic!("meh"); +268 | | } +269 | | println!("whee"); +270 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 4 + --> $DIR/cyclomatic_complexity.rs:274:1 + | +274 | pub fn read_file(input_path: &str) -> String { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 1 + --> $DIR/cyclomatic_complexity.rs:305:1 + | +305 | fn void(void: Void) { + | _^ starting here... +306 | | if true { +307 | | match void { +308 | | } +309 | | } +310 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 1 + --> $DIR/cyclomatic_complexity.rs:319:1 + | +319 | fn try() -> Result { + | _^ starting here... +320 | | match 5 { +321 | | 5 => Ok(5), +322 | | _ => return Err("bla"), +323 | | } +324 | | } + | |_^ ...ending here + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 1 + --> $DIR/cyclomatic_complexity.rs:327:1 + | +327 | fn try_again() -> Result { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 1 + --> $DIR/cyclomatic_complexity.rs:343:1 + | +343 | fn early() -> Result { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: the function has a cyclomatic complexity of 8 + --> $DIR/cyclomatic_complexity.rs:356:1 + | +356 | fn early_ret() -> i32 { + | ^ + | + = help: you could split it up into multiple smaller functions + +error: aborting due to 20 previous errors + diff --git a/tests/compile-fail/cyclomatic_complexity_attr_used.rs b/tests/ui/cyclomatic_complexity_attr_used.rs similarity index 78% rename from tests/compile-fail/cyclomatic_complexity_attr_used.rs rename to tests/ui/cyclomatic_complexity_attr_used.rs index f322a7b51da4..143888279796 100644 --- a/tests/compile-fail/cyclomatic_complexity_attr_used.rs +++ b/tests/ui/cyclomatic_complexity_attr_used.rs @@ -8,7 +8,7 @@ fn main() { } #[cyclomatic_complexity = "0"] -fn kaboom() { //~ ERROR: the function has a cyclomatic complexity of 3 +fn kaboom() { if 42 == 43 { panic!(); } else if "cake" == "lie" { diff --git a/tests/ui/cyclomatic_complexity_attr_used.stderr b/tests/ui/cyclomatic_complexity_attr_used.stderr new file mode 100644 index 000000000000..f5ee0e799916 --- /dev/null +++ b/tests/ui/cyclomatic_complexity_attr_used.stderr @@ -0,0 +1,22 @@ +error: the function has a cyclomatic complexity of 3 + --> $DIR/cyclomatic_complexity_attr_used.rs:11:1 + | +11 | fn kaboom() { + | _^ starting here... +12 | | if 42 == 43 { +13 | | panic!(); +14 | | } else if "cake" == "lie" { +15 | | println!("what?"); +16 | | } +17 | | } + | |_^ ...ending here + | +note: lint level defined here + --> $DIR/cyclomatic_complexity_attr_used.rs:3:9 + | +3 | #![deny(cyclomatic_complexity)] + | ^^^^^^^^^^^^^^^^^^^^^ + = help: you could split it up into multiple smaller functions + +error: aborting due to previous error + diff --git a/tests/compile-fail/derive.rs b/tests/ui/derive.rs similarity index 80% rename from tests/compile-fail/derive.rs rename to tests/ui/derive.rs index cf4467f30a59..7274c0fb7ad3 100644 --- a/tests/compile-fail/derive.rs +++ b/tests/ui/derive.rs @@ -16,7 +16,7 @@ impl PartialEq for Foo { } #[derive(Hash)] -//~^ ERROR you are deriving `Hash` but have implemented `PartialEq` explicitly + struct Bar; impl PartialEq for Bar { @@ -24,7 +24,7 @@ impl PartialEq for Bar { } #[derive(Hash)] -//~^ ERROR you are deriving `Hash` but have implemented `PartialEq` explicitly + struct Baz; impl PartialEq for Baz { @@ -35,7 +35,7 @@ impl PartialEq for Baz { struct Bah; impl Hash for Bah { -//~^ ERROR you are implementing `Hash` explicitly but have derived `PartialEq` + fn hash(&self, _: &mut H) {} } @@ -43,7 +43,7 @@ impl Hash for Bah { struct Qux; impl Clone for Qux { -//~^ ERROR you are implementing `Clone` explicitly on a `Copy` type + fn clone(&self) -> Self { Qux } } @@ -68,7 +68,7 @@ struct Lt<'a> { } impl<'a> Clone for Lt<'a> { -//~^ ERROR you are implementing `Clone` explicitly on a `Copy` type + fn clone(&self) -> Self { unimplemented!() } } diff --git a/tests/ui/derive.stderr b/tests/ui/derive.stderr new file mode 100644 index 000000000000..d435b52db441 --- /dev/null +++ b/tests/ui/derive.stderr @@ -0,0 +1,103 @@ +error: you are deriving `Hash` but have implemented `PartialEq` explicitly + --> $DIR/derive.rs:18:10 + | +18 | #[derive(Hash)] + | ^^^^ + | + = note: #[deny(derive_hash_xor_eq)] implied by #[deny(warnings)] +note: lint level defined here + --> $DIR/derive.rs:6:9 + | +6 | #![deny(warnings)] + | ^^^^^^^^ +note: `PartialEq` implemented here + --> $DIR/derive.rs:22:1 + | +22 | impl PartialEq for Bar { + | _^ starting here... +23 | | fn eq(&self, _: &Bar) -> bool { true } +24 | | } + | |_^ ...ending here + +error: you are deriving `Hash` but have implemented `PartialEq` explicitly + --> $DIR/derive.rs:26:10 + | +26 | #[derive(Hash)] + | ^^^^ + | + = note: #[deny(derive_hash_xor_eq)] implied by #[deny(warnings)] +note: `PartialEq` implemented here + --> $DIR/derive.rs:30:1 + | +30 | impl PartialEq for Baz { + | _^ starting here... +31 | | fn eq(&self, _: &Baz) -> bool { true } +32 | | } + | |_^ ...ending here + +error: you are implementing `Hash` explicitly but have derived `PartialEq` + --> $DIR/derive.rs:37:1 + | +37 | impl Hash for Bah { + | _^ starting here... +38 | | +39 | | fn hash(&self, _: &mut H) {} +40 | | } + | |_^ ...ending here + | + = note: #[deny(derive_hash_xor_eq)] implied by #[deny(warnings)] +note: `PartialEq` implemented here + --> $DIR/derive.rs:34:10 + | +34 | #[derive(PartialEq)] + | ^^^^^^^^^ + +error: you are implementing `Clone` explicitly on a `Copy` type + --> $DIR/derive.rs:45:1 + | +45 | impl Clone for Qux { + | _^ starting here... +46 | | +47 | | fn clone(&self) -> Self { Qux } +48 | | } + | |_^ ...ending here + | + = note: #[deny(expl_impl_clone_on_copy)] implied by #[deny(warnings)] +note: lint level defined here + --> $DIR/derive.rs:6:9 + | +6 | #![deny(warnings)] + | ^^^^^^^^ +note: consider deriving `Clone` or removing `Copy` + --> $DIR/derive.rs:45:1 + | +45 | impl Clone for Qux { + | _^ starting here... +46 | | +47 | | fn clone(&self) -> Self { Qux } +48 | | } + | |_^ ...ending here + +error: you are implementing `Clone` explicitly on a `Copy` type + --> $DIR/derive.rs:70:1 + | +70 | impl<'a> Clone for Lt<'a> { + | _^ starting here... +71 | | +72 | | fn clone(&self) -> Self { unimplemented!() } +73 | | } + | |_^ ...ending here + | + = note: #[deny(expl_impl_clone_on_copy)] implied by #[deny(warnings)] +note: consider deriving `Clone` or removing `Copy` + --> $DIR/derive.rs:70:1 + | +70 | impl<'a> Clone for Lt<'a> { + | _^ starting here... +71 | | +72 | | fn clone(&self) -> Self { unimplemented!() } +73 | | } + | |_^ ...ending here + +error: aborting due to 5 previous errors + diff --git a/tests/compile-fail/diverging_sub_expression.rs b/tests/ui/diverging_sub_expression.rs similarity index 64% rename from tests/compile-fail/diverging_sub_expression.rs rename to tests/ui/diverging_sub_expression.rs index 02e6d0693d1d..57e7a545b7c5 100644 --- a/tests/compile-fail/diverging_sub_expression.rs +++ b/tests/ui/diverging_sub_expression.rs @@ -15,8 +15,8 @@ impl A { #[allow(unused_variables, unnecessary_operation, short_circuit_statement)] fn main() { let b = true; - b || diverge(); //~ ERROR sub-expression diverges - b || A.foo(); //~ ERROR sub-expression diverges + b || diverge(); + b || A.foo(); } #[allow(dead_code, unused_variables)] @@ -25,16 +25,16 @@ fn foobar() { let x = match 5 { 4 => return, 5 => continue, - 6 => true || return, //~ ERROR sub-expression diverges - 7 => true || continue, //~ ERROR sub-expression diverges + 6 => true || return, + 7 => true || continue, 8 => break, 9 => diverge(), - 3 => true || diverge(), //~ ERROR sub-expression diverges + 3 => true || diverge(), 10 => match 42 { 99 => return, _ => true || panic!("boo"), }, - _ => true || break, //~ ERROR sub-expression diverges + _ => true || break, }; } } diff --git a/tests/ui/diverging_sub_expression.stderr b/tests/ui/diverging_sub_expression.stderr new file mode 100644 index 000000000000..108c228fdc9e --- /dev/null +++ b/tests/ui/diverging_sub_expression.stderr @@ -0,0 +1,44 @@ +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:18:10 + | +18 | b || diverge(); + | ^^^^^^^^^ + | +note: lint level defined here + --> $DIR/diverging_sub_expression.rs:3:9 + | +3 | #![deny(diverging_sub_expression)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:19:10 + | +19 | b || A.foo(); + | ^^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:28:26 + | +28 | 6 => true || return, + | ^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:29:26 + | +29 | 7 => true || continue, + | ^^^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:32:26 + | +32 | 3 => true || diverge(), + | ^^^^^^^^^ + +error: sub-expression diverges + --> $DIR/diverging_sub_expression.rs:37:26 + | +37 | _ => true || break, + | ^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/compile-fail/dlist.rs b/tests/ui/dlist.rs similarity index 53% rename from tests/compile-fail/dlist.rs rename to tests/ui/dlist.rs index 63c678eb69c2..10d0beab8344 100644 --- a/tests/compile-fail/dlist.rs +++ b/tests/ui/dlist.rs @@ -10,9 +10,9 @@ extern crate collections; use collections::linked_list::LinkedList; trait Foo { - type Baz = LinkedList; //~ ERROR I see you're using a LinkedList! - fn foo(LinkedList); //~ ERROR I see you're using a LinkedList! - const BAR : Option>; //~ ERROR I see you're using a LinkedList! + type Baz = LinkedList; + fn foo(LinkedList); + const BAR : Option>; } // ok, we don’t want to warn for implementations, see #605 @@ -23,14 +23,14 @@ impl Foo for LinkedList { struct Bar; impl Bar { - fn foo(_: LinkedList) {} //~ ERROR I see you're using a LinkedList! + fn foo(_: LinkedList) {} } -pub fn test(my_favourite_linked_list: LinkedList) { //~ ERROR I see you're using a LinkedList! +pub fn test(my_favourite_linked_list: LinkedList) { println!("{:?}", my_favourite_linked_list) } -pub fn test_ret() -> Option> { //~ ERROR I see you're using a LinkedList! +pub fn test_ret() -> Option> { unimplemented!(); } diff --git a/tests/ui/dlist.stderr b/tests/ui/dlist.stderr new file mode 100644 index 000000000000..7af01a32ec02 --- /dev/null +++ b/tests/ui/dlist.stderr @@ -0,0 +1,61 @@ +error: I see you're using a LinkedList! Perhaps you meant some other data structure? + --> $DIR/dlist.rs:13:16 + | +13 | type Baz = LinkedList; + | ^^^^^^^^^^^^^^ + | + = note: #[deny(linkedlist)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/dlist.rs:6:9 + | +6 | #![deny(clippy)] + | ^^^^^^ + = help: a VecDeque might work + +error: I see you're using a LinkedList! Perhaps you meant some other data structure? + --> $DIR/dlist.rs:14:12 + | +14 | fn foo(LinkedList); + | ^^^^^^^^^^^^^^ + | + = note: #[deny(linkedlist)] implied by #[deny(clippy)] + = help: a VecDeque might work + +error: I see you're using a LinkedList! Perhaps you meant some other data structure? + --> $DIR/dlist.rs:15:24 + | +15 | const BAR : Option>; + | ^^^^^^^^^^^^^^ + | + = note: #[deny(linkedlist)] implied by #[deny(clippy)] + = help: a VecDeque might work + +error: I see you're using a LinkedList! Perhaps you meant some other data structure? + --> $DIR/dlist.rs:26:15 + | +26 | fn foo(_: LinkedList) {} + | ^^^^^^^^^^^^^^ + | + = note: #[deny(linkedlist)] implied by #[deny(clippy)] + = help: a VecDeque might work + +error: I see you're using a LinkedList! Perhaps you meant some other data structure? + --> $DIR/dlist.rs:29:39 + | +29 | pub fn test(my_favourite_linked_list: LinkedList) { + | ^^^^^^^^^^^^^^ + | + = note: #[deny(linkedlist)] implied by #[deny(clippy)] + = help: a VecDeque might work + +error: I see you're using a LinkedList! Perhaps you meant some other data structure? + --> $DIR/dlist.rs:33:29 + | +33 | pub fn test_ret() -> Option> { + | ^^^^^^^^^^^^^^ + | + = note: #[deny(linkedlist)] implied by #[deny(clippy)] + = help: a VecDeque might work + +error: aborting due to 6 previous errors + diff --git a/tests/compile-fail/doc.rs b/tests/ui/doc.rs similarity index 69% rename from tests/compile-fail/doc.rs rename to tests/ui/doc.rs index 84283a8316e9..1e34b391915e 100644 --- a/tests/compile-fail/doc.rs +++ b/tests/ui/doc.rs @@ -1,5 +1,5 @@ //! This file tests for the DOC_MARKDOWN lint -//~^ ERROR: you should put `DOC_MARKDOWN` between ticks + #![feature(plugin)] #![plugin(clippy)] @@ -7,17 +7,17 @@ #![deny(doc_markdown)] /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) -//~^ ERROR: you should put `foo_bar` between ticks -//~| ERROR: you should put `foo::bar` between ticks + + /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun -//~^ ERROR: you should put `Foo::some_fun` between ticks + /// which should be reported only once despite being __doubly bad__. /// Here be ::is::a::global:path. -//~^ ERROR: you should put `is::a::global:path` between ticks + /// That's not code ~NotInCodeBlock~. -//~^ ERROR: you should put `NotInCodeBlock` between ticks + /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn foo_bar() { } @@ -32,7 +32,7 @@ fn foo_bar() { /// _foo bar_ /// ~~~ /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn multiline_codeblock() { } @@ -40,7 +40,7 @@ fn multiline_codeblock() { /// multiline /// emphasis_. /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn test_emphasis() { } @@ -55,7 +55,7 @@ fn test_emphasis() { /// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb /// NaN /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn test_units() { } @@ -65,15 +65,15 @@ fn test_units() { /// `💣` /// `❤️` /// ß_foo -//~^ ERROR: you should put `ß_foo` between ticks + /// ℝ_foo -//~^ ERROR: you should put `ℝ_foo` between ticks + /// 💣_foo /// ❤️_foo /// foo_ß -//~^ ERROR: you should put `foo_ß` between ticks + /// foo_ℝ -//~^ ERROR: you should put `foo_ℝ` between ticks + /// foo_💣 /// foo_❤️ /// [ßdummy textß][foo_1ß] @@ -89,16 +89,16 @@ fn test_units() { /// [foo3_💣]: dummy text /// [foo4_❤️]: dummy text /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn test_unicode() { } /// This test has [a link_with_underscores][chunked-example] inside it. See #823. -//~^ ERROR: you should put `link_with_underscores` between ticks + /// See also [the issue tracker](https://github.com/Manishearth/rust-clippy/search?q=doc_markdown&type=Issues) /// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link]. /// It can also be [inline_link2]. -//~^ ERROR: you should put `inline_link2` between ticks + /// /// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example /// [inline_link]: https://foobar @@ -110,7 +110,7 @@ fn test_unicode() { /// expression of the type `_ m c` (where `` /// is one of {`&`, '|'} and `` is one of {`!=`, `>=`, `>` , /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn main() { foo_bar(); multiline_codeblock(); @@ -124,9 +124,9 @@ fn main() { /// # CamelCaseThing /// /// Not a title #897 CamelCaseThing -//~^ ERROR: you should put `CamelCaseThing` between ticks + /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn issue897() { } @@ -134,7 +134,7 @@ fn issue897() { /// I am confused by brackets? (foo `x_y`) /// I am confused by brackets? (`x_y` foo) /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn issue900() { } @@ -148,7 +148,7 @@ fn issue900() { /// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html /// [helper_types]: ../helper_types/index.html /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn issue883() { } @@ -167,9 +167,9 @@ That's in a code block: `PackedNode` And BarQuz too. be_sure_we_got_to_the_end_of_it */ -//~^^^^^^^^ ERROR: you should put `FooBar` between ticks -//~^^^^ ERROR: you should put `BarQuz` between ticks -//~^^^^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + + + fn issue1073() { } @@ -181,9 +181,9 @@ That's in a code block: PackedNode And BarQuz too. be_sure_we_got_to_the_end_of_it */ -//~^^^^^^^^ ERROR: you should put `FooBar` between ticks -//~^^^^ ERROR: you should put `BarQuz` between ticks -//~^^^^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + + + fn issue1073_alt() { } @@ -194,6 +194,6 @@ fn issue1073_alt() { /// StillDont /// ```` /// be_sure_we_got_to_the_end_of_it -//~^ ERROR: you should put `be_sure_we_got_to_the_end_of_it` between ticks + fn four_quotes() { } diff --git a/tests/ui/doc.stderr b/tests/ui/doc.stderr new file mode 100644 index 000000000000..90df4766faef --- /dev/null +++ b/tests/ui/doc.stderr @@ -0,0 +1,182 @@ +error: you should put `DOC_MARKDOWN` between ticks in the documentation + --> $DIR/doc.rs:1:29 + | +1 | //! This file tests for the DOC_MARKDOWN lint + | ^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/doc.rs:7:9 + | +7 | #![deny(doc_markdown)] + | ^^^^^^^^^^^^ + +error: you should put `foo_bar` between ticks in the documentation + --> $DIR/doc.rs:9:9 + | +9 | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) + | ^^^^^^^ + +error: you should put `foo::bar` between ticks in the documentation + --> $DIR/doc.rs:9:51 + | +9 | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there) + | ^^^^^^^^ + +error: you should put `Foo::some_fun` between ticks in the documentation + --> $DIR/doc.rs:12:84 + | +12 | /// Markdown is _weird_. I mean _really weird_. This /_ is ok. So is `_`. But not Foo::some_fun + | ^^^^^^^^^^^^^ + +error: you should put `is::a::global:path` between ticks in the documentation + --> $DIR/doc.rs:15:13 + | +15 | /// Here be ::is::a::global:path. + | ^^^^^^^^^^^^^^^^^^^^ + +error: you should put `NotInCodeBlock` between ticks in the documentation + --> $DIR/doc.rs:17:21 + | +17 | /// That's not code ~NotInCodeBlock~. + | ^^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:19:5 + | +19 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:34:5 + | +34 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:42:5 + | +42 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:57:5 + | +57 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `ß_foo` between ticks in the documentation + --> $DIR/doc.rs:67:5 + | +67 | /// ß_foo + | ^^^^^ + +error: you should put `ℝ_foo` between ticks in the documentation + --> $DIR/doc.rs:69:5 + | +69 | /// ℝ_foo + | ^^^^^ + +error: you should put `foo_ß` between ticks in the documentation + --> $DIR/doc.rs:73:5 + | +73 | /// foo_ß + | ^^^^^ + +error: you should put `foo_ℝ` between ticks in the documentation + --> $DIR/doc.rs:75:5 + | +75 | /// foo_ℝ + | ^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:91:5 + | +91 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `link_with_underscores` between ticks in the documentation + --> $DIR/doc.rs:96:22 + | +96 | /// This test has [a link_with_underscores][chunked-example] inside it. See #823. + | ^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `inline_link2` between ticks in the documentation + --> $DIR/doc.rs:100:21 + | +100 | /// It can also be [inline_link2]. + | ^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:112:5 + | +112 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `CamelCaseThing` between ticks in the documentation + --> $DIR/doc.rs:126:22 + | +126 | /// Not a title #897 CamelCaseThing + | ^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:128:5 + | +128 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:136:5 + | +136 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:150:5 + | +150 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `FooBar` between ticks in the documentation + --> $DIR/doc.rs:162:42 + | +162 | /** E.g. serialization of an empty list: FooBar + | ^^^^^^ + +error: you should put `BarQuz` between ticks in the documentation + --> $DIR/doc.rs:167:5 + | +167 | And BarQuz too. + | ^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:168:1 + | +168 | be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `FooBar` between ticks in the documentation + --> $DIR/doc.rs:176:42 + | +176 | /** E.g. serialization of an empty list: FooBar + | ^^^^^^ + +error: you should put `BarQuz` between ticks in the documentation + --> $DIR/doc.rs:181:5 + | +181 | And BarQuz too. + | ^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:182:1 + | +182 | be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation + --> $DIR/doc.rs:196:5 + | +196 | /// be_sure_we_got_to_the_end_of_it + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 29 previous errors + diff --git a/tests/compile-fail/double_neg.rs b/tests/ui/double_neg.rs similarity index 51% rename from tests/compile-fail/double_neg.rs rename to tests/ui/double_neg.rs index 790ca93728ba..362b3a72dd75 100644 --- a/tests/compile-fail/double_neg.rs +++ b/tests/ui/double_neg.rs @@ -6,5 +6,5 @@ fn main() { let x = 1; -x; -(-x); - --x; //~ERROR: `--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op + --x; } diff --git a/tests/ui/double_neg.stderr b/tests/ui/double_neg.stderr new file mode 100644 index 000000000000..aeabbc8dfa90 --- /dev/null +++ b/tests/ui/double_neg.stderr @@ -0,0 +1,14 @@ +error: `--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op + --> $DIR/double_neg.rs:9:5 + | +9 | --x; + | ^^^ + | +note: lint level defined here + --> $DIR/double_neg.rs:4:8 + | +4 | #[deny(double_neg)] + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/compile-fail/double_parens.rs b/tests/ui/double_parens.rs similarity index 62% rename from tests/compile-fail/double_parens.rs rename to tests/ui/double_parens.rs index 2e415d7232df..208482eb6cec 100644 --- a/tests/compile-fail/double_parens.rs +++ b/tests/ui/double_parens.rs @@ -13,23 +13,23 @@ impl DummyStruct { } fn simple_double_parens() -> i32 { - ((0)) //~ERROR Consider removing unnecessary double parentheses + ((0)) } fn fn_double_parens() { - dummy_fn((0)); //~ERROR Consider removing unnecessary double parentheses + dummy_fn((0)); } fn method_double_parens(x: DummyStruct) { - x.dummy_method((0)); //~ERROR Consider removing unnecessary double parentheses + x.dummy_method((0)); } fn tuple_double_parens() -> (i32, i32) { - ((1, 2)) //~ERROR Consider removing unnecessary double parentheses + ((1, 2)) } fn unit_double_parens() { - (()) //~ERROR Consider removing unnecessary double parentheses + (()) } fn fn_tuple_ok() { diff --git a/tests/ui/double_parens.stderr b/tests/ui/double_parens.stderr new file mode 100644 index 000000000000..1011ad1c0141 --- /dev/null +++ b/tests/ui/double_parens.stderr @@ -0,0 +1,38 @@ +error: Consider removing unnecessary double parentheses + --> $DIR/double_parens.rs:16:5 + | +16 | ((0)) + | ^^^^^ + | +note: lint level defined here + --> $DIR/double_parens.rs:4:9 + | +4 | #![deny(double_parens)] + | ^^^^^^^^^^^^^ + +error: Consider removing unnecessary double parentheses + --> $DIR/double_parens.rs:20:14 + | +20 | dummy_fn((0)); + | ^^^ + +error: Consider removing unnecessary double parentheses + --> $DIR/double_parens.rs:24:20 + | +24 | x.dummy_method((0)); + | ^^^ + +error: Consider removing unnecessary double parentheses + --> $DIR/double_parens.rs:28:5 + | +28 | ((1, 2)) + | ^^^^^^^^ + +error: Consider removing unnecessary double parentheses + --> $DIR/double_parens.rs:32:5 + | +32 | (()) + | ^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/drop_forget_ref.rs b/tests/ui/drop_forget_ref.rs new file mode 100644 index 000000000000..911d3433e4d8 --- /dev/null +++ b/tests/ui/drop_forget_ref.rs @@ -0,0 +1,60 @@ +#![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); + forget(&SomeStruct); + + let mut owned1 = SomeStruct; + drop(&owned1); + drop(&&owned1); + drop(&mut owned1); + drop(owned1); //OK + let mut owned2 = SomeStruct; + forget(&owned2); + forget(&&owned2); + forget(&mut owned2); + forget(owned2); //OK + + let reference1 = &SomeStruct; + drop(reference1); + forget(&*reference1); + + let reference2 = &mut SomeStruct; + drop(reference2); + let reference3 = &mut SomeStruct; + forget(reference3); + + let ref reference4 = SomeStruct; + drop(reference4); + forget(reference4); +} + +#[allow(dead_code)] +fn test_generic_fn_drop(val: T) { + drop(&val); + drop(val); //OK +} + +#[allow(dead_code)] +fn test_generic_fn_forget(val: T) { + forget(&val); + forget(val); //OK +} + +#[allow(dead_code)] +fn test_similarly_named_function() { + fn drop(_val: T) {} + drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name + std::mem::drop(&SomeStruct); + fn forget(_val: T) {} + forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name + std::mem::forget(&SomeStruct); +} diff --git a/tests/ui/drop_forget_ref.stderr b/tests/ui/drop_forget_ref.stderr new file mode 100644 index 000000000000..80c724c19c42 --- /dev/null +++ b/tests/ui/drop_forget_ref.stderr @@ -0,0 +1,228 @@ +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:12:5 + | +12 | drop(&SomeStruct); + | ^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/drop_forget_ref.rs:4:9 + | +4 | #![deny(drop_ref, forget_ref)] + | ^^^^^^^^ +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:12:10 + | +12 | drop(&SomeStruct); + | ^^^^^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:13:5 + | +13 | forget(&SomeStruct); + | ^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/drop_forget_ref.rs:4:19 + | +4 | #![deny(drop_ref, forget_ref)] + | ^^^^^^^^^^ +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:13:12 + | +13 | forget(&SomeStruct); + | ^^^^^^^^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:16:5 + | +16 | drop(&owned1); + | ^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:16:10 + | +16 | drop(&owned1); + | ^^^^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:17:5 + | +17 | drop(&&owned1); + | ^^^^^^^^^^^^^^ + | +note: argument has type &&SomeStruct + --> $DIR/drop_forget_ref.rs:17:10 + | +17 | drop(&&owned1); + | ^^^^^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:18:5 + | +18 | drop(&mut owned1); + | ^^^^^^^^^^^^^^^^^ + | +note: argument has type &mut SomeStruct + --> $DIR/drop_forget_ref.rs:18:10 + | +18 | drop(&mut owned1); + | ^^^^^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:21:5 + | +21 | forget(&owned2); + | ^^^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:21:12 + | +21 | forget(&owned2); + | ^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:22:5 + | +22 | forget(&&owned2); + | ^^^^^^^^^^^^^^^^ + | +note: argument has type &&SomeStruct + --> $DIR/drop_forget_ref.rs:22:12 + | +22 | forget(&&owned2); + | ^^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:23:5 + | +23 | forget(&mut owned2); + | ^^^^^^^^^^^^^^^^^^^ + | +note: argument has type &mut SomeStruct + --> $DIR/drop_forget_ref.rs:23:12 + | +23 | forget(&mut owned2); + | ^^^^^^^^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:27:5 + | +27 | drop(reference1); + | ^^^^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:27:10 + | +27 | drop(reference1); + | ^^^^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:28:5 + | +28 | forget(&*reference1); + | ^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:28:12 + | +28 | forget(&*reference1); + | ^^^^^^^^^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:31:5 + | +31 | drop(reference2); + | ^^^^^^^^^^^^^^^^ + | +note: argument has type &mut SomeStruct + --> $DIR/drop_forget_ref.rs:31:10 + | +31 | drop(reference2); + | ^^^^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:33:5 + | +33 | forget(reference3); + | ^^^^^^^^^^^^^^^^^^ + | +note: argument has type &mut SomeStruct + --> $DIR/drop_forget_ref.rs:33:12 + | +33 | forget(reference3); + | ^^^^^^^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:36:5 + | +36 | drop(reference4); + | ^^^^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:36:10 + | +36 | drop(reference4); + | ^^^^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:37:5 + | +37 | forget(reference4); + | ^^^^^^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:37:12 + | +37 | forget(reference4); + | ^^^^^^^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:42:5 + | +42 | drop(&val); + | ^^^^^^^^^^ + | +note: argument has type &T + --> $DIR/drop_forget_ref.rs:42:10 + | +42 | drop(&val); + | ^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:48:5 + | +48 | forget(&val); + | ^^^^^^^^^^^^ + | +note: argument has type &T + --> $DIR/drop_forget_ref.rs:48:12 + | +48 | forget(&val); + | ^^^^ + +error: call to `std::mem::drop` with a reference argument. Dropping a reference does nothing + --> $DIR/drop_forget_ref.rs:56:5 + | +56 | std::mem::drop(&SomeStruct); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:56:20 + | +56 | std::mem::drop(&SomeStruct); + | ^^^^^^^^^^^ + +error: call to `std::mem::forget` with a reference argument. Forgetting a reference does nothing + --> $DIR/drop_forget_ref.rs:59:5 + | +59 | std::mem::forget(&SomeStruct); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type &SomeStruct + --> $DIR/drop_forget_ref.rs:59:22 + | +59 | std::mem::forget(&SomeStruct); + | ^^^^^^^^^^^ + +error: aborting due to 18 previous errors + diff --git a/tests/compile-fail/duplicate_underscore_argument.rs b/tests/ui/duplicate_underscore_argument.rs similarity index 76% rename from tests/compile-fail/duplicate_underscore_argument.rs rename to tests/ui/duplicate_underscore_argument.rs index 4d908e7f02bc..ca02002bcc02 100644 --- a/tests/compile-fail/duplicate_underscore_argument.rs +++ b/tests/ui/duplicate_underscore_argument.rs @@ -4,10 +4,10 @@ #![deny(duplicate_underscore_argument)] #[allow(dead_code, unused)] -fn join_the_dark_side(darth: i32, _darth: i32) {} //~ERROR `darth` already exists +fn join_the_dark_side(darth: i32, _darth: i32) {} fn join_the_light_side(knight: i32, _master: i32) {} // the Force is strong with this one fn main() { join_the_dark_side(0, 0); join_the_light_side(0, 0); -} \ No newline at end of file +} diff --git a/tests/ui/duplicate_underscore_argument.stderr b/tests/ui/duplicate_underscore_argument.stderr new file mode 100644 index 000000000000..3e507acd98bb --- /dev/null +++ b/tests/ui/duplicate_underscore_argument.stderr @@ -0,0 +1,14 @@ +error: `darth` already exists, having another argument having almost the same name makes code comprehension and documentation more difficult + --> $DIR/duplicate_underscore_argument.rs:7:23 + | +7 | fn join_the_dark_side(darth: i32, _darth: i32) {} + | ^^^^^ + | +note: lint level defined here + --> $DIR/duplicate_underscore_argument.rs:4:9 + | +4 | #![deny(duplicate_underscore_argument)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/empty_enum.rs b/tests/ui/empty_enum.rs new file mode 100644 index 000000000000..9f32b7ede10e --- /dev/null +++ b/tests/ui/empty_enum.rs @@ -0,0 +1,11 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#![allow(dead_code)] +#![deny(empty_enum)] + +enum Empty {} + + +fn main() { +} diff --git a/tests/ui/empty_enum.stderr b/tests/ui/empty_enum.stderr new file mode 100644 index 000000000000..2a5e1165fb37 --- /dev/null +++ b/tests/ui/empty_enum.stderr @@ -0,0 +1,19 @@ +error: enum with no variants + --> $DIR/empty_enum.rs:7:1 + | +7 | enum Empty {} + | ^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/empty_enum.rs:5:9 + | +5 | #![deny(empty_enum)] + | ^^^^^^^^^^ +help: consider using the uninhabited type `!` or a wrapper around it + --> $DIR/empty_enum.rs:7:1 + | +7 | enum Empty {} + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/compile-fail/entry.rs b/tests/ui/entry.rs similarity index 58% rename from tests/compile-fail/entry.rs rename to tests/ui/entry.rs index ec3b75abb371..816da06b956f 100644 --- a/tests/compile-fail/entry.rs +++ b/tests/ui/entry.rs @@ -11,51 +11,51 @@ fn foo() {} fn insert_if_absent0(m: &mut HashMap, k: K, v: V) { if !m.contains_key(&k) { m.insert(k, v); } - //~^ ERROR usage of `contains_key` followed by `insert` on a `HashMap` - //~| HELP consider - //~| SUGGESTION m.entry(k).or_insert(v) + + + } fn insert_if_absent1(m: &mut HashMap, k: K, v: V) { if !m.contains_key(&k) { foo(); m.insert(k, v); } - //~^ ERROR usage of `contains_key` followed by `insert` on a `HashMap` - //~| HELP consider - //~| SUGGESTION m.entry(k) + + + } fn insert_if_absent2(m: &mut HashMap, k: K, v: V) { if !m.contains_key(&k) { m.insert(k, v) } else { None }; - //~^ ERROR usage of `contains_key` followed by `insert` on a `HashMap` - //~| HELP consider - //~| SUGGESTION m.entry(k) + + + } fn insert_if_present2(m: &mut HashMap, k: K, v: V) { if m.contains_key(&k) { None } else { m.insert(k, v) }; - //~^ ERROR usage of `contains_key` followed by `insert` on a `HashMap` - //~| HELP consider - //~| SUGGESTION m.entry(k) + + + } fn insert_if_absent3(m: &mut HashMap, k: K, v: V) { if !m.contains_key(&k) { foo(); m.insert(k, v) } else { None }; - //~^ ERROR usage of `contains_key` followed by `insert` on a `HashMap` - //~| HELP consider - //~| SUGGESTION m.entry(k) + + + } fn insert_if_present3(m: &mut HashMap, k: K, v: V) { if m.contains_key(&k) { None } else { foo(); m.insert(k, v) }; - //~^ ERROR usage of `contains_key` followed by `insert` on a `HashMap` - //~| HELP consider - //~| SUGGESTION m.entry(k) + + + } fn insert_in_btreemap(m: &mut BTreeMap, k: K, v: V) { if !m.contains_key(&k) { foo(); m.insert(k, v) } else { None }; - //~^ ERROR usage of `contains_key` followed by `insert` on a `BTreeMap` - //~| HELP consider - //~| SUGGESTION m.entry(k) + + + } fn insert_other_if_absent(m: &mut HashMap, k: K, o: K, v: V) { diff --git a/tests/ui/entry.stderr b/tests/ui/entry.stderr new file mode 100644 index 000000000000..b4e09d2671b8 --- /dev/null +++ b/tests/ui/entry.stderr @@ -0,0 +1,70 @@ +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> $DIR/entry.rs:13:5 + | +13 | if !m.contains_key(&k) { m.insert(k, v); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/entry.rs:5:9 + | +5 | #![deny(map_entry)] + | ^^^^^^^^^ +help: consider using + | m.entry(k).or_insert(v) + +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> $DIR/entry.rs:20:5 + | +20 | if !m.contains_key(&k) { foo(); m.insert(k, v); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using + | m.entry(k) + +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> $DIR/entry.rs:27:5 + | +27 | if !m.contains_key(&k) { m.insert(k, v) } else { None }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using + | m.entry(k); + +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> $DIR/entry.rs:34:5 + | +34 | if m.contains_key(&k) { None } else { m.insert(k, v) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using + | m.entry(k); + +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> $DIR/entry.rs:41:5 + | +41 | if !m.contains_key(&k) { foo(); m.insert(k, v) } else { None }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using + | m.entry(k); + +error: usage of `contains_key` followed by `insert` on a `HashMap` + --> $DIR/entry.rs:48:5 + | +48 | if m.contains_key(&k) { None } else { foo(); m.insert(k, v) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using + | m.entry(k); + +error: usage of `contains_key` followed by `insert` on a `BTreeMap` + --> $DIR/entry.rs:55:5 + | +55 | if !m.contains_key(&k) { foo(); m.insert(k, v) } else { None }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using + | m.entry(k); + +error: aborting due to 7 previous errors + diff --git a/tests/compile-fail/enum_glob_use.rs b/tests/ui/enum_glob_use.rs similarity index 69% rename from tests/compile-fail/enum_glob_use.rs rename to tests/ui/enum_glob_use.rs index 86539c2b13ef..6becdb3c9aeb 100644 --- a/tests/compile-fail/enum_glob_use.rs +++ b/tests/ui/enum_glob_use.rs @@ -3,13 +3,13 @@ #![deny(clippy, clippy_pedantic)] #![allow(unused_imports, dead_code, missing_docs_in_private_items)] -use std::cmp::Ordering::*; //~ ERROR: don't use glob imports for enum variants +use std::cmp::Ordering::*; enum Enum { _Foo, } -use self::Enum::*; //~ ERROR: don't use glob imports for enum variants +use self::Enum::*; fn blarg() { use self::Enum::*; // ok, just for a function diff --git a/tests/ui/enum_glob_use.stderr b/tests/ui/enum_glob_use.stderr new file mode 100644 index 000000000000..657ab13ebbe4 --- /dev/null +++ b/tests/ui/enum_glob_use.stderr @@ -0,0 +1,23 @@ +error: don't use glob imports for enum variants + --> $DIR/enum_glob_use.rs:6:1 + | +6 | use std::cmp::Ordering::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_glob_use)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/enum_glob_use.rs:3:17 + | +3 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ + +error: don't use glob imports for enum variants + --> $DIR/enum_glob_use.rs:12:1 + | +12 | use self::Enum::*; + | ^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_glob_use)] implied by #[deny(clippy_pedantic)] + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/enum_variants.rs b/tests/ui/enum_variants.rs similarity index 61% rename from tests/compile-fail/enum_variants.rs rename to tests/ui/enum_variants.rs index 585535f9d999..8d7a41b986e2 100644 --- a/tests/compile-fail/enum_variants.rs +++ b/tests/ui/enum_variants.rs @@ -11,7 +11,7 @@ enum FakeCallType2 { } enum Foo { - cFoo, //~ ERROR: Variant name ends with the enum's name + cFoo, cBar, cBaz, } @@ -21,17 +21,17 @@ enum Fooo { cBar, } -enum Food { //~ ERROR: All variants have the same prefix: `Food` - FoodGood, //~ ERROR: Variant name starts with the enum's name - FoodMiddle, //~ ERROR: Variant name starts with the enum's name - FoodBad, //~ ERROR: Variant name starts with the enum's name +enum Food { + FoodGood, + FoodMiddle, + FoodBad, } enum Stuff { StuffBad, // no error } -enum BadCallType { //~ ERROR: All variants have the same prefix: `CallType` +enum BadCallType { CallTypeCall, CallTypeCreate, CallTypeDestroy, @@ -42,7 +42,7 @@ enum TwoCallType { // no error CallTypeCreate, } -enum Consts { //~ ERROR: All variants have the same prefix: `Constant` +enum Consts { ConstantInt, ConstantCake, ConstantLie, @@ -75,19 +75,19 @@ enum Sealll { WithOut, } -enum Seallll { //~ ERROR: All variants have the same prefix: `With` +enum Seallll { WithOutCake, WithOutTea, WithOut, } -enum NonCaps { //~ ERROR: All variants have the same prefix: `Prefix` +enum NonCaps { Prefix的, PrefixTea, PrefixCake, } -pub enum PubSeall { //~ ERROR: All variants have the same prefix: +pub enum PubSeall { WithOutCake, WithOutTea, WithOut, diff --git a/tests/ui/enum_variants.stderr b/tests/ui/enum_variants.stderr new file mode 100644 index 000000000000..5ff441605302 --- /dev/null +++ b/tests/ui/enum_variants.stderr @@ -0,0 +1,127 @@ +error: Variant name ends with the enum's name + --> $DIR/enum_variants.rs:14:5 + | +14 | cFoo, + | ^^^^ + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/enum_variants.rs:3:9 + | +3 | #![deny(clippy, pub_enum_variant_names)] + | ^^^^^^ + +error: Variant name starts with the enum's name + --> $DIR/enum_variants.rs:25:5 + | +25 | FoodGood, + | ^^^^^^^^ + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + +error: Variant name starts with the enum's name + --> $DIR/enum_variants.rs:26:5 + | +26 | FoodMiddle, + | ^^^^^^^^^^ + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + +error: Variant name starts with the enum's name + --> $DIR/enum_variants.rs:27:5 + | +27 | FoodBad, + | ^^^^^^^ + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + +error: All variants have the same prefix: `Food` + --> $DIR/enum_variants.rs:24:1 + | +24 | enum Food { + | _^ starting here... +25 | | FoodGood, +26 | | FoodMiddle, +27 | | FoodBad, +28 | | } + | |_^ ...ending here + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + = help: remove the prefixes and use full paths to the variants instead of glob imports + +error: All variants have the same prefix: `CallType` + --> $DIR/enum_variants.rs:34:1 + | +34 | enum BadCallType { + | _^ starting here... +35 | | CallTypeCall, +36 | | CallTypeCreate, +37 | | CallTypeDestroy, +38 | | } + | |_^ ...ending here + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + = help: remove the prefixes and use full paths to the variants instead of glob imports + +error: All variants have the same prefix: `Constant` + --> $DIR/enum_variants.rs:45:1 + | +45 | enum Consts { + | _^ starting here... +46 | | ConstantInt, +47 | | ConstantCake, +48 | | ConstantLie, +49 | | } + | |_^ ...ending here + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + = help: remove the prefixes and use full paths to the variants instead of glob imports + +error: All variants have the same prefix: `With` + --> $DIR/enum_variants.rs:78:1 + | +78 | enum Seallll { + | _^ starting here... +79 | | WithOutCake, +80 | | WithOutTea, +81 | | WithOut, +82 | | } + | |_^ ...ending here + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + = help: remove the prefixes and use full paths to the variants instead of glob imports + +error: All variants have the same prefix: `Prefix` + --> $DIR/enum_variants.rs:84:1 + | +84 | enum NonCaps { + | _^ starting here... +85 | | Prefix的, +86 | | PrefixTea, +87 | | PrefixCake, +88 | | } + | |_^ ...ending here + | + = note: #[deny(enum_variant_names)] implied by #[deny(clippy)] + = help: remove the prefixes and use full paths to the variants instead of glob imports + +error: All variants have the same prefix: `With` + --> $DIR/enum_variants.rs:90:1 + | +90 | pub enum PubSeall { + | _^ starting here... +91 | | WithOutCake, +92 | | WithOutTea, +93 | | WithOut, +94 | | } + | |_^ ...ending here + | +note: lint level defined here + --> $DIR/enum_variants.rs:3:17 + | +3 | #![deny(clippy, pub_enum_variant_names)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = help: remove the prefixes and use full paths to the variants instead of glob imports + +error: aborting due to 10 previous errors + diff --git a/tests/ui/enums_clike.rs b/tests/ui/enums_clike.rs new file mode 100644 index 000000000000..9b4cdbb56b81 --- /dev/null +++ b/tests/ui/enums_clike.rs @@ -0,0 +1,54 @@ +// ignore-x86 +#![feature(plugin, associated_consts)] +#![plugin(clippy)] +#![deny(clippy)] + +#![allow(unused)] + +#[repr(usize)] +enum NonPortable { + X = 0x1_0000_0000, + Y = 0, + Z = 0x7FFF_FFFF, + A = 0xFFFF_FFFF, +} + +enum NonPortableNoHint { + X = 0x1_0000_0000, + Y = 0, + Z = 0x7FFF_FFFF, + A = 0xFFFF_FFFF, +} + +#[repr(isize)] +enum NonPortableSigned { + X = -1, + Y = 0x7FFF_FFFF, + Z = 0xFFFF_FFFF, + A = 0x1_0000_0000, + B = std::i32::MIN as isize, + C = (std::i32::MIN as isize) - 1, +} + +enum NonPortableSignedNoHint { + X = -1, + Y = 0x7FFF_FFFF, + Z = 0xFFFF_FFFF, + A = 0x1_0000_0000, +} + +/* +FIXME: uncomment once https://github.com/rust-lang/rust/issues/31910 is fixed +#[repr(usize)] +enum NonPortable2 { + X = Trait::Number, + Y = 0, +} + +trait Trait { + const Number: usize = 0x1_0000_0000; +} +*/ + +fn main() { +} diff --git a/tests/ui/enums_clike.stderr b/tests/ui/enums_clike.stderr new file mode 100644 index 000000000000..0bfb732feb56 --- /dev/null +++ b/tests/ui/enums_clike.stderr @@ -0,0 +1,71 @@ +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:10:5 + | +10 | X = 0x1_0000_0000, + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/enums_clike.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:17:5 + | +17 | X = 0x1_0000_0000, + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] + +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:20:5 + | +20 | A = 0xFFFF_FFFF, + | ^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] + +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:27:5 + | +27 | Z = 0xFFFF_FFFF, + | ^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] + +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:28:5 + | +28 | A = 0x1_0000_0000, + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] + +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:30:5 + | +30 | C = (std::i32::MIN as isize) - 1, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] + +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:36:5 + | +36 | Z = 0xFFFF_FFFF, + | ^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] + +error: Clike enum variant discriminant is not portable to 32-bit targets + --> $DIR/enums_clike.rs:37:5 + | +37 | A = 0x1_0000_0000, + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(enum_clike_unportable_variant)] implied by #[deny(clippy)] + +error: aborting due to 8 previous errors + diff --git a/tests/ui/eq_op.rs b/tests/ui/eq_op.rs new file mode 100644 index 000000000000..842e5729fcd8 --- /dev/null +++ b/tests/ui/eq_op.rs @@ -0,0 +1,62 @@ +#![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; + "no" == "no"; + // even though I agree that no means no ;-) + false != false; + 1.5 < 1.5; + 1u64 >= 1u64; + + // casts, methods, parentheses + (1 as u64) & (1 as u64); + 1 ^ ((((((1)))))); + + // unary and binary operators + (-(2) < -(2)); + ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); + + + + (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; + + // various other things + ([1] != [1]); + ((1, 2) != (1, 2)); + vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros + + // const folding + 1 + 1 == 2; + 1 - 1 == 0; + + + 1 - 1; + 1 / 1; + true && true; + + true || true; + + + let a: u32 = 0; + let b: u32 = 0; + + a == b && b == a; + + a != b && b != a; + + a < b && b > a; + + a <= b && b >= a; + + + let mut a = vec![1]; + a == a; + 2*a.len() == 2*a.len(); // ok, functions + a.pop() == a.pop(); // ok, functions +} diff --git a/tests/ui/eq_op.stderr b/tests/ui/eq_op.stderr new file mode 100644 index 000000000000..dc2df524df25 --- /dev/null +++ b/tests/ui/eq_op.stderr @@ -0,0 +1,223 @@ +error: this boolean expression can be simplified + --> $DIR/eq_op.rs:41:5 + | +41 | true && true; + | ^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/eq_op.rs:7:8 + | +7 | #[deny(nonminimal_bool)] + | ^^^^^^^^^^^^^^^ +help: try + | true; + +error: this boolean expression can be simplified + --> $DIR/eq_op.rs:43:5 + | +43 | true || true; + | ^^^^^^^^^^^^ + | +help: try + | true; + +error: this boolean expression can be simplified + --> $DIR/eq_op.rs:49:5 + | +49 | a == b && b == a; + | ^^^^^^^^^^^^^^^^ + | +help: try + | a == b; + +error: this boolean expression can be simplified + --> $DIR/eq_op.rs:51:5 + | +51 | a != b && b != a; + | ^^^^^^^^^^^^^^^^ + | +help: try + | a != b; + +error: this boolean expression can be simplified + --> $DIR/eq_op.rs:53:5 + | +53 | a < b && b > a; + | ^^^^^^^^^^^^^^ + | +help: try + | a < b; + +error: this boolean expression can be simplified + --> $DIR/eq_op.rs:55:5 + | +55 | a <= b && b >= a; + | ^^^^^^^^^^^^^^^^ + | +help: try + | a <= b; + +error: equal expressions as operands to `==` + --> $DIR/eq_op.rs:10:5 + | +10 | 1 == 1; + | ^^^^^^ + | +note: lint level defined here + --> $DIR/eq_op.rs:4:8 + | +4 | #[deny(eq_op)] + | ^^^^^ + +error: equal expressions as operands to `==` + --> $DIR/eq_op.rs:11:5 + | +11 | "no" == "no"; + | ^^^^^^^^^^^^ + +error: equal expressions as operands to `!=` + --> $DIR/eq_op.rs:13:5 + | +13 | false != false; + | ^^^^^^^^^^^^^^ + +error: equal expressions as operands to `<` + --> $DIR/eq_op.rs:14:5 + | +14 | 1.5 < 1.5; + | ^^^^^^^^^ + +error: equal expressions as operands to `>=` + --> $DIR/eq_op.rs:15:5 + | +15 | 1u64 >= 1u64; + | ^^^^^^^^^^^^ + +error: equal expressions as operands to `&` + --> $DIR/eq_op.rs:18:5 + | +18 | (1 as u64) & (1 as u64); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `^` + --> $DIR/eq_op.rs:19:5 + | +19 | 1 ^ ((((((1)))))); + | ^^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `<` + --> $DIR/eq_op.rs:22:5 + | +22 | (-(2) < -(2)); + | ^^^^^^^^^^^^^ + +error: equal expressions as operands to `==` + --> $DIR/eq_op.rs:23:5 + | +23 | ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `&` + --> $DIR/eq_op.rs:23:6 + | +23 | ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); + | ^^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `&` + --> $DIR/eq_op.rs:23:27 + | +23 | ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1)); + | ^^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `==` + --> $DIR/eq_op.rs:27:5 + | +27 | (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `!=` + --> $DIR/eq_op.rs:30:5 + | +30 | ([1] != [1]); + | ^^^^^^^^^^^^ + +error: equal expressions as operands to `!=` + --> $DIR/eq_op.rs:31:5 + | +31 | ((1, 2) != (1, 2)); + | ^^^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `==` + --> $DIR/eq_op.rs:35:5 + | +35 | 1 + 1 == 2; + | ^^^^^^^^^^ + +error: equal expressions as operands to `==` + --> $DIR/eq_op.rs:36:5 + | +36 | 1 - 1 == 0; + | ^^^^^^^^^^ + +error: equal expressions as operands to `-` + --> $DIR/eq_op.rs:36:5 + | +36 | 1 - 1 == 0; + | ^^^^^ + +error: equal expressions as operands to `-` + --> $DIR/eq_op.rs:39:5 + | +39 | 1 - 1; + | ^^^^^ + +error: equal expressions as operands to `/` + --> $DIR/eq_op.rs:40:5 + | +40 | 1 / 1; + | ^^^^^ + +error: equal expressions as operands to `&&` + --> $DIR/eq_op.rs:41:5 + | +41 | true && true; + | ^^^^^^^^^^^^ + +error: equal expressions as operands to `||` + --> $DIR/eq_op.rs:43:5 + | +43 | true || true; + | ^^^^^^^^^^^^ + +error: equal expressions as operands to `&&` + --> $DIR/eq_op.rs:49:5 + | +49 | a == b && b == a; + | ^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `&&` + --> $DIR/eq_op.rs:51:5 + | +51 | a != b && b != a; + | ^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `&&` + --> $DIR/eq_op.rs:53:5 + | +53 | a < b && b > a; + | ^^^^^^^^^^^^^^ + +error: equal expressions as operands to `&&` + --> $DIR/eq_op.rs:55:5 + | +55 | a <= b && b >= a; + | ^^^^^^^^^^^^^^^^ + +error: equal expressions as operands to `==` + --> $DIR/eq_op.rs:59:5 + | +59 | a == a; + | ^^^^^^ + +error: aborting due to 32 previous errors + diff --git a/tests/compile-fail/escape_analysis.rs b/tests/ui/escape_analysis.rs similarity index 80% rename from tests/compile-fail/escape_analysis.rs rename to tests/ui/escape_analysis.rs index 1d4bc89ef492..595857b82df4 100644 --- a/tests/compile-fail/escape_analysis.rs +++ b/tests/ui/escape_analysis.rs @@ -30,11 +30,11 @@ fn ok_box_trait(boxed_trait: &Box) { } fn warn_call() { - let x = box A; //~ ERROR local variable + let x = box A; x.foo(); } -fn warn_arg(x: Box) { //~ ERROR local variable +fn warn_arg(x: Box) { x.foo(); } @@ -46,16 +46,16 @@ fn nowarn_closure_arg() { fn warn_rename_call() { let x = box A; - let y = x; //~ ERROR local variable + let y = x; y.foo(); // via autoderef } fn warn_notuse() { - let bz = box A; //~ ERROR local variable + let bz = box A; } fn warn_pass() { - let bz = box A; //~ ERROR local variable + let bz = box A; take_ref(&bz); // via deref coercion } @@ -85,7 +85,7 @@ fn take_ref(x: &A) {} fn nowarn_ref_take() { // false positive, should actually warn - let x = box A; //~ ERROR local variable + let x = box A; let y = &x; take_box(y); } @@ -98,7 +98,7 @@ fn nowarn_match() { } fn warn_match() { - let x = box A; //~ ERROR local variable + let x = box A; match &x { // not moved ref y => () } @@ -127,5 +127,5 @@ pub struct PeekableSeekable { _peeked: I::Item, } -pub fn new(_needs_name: Box>) -> () { //~ ERROR local variable doesn't need +pub fn new(_needs_name: Box>) -> () { } diff --git a/tests/ui/escape_analysis.stderr b/tests/ui/escape_analysis.stderr new file mode 100644 index 000000000000..e3898e4b2774 --- /dev/null +++ b/tests/ui/escape_analysis.stderr @@ -0,0 +1,56 @@ +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:33:9 + | +33 | let x = box A; + | ^ + | +note: lint level defined here + --> $DIR/escape_analysis.rs:5:9 + | +5 | #![deny(boxed_local)] + | ^^^^^^^^^^^ + +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:37:13 + | +37 | fn warn_arg(x: Box) { + | ^ + +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:49:9 + | +49 | let y = x; + | ^ + +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:54:9 + | +54 | let bz = box A; + | ^^ + +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:58:9 + | +58 | let bz = box A; + | ^^ + +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:88:9 + | +88 | let x = box A; + | ^ + +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:101:9 + | +101 | let x = box A; + | ^ + +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:130:12 + | +130 | pub fn new(_needs_name: Box>) -> () { + | ^^^^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/compile-fail/eta.rs b/tests/ui/eta.rs similarity index 69% rename from tests/compile-fail/eta.rs rename to tests/ui/eta.rs index c932f8f9a0fe..90ffa61216fd 100644 --- a/tests/compile-fail/eta.rs +++ b/tests/ui/eta.rs @@ -5,20 +5,20 @@ fn main() { let a = Some(1u8).map(|a| foo(a)); - //~^ ERROR redundant closure found - //~| HELP remove closure as shown - //~| SUGGESTION let a = Some(1u8).map(foo); + + + meta(|a| foo(a)); - //~^ ERROR redundant closure found - //~| HELP remove closure as shown - //~| SUGGESTION meta(foo); + + + let c = Some(1u8).map(|a| {1+2; foo}(a)); - //~^ ERROR redundant closure found - //~| HELP remove closure as shown - //~| SUGGESTION let c = Some(1u8).map({1+2; foo}); + + + let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted - //~^ WARN needless_borrow + unsafe { Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn } @@ -26,9 +26,9 @@ fn main() { // See #815 let e = Some(1u8).map(|a| divergent(a)); let e = Some(1u8).map(|a| generic(a)); - //~^ ERROR redundant closure found - //~| HELP remove closure as shown - //~| SUGGESTION map(generic); + + + let e = Some(1u8).map(generic); // See #515 diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr new file mode 100644 index 000000000000..4683ae2708f2 --- /dev/null +++ b/tests/ui/eta.stderr @@ -0,0 +1,51 @@ +error: redundant closure found + --> $DIR/eta.rs:7:27 + | +7 | let a = Some(1u8).map(|a| foo(a)); + | ^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/eta.rs:4:9 + | +4 | #![deny(redundant_closure)] + | ^^^^^^^^^^^^^^^^^ +help: remove closure as shown: + | let a = Some(1u8).map(foo); + +error: redundant closure found + --> $DIR/eta.rs:11:10 + | +11 | meta(|a| foo(a)); + | ^^^^^^^^^^ + | +help: remove closure as shown: + | meta(foo); + +error: redundant closure found + --> $DIR/eta.rs:15:27 + | +15 | let c = Some(1u8).map(|a| {1+2; foo}(a)); + | ^^^^^^^^^^^^^^^^^ + | +help: remove closure as shown: + | let c = Some(1u8).map({1+2; foo}); + +warning: this expression borrows a reference that is immediately dereferenced by the compiler + --> $DIR/eta.rs:20:21 + | +20 | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted + | ^^^ + | + = note: #[warn(needless_borrow)] on by default + +error: redundant closure found + --> $DIR/eta.rs:28:27 + | +28 | let e = Some(1u8).map(|a| generic(a)); + | ^^^^^^^^^^^^^^ + | +help: remove closure as shown: + | let e = Some(1u8).map(generic); + +error: aborting due to 4 previous errors + diff --git a/tests/compile-fail/eval_order_dependence.rs b/tests/ui/eval_order_dependence.rs similarity index 87% rename from tests/compile-fail/eval_order_dependence.rs rename to tests/ui/eval_order_dependence.rs index 0b2605d01bd5..851a199f929f 100644 --- a/tests/compile-fail/eval_order_dependence.rs +++ b/tests/ui/eval_order_dependence.rs @@ -6,21 +6,21 @@ fn main() { let mut x = 0; let a = { x = 1; 1 } + x; - //~^ ERROR unsequenced read + // Example from iss#277 - x += { x = 20; 2 }; //~ERROR unsequenced read + x += { x = 20; 2 }; // Does it work in weird places? // ...in the base for a struct expression? struct Foo { a: i32, b: i32 }; let base = Foo { a: 4, b: 5 }; let foo = Foo { a: x, .. { x = 6; base } }; - //~^ ERROR unsequenced read + // ...inside a closure? let closure = || { let mut x = 0; - x += { x = 20; 2 }; //~ERROR unsequenced read + x += { x = 20; 2 }; }; // ...not across a closure? let mut y = 0; diff --git a/tests/ui/eval_order_dependence.stderr b/tests/ui/eval_order_dependence.stderr new file mode 100644 index 000000000000..ba985dd907a0 --- /dev/null +++ b/tests/ui/eval_order_dependence.stderr @@ -0,0 +1,55 @@ +error: unsequenced read of a variable + --> $DIR/eval_order_dependence.rs:8:28 + | +8 | let a = { x = 1; 1 } + x; + | ^ + | +note: lint level defined here + --> $DIR/eval_order_dependence.rs:4:8 + | +4 | #[deny(eval_order_dependence)] + | ^^^^^^^^^^^^^^^^^^^^^ +note: whether read occurs before this write depends on evaluation order + --> $DIR/eval_order_dependence.rs:8:15 + | +8 | let a = { x = 1; 1 } + x; + | ^^^^^ + +error: unsequenced read of a variable + --> $DIR/eval_order_dependence.rs:12:5 + | +12 | x += { x = 20; 2 }; + | ^ + | +note: whether read occurs before this write depends on evaluation order + --> $DIR/eval_order_dependence.rs:12:12 + | +12 | x += { x = 20; 2 }; + | ^^^^^^ + +error: unsequenced read of a variable + --> $DIR/eval_order_dependence.rs:18:24 + | +18 | let foo = Foo { a: x, .. { x = 6; base } }; + | ^ + | +note: whether read occurs before this write depends on evaluation order + --> $DIR/eval_order_dependence.rs:18:32 + | +18 | let foo = Foo { a: x, .. { x = 6; base } }; + | ^^^^^ + +error: unsequenced read of a variable + --> $DIR/eval_order_dependence.rs:23:9 + | +23 | x += { x = 20; 2 }; + | ^ + | +note: whether read occurs before this write depends on evaluation order + --> $DIR/eval_order_dependence.rs:23:16 + | +23 | x += { x = 20; 2 }; + | ^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/compile-fail/filter_methods.rs b/tests/ui/filter_methods.rs similarity index 65% rename from tests/compile-fail/filter_methods.rs rename to tests/ui/filter_methods.rs index 20803c8d0e85..922f9fba6a86 100644 --- a/tests/compile-fail/filter_methods.rs +++ b/tests/ui/filter_methods.rs @@ -5,22 +5,22 @@ #![allow(missing_docs_in_private_items)] fn main() { - let _: Vec<_> = vec![5; 6].into_iter() //~ERROR called `filter(p).map(q)` on an `Iterator` + let _: Vec<_> = vec![5; 6].into_iter() .filter(|&x| x == 0) .map(|x| x * 2) .collect(); - let _: Vec<_> = vec![5_i8; 6].into_iter() //~ERROR called `filter(p).flat_map(q)` on an `Iterator` + let _: Vec<_> = vec![5_i8; 6].into_iter() .filter(|&x| x == 0) .flat_map(|x| x.checked_mul(2)) .collect(); - let _: Vec<_> = vec![5_i8; 6].into_iter() //~ERROR called `filter_map(p).flat_map(q)` on an `Iterator` + let _: Vec<_> = vec![5_i8; 6].into_iter() .filter_map(|x| x.checked_mul(2)) .flat_map(|x| x.checked_mul(2)) .collect(); - let _: Vec<_> = vec![5_i8; 6].into_iter() //~ERROR called `filter_map(p).map(q)` on an `Iterator` + let _: Vec<_> = vec![5_i8; 6].into_iter() .filter_map(|x| x.checked_mul(2)) .map(|x| x.checked_mul(2)) .collect(); diff --git a/tests/ui/filter_methods.stderr b/tests/ui/filter_methods.stderr new file mode 100644 index 000000000000..8de65e0f4c52 --- /dev/null +++ b/tests/ui/filter_methods.stderr @@ -0,0 +1,51 @@ +error: called `filter(p).map(q)` on an `Iterator`. This is more succinctly expressed by calling `.filter_map(..)` instead. + --> $DIR/filter_methods.rs:8:21 + | +8 | let _: Vec<_> = vec![5; 6].into_iter() + | _____________________^ starting here... +9 | | .filter(|&x| x == 0) +10 | | .map(|x| x * 2) + | |_____________________________________________^ ...ending here + | + = note: #[deny(filter_map)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/filter_methods.rs:4:17 + | +4 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ + +error: called `filter(p).flat_map(q)` on an `Iterator`. This is more succinctly expressed by calling `.flat_map(..)` and filtering by returning an empty Iterator. + --> $DIR/filter_methods.rs:13:21 + | +13 | let _: Vec<_> = vec![5_i8; 6].into_iter() + | _____________________^ starting here... +14 | | .filter(|&x| x == 0) +15 | | .flat_map(|x| x.checked_mul(2)) + | |_______________________________________________________________^ ...ending here + | + = note: #[deny(filter_map)] implied by #[deny(clippy_pedantic)] + +error: called `filter_map(p).flat_map(q)` on an `Iterator`. This is more succinctly expressed by calling `.flat_map(..)` and filtering by returning an empty Iterator. + --> $DIR/filter_methods.rs:18:21 + | +18 | let _: Vec<_> = vec![5_i8; 6].into_iter() + | _____________________^ starting here... +19 | | .filter_map(|x| x.checked_mul(2)) +20 | | .flat_map(|x| x.checked_mul(2)) + | |_______________________________________________________________^ ...ending here + | + = note: #[deny(filter_map)] implied by #[deny(clippy_pedantic)] + +error: called `filter_map(p).map(q)` on an `Iterator`. This is more succinctly expressed by only calling `.filter_map(..)` instead. + --> $DIR/filter_methods.rs:23:21 + | +23 | let _: Vec<_> = vec![5_i8; 6].into_iter() + | _____________________^ starting here... +24 | | .filter_map(|x| x.checked_mul(2)) +25 | | .map(|x| x.checked_mul(2)) + | |__________________________________________________________^ ...ending here + | + = note: #[deny(filter_map)] implied by #[deny(clippy_pedantic)] + +error: aborting due to 4 previous errors + diff --git a/tests/compile-fail/float_cmp.rs b/tests/ui/float_cmp.rs similarity index 61% rename from tests/compile-fail/float_cmp.rs rename to tests/ui/float_cmp.rs index 314cc7214255..de897caca08e 100644 --- a/tests/compile-fail/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -41,46 +41,46 @@ fn main() { ZERO + ZERO != 1.0; //no error, comparison with zero is ok ONE == 1f32; - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (ONE - 1f32).abs() < error + + + ONE == 1.0 + 0.0; - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (ONE - (1.0 + 0.0)).abs() < error + + + ONE + ONE == ZERO + ONE + ONE; - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (ONE + ONE - (ZERO + ONE + ONE)).abs() < error + + + ONE != 2.0; - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (ONE - 2.0).abs() < error + + + ONE != 0.0; // no error, comparison with zero is ok twice(ONE) != ONE; - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (twice(ONE) - ONE).abs() < error + + + ONE as f64 != 2.0; - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (ONE as f64 - 2.0).abs() < error + + + ONE as f64 != 0.0; // no error, comparison with zero is ok let x : f64 = 1.0; x == 1.0; - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (x - 1.0).abs() < error + + + x != 0f64; // no error, comparison with zero is ok twice(x) != twice(ONE as f64); - //~^ ERROR strict comparison of f32 or f64 - //~| HELP within some error - //~| SUGGESTION (twice(x) - twice(ONE as f64)).abs() < error + + + x < 0.0; // no errors, lower or greater comparisons need no fuzzyness diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr new file mode 100644 index 000000000000..8c6abadadecd --- /dev/null +++ b/tests/ui/float_cmp.stderr @@ -0,0 +1,119 @@ +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:43:5 + | +43 | ONE == 1f32; + | ^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/float_cmp.rs:4:9 + | +4 | #![deny(float_cmp)] + | ^^^^^^^^^ +help: consider comparing them within some error + | (ONE - 1f32).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:43:5 + | +43 | ONE == 1f32; + | ^^^^^^^^^^^ + +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:47:5 + | +47 | ONE == 1.0 + 0.0; + | ^^^^^^^^^^^^^^^^ + | +help: consider comparing them within some error + | (ONE - (1.0 + 0.0)).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:47:5 + | +47 | ONE == 1.0 + 0.0; + | ^^^^^^^^^^^^^^^^ + +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:52:5 + | +52 | ONE + ONE == ZERO + ONE + ONE; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider comparing them within some error + | (ONE + ONE - (ZERO + ONE + ONE)).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:52:5 + | +52 | ONE + ONE == ZERO + ONE + ONE; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:57:5 + | +57 | ONE != 2.0; + | ^^^^^^^^^^ + | +help: consider comparing them within some error + | (ONE - 2.0).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:57:5 + | +57 | ONE != 2.0; + | ^^^^^^^^^^ + +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:62:5 + | +62 | twice(ONE) != ONE; + | ^^^^^^^^^^^^^^^^^ + | +help: consider comparing them within some error + | (twice(ONE) - ONE).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:62:5 + | +62 | twice(ONE) != ONE; + | ^^^^^^^^^^^^^^^^^ + +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:66:5 + | +66 | ONE as f64 != 2.0; + | ^^^^^^^^^^^^^^^^^ + | +help: consider comparing them within some error + | (ONE as f64 - 2.0).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:66:5 + | +66 | ONE as f64 != 2.0; + | ^^^^^^^^^^^^^^^^^ + +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:74:5 + | +74 | x == 1.0; + | ^^^^^^^^ + | +help: consider comparing them within some error + | (x - 1.0).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:74:5 + | +74 | x == 1.0; + | ^^^^^^^^ + +error: strict comparison of f32 or f64 + --> $DIR/float_cmp.rs:80:5 + | +80 | twice(x) != twice(ONE as f64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider comparing them within some error + | (twice(x) - twice(ONE as f64)).abs() < error; +note: std::f32::EPSILON and std::f64::EPSILON are available. + --> $DIR/float_cmp.rs:80:5 + | +80 | twice(x) != twice(ONE as f64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/compile-fail/for_loop.rs b/tests/ui/for_loop.rs similarity index 51% rename from tests/compile-fail/for_loop.rs rename to tests/ui/for_loop.rs index 09b0431c6566..42599f851541 100644 --- a/tests/compile-fail/for_loop.rs +++ b/tests/ui/for_loop.rs @@ -16,43 +16,43 @@ fn for_loop_over_option_and_result() { // check FOR_LOOP_OVER_OPTION lint for x in option { - //~^ ERROR for loop over `option`, which is an `Option`. - //~| HELP consider replacing `for x in option` with `if let Some(x) = option` + + println!("{}", x); } // check FOR_LOOP_OVER_RESULT lint for x in result { - //~^ ERROR for loop over `result`, which is a `Result`. - //~| HELP consider replacing `for x in result` with `if let Ok(x) = result` + + println!("{}", x); } for x in option.ok_or("x not found") { - //~^ ERROR for loop over `option.ok_or("x not found")`, which is a `Result`. - //~| HELP consider replacing `for x in option.ok_or("x not found")` with `if let Ok(x) = option.ok_or("x not found")` + + println!("{}", x); } // make sure LOOP_OVER_NEXT lint takes precedence when next() is the last call in the chain for x in v.iter().next() { - //~^ ERROR you are iterating over `Iterator::next()` which is an Option + println!("{}", x); } // make sure we lint when next() is not the last call in the chain for x in v.iter().next().and(Some(0)) { - //~^ ERROR for loop over `v.iter().next().and(Some(0))`, which is an `Option` - //~| HELP consider replacing `for x in v.iter().next().and(Some(0))` with `if let Some(x) = v.iter().next().and(Some(0))` + + println!("{}", x); } for x in v.iter().next().ok_or("x not found") { - //~^ ERROR for loop over `v.iter().next().ok_or("x not found")`, which is a `Result` - //~| HELP consider replacing `for x in v.iter().next().ok_or("x not found")` with `if let Ok(x) = v.iter().next().ok_or("x not found")` + + println!("{}", x); } @@ -97,47 +97,47 @@ fn main() { let mut vec = vec![1, 2, 3, 4]; let vec2 = vec![1, 2, 3, 4]; for i in 0..vec.len() { - //~^ ERROR `i` is only used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in &vec { + + + + println!("{}", vec[i]); } for i in 0..vec.len() { - //~^ WARNING unused variable + let i = 42; // make a different `i` println!("{}", vec[i]); // ok, not the `i` of the for-loop } for i in 0..vec.len() { let _ = vec[i]; } - //~^ ERROR `i` is only used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in &vec { let _ = vec[i]; } + + + + // ICE #746 for j in 0..4 { - //~^ ERROR `j` is only used to index `STATIC` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in STATIC.iter().take(4) { + + + + println!("{:?}", STATIC[j]); } for j in 0..4 { - //~^ ERROR `j` is only used to index `CONST` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in CONST.iter().take(4) { + + + + println!("{:?}", CONST[j]); } for i in 0..vec.len() { - //~^ ERROR `i` is used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for (i, ) in vec.iter().enumerate() { + + + + println!("{} {}", vec[i], i); } for i in 0..vec.len() { // not an error, indexing more than one variable @@ -145,90 +145,90 @@ fn main() { } for i in 0..vec.len() { - //~^ ERROR `i` is only used to index `vec2` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in vec2.iter().take(vec.len()) { + + + + println!("{}", vec2[i]); } for i in 5..vec.len() { - //~^ ERROR `i` is only used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in vec.iter().skip(5) { + + + + println!("{}", vec[i]); } for i in 0..MAX_LEN { - //~^ ERROR `i` is only used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in vec.iter().take(MAX_LEN) { + + + + println!("{}", vec[i]); } for i in 0...MAX_LEN { - //~^ ERROR `i` is only used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in vec.iter().take(MAX_LEN + 1) { + + + + println!("{}", vec[i]); } for i in 5..10 { - //~^ ERROR `i` is only used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in vec.iter().take(10).skip(5) { + + + + println!("{}", vec[i]); } for i in 5...10 { - //~^ ERROR `i` is only used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for in vec.iter().take(10 + 1).skip(5) { + + + + println!("{}", vec[i]); } for i in 5..vec.len() { - //~^ ERROR `i` is used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for (i, ) in vec.iter().enumerate().skip(5) { + + + + println!("{} {}", vec[i], i); } for i in 5..10 { - //~^ ERROR `i` is used to index `vec` - //~| HELP consider - //~| HELP consider - //~| SUGGESTION for (i, ) in vec.iter().enumerate().take(10).skip(5) { + + + + println!("{} {}", vec[i], i); } for i in 10..0 { - //~^ERROR this range is empty so this for loop will never run - //~|HELP consider - //~|SUGGESTION (0..10).rev() + + + println!("{}", i); } for i in 10...0 { - //~^ERROR this range is empty so this for loop will never run - //~|HELP consider - //~|SUGGESTION (0...10).rev() + + + println!("{}", i); } - for i in MAX_LEN..0 { //~ERROR this range is empty so this for loop will never run - //~|HELP consider - //~|SUGGESTION (0..MAX_LEN).rev() + for i in MAX_LEN..0 { + + println!("{}", i); } - for i in 5..5 { //~ERROR this range is empty so this for loop will never run + for i in 5..5 { println!("{}", i); } @@ -250,20 +250,20 @@ fn main() { // testing that the empty range lint folds constants for i in 10..5+4 { - //~^ ERROR this range is empty so this for loop will never run - //~| HELP if you are attempting to iterate over this range in reverse - //~| SUGGESTION for i in (5+4..10).rev() { + + + println!("{}", i); } for i in (5+2)..(3-1) { - //~^ ERROR this range is empty so this for loop will never run - //~| HELP if you are attempting to iterate over this range in reverse - //~| SUGGESTION for i in ((3-1)..(5+2)).rev() { + + + println!("{}", i); } - for i in (5+2)..(8-1) { //~ERROR this range is empty so this for loop will never run + for i in (5+2)..(8-1) { println!("{}", i); } @@ -287,98 +287,98 @@ fn main() { } for _v in vec.iter() { } - //~^ ERROR it is more idiomatic to loop over `&vec` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &vec { + + + for _v in vec.iter_mut() { } - //~^ ERROR it is more idiomatic to loop over `&mut vec` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &mut vec { + + + let out_vec = vec![1,2,3]; for _v in out_vec.into_iter() { } - //~^ ERROR it is more idiomatic to loop over `out_vec` instead of `out_vec.into_iter()` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in out_vec { + + + for _v in &vec { } // these are fine for _v in &mut vec { } // these are fine for _v in [1, 2, 3].iter() { } - //~^ ERROR it is more idiomatic to loop over `&[ - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &[1, 2, 3] { + + + for _v in (&mut [1, 2, 3]).iter() { } // no error for _v in [0; 32].iter() {} - //~^ ERROR it is more idiomatic to loop over `&[ - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &[0; 32] { + + + for _v in [0; 33].iter() {} // no error let ll: LinkedList<()> = LinkedList::new(); for _v in ll.iter() { } - //~^ ERROR it is more idiomatic to loop over `&ll` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &ll { + + + let vd: VecDeque<()> = VecDeque::new(); for _v in vd.iter() { } - //~^ ERROR it is more idiomatic to loop over `&vd` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &vd { + + + let bh: BinaryHeap<()> = BinaryHeap::new(); for _v in bh.iter() { } - //~^ ERROR it is more idiomatic to loop over `&bh` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &bh { + + + let hm: HashMap<(), ()> = HashMap::new(); for _v in hm.iter() { } - //~^ ERROR it is more idiomatic to loop over `&hm` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &hm { + + + let bt: BTreeMap<(), ()> = BTreeMap::new(); for _v in bt.iter() { } - //~^ ERROR it is more idiomatic to loop over `&bt` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &bt { + + + let hs: HashSet<()> = HashSet::new(); for _v in hs.iter() { } - //~^ ERROR it is more idiomatic to loop over `&hs` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &hs { + + + let bs: BTreeSet<()> = BTreeSet::new(); for _v in bs.iter() { } - //~^ ERROR it is more idiomatic to loop over `&bs` - //~| HELP to write this more concisely, try looping over - //~| SUGGESTION for _v in &bs { - for _v in vec.iter().next() { } //~ERROR you are iterating over `Iterator::next()` + + + + for _v in vec.iter().next() { } let u = Unrelated(vec![]); for _v in u.next() { } // no error for _v in u.iter() { } // no error let mut out = vec![]; - vec.iter().map(|x| out.push(x)).collect::>(); //~ERROR you are collect()ing an iterator + vec.iter().map(|x| out.push(x)).collect::>(); let _y = vec.iter().map(|x| out.push(x)).collect::>(); // this is fine // Loop with explicit counter variable let mut _index = 0; - for _v in &vec { _index += 1 } //~ERROR the variable `_index` is used as a loop counter + for _v in &vec { _index += 1 } let mut _index = 1; _index = 0; - for _v in &vec { _index += 1 } //~ERROR the variable `_index` is used as a loop counter + for _v in &vec { _index += 1 } // Potential false positives let mut _index = 0; @@ -439,19 +439,19 @@ fn main() { let m : HashMap = HashMap::new(); for (_, v) in &m { - //~^ you seem to want to iterate on a map's values - //~| HELP use the corresponding method - //~| HELP use the corresponding method - //~| SUGGESTION for v in m.values() { + + + + let _v = v; } let m : Rc> = Rc::new(HashMap::new()); for (_, v) in &*m { - //~^ you seem to want to iterate on a map's values - //~| HELP use the corresponding method - //~| HELP use the corresponding method - //~| SUGGESTION for v in (*m).values() { + + + + let _v = v; // Here the `*` is not actually necesarry, but the test tests that we don't suggest // `in *m.values()` as we used to @@ -459,29 +459,29 @@ fn main() { let mut m : HashMap = HashMap::new(); for (_, v) in &mut m { - //~^ you seem to want to iterate on a map's values - //~| HELP use the corresponding method - //~| HELP use the corresponding method - //~| SUGGESTION for v in m.values_mut() + + + + let _v = v; } let m: &mut HashMap = &mut HashMap::new(); for (_, v) in &mut *m { - //~^ you seem to want to iterate on a map's values - //~| HELP use the corresponding method - //~| HELP use the corresponding method - //~| SUGGESTION for v in (*m).values_mut() + + + + let _v = v; } let m : HashMap = HashMap::new(); let rm = &m; for (k, _value) in rm { - //~^ you seem to want to iterate on a map's keys - //~| HELP use the corresponding method - //~| HELP use the corresponding method - //~| SUGGESTION for k in rm.keys() { + + + + let _k = k; } diff --git a/tests/ui/for_loop.stderr b/tests/ui/for_loop.stderr new file mode 100644 index 000000000000..2e9e5d1fe376 --- /dev/null +++ b/tests/ui/for_loop.stderr @@ -0,0 +1,632 @@ +error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement. + --> $DIR/for_loop.rs:18:14 + | +18 | for x in option { + | ^^^^^^ + | + = note: #[deny(for_loop_over_option)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/for_loop.rs:10:8 + | +10 | #[deny(clippy)] + | ^^^^^^ + = help: consider replacing `for x in option` with `if let Some(x) = option` + +error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement. + --> $DIR/for_loop.rs:26:14 + | +26 | for x in result { + | ^^^^^^ + | + = note: #[deny(for_loop_over_result)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/for_loop.rs:10:8 + | +10 | #[deny(clippy)] + | ^^^^^^ + = help: consider replacing `for x in result` with `if let Ok(x) = result` + +error: for loop over `option.ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement. + --> $DIR/for_loop.rs:32:14 + | +32 | for x in option.ok_or("x not found") { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(for_loop_over_result)] implied by #[deny(clippy)] + = help: consider replacing `for x in option.ok_or("x not found")` with `if let Ok(x) = option.ok_or("x not found")` + +error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want + --> $DIR/for_loop.rs:40:5 + | +40 | for x in v.iter().next() { + | _____^ starting here... +41 | | +42 | | println!("{}", x); +43 | | } + | |_____^ ...ending here + | + = note: #[deny(iter_next_loop)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/for_loop.rs:10:8 + | +10 | #[deny(clippy)] + | ^^^^^^ + +error: for loop over `v.iter().next().and(Some(0))`, which is an `Option`. This is more readably written as an `if let` statement. + --> $DIR/for_loop.rs:47:14 + | +47 | for x in v.iter().next().and(Some(0)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(for_loop_over_option)] implied by #[deny(clippy)] + = help: consider replacing `for x in v.iter().next().and(Some(0))` with `if let Some(x) = v.iter().next().and(Some(0))` + +error: for loop over `v.iter().next().ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement. + --> $DIR/for_loop.rs:53:14 + | +53 | for x in v.iter().next().ok_or("x not found") { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(for_loop_over_result)] implied by #[deny(clippy)] + = help: consider replacing `for x in v.iter().next().ok_or("x not found")` with `if let Ok(x) = v.iter().next().ok_or("x not found")` + +error: the loop variable `i` is only used to index `vec`. + --> $DIR/for_loop.rs:99:5 + | +99 | for i in 0..vec.len() { + | _____^ starting here... +100 | | +101 | | +102 | | +103 | | +104 | | println!("{}", vec[i]); +105 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/for_loop.rs:90:8 + | +90 | #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)] + | ^^^^^^^^^^^^^^^^^^^ +help: consider using an iterator + | for in &vec { + +warning: unused variable: `i` + --> $DIR/for_loop.rs:107:9 + | +107 | for i in 0..vec.len() { + | ^ + | + = note: #[warn(unused_variables)] on by default + +error: the loop variable `i` is only used to index `vec`. + --> $DIR/for_loop.rs:113:5 + | +113 | for i in 0..vec.len() { let _ = vec[i]; } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using an iterator + | for in &vec { let _ = vec[i]; } + +error: the loop variable `j` is only used to index `STATIC`. + --> $DIR/for_loop.rs:120:5 + | +120 | for j in 0..4 { + | _____^ starting here... +121 | | +122 | | +123 | | +124 | | +125 | | println!("{:?}", STATIC[j]); +126 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in STATIC.iter().take(4) { + +error: the loop variable `j` is only used to index `CONST`. + --> $DIR/for_loop.rs:128:5 + | +128 | for j in 0..4 { + | _____^ starting here... +129 | | +130 | | +131 | | +132 | | +133 | | println!("{:?}", CONST[j]); +134 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in CONST.iter().take(4) { + +error: the loop variable `i` is used to index `vec` + --> $DIR/for_loop.rs:136:5 + | +136 | for i in 0..vec.len() { + | _____^ starting here... +137 | | +138 | | +139 | | +140 | | +141 | | println!("{} {}", vec[i], i); +142 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for (i, ) in vec.iter().enumerate() { + +error: the loop variable `i` is only used to index `vec2`. + --> $DIR/for_loop.rs:147:5 + | +147 | for i in 0..vec.len() { + | _____^ starting here... +148 | | +149 | | +150 | | +151 | | +152 | | println!("{}", vec2[i]); +153 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in vec2.iter().take(vec.len()) { + +error: the loop variable `i` is only used to index `vec`. + --> $DIR/for_loop.rs:155:5 + | +155 | for i in 5..vec.len() { + | _____^ starting here... +156 | | +157 | | +158 | | +159 | | +160 | | println!("{}", vec[i]); +161 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in vec.iter().skip(5) { + +error: the loop variable `i` is only used to index `vec`. + --> $DIR/for_loop.rs:163:5 + | +163 | for i in 0..MAX_LEN { + | _____^ starting here... +164 | | +165 | | +166 | | +167 | | +168 | | println!("{}", vec[i]); +169 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in vec.iter().take(MAX_LEN) { + +error: the loop variable `i` is only used to index `vec`. + --> $DIR/for_loop.rs:171:5 + | +171 | for i in 0...MAX_LEN { + | _____^ starting here... +172 | | +173 | | +174 | | +175 | | +176 | | println!("{}", vec[i]); +177 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in vec.iter().take(MAX_LEN + 1) { + +error: the loop variable `i` is only used to index `vec`. + --> $DIR/for_loop.rs:179:5 + | +179 | for i in 5..10 { + | _____^ starting here... +180 | | +181 | | +182 | | +183 | | +184 | | println!("{}", vec[i]); +185 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in vec.iter().take(10).skip(5) { + +error: the loop variable `i` is only used to index `vec`. + --> $DIR/for_loop.rs:187:5 + | +187 | for i in 5...10 { + | _____^ starting here... +188 | | +189 | | +190 | | +191 | | +192 | | println!("{}", vec[i]); +193 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for in vec.iter().take(10 + 1).skip(5) { + +error: the loop variable `i` is used to index `vec` + --> $DIR/for_loop.rs:195:5 + | +195 | for i in 5..vec.len() { + | _____^ starting here... +196 | | +197 | | +198 | | +199 | | +200 | | println!("{} {}", vec[i], i); +201 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for (i, ) in vec.iter().enumerate().skip(5) { + +error: the loop variable `i` is used to index `vec` + --> $DIR/for_loop.rs:203:5 + | +203 | for i in 5..10 { + | _____^ starting here... +204 | | +205 | | +206 | | +207 | | +208 | | println!("{} {}", vec[i], i); +209 | | } + | |_____^ ...ending here + | +help: consider using an iterator + | for (i, ) in vec.iter().enumerate().take(10).skip(5) { + +error: this range is empty so this for loop will never run + --> $DIR/for_loop.rs:211:5 + | +211 | for i in 10..0 { + | _____^ starting here... +212 | | +213 | | +214 | | +215 | | println!("{}", i); +216 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/for_loop.rs:90:90 + | +90 | #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)] + | ^^^^^^^^^^^^^^^^^^ +help: consider using the following if you are attempting to iterate over this range in reverse + | for i in (0..10).rev() { + +error: this range is empty so this for loop will never run + --> $DIR/for_loop.rs:218:5 + | +218 | for i in 10...0 { + | _____^ starting here... +219 | | +220 | | +221 | | +222 | | println!("{}", i); +223 | | } + | |_____^ ...ending here + | +help: consider using the following if you are attempting to iterate over this range in reverse + | for i in (0...10).rev() { + +error: this range is empty so this for loop will never run + --> $DIR/for_loop.rs:225:5 + | +225 | for i in MAX_LEN..0 { + | _____^ starting here... +226 | | +227 | | +228 | | println!("{}", i); +229 | | } + | |_____^ ...ending here + | +help: consider using the following if you are attempting to iterate over this range in reverse + | for i in (0..MAX_LEN).rev() { + +error: this range is empty so this for loop will never run + --> $DIR/for_loop.rs:231:5 + | +231 | for i in 5..5 { + | _____^ starting here... +232 | | println!("{}", i); +233 | | } + | |_____^ ...ending here + +error: this range is empty so this for loop will never run + --> $DIR/for_loop.rs:252:5 + | +252 | for i in 10..5+4 { + | _____^ starting here... +253 | | +254 | | +255 | | +256 | | println!("{}", i); +257 | | } + | |_____^ ...ending here + | +help: consider using the following if you are attempting to iterate over this range in reverse + | for i in (5+4..10).rev() { + +error: this range is empty so this for loop will never run + --> $DIR/for_loop.rs:259:5 + | +259 | for i in (5+2)..(3-1) { + | _____^ starting here... +260 | | +261 | | +262 | | +263 | | println!("{}", i); +264 | | } + | |_____^ ...ending here + | +help: consider using the following if you are attempting to iterate over this range in reverse + | for i in ((3-1)..(5+2)).rev() { + +error: this range is empty so this for loop will never run + --> $DIR/for_loop.rs:266:5 + | +266 | for i in (5+2)..(8-1) { + | _____^ starting here... +267 | | println!("{}", i); +268 | | } + | |_____^ ...ending here + +error: it is more idiomatic to loop over `&vec` instead of `vec.iter()` + --> $DIR/for_loop.rs:289:15 + | +289 | for _v in vec.iter() { } + | ^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/for_loop.rs:90:29 + | +90 | #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)] + | ^^^^^^^^^^^^^^^^^^ +help: to write this more concisely, try looping over + | for _v in &vec { } + +error: it is more idiomatic to loop over `&mut vec` instead of `vec.iter_mut()` + --> $DIR/for_loop.rs:294:15 + | +294 | for _v in vec.iter_mut() { } + | ^^^^^^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &mut vec { } + +error: it is more idiomatic to loop over `out_vec` instead of `out_vec.into_iter()` + --> $DIR/for_loop.rs:300:15 + | +300 | for _v in out_vec.into_iter() { } + | ^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/for_loop.rs:90:49 + | +90 | #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)] + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: to write this more concisely, try looping over + | for _v in out_vec { } + +error: it is more idiomatic to loop over `&[1, 2, 3]` instead of `[1, 2, 3].iter()` + --> $DIR/for_loop.rs:308:15 + | +308 | for _v in [1, 2, 3].iter() { } + | ^^^^^^^^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &[1, 2, 3] { } + +error: it is more idiomatic to loop over `&[0; 32]` instead of `[0; 32].iter()` + --> $DIR/for_loop.rs:315:15 + | +315 | for _v in [0; 32].iter() {} + | ^^^^^^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &[0; 32] {} + +error: it is more idiomatic to loop over `&ll` instead of `ll.iter()` + --> $DIR/for_loop.rs:323:15 + | +323 | for _v in ll.iter() { } + | ^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &ll { } + +error: it is more idiomatic to loop over `&vd` instead of `vd.iter()` + --> $DIR/for_loop.rs:329:15 + | +329 | for _v in vd.iter() { } + | ^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &vd { } + +error: it is more idiomatic to loop over `&bh` instead of `bh.iter()` + --> $DIR/for_loop.rs:335:15 + | +335 | for _v in bh.iter() { } + | ^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &bh { } + +error: it is more idiomatic to loop over `&hm` instead of `hm.iter()` + --> $DIR/for_loop.rs:341:15 + | +341 | for _v in hm.iter() { } + | ^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &hm { } + +error: it is more idiomatic to loop over `&bt` instead of `bt.iter()` + --> $DIR/for_loop.rs:347:15 + | +347 | for _v in bt.iter() { } + | ^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &bt { } + +error: it is more idiomatic to loop over `&hs` instead of `hs.iter()` + --> $DIR/for_loop.rs:353:15 + | +353 | for _v in hs.iter() { } + | ^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &hs { } + +error: it is more idiomatic to loop over `&bs` instead of `bs.iter()` + --> $DIR/for_loop.rs:359:15 + | +359 | for _v in bs.iter() { } + | ^^^^^^^^^ + | +help: to write this more concisely, try looping over + | for _v in &bs { } + +error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want + --> $DIR/for_loop.rs:365:5 + | +365 | for _v in vec.iter().next() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/for_loop.rs:90:74 + | +90 | #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)] + | ^^^^^^^^^^^^^^ + +error: you are collect()ing an iterator and throwing away the result. Consider using an explicit for loop to exhaust the iterator + --> $DIR/for_loop.rs:372:5 + | +372 | vec.iter().map(|x| out.push(x)).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/for_loop.rs:91:8 + | +91 | #[deny(unused_collect)] + | ^^^^^^^^^^^^^^ + +error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators + --> $DIR/for_loop.rs:377:5 + | +377 | for _v in &vec { _index += 1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/for_loop.rs:90:110 + | +90 | #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators + --> $DIR/for_loop.rs:381:5 + | +381 | for _v in &vec { _index += 1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: you seem to want to iterate on a map's values + --> $DIR/for_loop.rs:441:5 + | +441 | for (_, v) in &m { + | _____^ starting here... +442 | | +443 | | +444 | | +445 | | +446 | | let _v = v; +447 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/for_loop.rs:90:133 + | +90 | #[deny(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)] + | ^^^^^^^^^^ +help: use the corresponding method + | for v in m.values() { + +error: you seem to want to iterate on a map's values + --> $DIR/for_loop.rs:450:5 + | +450 | for (_, v) in &*m { + | _____^ starting here... +451 | | +452 | | +453 | | +454 | | +455 | | let _v = v; +456 | | // Here the `*` is not actually necesarry, but the test tests that we don't suggest +457 | | // `in *m.values()` as we used to +458 | | } + | |_____^ ...ending here + | +help: use the corresponding method + | for v in (*m).values() { + +error: you seem to want to iterate on a map's values + --> $DIR/for_loop.rs:461:5 + | +461 | for (_, v) in &mut m { + | _____^ starting here... +462 | | +463 | | +464 | | +465 | | +466 | | let _v = v; +467 | | } + | |_____^ ...ending here + | +help: use the corresponding method + | for v in m.values_mut() { + +error: you seem to want to iterate on a map's values + --> $DIR/for_loop.rs:470:5 + | +470 | for (_, v) in &mut *m { + | _____^ starting here... +471 | | +472 | | +473 | | +474 | | +475 | | let _v = v; +476 | | } + | |_____^ ...ending here + | +help: use the corresponding method + | for v in (*m).values_mut() { + +error: you seem to want to iterate on a map's keys + --> $DIR/for_loop.rs:480:5 + | +480 | for (k, _value) in rm { + | _____^ starting here... +481 | | +482 | | +483 | | +484 | | +485 | | let _k = k; +486 | | } + | |_____^ ...ending here + | +help: use the corresponding method + | for k in rm.keys() { + +error: aborting due to 47 previous errors + diff --git a/tests/compile-fail/format.rs b/tests/ui/format.rs similarity index 83% rename from tests/compile-fail/format.rs rename to tests/ui/format.rs index 4fff131f6e75..67561dca87d0 100644 --- a/tests/compile-fail/format.rs +++ b/tests/ui/format.rs @@ -3,16 +3,16 @@ #![deny(useless_format)] fn main() { - format!("foo"); //~ERROR useless use of `format!` + format!("foo"); - format!("{}", "foo"); //~ERROR useless use of `format!` + format!("{}", "foo"); format!("{:?}", "foo"); // we only want to warn about `{}` format!("{:+}", "foo"); // we only want to warn about `{}` format!("foo {}", "bar"); format!("{} bar", "foo"); let arg: String = "".to_owned(); - format!("{}", arg); //~ERROR useless use of `format!` + format!("{}", arg); format!("{:?}", arg); // we only want to warn about `{}` format!("{:+}", arg); // we only want to warn about `{}` format!("foo {}", arg); diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr new file mode 100644 index 000000000000..51e0c5b6d633 --- /dev/null +++ b/tests/ui/format.stderr @@ -0,0 +1,26 @@ +error: useless use of `format!` + --> $DIR/format.rs:6:5 + | +6 | format!("foo"); + | ^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/format.rs:3:9 + | +3 | #![deny(useless_format)] + | ^^^^^^^^^^^^^^ + +error: useless use of `format!` + --> $DIR/format.rs:8:5 + | +8 | format!("{}", "foo"); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: useless use of `format!` + --> $DIR/format.rs:15:5 + | +15 | format!("{}", arg); + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/compile-fail/formatting.rs b/tests/ui/formatting.rs similarity index 54% rename from tests/compile-fail/formatting.rs rename to tests/ui/formatting.rs index 6c6671b0aa40..8d3c1d938e55 100644 --- a/tests/compile-fail/formatting.rs +++ b/tests/ui/formatting.rs @@ -13,8 +13,8 @@ fn main() { // weird `else if` formatting: if foo() { } if foo() { - //~^ ERROR this looks like an `else if` but the `else` is missing - //~| NOTE add the missing `else` or + + } let _ = { // if as the last expression @@ -22,8 +22,8 @@ fn main() { if foo() { } if foo() { - //~^ ERROR this looks like an `else if` but the `else` is missing - //~| NOTE add the missing `else` or + + } else { } @@ -32,8 +32,8 @@ fn main() { let _ = { // if in the middle of a block if foo() { } if foo() { - //~^ ERROR this looks like an `else if` but the `else` is missing - //~| NOTE add the missing `else` or + + } else { } @@ -43,15 +43,15 @@ fn main() { if foo() { } else - //~^ ERROR this is an `else if` but the formatting might hide it - //~| NOTE remove the `else` or + + if foo() { // the span of the above error should continue here } if foo() { } - //~^ ERROR this is an `else if` but the formatting might hide it - //~| NOTE remove the `else` or + + else if foo() { // the span of the above error should continue here } @@ -81,16 +81,16 @@ fn main() { // weird op_eq formatting: let mut a = 42; a =- 35; - //~^ ERROR this looks like you are trying to use `.. -= ..`, but you really are doing `.. = (- ..)` - //~| NOTE to remove this lint, use either `-=` or `= -` + + a =* &191; - //~^ ERROR this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)` - //~| NOTE to remove this lint, use either `*=` or `= *` + + let mut b = true; b =! false; - //~^ ERROR this looks like you are trying to use `.. != ..`, but you really are doing `.. = (! ..)` - //~| NOTE to remove this lint, use either `!=` or `= !` + + // those are ok: a = -35; @@ -100,14 +100,14 @@ fn main() { // possible missing comma in an array let _ = &[ -1, -2, -3 // <= no coma here - //~^ ERROR possibly missing a comma here - //~| NOTE to remove this lint, add a comma or write the expr in a single line + + -4, -5, -6 ]; let _ = &[ -1, -2, -3 // <= no coma here - //~^ ERROR possibly missing a comma here - //~| NOTE to remove this lint, add a comma or write the expr in a single line + + *4, -5, -6 ]; diff --git a/tests/ui/formatting.stderr b/tests/ui/formatting.stderr new file mode 100644 index 000000000000..68260410fa99 --- /dev/null +++ b/tests/ui/formatting.stderr @@ -0,0 +1,116 @@ +error: this looks like an `else if` but the `else` is missing + --> $DIR/formatting.rs:15:6 + | +15 | } if foo() { + | ^ + | + = note: #[deny(suspicious_else_formatting)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/formatting.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + = note: to remove this lint, add the missing `else` or add a new line before the second `if` + +error: this looks like an `else if` but the `else` is missing + --> $DIR/formatting.rs:24:10 + | +24 | } if foo() { + | ^ + | + = note: #[deny(suspicious_else_formatting)] implied by #[deny(clippy)] + = note: to remove this lint, add the missing `else` or add a new line before the second `if` + +error: this looks like an `else if` but the `else` is missing + --> $DIR/formatting.rs:34:10 + | +34 | } if foo() { + | ^ + | + = note: #[deny(suspicious_else_formatting)] implied by #[deny(clippy)] + = note: to remove this lint, add the missing `else` or add a new line before the second `if` + +error: this is an `else if` but the formatting might hide it + --> $DIR/formatting.rs:45:6 + | +45 | } else + | ______^ starting here... +46 | | +47 | | +48 | | if foo() { // the span of the above error should continue here + | |____^ ...ending here + | + = note: #[deny(suspicious_else_formatting)] implied by #[deny(clippy)] + = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` + +error: this is an `else if` but the formatting might hide it + --> $DIR/formatting.rs:52:6 + | +52 | } + | ______^ starting here... +53 | | +54 | | +55 | | else +56 | | if foo() { // the span of the above error should continue here + | |____^ ...ending here + | + = note: #[deny(suspicious_else_formatting)] implied by #[deny(clippy)] + = note: to remove this lint, remove the `else` or remove the new line between `else` and `if` + +error: this looks like you are trying to use `.. -= ..`, but you really are doing `.. = (- ..)` + --> $DIR/formatting.rs:83:6 + | +83 | a =- 35; + | ^^^^ + | + = note: #[deny(suspicious_assignment_formatting)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/formatting.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + = note: to remove this lint, use either `-=` or `= -` + +error: this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)` + --> $DIR/formatting.rs:86:6 + | +86 | a =* &191; + | ^^^^ + | + = note: #[deny(suspicious_assignment_formatting)] implied by #[deny(clippy)] + = note: to remove this lint, use either `*=` or `= *` + +error: this looks like you are trying to use `.. != ..`, but you really are doing `.. = (! ..)` + --> $DIR/formatting.rs:91:6 + | +91 | b =! false; + | ^^^^ + | + = note: #[deny(suspicious_assignment_formatting)] implied by #[deny(clippy)] + = note: to remove this lint, use either `!=` or `= !` + +error: possibly missing a comma here + --> $DIR/formatting.rs:102:19 + | +102 | -1, -2, -3 // <= no coma here + | ^ + | + = note: #[deny(possible_missing_comma)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/formatting.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + = note: to remove this lint, add a comma or write the expr in a single line + +error: possibly missing a comma here + --> $DIR/formatting.rs:108:19 + | +108 | -1, -2, -3 // <= no coma here + | ^ + | + = note: #[deny(possible_missing_comma)] implied by #[deny(clippy)] + = note: to remove this lint, add a comma or write the expr in a single line + +error: aborting due to 10 previous errors + diff --git a/tests/compile-fail/functions.rs b/tests/ui/functions.rs similarity index 68% rename from tests/compile-fail/functions.rs rename to tests/ui/functions.rs index 60a074df0f5b..bb09be575fdc 100644 --- a/tests/compile-fail/functions.rs +++ b/tests/ui/functions.rs @@ -9,7 +9,7 @@ fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {} fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) { - //~^ ERROR: this function has too many arguments (8/7) + } // don't lint extern fns @@ -18,7 +18,7 @@ extern fn extern_fn(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, pub trait Foo { fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool); fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()); - //~^ ERROR: this function has too many arguments (8/7) + fn ptr(p: *const u8); } @@ -28,7 +28,7 @@ pub struct Bar; impl Bar { fn good_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {} fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} - //~^ ERROR: this function has too many arguments (8/7) + } // ok, we don’t want to warn implementations @@ -38,11 +38,11 @@ impl Foo for Bar { fn ptr(p: *const u8) { println!("{}", unsafe { *p }); - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + println!("{:?}", unsafe { p.as_ref() }); - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + unsafe { std::ptr::read(p) }; - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + } } @@ -54,11 +54,11 @@ fn private(p: *const u8) { pub fn public(p: *const u8) { println!("{}", unsafe { *p }); - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + println!("{:?}", unsafe { p.as_ref() }); - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + unsafe { std::ptr::read(p) }; - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + } impl Bar { @@ -68,11 +68,11 @@ impl Bar { pub fn public(self, p: *const u8) { println!("{}", unsafe { *p }); - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + println!("{:?}", unsafe { p.as_ref() }); - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + unsafe { std::ptr::read(p) }; - //~^ ERROR: this public function dereferences a raw pointer but is not marked `unsafe` + } pub fn public_ok(self, p: *const u8) { diff --git a/tests/ui/functions.stderr b/tests/ui/functions.stderr new file mode 100644 index 000000000000..4a21f9466c99 --- /dev/null +++ b/tests/ui/functions.stderr @@ -0,0 +1,111 @@ +error: this function has too many arguments (8/7) + --> $DIR/functions.rs:11:1 + | +11 | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) { + | _^ starting here... +12 | | +13 | | } + | |_^ ...ending here + | + = note: #[deny(too_many_arguments)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/functions.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + +error: this function has too many arguments (8/7) + --> $DIR/functions.rs:20:5 + | +20 | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(too_many_arguments)] implied by #[deny(clippy)] + +error: this function has too many arguments (8/7) + --> $DIR/functions.rs:30:5 + | +30 | fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(too_many_arguments)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:40:34 + | +40 | println!("{}", unsafe { *p }); + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/functions.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:42:35 + | +42 | println!("{:?}", unsafe { p.as_ref() }); + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:44:33 + | +44 | unsafe { std::ptr::read(p) }; + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:56:30 + | +56 | println!("{}", unsafe { *p }); + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:58:31 + | +58 | println!("{:?}", unsafe { p.as_ref() }); + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:60:29 + | +60 | unsafe { std::ptr::read(p) }; + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:70:34 + | +70 | println!("{}", unsafe { *p }); + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:72:35 + | +72 | println!("{:?}", unsafe { p.as_ref() }); + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: this public function dereferences a raw pointer but is not marked `unsafe` + --> $DIR/functions.rs:74:33 + | +74 | unsafe { std::ptr::read(p) }; + | ^ + | + = note: #[deny(not_unsafe_ptr_arg_deref)] implied by #[deny(clippy)] + +error: aborting due to 12 previous errors + diff --git a/tests/compile-fail/identity_op.rs b/tests/ui/identity_op.rs similarity index 57% rename from tests/compile-fail/identity_op.rs rename to tests/ui/identity_op.rs index 6a0b5e927cf7..ea68ec3e1abc 100644 --- a/tests/compile-fail/identity_op.rs +++ b/tests/ui/identity_op.rs @@ -10,21 +10,21 @@ const ZERO : i64 = 0; fn main() { let x = 0; - x + 0; //~ERROR the operation is ineffective - x + (1 - 1); //~ERROR the operation is ineffective + x + 0; + x + (1 - 1); x + 1; - 0 + x; //~ERROR the operation is ineffective + 0 + x; 1 + x; x - ZERO; //no error, as we skip lookups (for now) - x | (0); //~ERROR the operation is ineffective + x | (0); ((ZERO)) | x; //no error, as we skip lookups (for now) - x * 1; //~ERROR the operation is ineffective - 1 * x; //~ERROR the operation is ineffective + x * 1; + 1 * x; x / ONE; //no error, as we skip lookups (for now) x / 2; //no false positive x & NEG_ONE; //no error, as we skip lookups (for now) - -1 & x; //~ERROR the operation is ineffective + -1 & x; } diff --git a/tests/ui/identity_op.stderr b/tests/ui/identity_op.stderr new file mode 100644 index 000000000000..ab455ad15855 --- /dev/null +++ b/tests/ui/identity_op.stderr @@ -0,0 +1,50 @@ +error: the operation is ineffective. Consider reducing it to `x` + --> $DIR/identity_op.rs:13:5 + | +13 | x + 0; + | ^^^^^ + | +note: lint level defined here + --> $DIR/identity_op.rs:9:8 + | +9 | #[deny(identity_op)] + | ^^^^^^^^^^^ + +error: the operation is ineffective. Consider reducing it to `x` + --> $DIR/identity_op.rs:14:5 + | +14 | x + (1 - 1); + | ^^^^^^^^^^^ + +error: the operation is ineffective. Consider reducing it to `x` + --> $DIR/identity_op.rs:16:5 + | +16 | 0 + x; + | ^^^^^ + +error: the operation is ineffective. Consider reducing it to `x` + --> $DIR/identity_op.rs:19:5 + | +19 | x | (0); + | ^^^^^^^ + +error: the operation is ineffective. Consider reducing it to `x` + --> $DIR/identity_op.rs:22:5 + | +22 | x * 1; + | ^^^^^ + +error: the operation is ineffective. Consider reducing it to `x` + --> $DIR/identity_op.rs:23:5 + | +23 | 1 * x; + | ^^^^^ + +error: the operation is ineffective. Consider reducing it to `x` + --> $DIR/identity_op.rs:29:5 + | +29 | -1 & x; + | ^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/tests/ui/if_let_redundant_pattern_matching.rs b/tests/ui/if_let_redundant_pattern_matching.rs new file mode 100644 index 000000000000..c48518304e2a --- /dev/null +++ b/tests/ui/if_let_redundant_pattern_matching.rs @@ -0,0 +1,53 @@ +#![feature(plugin)] + +#![plugin(clippy)] +#![deny(clippy)] +#![deny(if_let_redundant_pattern_matching)] + + +fn main() { + if let Ok(_) = Ok::(42) {} + + + + + if let Err(_) = Err::(42) { + + + + } + + if let None = None::<()> { + + + + } + + if let Some(_) = Some(42) { + + + + } + + if Ok::(42).is_ok() { + + } + + if Err::(42).is_err() { + + } + + if None::.is_none() { + + } + + if Some(42).is_some() { + + } + + if let Ok(x) = Ok::(42) { + println!("{}", x); + } +} + + diff --git a/tests/ui/if_let_redundant_pattern_matching.stderr b/tests/ui/if_let_redundant_pattern_matching.stderr new file mode 100644 index 000000000000..cc011b4a90c9 --- /dev/null +++ b/tests/ui/if_let_redundant_pattern_matching.stderr @@ -0,0 +1,47 @@ +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/if_let_redundant_pattern_matching.rs:9:12 + | +9 | if let Ok(_) = Ok::(42) {} + | ^^^^^ + | + = note: #[deny(if_let_redundant_pattern_matching)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/if_let_redundant_pattern_matching.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ +help: try this + | if Ok::(42).is_ok() {} + +error: redundant pattern matching, consider using `is_err()` + --> $DIR/if_let_redundant_pattern_matching.rs:14:12 + | +14 | if let Err(_) = Err::(42) { + | ^^^^^^ + | + = note: #[deny(if_let_redundant_pattern_matching)] implied by #[deny(clippy)] +help: try this + | if Err::(42).is_err() { + +error: redundant pattern matching, consider using `is_none()` + --> $DIR/if_let_redundant_pattern_matching.rs:20:12 + | +20 | if let None = None::<()> { + | ^^^^ + | + = note: #[deny(if_let_redundant_pattern_matching)] implied by #[deny(clippy)] +help: try this + | if None::<()>.is_none() { + +error: redundant pattern matching, consider using `is_some()` + --> $DIR/if_let_redundant_pattern_matching.rs:26:12 + | +26 | if let Some(_) = Some(42) { + | ^^^^^^^ + | + = note: #[deny(if_let_redundant_pattern_matching)] implied by #[deny(clippy)] +help: try this + | if Some(42).is_some() { + +error: aborting due to 4 previous errors + diff --git a/tests/compile-fail/if_not_else.rs b/tests/ui/if_not_else.rs similarity index 70% rename from tests/compile-fail/if_not_else.rs rename to tests/ui/if_not_else.rs index a72699adafd8..5cdc6ce8678c 100644 --- a/tests/compile-fail/if_not_else.rs +++ b/tests/ui/if_not_else.rs @@ -6,12 +6,12 @@ fn bla() -> bool { unimplemented!() } fn main() { - if !bla() { //~ ERROR: Unnecessary boolean `not` operation + if !bla() { println!("Bugs"); } else { println!("Bunny"); } - if 4 != 5 { //~ ERROR: Unnecessary `!=` operation + if 4 != 5 { println!("Bugs"); } else { println!("Bunny"); diff --git a/tests/ui/if_not_else.stderr b/tests/ui/if_not_else.stderr new file mode 100644 index 000000000000..ecdd7254d70b --- /dev/null +++ b/tests/ui/if_not_else.stderr @@ -0,0 +1,33 @@ +error: Unnecessary boolean `not` operation + --> $DIR/if_not_else.rs:9:5 + | +9 | if !bla() { + | _____^ starting here... +10 | | println!("Bugs"); +11 | | } else { +12 | | println!("Bunny"); +13 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/if_not_else.rs:4:9 + | +4 | #![deny(if_not_else)] + | ^^^^^^^^^^^ + = help: remove the `!` and swap the blocks of the if/else + +error: Unnecessary `!=` operation + --> $DIR/if_not_else.rs:14:5 + | +14 | if 4 != 5 { + | _____^ starting here... +15 | | println!("Bugs"); +16 | | } else { +17 | | println!("Bunny"); +18 | | } + | |_____^ ...ending here + | + = help: change to `==` and swap the blocks of the if/else + +error: aborting due to 2 previous errors + diff --git a/tests/ui/invalid_upcast_comparisons.rs b/tests/ui/invalid_upcast_comparisons.rs new file mode 100644 index 000000000000..952cf1e4361c --- /dev/null +++ b/tests/ui/invalid_upcast_comparisons.rs @@ -0,0 +1,35 @@ +#![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; + (u8_max as u32) > 20; + + (zero as i32) < -5; + (zero as i32) < 10; + + -5 < (zero as i32); + 0 <= (zero as i32); + 0 < (zero as i32); + + -5 > (zero as i32); + -5 >= (u8_max as i32); + 1337 == (u8_max as i32); + + -5 == (zero as i32); + -5 != (u8_max as i32); + + // 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; +} diff --git a/tests/ui/invalid_upcast_comparisons.stderr b/tests/ui/invalid_upcast_comparisons.stderr new file mode 100644 index 000000000000..e7eda752f388 --- /dev/null +++ b/tests/ui/invalid_upcast_comparisons.stderr @@ -0,0 +1,62 @@ +error: because of the numeric bounds on `u8_max` prior to casting, this expression is always false + --> $DIR/invalid_upcast_comparisons.rs:10:5 + | +10 | (u8_max as u32) > 300; + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/invalid_upcast_comparisons.rs:4:9 + | +4 | #![deny(invalid_upcast_comparisons)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `zero` prior to casting, this expression is always false + --> $DIR/invalid_upcast_comparisons.rs:13:5 + | +13 | (zero as i32) < -5; + | ^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `zero` prior to casting, this expression is always true + --> $DIR/invalid_upcast_comparisons.rs:16:5 + | +16 | -5 < (zero as i32); + | ^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `zero` prior to casting, this expression is always true + --> $DIR/invalid_upcast_comparisons.rs:17:5 + | +17 | 0 <= (zero as i32); + | ^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `zero` prior to casting, this expression is always false + --> $DIR/invalid_upcast_comparisons.rs:20:5 + | +20 | -5 > (zero as i32); + | ^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `u8_max` prior to casting, this expression is always false + --> $DIR/invalid_upcast_comparisons.rs:21:5 + | +21 | -5 >= (u8_max as i32); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `u8_max` prior to casting, this expression is always false + --> $DIR/invalid_upcast_comparisons.rs:22:5 + | +22 | 1337 == (u8_max as i32); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `zero` prior to casting, this expression is always false + --> $DIR/invalid_upcast_comparisons.rs:24:5 + | +24 | -5 == (zero as i32); + | ^^^^^^^^^^^^^^^^^^^ + +error: because of the numeric bounds on `u8_max` prior to casting, this expression is always true + --> $DIR/invalid_upcast_comparisons.rs:25:5 + | +25 | -5 != (u8_max as i32); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 9 previous errors + diff --git a/tests/compile-fail/item_after_statement.rs b/tests/ui/item_after_statement.rs similarity index 52% rename from tests/compile-fail/item_after_statement.rs rename to tests/ui/item_after_statement.rs index 4be89176fc7d..09b509673dc3 100644 --- a/tests/compile-fail/item_after_statement.rs +++ b/tests/ui/item_after_statement.rs @@ -9,11 +9,11 @@ fn ok() { fn last() { foo(); - fn foo() { println!("foo"); } //~ ERROR adding items after statements is confusing + fn foo() { println!("foo"); } } fn main() { foo(); - fn foo() { println!("foo"); } //~ ERROR adding items after statements is confusing + fn foo() { println!("foo"); } foo(); } diff --git a/tests/ui/item_after_statement.stderr b/tests/ui/item_after_statement.stderr new file mode 100644 index 000000000000..318db240ca2b --- /dev/null +++ b/tests/ui/item_after_statement.stderr @@ -0,0 +1,20 @@ +error: adding items after statements is confusing, since items exist from the start of the scope + --> $DIR/item_after_statement.rs:12:5 + | +12 | fn foo() { println!("foo"); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/item_after_statement.rs:3:9 + | +3 | #![deny(items_after_statements)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: adding items after statements is confusing, since items exist from the start of the scope + --> $DIR/item_after_statement.rs:17:5 + | +17 | fn foo() { println!("foo"); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs new file mode 100644 index 000000000000..5bbcb93910b9 --- /dev/null +++ b/tests/ui/large_enum_variant.rs @@ -0,0 +1,53 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#![allow(dead_code)] +#![allow(unused_variables)] +#![deny(large_enum_variant)] + +enum LargeEnum { + A(i32), + B([i32; 8000]), + + +} + +enum GenericEnum { + A(i32), + B([i32; 8000]), + + + C([T; 8000]), + D(T, [i32; 8000]), + +} + +trait SomeTrait { + type Item; +} + +enum LargeEnumGeneric { + Var(A::Item), // regression test, this used to ICE +} + +enum AnotherLargeEnum { + VariantOk(i32, u32), + ContainingLargeEnum(LargeEnum), + + + ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), + + VoidVariant, + StructLikeLittle { x: i32, y: i32 }, + StructLikeLarge { x: [i32; 8000], y: i32 }, + + StructLikeLarge2 { + x: + [i32; 8000] + + }, +} + +fn main() { + +} diff --git a/tests/ui/large_enum_variant.stderr b/tests/ui/large_enum_variant.stderr new file mode 100644 index 000000000000..77155b6ab5fe --- /dev/null +++ b/tests/ui/large_enum_variant.stderr @@ -0,0 +1,84 @@ +error: large enum variant found + --> $DIR/large_enum_variant.rs:10:5 + | +10 | B([i32; 8000]), + | ^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/large_enum_variant.rs:6:9 + | +6 | #![deny(large_enum_variant)] + | ^^^^^^^^^^^^^^^^^^ +help: consider boxing the large fields to reduce the total size of the enum + | B(Box<[i32; 8000]>), + +error: large enum variant found + --> $DIR/large_enum_variant.rs:17:5 + | +17 | B([i32; 8000]), + | ^^^^^^^^^^^^^^ + | +help: consider boxing the large fields to reduce the total size of the enum + | B(Box<[i32; 8000]>), + +error: large enum variant found + --> $DIR/large_enum_variant.rs:21:5 + | +21 | D(T, [i32; 8000]), + | ^^^^^^^^^^^^^^^^^ + | +help: consider boxing the large fields to reduce the total size of the enum + --> $DIR/large_enum_variant.rs:21:5 + | +21 | D(T, [i32; 8000]), + | ^^^^^^^^^^^^^^^^^ + +error: large enum variant found + --> $DIR/large_enum_variant.rs:35:5 + | +35 | ContainingLargeEnum(LargeEnum), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider boxing the large fields to reduce the total size of the enum + | ContainingLargeEnum(Box), + +error: large enum variant found + --> $DIR/large_enum_variant.rs:38:5 + | +38 | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider boxing the large fields to reduce the total size of the enum + --> $DIR/large_enum_variant.rs:38:5 + | +38 | ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: large enum variant found + --> $DIR/large_enum_variant.rs:42:5 + | +42 | StructLikeLarge { x: [i32; 8000], y: i32 }, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider boxing the large fields to reduce the total size of the enum + --> $DIR/large_enum_variant.rs:42:5 + | +42 | StructLikeLarge { x: [i32; 8000], y: i32 }, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: large enum variant found + --> $DIR/large_enum_variant.rs:44:5 + | +44 | StructLikeLarge2 { + | _____^ starting here... +45 | | x: +46 | | [i32; 8000] +47 | | +48 | | }, + | |_____^ ...ending here + | +help: consider boxing the large fields to reduce the total size of the enum + | Box<[i32; 8000]> + +error: aborting due to 7 previous errors + diff --git a/tests/compile-fail/len_zero.rs b/tests/ui/len_zero.rs similarity index 66% rename from tests/compile-fail/len_zero.rs rename to tests/ui/len_zero.rs index b640c6db3a3c..a310eeef3846 100644 --- a/tests/compile-fail/len_zero.rs +++ b/tests/ui/len_zero.rs @@ -7,7 +7,7 @@ pub struct PubOne; impl PubOne { - pub fn len(self: &Self) -> isize { //~ERROR item `PubOne` has a public `len` method but no corresponding `is_empty` + pub fn len(self: &Self) -> isize { 1 } } @@ -29,7 +29,7 @@ impl One { } pub trait PubTraitsToo { - fn len(self: &Self) -> isize; //~ERROR trait `PubTraitsToo` has a `len` method but no `is_empty` + fn len(self: &Self) -> isize; } impl PubTraitsToo for One { @@ -63,7 +63,7 @@ impl HasPrivateIsEmpty { pub struct HasIsEmpty; impl HasIsEmpty { - pub fn len(self: &Self) -> isize { //~ERROR item `HasIsEmpty` has a public `len` method but a private `is_empty` + pub fn len(self: &Self) -> isize { 1 } @@ -92,7 +92,7 @@ impl WithIsEmpty for Wither { pub struct HasWrongIsEmpty; impl HasWrongIsEmpty { - pub fn len(self: &Self) -> isize { //~ERROR item `HasWrongIsEmpty` has a public `len` method but no corresponding `is_empty` + pub fn len(self: &Self) -> isize { 1 } @@ -104,16 +104,16 @@ impl HasWrongIsEmpty { fn main() { let x = [1, 2]; if x.len() == 0 { - //~^ERROR length comparison to zero - //~|HELP consider using `is_empty` - //~|SUGGESTION x.is_empty() + + + println!("This should not happen!"); } if "".len() == 0 { - //~^ERROR length comparison to zero - //~|HELP consider using `is_empty` - //~|SUGGESTION "".is_empty() + + + } let y = One; @@ -128,30 +128,30 @@ fn main() { let has_is_empty = HasIsEmpty; if has_is_empty.len() == 0 { - //~^ERROR length comparison to zero - //~|HELP consider using `is_empty` - //~|SUGGESTION has_is_empty.is_empty() + + + println!("Or this!"); } if has_is_empty.len() != 0 { - //~^ERROR length comparison to zero - //~|HELP consider using `is_empty` - //~|SUGGESTION !has_is_empty.is_empty() + + + println!("Or this!"); } if has_is_empty.len() > 0 { - //~^ERROR length comparison to zero - //~|HELP consider using `is_empty` - //~|SUGGESTION !has_is_empty.is_empty() + + + println!("Or this!"); } assert!(!has_is_empty.is_empty()); let with_is_empty: &WithIsEmpty = &Wither; if with_is_empty.len() == 0 { - //~^ERROR length comparison to zero - //~|HELP consider using `is_empty` - //~|SUGGESTION with_is_empty.is_empty() + + + println!("Or this!"); } assert!(!with_is_empty.is_empty()); diff --git a/tests/ui/len_zero.stderr b/tests/ui/len_zero.stderr new file mode 100644 index 000000000000..5aaaecf55cb7 --- /dev/null +++ b/tests/ui/len_zero.stderr @@ -0,0 +1,100 @@ +error: item `PubOne` has a public `len` method but no corresponding `is_empty` method + --> $DIR/len_zero.rs:10:5 + | +10 | pub fn len(self: &Self) -> isize { + | _____^ starting here... +11 | | 1 +12 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/len_zero.rs:4:9 + | +4 | #![deny(len_without_is_empty, len_zero)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: trait `PubTraitsToo` has a `len` method but no `is_empty` method + --> $DIR/len_zero.rs:32:5 + | +32 | fn len(self: &Self) -> isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: item `HasIsEmpty` has a public `len` method but a private `is_empty` method + --> $DIR/len_zero.rs:66:5 + | +66 | pub fn len(self: &Self) -> isize { + | _____^ starting here... +67 | | 1 +68 | | } + | |_____^ ...ending here + +error: item `HasWrongIsEmpty` has a public `len` method but no corresponding `is_empty` method + --> $DIR/len_zero.rs:95:5 + | +95 | pub fn len(self: &Self) -> isize { + | _____^ starting here... +96 | | 1 +97 | | } + | |_____^ ...ending here + +error: length comparison to zero + --> $DIR/len_zero.rs:106:8 + | +106 | if x.len() == 0 { + | ^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/len_zero.rs:4:31 + | +4 | #![deny(len_without_is_empty, len_zero)] + | ^^^^^^^^ +help: consider using `is_empty` + | if x.is_empty() { + +error: length comparison to zero + --> $DIR/len_zero.rs:113:8 + | +113 | if "".len() == 0 { + | ^^^^^^^^^^^^^ + | +help: consider using `is_empty` + | if "".is_empty() { + +error: length comparison to zero + --> $DIR/len_zero.rs:130:8 + | +130 | if has_is_empty.len() == 0 { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `is_empty` + | if has_is_empty.is_empty() { + +error: length comparison to zero + --> $DIR/len_zero.rs:136:8 + | +136 | if has_is_empty.len() != 0 { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `is_empty` + | if !has_is_empty.is_empty() { + +error: length comparison to zero + --> $DIR/len_zero.rs:142:8 + | +142 | if has_is_empty.len() > 0 { + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `is_empty` + | if !has_is_empty.is_empty() { + +error: length comparison to zero + --> $DIR/len_zero.rs:151:8 + | +151 | if with_is_empty.len() == 0 { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using `is_empty` + | if with_is_empty.is_empty() { + +error: aborting due to 10 previous errors + diff --git a/tests/compile-fail/let_if_seq.rs b/tests/ui/let_if_seq.rs similarity index 72% rename from tests/compile-fail/let_if_seq.rs rename to tests/ui/let_if_seq.rs index b49e5a261223..9e221cc5bc23 100644 --- a/tests/compile-fail/let_if_seq.rs +++ b/tests/ui/let_if_seq.rs @@ -55,17 +55,17 @@ fn main() { issue985_alt(); let mut foo = 0; - //~^ ERROR `if _ { .. } else { .. }` is an expression - //~| HELP more idiomatic - //~| SUGGESTION let foo = if f() { 42 } else { 0 }; + + + if f() { foo = 42; } let mut bar = 0; - //~^ ERROR `if _ { .. } else { .. }` is an expression - //~| HELP more idiomatic - //~| SUGGESTION let bar = if f() { ..; 42 } else { ..; 0 }; + + + if f() { f(); bar = 42; @@ -75,9 +75,9 @@ fn main() { } let quz; - //~^ ERROR `if _ { .. } else { .. }` is an expression - //~| HELP more idiomatic - //~| SUGGESTION let quz = if f() { 42 } else { 0 }; + + + if f() { quz = 42; @@ -109,9 +109,9 @@ fn main() { // baz needs to be mut let mut baz = 0; - //~^ ERROR `if _ { .. } else { .. }` is an expression - //~| HELP more idiomatic - //~| SUGGESTION let baz = if f() { 42 } else { 0 }; + + + if f() { baz = 42; } diff --git a/tests/ui/let_if_seq.stderr b/tests/ui/let_if_seq.stderr new file mode 100644 index 000000000000..fb5ef47ce0f7 --- /dev/null +++ b/tests/ui/let_if_seq.stderr @@ -0,0 +1,60 @@ +error: `if _ { .. } else { .. }` is an expression + --> $DIR/let_if_seq.rs:57:5 + | +57 | let mut foo = 0; + | _____^ starting here... +58 | | +59 | | +60 | | +61 | | if f() { +62 | | foo = 42; +63 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/let_if_seq.rs:5:9 + | +5 | #![deny(useless_let_if_seq)] + | ^^^^^^^^^^^^^^^^^^ +help: it is more idiomatic to write + | let foo = if f() { 42 } else { 0 }; + = note: you might not need `mut` at all + +error: `if _ { .. } else { .. }` is an expression + --> $DIR/let_if_seq.rs:65:5 + | +65 | let mut bar = 0; + | ^ + | +help: it is more idiomatic to write + | let bar = if f() { ..; 42 } else { ..; 0 }; + = note: you might not need `mut` at all + +error: `if _ { .. } else { .. }` is an expression + --> $DIR/let_if_seq.rs:77:5 + | +77 | let quz; + | ^ + | +help: it is more idiomatic to write + | let quz = if f() { 42 } else { 0 }; + +error: `if _ { .. } else { .. }` is an expression + --> $DIR/let_if_seq.rs:111:5 + | +111 | let mut baz = 0; + | _____^ starting here... +112 | | +113 | | +114 | | +115 | | if f() { +116 | | baz = 42; +117 | | } + | |_____^ ...ending here + | +help: it is more idiomatic to write + | let baz = if f() { 42 } else { 0 }; + = note: you might not need `mut` at all + +error: aborting due to 4 previous errors + diff --git a/tests/compile-fail/let_return.rs b/tests/ui/let_return.rs similarity index 64% rename from tests/compile-fail/let_return.rs rename to tests/ui/let_return.rs index 477786813dba..de0bb9b3cc1c 100644 --- a/tests/compile-fail/let_return.rs +++ b/tests/ui/let_return.rs @@ -6,14 +6,14 @@ fn test() -> i32 { let _y = 0; // no warning - let x = 5; //~NOTE this expression can be directly returned - x //~ERROR returning the result of a let binding + let x = 5; + x } fn test_inner() -> i32 { if true { - let x = 5; //~NOTE this expression can be directly returned - x //~ERROR returning the result of a let binding + let x = 5; + x } else { 0 } diff --git a/tests/ui/let_return.stderr b/tests/ui/let_return.stderr new file mode 100644 index 000000000000..8b5cfa6f31d0 --- /dev/null +++ b/tests/ui/let_return.stderr @@ -0,0 +1,31 @@ +error: returning the result of a let binding from a block. Consider returning the expression directly. + --> $DIR/let_return.rs:10:5 + | +10 | x + | ^ + | +note: lint level defined here + --> $DIR/let_return.rs:5:9 + | +5 | #![deny(let_and_return)] + | ^^^^^^^^^^^^^^ +note: this expression can be directly returned + --> $DIR/let_return.rs:9:13 + | +9 | let x = 5; + | ^ + +error: returning the result of a let binding from a block. Consider returning the expression directly. + --> $DIR/let_return.rs:16:9 + | +16 | x + | ^ + | +note: this expression can be directly returned + --> $DIR/let_return.rs:15:17 + | +15 | let x = 5; + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/let_unit.rs b/tests/ui/let_unit.rs similarity index 74% rename from tests/compile-fail/let_unit.rs rename to tests/ui/let_unit.rs index a0143406e52d..fe541f3054c1 100644 --- a/tests/compile-fail/let_unit.rs +++ b/tests/ui/let_unit.rs @@ -11,11 +11,11 @@ macro_rules! let_and_return { } fn main() { - let _x = println!("x"); //~ERROR this let-binding has unit value + let _x = println!("x"); let _y = 1; // this is fine let _z = ((), 1); // this as well if true { - let _a = (); //~ERROR this let-binding has unit value + let _a = (); } let_and_return!(()) // should be fine diff --git a/tests/ui/let_unit.stderr b/tests/ui/let_unit.stderr new file mode 100644 index 000000000000..abeeb3b3981b --- /dev/null +++ b/tests/ui/let_unit.stderr @@ -0,0 +1,20 @@ +error: this let-binding has unit value. Consider omitting `let _x =` + --> $DIR/let_unit.rs:14:5 + | +14 | let _x = println!("x"); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/let_unit.rs:4:9 + | +4 | #![deny(let_unit_value)] + | ^^^^^^^^^^^^^^ + +error: this let-binding has unit value. Consider omitting `let _a =` + --> $DIR/let_unit.rs:18:9 + | +18 | let _a = (); + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/lifetimes.rs b/tests/ui/lifetimes.rs similarity index 87% rename from tests/compile-fail/lifetimes.rs rename to tests/ui/lifetimes.rs index 408b6762df69..ade0deeea2ca 100644 --- a/tests/compile-fail/lifetimes.rs +++ b/tests/ui/lifetimes.rs @@ -5,10 +5,10 @@ #![allow(dead_code)] fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) { } -//~^ERROR explicit lifetimes given + fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) { } -//~^ERROR explicit lifetimes given + fn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) { } // no error, same lifetime on two params @@ -17,7 +17,7 @@ fn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) { } // no error, stat fn mut_and_static_input(_x: &mut u8, _y: &'static str) { } fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { x } -//~^ERROR explicit lifetimes given + fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 { x } // no error, multiple input refs @@ -30,18 +30,18 @@ fn deep_reference_1<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> { Ok(x) fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 { x.unwrap() } // no error, two input refs fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { Ok(x) } -//~^ERROR explicit lifetimes given + // where clause, but without lifetimes fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> where T: Copy { Ok(x) } -//~^ERROR explicit lifetimes given + type Ref<'r> = &'r u8; fn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) { } // no error, same lifetime on two params fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) { } -//~^ERROR explicit lifetimes given + fn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) { } // no error, bounded lifetime @@ -55,7 +55,7 @@ fn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> where F: Fn(Lt<'a, I>) -> Lt<'a, I> // no error, fn bound references 'a { unreachable!() } -fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> //~ERROR explicit lifetimes given +fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> where for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I> { unreachable!() } @@ -65,12 +65,12 @@ struct X { impl X { fn self_and_out<'s>(&'s self) -> &'s u8 { &self.x } - //~^ERROR explicit lifetimes given + fn self_and_in_out<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 { &self.x } // no error, multiple input refs fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) { } - //~^ERROR explicit lifetimes given + fn self_and_same_in<'s>(&'s self, _x: &'s u8) { } // no error, same lifetimes on two params } @@ -86,7 +86,7 @@ fn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 { unimplemented!() } -fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { unimplemented!() } //~ERROR explicit lifetimes given +fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { unimplemented!() } // no warning, two input lifetimes (named on the reference, anonymous on Foo) fn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str { unimplemented!() } @@ -106,11 +106,11 @@ fn trait_obj_elided<'a>(_arg: &'a WithLifetime) -> &'a str { unimplemented!() } // this should warn because there is no lifetime on Drop, so this would be // unambiguous if we elided the lifetime -fn trait_obj_elided2<'a>(_arg: &'a Drop) -> &'a str { unimplemented!() } //~ERROR explicit lifetimes given +fn trait_obj_elided2<'a>(_arg: &'a Drop) -> &'a str { unimplemented!() } type FooAlias<'a> = Foo<'a>; -fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { unimplemented!() } //~ERROR explicit lifetimes given +fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { unimplemented!() } // no warning, two input lifetimes (named on the reference, anonymous on Foo) fn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str { unimplemented!() } @@ -121,11 +121,11 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a> ) -> &'a str { unimplemented!() } // no warning, two input lifetimes fn alias_with_lt4<'a, 'b>(_foo: &'a FooAlias<'b> ) -> &'a str { unimplemented!() } -fn named_input_elided_output<'a>(_arg: &'a str) -> &str { unimplemented!() } //~ERROR explicit lifetimes given +fn named_input_elided_output<'a>(_arg: &'a str) -> &str { unimplemented!() } fn elided_input_named_output<'a>(_arg: &str) -> &'a str { unimplemented!() } -fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { unimplemented!() } //~ERROR explicit lifetimes given +fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { unimplemented!() } fn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) { unimplemented!() } fn main() { diff --git a/tests/ui/lifetimes.stderr b/tests/ui/lifetimes.stderr new file mode 100644 index 000000000000..6d213ad45f24 --- /dev/null +++ b/tests/ui/lifetimes.stderr @@ -0,0 +1,95 @@ +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:7:1 + | +7 | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/lifetimes.rs:4:9 + | +4 | #![deny(needless_lifetimes, unused_lifetimes)] + | ^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:10:1 + | +10 | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:19:1 + | +19 | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 { x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:32:1 + | +32 | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> { Ok(x) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:36:1 + | +36 | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> where T: Copy { Ok(x) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:43:1 + | +43 | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:58:1 + | +58 | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I> + | _^ starting here... +59 | | where for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I> +60 | | { unreachable!() } + | |__________________^ ...ending here + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:67:5 + | +67 | fn self_and_out<'s>(&'s self) -> &'s u8 { &self.x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:72:5 + | +72 | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:89:1 + | +89 | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:109:1 + | +109 | fn trait_obj_elided2<'a>(_arg: &'a Drop) -> &'a str { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:113:1 + | +113 | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:124:1 + | +124 | fn named_input_elided_output<'a>(_arg: &'a str) -> &str { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: explicit lifetimes given in parameter types where they could be elided + --> $DIR/lifetimes.rs:128:1 + | +128 | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 14 previous errors + diff --git a/tests/compile-fail/lint_pass.rs b/tests/ui/lint_pass.rs similarity index 86% rename from tests/compile-fail/lint_pass.rs rename to tests/ui/lint_pass.rs index 980ae5cb7a11..5b65a5c3a26d 100644 --- a/tests/compile-fail/lint_pass.rs +++ b/tests/ui/lint_pass.rs @@ -10,7 +10,7 @@ use rustc::lint::{LintPass, LintArray}; declare_lint! { GOOD_LINT, Warn, "good lint" } declare_lint! { MISSING_LINT, Warn, "missing lint" } -//~^ ERROR: the lint `MISSING_LINT` is not added to any `LintPass` + pub struct Pass; diff --git a/tests/ui/lint_pass.stderr b/tests/ui/lint_pass.stderr new file mode 100644 index 000000000000..2439007feace --- /dev/null +++ b/tests/ui/lint_pass.stderr @@ -0,0 +1,14 @@ +error: the lint `MISSING_LINT` is not added to any `LintPass` + --> $DIR/lint_pass.rs:12:1 + | +12 | declare_lint! { MISSING_LINT, Warn, "missing lint" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/lint_pass.rs:5:9 + | +5 | #![deny(lint_without_lint_pass)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/literals.rs b/tests/ui/literals.rs new file mode 100644 index 000000000000..e4cee81d53f0 --- /dev/null +++ b/tests/ui/literals.rs @@ -0,0 +1,38 @@ +#![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; + let fail2 = 0xabCD_u32; + let fail2 = 0xabCD_isize; + + let ok6 = 1234_i32; + let ok7 = 1234_f32; + let ok8 = 1234_isize; + let fail3 = 1234i32; + let fail4 = 1234u32; + let fail5 = 1234isize; + let fail6 = 1234usize; + let fail7 = 1.5f32; + + let ok9 = 0; + let ok10 = 0_i64; + let fail8 = 0123; + + + + + + + let ok11 = 0o123; + let ok12 = 0b101010; +} diff --git a/tests/ui/literals.stderr b/tests/ui/literals.stderr new file mode 100644 index 000000000000..b9a0fc041811 --- /dev/null +++ b/tests/ui/literals.stderr @@ -0,0 +1,78 @@ +error: inconsistent casing in hexadecimal literal + --> $DIR/literals.rs:14:17 + | +14 | let fail1 = 0xabCD; + | ^^^^^^ + | +note: lint level defined here + --> $DIR/literals.rs:3:9 + | +3 | #![deny(mixed_case_hex_literals)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: inconsistent casing in hexadecimal literal + --> $DIR/literals.rs:15:17 + | +15 | let fail2 = 0xabCD_u32; + | ^^^^^^^^^^ + +error: inconsistent casing in hexadecimal literal + --> $DIR/literals.rs:16:17 + | +16 | let fail2 = 0xabCD_isize; + | ^^^^^^^^^^^^ + +error: integer type suffix should be separated by an underscore + --> $DIR/literals.rs:21:17 + | +21 | let fail3 = 1234i32; + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/literals.rs:4:9 + | +4 | #![deny(unseparated_literal_suffix)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: integer type suffix should be separated by an underscore + --> $DIR/literals.rs:22:17 + | +22 | let fail4 = 1234u32; + | ^^^^^^^ + +error: integer type suffix should be separated by an underscore + --> $DIR/literals.rs:23:17 + | +23 | let fail5 = 1234isize; + | ^^^^^^^^^ + +error: integer type suffix should be separated by an underscore + --> $DIR/literals.rs:24:17 + | +24 | let fail6 = 1234usize; + | ^^^^^^^^^ + +error: float type suffix should be separated by an underscore + --> $DIR/literals.rs:25:17 + | +25 | let fail7 = 1.5f32; + | ^^^^^^ + +error: this is a decimal constant + --> $DIR/literals.rs:29:17 + | +29 | let fail8 = 0123; + | ^^^^ + | +note: lint level defined here + --> $DIR/literals.rs:5:9 + | +5 | #![deny(zero_prefixed_literal)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: if you mean to use a decimal constant, remove the `0` to remove confusion: + | let fail8 = 123; +help: if you mean to use an octal constant, use `0o`: + | let fail8 = 0o123; + +error: aborting due to 9 previous errors + diff --git a/tests/compile-fail/map_clone.rs b/tests/ui/map_clone.rs similarity index 53% rename from tests/compile-fail/map_clone.rs rename to tests/ui/map_clone.rs index b4f97ae8e6e4..f62d73532dd1 100644 --- a/tests/compile-fail/map_clone.rs +++ b/tests/ui/map_clone.rs @@ -9,30 +9,30 @@ use std::ops::Deref; fn map_clone_iter() { let x = [1,2,3]; - x.iter().map(|y| y.clone()); //~ ERROR you seem to be using .map() - //~^ HELP try - x.iter().map(|&y| y); //~ ERROR you seem to be using .map() - //~^ HELP try - x.iter().map(|y| *y); //~ ERROR you seem to be using .map() - //~^ HELP try - x.iter().map(|y| { y.clone() }); //~ ERROR you seem to be using .map() - //~^ HELP try - x.iter().map(|&y| { y }); //~ ERROR you seem to be using .map() - //~^ HELP try - x.iter().map(|y| { *y }); //~ ERROR you seem to be using .map() - //~^ HELP try - x.iter().map(Clone::clone); //~ ERROR you seem to be using .map() - //~^ HELP try + x.iter().map(|y| y.clone()); + + x.iter().map(|&y| y); + + x.iter().map(|y| *y); + + x.iter().map(|y| { y.clone() }); + + x.iter().map(|&y| { y }); + + x.iter().map(|y| { *y }); + + x.iter().map(Clone::clone); + } fn map_clone_option() { let x = Some(4); - x.as_ref().map(|y| y.clone()); //~ ERROR you seem to be using .map() - //~^ HELP try - x.as_ref().map(|&y| y); //~ ERROR you seem to be using .map() - //~^ HELP try - x.as_ref().map(|y| *y); //~ ERROR you seem to be using .map() - //~^ HELP try + x.as_ref().map(|y| y.clone()); + + x.as_ref().map(|&y| y); + + x.as_ref().map(|y| *y); + } fn not_linted_option() { @@ -87,8 +87,8 @@ impl Deref for UnusualDeref { fn map_clone_deref() { let x = Some(UnusualDeref); - let _: Option = x.as_ref().map(|y| *y); //~ ERROR you seem to be using .map() - //~^ HELP try + let _: Option = x.as_ref().map(|y| *y); + // Not linted: using deref conversion let _: Option = x.map(|y| *y); diff --git a/tests/ui/map_clone.stderr b/tests/ui/map_clone.stderr new file mode 100644 index 000000000000..0a8a659d7206 --- /dev/null +++ b/tests/ui/map_clone.stderr @@ -0,0 +1,106 @@ +error: you seem to be using .map() to clone the contents of an iterator, consider using `.cloned()` + --> $DIR/map_clone.rs:12:5 + | +12 | x.iter().map(|y| y.clone()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/map_clone.rs:4:9 + | +4 | #![deny(map_clone)] + | ^^^^^^^^^ + = help: try + x.iter().cloned() + +error: you seem to be using .map() to clone the contents of an iterator, consider using `.cloned()` + --> $DIR/map_clone.rs:14:5 + | +14 | x.iter().map(|&y| y); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.iter().cloned() + +error: you seem to be using .map() to clone the contents of an iterator, consider using `.cloned()` + --> $DIR/map_clone.rs:16:5 + | +16 | x.iter().map(|y| *y); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.iter().cloned() + +error: you seem to be using .map() to clone the contents of an iterator, consider using `.cloned()` + --> $DIR/map_clone.rs:18:5 + | +18 | x.iter().map(|y| { y.clone() }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.iter().cloned() + +error: you seem to be using .map() to clone the contents of an iterator, consider using `.cloned()` + --> $DIR/map_clone.rs:20:5 + | +20 | x.iter().map(|&y| { y }); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.iter().cloned() + +error: you seem to be using .map() to clone the contents of an iterator, consider using `.cloned()` + --> $DIR/map_clone.rs:22:5 + | +22 | x.iter().map(|y| { *y }); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.iter().cloned() + +error: you seem to be using .map() to clone the contents of an iterator, consider using `.cloned()` + --> $DIR/map_clone.rs:24:5 + | +24 | x.iter().map(Clone::clone); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.iter().cloned() + +error: you seem to be using .map() to clone the contents of an Option, consider using `.cloned()` + --> $DIR/map_clone.rs:30:5 + | +30 | x.as_ref().map(|y| y.clone()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.as_ref().cloned() + +error: you seem to be using .map() to clone the contents of an Option, consider using `.cloned()` + --> $DIR/map_clone.rs:32:5 + | +32 | x.as_ref().map(|&y| y); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.as_ref().cloned() + +error: you seem to be using .map() to clone the contents of an Option, consider using `.cloned()` + --> $DIR/map_clone.rs:34:5 + | +34 | x.as_ref().map(|y| *y); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.as_ref().cloned() + +error: you seem to be using .map() to clone the contents of an Option, consider using `.cloned()` + --> $DIR/map_clone.rs:90:35 + | +90 | let _: Option = x.as_ref().map(|y| *y); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try + x.as_ref().cloned() + +error: aborting due to 11 previous errors + diff --git a/tests/compile-fail/matches.rs b/tests/ui/matches.rs similarity index 56% rename from tests/compile-fail/matches.rs rename to tests/ui/matches.rs index 6cfb45e1f7e6..00faed26818a 100644 --- a/tests/compile-fail/matches.rs +++ b/tests/ui/matches.rs @@ -24,9 +24,9 @@ fn dummy() { fn unwrap_addr() -> Option<&'static ExprNode> { match ExprNode::Butterflies { - //~^ ERROR you seem to be trying to use match - //~| HELP try - //~| SUGGESTION if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else { let x = 5; None } + + + ExprNode::ExprAddrOf => Some(&NODE), _ => { let x = 5; None }, } @@ -36,18 +36,18 @@ fn single_match(){ let x = Some(1u8); match x { - //~^ ERROR you seem to be trying to use match - //~| HELP try - //~| SUGGESTION if let Some(y) = x { println!("{:?}", y); }; + + + Some(y) => { println!("{:?}", y); } _ => () }; let z = (1u8,1u8); match z { - //~^ ERROR you seem to be trying to use match - //~| HELP try - //~| SUGGESTION if let (2...3, 7...9) = z { dummy() }; + + + (2...3, 7...9) => dummy(), _ => {} }; @@ -70,17 +70,17 @@ fn single_match_know_enum() { let y : Result<_, i8> = Ok(1i8); match x { - //~^ ERROR you seem to be trying to use match - //~| HELP try - //~| SUGGESTION if let Some(y) = x { dummy() }; + + + Some(y) => dummy(), None => () }; match y { - //~^ ERROR you seem to be trying to use match - //~| HELP try - //~| SUGGESTION if let Ok(y) = y { dummy() }; + + + Ok(y) => dummy(), Err(..) => () }; @@ -88,9 +88,9 @@ fn single_match_know_enum() { let c = Cow::Borrowed(""); match c { - //~^ ERROR you seem to be trying to use match - //~| HELP try - //~| SUGGESTION if let Cow::Borrowed(..) = c { dummy() }; + + + Cow::Borrowed(..) => dummy(), Cow::Owned(..) => (), }; @@ -112,51 +112,51 @@ fn match_bool() { let test: bool = true; match test { - //~^ ERROR you seem to be trying to match on a boolean expression - //~| HELP consider - //~| SUGGESTION if test { 0 } else { 42 }; + + + true => 0, false => 42, }; let option = 1; match option == 1 { - //~^ ERROR you seem to be trying to match on a boolean expression - //~| HELP consider - //~| SUGGESTION if option == 1 { 1 } else { 0 }; + + + true => 1, false => 0, }; match test { - //~^ ERROR you seem to be trying to match on a boolean expression - //~| HELP consider - //~| SUGGESTION if !test { println!("Noooo!"); }; + + + true => (), false => { println!("Noooo!"); } }; match test { - //~^ ERROR you seem to be trying to match on a boolean expression - //~| HELP consider - //~| SUGGESTION if !test { println!("Noooo!"); }; + + + false => { println!("Noooo!"); } _ => (), }; match test && test { - //~^ ERROR you seem to be trying to match on a boolean expression - //~| HELP consider - //~| SUGGESTION if !(test && test) { println!("Noooo!"); }; - //~| ERROR equal expressions as operands + + + + false => { println!("Noooo!"); } _ => (), }; match test { - //~^ ERROR you seem to be trying to match on a boolean expression - //~| HELP consider - //~| SUGGESTION if test { println!("Yes!"); } else { println!("Noooo!"); }; + + + false => { println!("Noooo!"); } true => { println!("Yes!"); } }; @@ -173,9 +173,9 @@ fn ref_pats() { { let v = &Some(0); match v { - //~^ERROR add `&` to all patterns - //~|HELP instead of - //~|SUGGESTION match *v { .. } + + + &Some(v) => println!("{:?}", v), &None => println!("none"), } @@ -186,18 +186,18 @@ fn ref_pats() { } let tup =& (1, 2); match tup { - //~^ERROR add `&` to all patterns - //~|HELP instead of - //~|SUGGESTION match *tup { .. } + + + &(v, 1) => println!("{}", v), _ => println!("none"), } // special case: using & both in expr and pats let w = Some(0); match &w { - //~^ERROR add `&` to both - //~|HELP try - //~|SUGGESTION match w { .. } + + + &Some(v) => println!("{:?}", v), &None => println!("none"), } @@ -209,17 +209,17 @@ fn ref_pats() { let a = &Some(0); if let &None = a { - //~^ERROR add `&` to all patterns - //~|HELP instead of - //~|SUGGESTION if let .. = *a { .. } + + + println!("none"); } let b = Some(0); if let &None = &b { - //~^ERROR add `&` to both - //~|HELP try - //~|SUGGESTION if let .. = b { .. } + + + println!("none"); } } @@ -228,27 +228,27 @@ fn overlapping() { const FOO : u64 = 2; match 42 { - 0 ... 10 => println!("0 ... 10"), //~ERROR: some ranges overlap - 0 ... 11 => println!("0 ... 11"), //~NOTE overlaps with this + 0 ... 10 => println!("0 ... 10"), + 0 ... 11 => println!("0 ... 11"), _ => (), } match 42 { - 0 ... 5 => println!("0 ... 5"), //~ERROR: some ranges overlap + 0 ... 5 => println!("0 ... 5"), 6 ... 7 => println!("6 ... 7"), - FOO ... 11 => println!("0 ... 11"), //~NOTE overlaps with this + FOO ... 11 => println!("0 ... 11"), _ => (), } match 42 { - 2 => println!("2"), //~NOTE overlaps with this - 0 ... 5 => println!("0 ... 5"), //~ERROR: some ranges overlap + 2 => println!("2"), + 0 ... 5 => println!("0 ... 5"), _ => (), } match 42 { - 2 => println!("2"), //~NOTE overlaps with this - 0 ... 2 => println!("0 ... 2"), //~ERROR: some ranges overlap + 2 => println!("2"), + 0 ... 2 => println!("0 ... 2"), _ => (), } @@ -271,8 +271,8 @@ fn overlapping() { } match 42 { - 0 .. 11 => println!("0 .. 11"), //~ERROR: some ranges overlap - 0 ... 11 => println!("0 ... 11"), //~NOTE overlaps with this + 0 .. 11 => println!("0 .. 11"), + 0 ... 11 => println!("0 ... 11"), _ => (), } diff --git a/tests/ui/matches.stderr b/tests/ui/matches.stderr new file mode 100644 index 000000000000..bc254cb0bcb3 --- /dev/null +++ b/tests/ui/matches.stderr @@ -0,0 +1,392 @@ +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:26:5 + | +26 | match ExprNode::Butterflies { + | _____^ starting here... +27 | | +28 | | +29 | | +30 | | ExprNode::ExprAddrOf => Some(&NODE), +31 | | _ => { let x = 5; None }, +32 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/matches.rs:7:9 + | +7 | #![deny(single_match_else)] + | ^^^^^^^^^^^^^^^^^ +help: try this + | if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else { let x = 5; None } + +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:38:5 + | +38 | match x { + | _____^ starting here... +39 | | +40 | | +41 | | +42 | | Some(y) => { println!("{:?}", y); } +43 | | _ => () +44 | | }; + | |_____^ ...ending here + | + = note: #[deny(single_match)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/matches.rs:5:9 + | +5 | #![deny(clippy)] + | ^^^^^^ +help: try this + | if let Some(y) = x { println!("{:?}", y); }; + +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:47:5 + | +47 | match z { + | _____^ starting here... +48 | | +49 | | +50 | | +51 | | (2...3, 7...9) => dummy(), +52 | | _ => {} +53 | | }; + | |_____^ ...ending here + | + = note: #[deny(single_match)] implied by #[deny(clippy)] +help: try this + | if let (2...3, 7...9) = z { dummy() }; + +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:72:5 + | +72 | match x { + | _____^ starting here... +73 | | +74 | | +75 | | +76 | | Some(y) => dummy(), +77 | | None => () +78 | | }; + | |_____^ ...ending here + | + = note: #[deny(single_match)] implied by #[deny(clippy)] +help: try this + | if let Some(y) = x { dummy() }; + +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:80:5 + | +80 | match y { + | _____^ starting here... +81 | | +82 | | +83 | | +84 | | Ok(y) => dummy(), +85 | | Err(..) => () +86 | | }; + | |_____^ ...ending here + | + = note: #[deny(single_match)] implied by #[deny(clippy)] +help: try this + | if let Ok(y) = y { dummy() }; + +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:90:5 + | +90 | match c { + | _____^ starting here... +91 | | +92 | | +93 | | +94 | | Cow::Borrowed(..) => dummy(), +95 | | Cow::Owned(..) => (), +96 | | }; + | |_____^ ...ending here + | + = note: #[deny(single_match)] implied by #[deny(clippy)] +help: try this + | if let Cow::Borrowed(..) = c { dummy() }; + +error: you seem to be trying to match on a boolean expression + --> $DIR/matches.rs:114:5 + | +114 | match test { + | _____^ starting here... +115 | | +116 | | +117 | | +118 | | true => 0, +119 | | false => 42, +120 | | }; + | |_____^ ...ending here + | + = note: #[deny(match_bool)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/matches.rs:5:9 + | +5 | #![deny(clippy)] + | ^^^^^^ +help: consider using an if/else expression + | if test { 0 } else { 42 }; + +error: you seem to be trying to match on a boolean expression + --> $DIR/matches.rs:123:5 + | +123 | match option == 1 { + | _____^ starting here... +124 | | +125 | | +126 | | +127 | | true => 1, +128 | | false => 0, +129 | | }; + | |_____^ ...ending here + | + = note: #[deny(match_bool)] implied by #[deny(clippy)] +help: consider using an if/else expression + | if option == 1 { 1 } else { 0 }; + +error: you seem to be trying to match on a boolean expression + --> $DIR/matches.rs:131:5 + | +131 | match test { + | _____^ starting here... +132 | | +133 | | +134 | | +135 | | true => (), +136 | | false => { println!("Noooo!"); } +137 | | }; + | |_____^ ...ending here + | + = note: #[deny(match_bool)] implied by #[deny(clippy)] +help: consider using an if/else expression + | if !test { println!("Noooo!"); }; + +error: you seem to be trying to match on a boolean expression + --> $DIR/matches.rs:139:5 + | +139 | match test { + | _____^ starting here... +140 | | +141 | | +142 | | +143 | | false => { println!("Noooo!"); } +144 | | _ => (), +145 | | }; + | |_____^ ...ending here + | + = note: #[deny(match_bool)] implied by #[deny(clippy)] +help: consider using an if/else expression + | if !test { println!("Noooo!"); }; + +error: you seem to be trying to match on a boolean expression + --> $DIR/matches.rs:147:5 + | +147 | match test && test { + | _____^ starting here... +148 | | +149 | | +150 | | +151 | | +152 | | false => { println!("Noooo!"); } +153 | | _ => (), +154 | | }; + | |_____^ ...ending here + | + = note: #[deny(match_bool)] implied by #[deny(clippy)] +help: consider using an if/else expression + | if !(test && test) { println!("Noooo!"); }; + +error: equal expressions as operands to `&&` + --> $DIR/matches.rs:147:11 + | +147 | match test && test { + | ^^^^^^^^^^^^ + | + = note: #[deny(eq_op)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/matches.rs:5:9 + | +5 | #![deny(clippy)] + | ^^^^^^ + +error: you seem to be trying to match on a boolean expression + --> $DIR/matches.rs:156:5 + | +156 | match test { + | _____^ starting here... +157 | | +158 | | +159 | | +160 | | false => { println!("Noooo!"); } +161 | | true => { println!("Yes!"); } +162 | | }; + | |_____^ ...ending here + | + = note: #[deny(match_bool)] implied by #[deny(clippy)] +help: consider using an if/else expression + | if test { println!("Yes!"); } else { println!("Noooo!"); }; + +error: you don't need to add `&` to all patterns + --> $DIR/matches.rs:175:9 + | +175 | match v { + | _________^ starting here... +176 | | +177 | | +178 | | +179 | | &Some(v) => println!("{:?}", v), +180 | | &None => println!("none"), +181 | | } + | |_________^ ...ending here + | + = note: #[deny(match_ref_pats)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/matches.rs:5:9 + | +5 | #![deny(clippy)] + | ^^^^^^ +help: instead of prefixing all patterns with `&`, you can dereference the expression + | match *v { .. } + +error: you don't need to add `&` to all patterns + --> $DIR/matches.rs:188:5 + | +188 | match tup { + | _____^ starting here... +189 | | +190 | | +191 | | +192 | | &(v, 1) => println!("{}", v), +193 | | _ => println!("none"), +194 | | } + | |_____^ ...ending here + | + = note: #[deny(match_ref_pats)] implied by #[deny(clippy)] +help: instead of prefixing all patterns with `&`, you can dereference the expression + | match *tup { .. } + +error: you don't need to add `&` to both the expression and the patterns + --> $DIR/matches.rs:197:5 + | +197 | match &w { + | _____^ starting here... +198 | | +199 | | +200 | | +201 | | &Some(v) => println!("{:?}", v), +202 | | &None => println!("none"), +203 | | } + | |_____^ ...ending here + | + = note: #[deny(match_ref_pats)] implied by #[deny(clippy)] +help: try + | match w { .. } + +error: you don't need to add `&` to all patterns + --> $DIR/matches.rs:211:5 + | +211 | if let &None = a { + | _____^ starting here... +212 | | +213 | | +214 | | +215 | | println!("none"); +216 | | } + | |_____^ ...ending here + | + = note: #[deny(match_ref_pats)] implied by #[deny(clippy)] +help: instead of prefixing all patterns with `&`, you can dereference the expression + | if let .. = *a { .. } + +error: you don't need to add `&` to both the expression and the patterns + --> $DIR/matches.rs:219:5 + | +219 | if let &None = &b { + | _____^ starting here... +220 | | +221 | | +222 | | +223 | | println!("none"); +224 | | } + | |_____^ ...ending here + | + = note: #[deny(match_ref_pats)] implied by #[deny(clippy)] +help: try + | if let .. = b { .. } + +error: some ranges overlap + --> $DIR/matches.rs:231:9 + | +231 | 0 ... 10 => println!("0 ... 10"), + | ^^^^^^^^ + | + = note: #[deny(match_overlapping_arm)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/matches.rs:5:9 + | +5 | #![deny(clippy)] + | ^^^^^^ +note: overlaps with this + --> $DIR/matches.rs:232:9 + | +232 | 0 ... 11 => println!("0 ... 11"), + | ^^^^^^^^ + +error: some ranges overlap + --> $DIR/matches.rs:237:9 + | +237 | 0 ... 5 => println!("0 ... 5"), + | ^^^^^^^ + | + = note: #[deny(match_overlapping_arm)] implied by #[deny(clippy)] +note: overlaps with this + --> $DIR/matches.rs:239:9 + | +239 | FOO ... 11 => println!("0 ... 11"), + | ^^^^^^^^^^ + +error: some ranges overlap + --> $DIR/matches.rs:245:9 + | +245 | 0 ... 5 => println!("0 ... 5"), + | ^^^^^^^ + | + = note: #[deny(match_overlapping_arm)] implied by #[deny(clippy)] +note: overlaps with this + --> $DIR/matches.rs:244:9 + | +244 | 2 => println!("2"), + | ^ + +error: some ranges overlap + --> $DIR/matches.rs:251:9 + | +251 | 0 ... 2 => println!("0 ... 2"), + | ^^^^^^^ + | + = note: #[deny(match_overlapping_arm)] implied by #[deny(clippy)] +note: overlaps with this + --> $DIR/matches.rs:250:9 + | +250 | 2 => println!("2"), + | ^ + +error: some ranges overlap + --> $DIR/matches.rs:274:9 + | +274 | 0 .. 11 => println!("0 .. 11"), + | ^^^^^^^ + | + = note: #[deny(match_overlapping_arm)] implied by #[deny(clippy)] +note: overlaps with this + --> $DIR/matches.rs:275:9 + | +275 | 0 ... 11 => println!("0 ... 11"), + | ^^^^^^^^ + +error: aborting due to 23 previous errors + diff --git a/tests/compile-fail/mem_forget.rs b/tests/ui/mem_forget.rs similarity index 75% rename from tests/compile-fail/mem_forget.rs rename to tests/ui/mem_forget.rs index c8cebcb2a42d..9832bd992c1c 100644 --- a/tests/compile-fail/mem_forget.rs +++ b/tests/ui/mem_forget.rs @@ -14,15 +14,15 @@ fn main() { let six: Arc = Arc::new(6); memstuff::forget(six); - //~^ ERROR usage of mem::forget on Drop type + let seven: Rc = Rc::new(7); std::mem::forget(seven); - //~^ ERROR usage of mem::forget on Drop type + let eight: Vec = vec![8]; forgetSomething(eight); - //~^ ERROR usage of mem::forget on Drop type + std::mem::forget(7); } diff --git a/tests/ui/mem_forget.stderr b/tests/ui/mem_forget.stderr new file mode 100644 index 000000000000..47c61adfbbf8 --- /dev/null +++ b/tests/ui/mem_forget.stderr @@ -0,0 +1,26 @@ +error: usage of mem::forget on Drop type + --> $DIR/mem_forget.rs:16:5 + | +16 | memstuff::forget(six); + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/mem_forget.rs:10:8 + | +10 | #[deny(mem_forget)] + | ^^^^^^^^^^ + +error: usage of mem::forget on Drop type + --> $DIR/mem_forget.rs:20:5 + | +20 | std::mem::forget(seven); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: usage of mem::forget on Drop type + --> $DIR/mem_forget.rs:24:5 + | +24 | forgetSomething(eight); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs new file mode 100644 index 000000000000..da37ac8f566a --- /dev/null +++ b/tests/ui/methods.rs @@ -0,0 +1,691 @@ +#![feature(plugin)] +#![feature(const_fn)] +#![plugin(clippy)] + +#![deny(clippy, clippy_pedantic)] +#![allow(blacklisted_name, unused, print_stdout, non_ascii_literal, new_without_default, new_without_default_derive, missing_docs_in_private_items)] + +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::collections::HashSet; +use std::collections::VecDeque; +use std::ops::Mul; +use std::iter::FromIterator; + +struct T; + +impl T { + 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 } + + fn to_something(self) -> u32 { 0 } + + fn new(self) {} + + +} + +struct Lt<'a> { + foo: &'a u32, +} + +impl<'a> Lt<'a> { + // The lifetime is different, but that’s irrelevant, see #734 + #[allow(needless_lifetimes)] + pub fn new<'b>(s: &'b str) -> Lt<'b> { unimplemented!() } +} + +struct Lt2<'a> { + foo: &'a u32, +} + +impl<'a> Lt2<'a> { + // The lifetime is different, but that’s irrelevant, see #734 + pub fn new(s: &str) -> Lt2 { unimplemented!() } +} + +struct Lt3<'a> { + foo: &'a u32, +} + +impl<'a> Lt3<'a> { + // The lifetime is different, but that’s irrelevant, see #734 + pub fn new() -> Lt3<'static> { unimplemented!() } +} + +#[derive(Clone,Copy)] +struct U; + +impl U { + fn new() -> Self { U } + fn to_something(self) -> u32 { 0 } // ok because U is Copy +} + +struct V { + _dummy: T +} + +impl V { + fn new() -> Option> { None } +} + +impl Mul for T { + type Output = T; + fn mul(self, other: T) -> T { self } // no error, obviously +} + +/// Utility macro to test linting behavior in `option_methods()` +/// The lints included in `option_methods()` should not lint if the call to map is partially +/// within a macro +macro_rules! opt_map { + ($opt:expr, $map:expr) => {($opt).map($map)}; +} + +/// Checks implementation of the following lints: +/// * `OPTION_MAP_UNWRAP_OR` +/// * `OPTION_MAP_UNWRAP_OR_ELSE` +fn option_methods() { + let opt = Some(1); + + // Check OPTION_MAP_UNWRAP_OR + // single line case + 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| { + x + 1 + } + ).unwrap_or(0); + let _ = opt.map(|x| x + 1) + .unwrap_or({ + 0 + }); + // macro case + let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint + + // Check OPTION_MAP_UNWRAP_OR_ELSE + // single line case + 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| { + x + 1 + } + ).unwrap_or_else(|| 0); + let _ = opt.map(|x| x + 1) + .unwrap_or_else(|| + 0 + ); + // macro case + let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint +} + +/// Struct to generate false positives for things with .iter() +#[derive(Copy, Clone)] +struct HasIter; + +impl HasIter { + fn iter(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } + + fn iter_mut(self) -> IteratorFalsePositives { + IteratorFalsePositives { foo: 0 } + } +} + +/// Struct to generate false positive for Iterator-based lints +#[derive(Copy, Clone)] +struct IteratorFalsePositives { + foo: u32, +} + +impl IteratorFalsePositives { + fn filter(self) -> IteratorFalsePositives { + self + } + + fn next(self) -> IteratorFalsePositives { + self + } + + fn find(self) -> Option { + Some(self.foo) + } + + fn position(self) -> Option { + Some(self.foo) + } + + fn rposition(self) -> Option { + Some(self.foo) + } + + fn nth(self, n: usize) -> Option { + Some(self.foo) + } + + fn skip(self, _: usize) -> IteratorFalsePositives { + self + } +} + +#[derive(Copy, Clone)] +struct HasChars; + +impl HasChars { + fn chars(self) -> std::str::Chars<'static> { + "HasChars".chars() + } +} + +/// Checks implementation of `FILTER_NEXT` lint +fn filter_next() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + + // check single-line case + let _ = v.iter().filter(|&x| *x < 0).next(); + + + + // check multi-line case + let _ = v.iter().filter(|&x| { + *x < 0 + } + ).next(); + + // check that we don't lint if the caller is not an Iterator + let foo = IteratorFalsePositives { foo: 0 }; + let _ = foo.filter().next(); +} + +/// Checks implementation of `SEARCH_IS_SOME` lint +fn search_is_some() { + let v = vec![3, 2, 1, 0, -1, -2, -3]; + + // check `find().is_some()`, single-line + let _ = v.iter().find(|&x| *x < 0).is_some(); + + + + // check `find().is_some()`, multi-line + let _ = v.iter().find(|&x| { + *x < 0 + } + ).is_some(); + + // check `position().is_some()`, single-line + let _ = v.iter().position(|&x| x < 0).is_some(); + + + + // check `position().is_some()`, multi-line + let _ = v.iter().position(|&x| { + x < 0 + } + ).is_some(); + + // check `rposition().is_some()`, single-line + let _ = v.iter().rposition(|&x| x < 0).is_some(); + + + + // check `rposition().is_some()`, multi-line + let _ = v.iter().rposition(|&x| { + x < 0 + } + ).is_some(); + + // check that we don't lint if the caller is not an Iterator + let foo = IteratorFalsePositives { foo: 0 }; + let _ = foo.find().is_some(); + let _ = foo.position().is_some(); + let _ = foo.rposition().is_some(); +} + +/// Checks implementation of the `OR_FUN_CALL` lint +fn or_fun_call() { + struct Foo; + + impl Foo { + fn new() -> Foo { Foo } + } + + enum Enum { + A(i32), + } + + const fn make_const(i: i32) -> i32 { i } + + fn make() -> T { unimplemented!(); } + + let with_enum = Some(Enum::A(1)); + with_enum.unwrap_or(Enum::A(5)); + + let with_const_fn = Some(1); + with_const_fn.unwrap_or(make_const(5)); + + let with_constructor = Some(vec![1]); + with_constructor.unwrap_or(make()); + + + + + let with_new = Some(vec![1]); + with_new.unwrap_or(Vec::new()); + + + + + let with_const_args = Some(vec![1]); + with_const_args.unwrap_or(Vec::with_capacity(12)); + + + + + let with_err : Result<_, ()> = Ok(vec![1]); + with_err.unwrap_or(make()); + + + + + let with_err_args : Result<_, ()> = Ok(vec![1]); + with_err_args.unwrap_or(Vec::with_capacity(12)); + + + + + let with_default_trait = Some(1); + with_default_trait.unwrap_or(Default::default()); + + + + + let with_default_type = Some(1); + with_default_type.unwrap_or(u64::default()); + + + + + let with_vec = Some(vec![1]); + with_vec.unwrap_or(vec![]); + + + // FIXME #944: ~|SUGGESTION with_vec.unwrap_or_else(|| vec![]); + + let without_default = Some(Foo); + without_default.unwrap_or(Foo::new()); + + + + + let mut map = HashMap::::new(); + map.entry(42).or_insert(String::new()); + + + + + let mut btree = BTreeMap::::new(); + btree.entry(42).or_insert(String::new()); + + + + + let stringy = Some(String::from("")); + let _ = stringy.unwrap_or("".to_owned()); + + + +} + +/// Checks implementation of `ITER_NTH` lint +fn iter_nth() { + let mut some_vec = vec![0, 1, 2, 3]; + let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); + let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect(); + + { + // Make sure we lint `.iter()` for relevant types + let bad_vec = some_vec.iter().nth(3); + + let bad_slice = &some_vec[..].iter().nth(3); + + let bad_boxed_slice = boxed_slice.iter().nth(3); + + let bad_vec_deque = some_vec_deque.iter().nth(3); + + } + + { + // Make sure we lint `.iter_mut()` for relevant types + let bad_vec = some_vec.iter_mut().nth(3); + + } + { + let bad_slice = &some_vec[..].iter_mut().nth(3); + + } + { + let bad_vec_deque = some_vec_deque.iter_mut().nth(3); + + } + + // Make sure we don't lint for non-relevant types + let false_positive = HasIter; + let ok = false_positive.iter().nth(3); + let ok_mut = false_positive.iter_mut().nth(3); +} + +/// Checks implementation of `ITER_SKIP_NEXT` lint +fn iter_skip_next() { + let mut some_vec = vec![0, 1, 2, 3]; + + let _ = some_vec.iter().skip(42).next(); + + + let _ = some_vec.iter().cycle().skip(42).next(); + + + let _ = (1..10).skip(10).next(); + + + let _ = &some_vec[..].iter().skip(3).next(); + + + let foo = IteratorFalsePositives { foo : 0 }; + let _ = foo.skip(42).next(); + let _ = foo.filter().skip(42).next(); +} + +struct GetFalsePositive { + arr: [u32; 3], +} + +impl GetFalsePositive { + fn get(&self, pos: usize) -> Option<&u32> { self.arr.get(pos) } + fn get_mut(&mut self, pos: usize) -> Option<&mut u32> { self.arr.get_mut(pos) } +} + +/// Checks implementation of `GET_UNWRAP` lint +fn get_unwrap() { + let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); + let mut some_slice = &mut [0, 1, 2, 3]; + let mut some_vec = vec![0, 1, 2, 3]; + let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect(); + let mut some_hashmap: HashMap = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]); + let mut some_btreemap: BTreeMap = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]); + let mut false_positive = GetFalsePositive { arr: [0, 1, 2] }; + + { // Test `get().unwrap()` + let _ = boxed_slice.get(1).unwrap(); + + + + let _ = some_slice.get(0).unwrap(); + + + + let _ = some_vec.get(0).unwrap(); + + + + let _ = some_vecdeque.get(0).unwrap(); + + + + let _ = some_hashmap.get(&1).unwrap(); + + + + let _ = some_btreemap.get(&1).unwrap(); + + + + + let _ = false_positive.get(0).unwrap(); + } + + { // Test `get_mut().unwrap()` + *boxed_slice.get_mut(0).unwrap() = 1; + + + + *some_slice.get_mut(0).unwrap() = 1; + + + + *some_vec.get_mut(0).unwrap() = 1; + + + + *some_vecdeque.get_mut(0).unwrap() = 1; + + + + + // Check false positives + *some_hashmap.get_mut(&1).unwrap() = 'b'; + *some_btreemap.get_mut(&1).unwrap() = 'b'; + *false_positive.get_mut(0).unwrap() = 1; + } +} + + +#[allow(similar_names)] +fn main() { + use std::io; + + let opt = Some(0); + let _ = opt.unwrap(); + + let res: Result = Ok(0); + let _ = res.unwrap(); + + res.ok().expect("disaster!"); + // the following should not warn, since `expect` isn't implemented unless + // the error type implements `Debug` + let res2: Result = Ok(0); + res2.ok().expect("oh noes!"); + let res3: Result>= Ok(0); + res3.ok().expect("whoof"); + let res4: Result = Ok(0); + res4.ok().expect("argh"); + let res5: io::Result = Ok(0); + res5.ok().expect("oops"); + let res6: Result = Ok(0); + res6.ok().expect("meh"); +} + +struct MyError(()); // doesn't implement Debug + +#[derive(Debug)] +struct MyErrorWithParam { + x: T +} + +#[allow(unnecessary_operation)] +fn starts_with() { + "".chars().next() == Some(' '); + + + + + Some(' ') != "".chars().next(); + + + +} + +fn str_extend_chars() { + let abc = "abc"; + let def = String::from("def"); + let mut s = String::new(); + + s.push_str(abc); + s.extend(abc.chars()); + + + + + s.push_str("abc"); + s.extend("abc".chars()); + + + + + s.push_str(&def); + s.extend(def.chars()); + + + + + s.extend(abc.chars().skip(1)); + s.extend("abc".chars().skip(1)); + s.extend(['a', 'b', 'c'].iter()); + + let f = HasChars; + s.extend(f.chars()); +} + +fn clone_on_copy() { + 42.clone(); + + + vec![1].clone(); // ok, not a Copy type + Some(vec![1]).clone(); // ok, not a Copy type + (&42).clone(); + + +} + +fn clone_on_copy_generic(t: T) { + t.clone(); + + + Some(t).clone(); + + +} + +fn clone_on_double_ref() { + let x = vec![1]; + let y = &&x; + let z: &Vec<_> = y.clone(); + + + println!("{:p} {:p}",*y, z); +} + +fn single_char_pattern() { + let x = "foo"; + x.split("x"); + + + + + x.split("xx"); + + x.split('x'); + + let y = "x"; + x.split(y); + + // Not yet testing for multi-byte characters + // Changing `r.len() == 1` to `r.chars().count() == 1` in `lint_single_char_pattern` + // should have done this but produced an ICE + // + // We may not want to suggest changing these anyway + // See: https://github.com/Manishearth/rust-clippy/issues/650#issuecomment-184328984 + x.split("ß"); + x.split("ℝ"); + x.split("💣"); + // Can't use this lint for unicode code points which don't fit in a char + x.split("❤️"); + + x.contains("x"); + + + + x.starts_with("x"); + + + + x.ends_with("x"); + + + + x.find("x"); + + + + x.rfind("x"); + + + + x.rsplit("x"); + + + + x.split_terminator("x"); + + + + x.rsplit_terminator("x"); + + + + x.splitn(0, "x"); + + + + x.rsplitn(0, "x"); + + + + x.matches("x"); + + + + x.rmatches("x"); + + + + x.match_indices("x"); + + + + x.rmatch_indices("x"); + + + + x.trim_left_matches("x"); + + + + x.trim_right_matches("x"); + + + + + let h = HashSet::::new(); + h.contains("X"); // should not warn +} + +#[allow(result_unwrap_used)] +fn temporary_cstring() { + use std::ffi::CString; + + CString::new("foo").unwrap().as_ptr(); + + + +} diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr new file mode 100644 index 000000000000..f4294d8b396b --- /dev/null +++ b/tests/ui/methods.stderr @@ -0,0 +1,954 @@ +error: defining a method called `add` on this type; consider implementing the `std::ops::Add` trait or choosing a less ambiguous name + --> $DIR/methods.rs:18:5 + | +18 | fn add(self, other: T) -> T { self } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(should_implement_trait)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + +error: defining a method called `drop` on this type; consider implementing the `std::ops::Drop` trait or choosing a less ambiguous name + --> $DIR/methods.rs:19:5 + | +19 | fn drop(&mut self) { } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(should_implement_trait)] implied by #[deny(clippy)] + +error: methods called `into_*` usually take self by value; consider choosing a less ambiguous name + --> $DIR/methods.rs:26:17 + | +26 | fn into_u16(&self) -> u16 { 0 } + | ^^^^^ + | + = note: #[deny(wrong_self_convention)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + +error: methods called `to_*` usually take self by reference; consider choosing a less ambiguous name + --> $DIR/methods.rs:28:21 + | +28 | fn to_something(self) -> u32 { 0 } + | ^^^^ + | + = note: #[deny(wrong_self_convention)] implied by #[deny(clippy)] + +error: methods called `new` usually take no self; consider choosing a less ambiguous name + --> $DIR/methods.rs:30:12 + | +30 | fn new(self) {} + | ^^^^ + | + = note: #[deny(wrong_self_convention)] implied by #[deny(clippy)] + +error: methods called `new` usually return `Self` + --> $DIR/methods.rs:30:5 + | +30 | fn new(self) {} + | ^^^^^^^^^^^^^^^ + | + = note: #[deny(new_ret_no_self)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + +error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead + --> $DIR/methods.rs:99:13 + | +99 | let _ = opt.map(|x| x + 1) + | _____________^ starting here... +100 | | +101 | | .unwrap_or(0); // should lint even though this call is on a separate line + | |____________________________^ ...ending here + | + = note: #[deny(option_map_unwrap_or)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/methods.rs:5:17 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ + = note: replace `map(|x| x + 1).unwrap_or(0)` with `map_or(0, |x| x + 1)` + +error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead + --> $DIR/methods.rs:103:13 + | +103 | let _ = opt.map(|x| { + | _____________^ starting here... +104 | | x + 1 +105 | | } +106 | | ).unwrap_or(0); + | |____________________________^ ...ending here + | + = note: #[deny(option_map_unwrap_or)] implied by #[deny(clippy_pedantic)] + +error: called `map(f).unwrap_or(a)` on an Option value. This can be done more directly by calling `map_or(a, f)` instead + --> $DIR/methods.rs:107:13 + | +107 | let _ = opt.map(|x| x + 1) + | _____________^ starting here... +108 | | .unwrap_or({ +109 | | 0 +110 | | }); + | |__________________^ ...ending here + | + = note: #[deny(option_map_unwrap_or)] implied by #[deny(clippy_pedantic)] + +error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead + --> $DIR/methods.rs:116:13 + | +116 | let _ = opt.map(|x| x + 1) + | _____________^ starting here... +117 | | +118 | | .unwrap_or_else(|| 0); // should lint even though this call is on a separate line + | |____________________________________^ ...ending here + | + = note: #[deny(option_map_unwrap_or_else)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/methods.rs:5:17 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ + = note: replace `map(|x| x + 1).unwrap_or_else(|| 0)` with `with map_or_else(|| 0, |x| x + 1)` + +error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead + --> $DIR/methods.rs:120:13 + | +120 | let _ = opt.map(|x| { + | _____________^ starting here... +121 | | x + 1 +122 | | } +123 | | ).unwrap_or_else(|| 0); + | |____________________________________^ ...ending here + | + = note: #[deny(option_map_unwrap_or_else)] implied by #[deny(clippy_pedantic)] + +error: called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling `map_or_else(g, f)` instead + --> $DIR/methods.rs:124:13 + | +124 | let _ = opt.map(|x| x + 1) + | _____________^ starting here... +125 | | .unwrap_or_else(|| +126 | | 0 +127 | | ); + | |_________________^ ...ending here + | + = note: #[deny(option_map_unwrap_or_else)] implied by #[deny(clippy_pedantic)] + +error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead. + --> $DIR/methods.rs:196:13 + | +196 | let _ = v.iter().filter(|&x| *x < 0).next(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(filter_next)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + = note: replace `filter(|&x| *x < 0).next()` with `find(|&x| *x < 0)` + +error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead. + --> $DIR/methods.rs:201:13 + | +201 | let _ = v.iter().filter(|&x| { + | _____________^ starting here... +202 | | *x < 0 +203 | | } +204 | | ).next(); + | |___________________________^ ...ending here + | + = note: #[deny(filter_next)] implied by #[deny(clippy)] + +error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`. + --> $DIR/methods.rs:216:13 + | +216 | let _ = v.iter().find(|&x| *x < 0).is_some(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(search_is_some)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + = note: replace `find(|&x| *x < 0).is_some()` with `any(|&x| *x < 0)` + +error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`. + --> $DIR/methods.rs:221:13 + | +221 | let _ = v.iter().find(|&x| { + | _____________^ starting here... +222 | | *x < 0 +223 | | } +224 | | ).is_some(); + | |______________________________^ ...ending here + | + = note: #[deny(search_is_some)] implied by #[deny(clippy)] + +error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`. + --> $DIR/methods.rs:227:13 + | +227 | let _ = v.iter().position(|&x| x < 0).is_some(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(search_is_some)] implied by #[deny(clippy)] + = note: replace `position(|&x| x < 0).is_some()` with `any(|&x| x < 0)` + +error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`. + --> $DIR/methods.rs:232:13 + | +232 | let _ = v.iter().position(|&x| { + | _____________^ starting here... +233 | | x < 0 +234 | | } +235 | | ).is_some(); + | |______________________________^ ...ending here + | + = note: #[deny(search_is_some)] implied by #[deny(clippy)] + +error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`. + --> $DIR/methods.rs:238:13 + | +238 | let _ = v.iter().rposition(|&x| x < 0).is_some(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(search_is_some)] implied by #[deny(clippy)] + = note: replace `rposition(|&x| x < 0).is_some()` with `any(|&x| x < 0)` + +error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`. + --> $DIR/methods.rs:243:13 + | +243 | let _ = v.iter().rposition(|&x| { + | _____________^ starting here... +244 | | x < 0 +245 | | } +246 | | ).is_some(); + | |______________________________^ ...ending here + | + = note: #[deny(search_is_some)] implied by #[deny(clippy)] + +error: use of `unwrap_or` followed by a function call + --> $DIR/methods.rs:278:5 + | +278 | with_constructor.unwrap_or(make()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ +help: try this + | with_constructor.unwrap_or_else(make); + +error: use of `unwrap_or` followed by a call to `new` + --> $DIR/methods.rs:284:5 + | +284 | with_new.unwrap_or(Vec::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | with_new.unwrap_or_default(); + +error: use of `unwrap_or` followed by a function call + --> $DIR/methods.rs:290:5 + | +290 | with_const_args.unwrap_or(Vec::with_capacity(12)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | with_const_args.unwrap_or_else(|| Vec::with_capacity(12)); + +error: use of `unwrap_or` followed by a function call + --> $DIR/methods.rs:296:5 + | +296 | with_err.unwrap_or(make()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | with_err.unwrap_or_else(|_| make()); + +error: use of `unwrap_or` followed by a function call + --> $DIR/methods.rs:302:5 + | +302 | with_err_args.unwrap_or(Vec::with_capacity(12)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | with_err_args.unwrap_or_else(|_| Vec::with_capacity(12)); + +error: use of `unwrap_or` followed by a call to `default` + --> $DIR/methods.rs:308:5 + | +308 | with_default_trait.unwrap_or(Default::default()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | with_default_trait.unwrap_or_default(); + +error: use of `unwrap_or` followed by a call to `default` + --> $DIR/methods.rs:314:5 + | +314 | with_default_type.unwrap_or(u64::default()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | with_default_type.unwrap_or_default(); + +error: use of `unwrap_or` followed by a function call + --> $DIR/methods.rs:320:5 + | +320 | with_vec.unwrap_or(vec![]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | with_vec.unwrap_or_else(|| < [ _ ] > :: into_vec ( box [ $ ( $ x ) , * ] )); + +error: use of `unwrap_or` followed by a function call + --> $DIR/methods.rs:326:5 + | +326 | without_default.unwrap_or(Foo::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | without_default.unwrap_or_else(Foo::new); + +error: use of `or_insert` followed by a function call + --> $DIR/methods.rs:332:5 + | +332 | map.entry(42).or_insert(String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | map.entry(42).or_insert_with(String::new); + +error: use of `or_insert` followed by a function call + --> $DIR/methods.rs:338:5 + | +338 | btree.entry(42).or_insert(String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | btree.entry(42).or_insert_with(String::new); + +error: use of `unwrap_or` followed by a function call + --> $DIR/methods.rs:344:13 + | +344 | let _ = stringy.unwrap_or("".to_owned()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(or_fun_call)] implied by #[deny(clippy)] +help: try this + | let _ = stringy.unwrap_or_else(|| "".to_owned()); + +error: called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more readable + --> $DIR/methods.rs:358:23 + | +358 | let bad_vec = some_vec.iter().nth(3); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_nth)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + +error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable + --> $DIR/methods.rs:360:26 + | +360 | let bad_slice = &some_vec[..].iter().nth(3); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_nth)] implied by #[deny(clippy)] + +error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable + --> $DIR/methods.rs:362:31 + | +362 | let bad_boxed_slice = boxed_slice.iter().nth(3); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_nth)] implied by #[deny(clippy)] + +error: called `.iter().nth()` on a VecDeque. Calling `.get()` is both faster and more readable + --> $DIR/methods.rs:364:29 + | +364 | let bad_vec_deque = some_vec_deque.iter().nth(3); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_nth)] implied by #[deny(clippy)] + +error: called `.iter_mut().nth()` on a Vec. Calling `.get_mut()` is both faster and more readable + --> $DIR/methods.rs:370:23 + | +370 | let bad_vec = some_vec.iter_mut().nth(3); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_nth)] implied by #[deny(clippy)] + +error: called `.iter_mut().nth()` on a slice. Calling `.get_mut()` is both faster and more readable + --> $DIR/methods.rs:374:26 + | +374 | let bad_slice = &some_vec[..].iter_mut().nth(3); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_nth)] implied by #[deny(clippy)] + +error: called `.iter_mut().nth()` on a VecDeque. Calling `.get_mut()` is both faster and more readable + --> $DIR/methods.rs:378:29 + | +378 | let bad_vec_deque = some_vec_deque.iter_mut().nth(3); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_nth)] implied by #[deny(clippy)] + +error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` + --> $DIR/methods.rs:392:13 + | +392 | let _ = some_vec.iter().skip(42).next(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_skip_next)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + +error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` + --> $DIR/methods.rs:395:13 + | +395 | let _ = some_vec.iter().cycle().skip(42).next(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_skip_next)] implied by #[deny(clippy)] + +error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` + --> $DIR/methods.rs:398:13 + | +398 | let _ = (1..10).skip(10).next(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_skip_next)] implied by #[deny(clippy)] + +error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)` + --> $DIR/methods.rs:401:14 + | +401 | let _ = &some_vec[..].iter().skip(3).next(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(iter_skip_next)] implied by #[deny(clippy)] + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/methods.rs:429:17 + | +429 | let _ = boxed_slice.get(1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ +help: try this + | let _ = &boxed_slice[1]; + +error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/methods.rs:433:17 + | +433 | let _ = some_slice.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | let _ = &some_slice[0]; + +error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise + --> $DIR/methods.rs:437:17 + | +437 | let _ = some_vec.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | let _ = &some_vec[0]; + +error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise + --> $DIR/methods.rs:441:17 + | +441 | let _ = some_vecdeque.get(0).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | let _ = &some_vecdeque[0]; + +error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise + --> $DIR/methods.rs:445:17 + | +445 | let _ = some_hashmap.get(&1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | let _ = &some_hashmap[&1]; + +error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise + --> $DIR/methods.rs:449:17 + | +449 | let _ = some_btreemap.get(&1).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | let _ = &some_btreemap[&1]; + +error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/methods.rs:458:10 + | +458 | *boxed_slice.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | *&mut boxed_slice[0] = 1; + +error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise + --> $DIR/methods.rs:462:10 + | +462 | *some_slice.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | *&mut some_slice[0] = 1; + +error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise + --> $DIR/methods.rs:466:10 + | +466 | *some_vec.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | *&mut some_vec[0] = 1; + +error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise + --> $DIR/methods.rs:470:10 + | +470 | *some_vecdeque.get_mut(0).unwrap() = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(get_unwrap)] implied by #[deny(clippy)] +help: try this + | *&mut some_vecdeque[0] = 1; + +error: used unwrap() on an Option value. If you don't want to handle the None case gracefully, consider using expect() to provide a better panic message + --> $DIR/methods.rs:488:13 + | +488 | let _ = opt.unwrap(); + | ^^^^^^^^^^^^ + | + = note: #[deny(option_unwrap_used)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/methods.rs:5:17 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ + +error: used unwrap() on a Result value. If you don't want to handle the Err case gracefully, consider using expect() to provide a better panic message + --> $DIR/methods.rs:491:13 + | +491 | let _ = res.unwrap(); + | ^^^^^^^^^^^^ + | + = note: #[deny(result_unwrap_used)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/methods.rs:5:17 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ + +error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` + --> $DIR/methods.rs:493:5 + | +493 | res.ok().expect("disaster!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(ok_expect)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + +error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` + --> $DIR/methods.rs:499:5 + | +499 | res3.ok().expect("whoof"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(ok_expect)] implied by #[deny(clippy)] + +error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` + --> $DIR/methods.rs:501:5 + | +501 | res4.ok().expect("argh"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(ok_expect)] implied by #[deny(clippy)] + +error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` + --> $DIR/methods.rs:503:5 + | +503 | res5.ok().expect("oops"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(ok_expect)] implied by #[deny(clippy)] + +error: called `ok().expect()` on a Result value. You can call `expect` directly on the `Result` + --> $DIR/methods.rs:505:5 + | +505 | res6.ok().expect("meh"); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(ok_expect)] implied by #[deny(clippy)] + +error: you should use the `starts_with` method + --> $DIR/methods.rs:517:5 + | +517 | "".chars().next() == Some(' '); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(chars_next_cmp)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ +help: like this + | "".starts_with(' '); + +error: you should use the `starts_with` method + --> $DIR/methods.rs:522:5 + | +522 | Some(' ') != "".chars().next(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(chars_next_cmp)] implied by #[deny(clippy)] +help: like this + | !"".starts_with(' '); + +error: calling `.extend(_.chars())` + --> $DIR/methods.rs:534:5 + | +534 | s.extend(abc.chars()); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(string_extend_chars)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ +help: try this + | s.push_str(abc); + +error: calling `.extend(_.chars())` + --> $DIR/methods.rs:540:5 + | +540 | s.extend("abc".chars()); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(string_extend_chars)] implied by #[deny(clippy)] +help: try this + | s.push_str("abc"); + +error: calling `.extend(_.chars())` + --> $DIR/methods.rs:546:5 + | +546 | s.extend(def.chars()); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(string_extend_chars)] implied by #[deny(clippy)] +help: try this + | s.push_str(&def); + +error: using `clone` on a `Copy` type + --> $DIR/methods.rs:560:5 + | +560 | 42.clone(); + | ^^^^^^^^^^ + | + = note: #[deny(clone_on_copy)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ +help: try removing the `clone` call + | 42; + +error: using `clone` on a `Copy` type + --> $DIR/methods.rs:565:5 + | +565 | (&42).clone(); + | ^^^^^^^^^^^^^ + | + = note: #[deny(clone_on_copy)] implied by #[deny(clippy)] +help: try dereferencing it + | *(&42); + +error: using `clone` on a `Copy` type + --> $DIR/methods.rs:571:5 + | +571 | t.clone(); + | ^^^^^^^^^ + | + = note: #[deny(clone_on_copy)] implied by #[deny(clippy)] +help: try removing the `clone` call + | t; + +error: using `clone` on a `Copy` type + --> $DIR/methods.rs:574:5 + | +574 | Some(t).clone(); + | ^^^^^^^^^^^^^^^ + | + = note: #[deny(clone_on_copy)] implied by #[deny(clippy)] +help: try removing the `clone` call + | Some(t); + +error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type + --> $DIR/methods.rs:582:22 + | +582 | let z: &Vec<_> = y.clone(); + | ^^^^^^^^^ + | + = note: #[deny(clone_double_ref)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ +help: try dereferencing it + | let z: &Vec<_> = (*y).clone(); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:590:13 + | +590 | x.split("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ +help: try using a char instead: + | x.split('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:614:16 + | +614 | x.contains("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.contains('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:618:19 + | +618 | x.starts_with("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.starts_with('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:622:17 + | +622 | x.ends_with("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.ends_with('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:626:12 + | +626 | x.find("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.find('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:630:13 + | +630 | x.rfind("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.rfind('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:634:14 + | +634 | x.rsplit("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.rsplit('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:638:24 + | +638 | x.split_terminator("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.split_terminator('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:642:25 + | +642 | x.rsplit_terminator("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.rsplit_terminator('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:646:17 + | +646 | x.splitn(0, "x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.splitn(0, 'x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:650:18 + | +650 | x.rsplitn(0, "x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.rsplitn(0, 'x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:654:15 + | +654 | x.matches("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.matches('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:658:16 + | +658 | x.rmatches("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.rmatches('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:662:21 + | +662 | x.match_indices("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.match_indices('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:666:22 + | +666 | x.rmatch_indices("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.rmatch_indices('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:670:25 + | +670 | x.trim_left_matches("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.trim_left_matches('x'); + +error: single-character string constant used as pattern + --> $DIR/methods.rs:674:26 + | +674 | x.trim_right_matches("x"); + | ^^^ + | + = note: #[deny(single_char_pattern)] implied by #[deny(clippy)] +help: try using a char instead: + | x.trim_right_matches('x'); + +error: you are getting the inner pointer of a temporary `CString` + --> $DIR/methods.rs:687:5 + | +687 | CString::new("foo").unwrap().as_ptr(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(temporary_cstring_as_ptr)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/methods.rs:5:9 + | +5 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^ + = note: that pointer will be invalid outside this expression +help: assign the `CString` to a variable to extend its lifetime + --> $DIR/methods.rs:687:5 + | +687 | CString::new("foo").unwrap().as_ptr(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 88 previous errors + diff --git a/tests/ui/min_max.rs b/tests/ui/min_max.rs new file mode 100644 index 000000000000..d74e52732633 --- /dev/null +++ b/tests/ui/min_max.rs @@ -0,0 +1,33 @@ +#![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)); + min(max(3, x), 1); + max(min(x, 1), 3); + max(3, min(x, 1)); + + my_max(3, my_min(x, 1)); + + 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)); + max(min(s, "Apple"), "Zoo"); + + max("Apple", min(s, "Zoo")); // ok +} diff --git a/tests/ui/min_max.stderr b/tests/ui/min_max.stderr new file mode 100644 index 000000000000..1170373ab985 --- /dev/null +++ b/tests/ui/min_max.stderr @@ -0,0 +1,63 @@ +error: this min/max combination leads to constant result + --> $DIR/min_max.rs:15:5 + | +15 | min(1, max(3, x)); + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(min_max)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/min_max.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + +error: this min/max combination leads to constant result + --> $DIR/min_max.rs:16:5 + | +16 | min(max(3, x), 1); + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(min_max)] implied by #[deny(clippy)] + +error: this min/max combination leads to constant result + --> $DIR/min_max.rs:17:5 + | +17 | max(min(x, 1), 3); + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(min_max)] implied by #[deny(clippy)] + +error: this min/max combination leads to constant result + --> $DIR/min_max.rs:18:5 + | +18 | max(3, min(x, 1)); + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(min_max)] implied by #[deny(clippy)] + +error: this min/max combination leads to constant result + --> $DIR/min_max.rs:20:5 + | +20 | my_max(3, my_min(x, 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(min_max)] implied by #[deny(clippy)] + +error: this min/max combination leads to constant result + --> $DIR/min_max.rs:29:5 + | +29 | min("Apple", max("Zoo", s)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(min_max)] implied by #[deny(clippy)] + +error: this min/max combination leads to constant result + --> $DIR/min_max.rs:30:5 + | +30 | max(min(s, "Apple"), "Zoo"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(min_max)] implied by #[deny(clippy)] + +error: aborting due to 7 previous errors + diff --git a/tests/compile-fail/missing-doc.rs b/tests/ui/missing-doc.rs similarity index 51% rename from tests/compile-fail/missing-doc.rs rename to tests/ui/missing-doc.rs index acd86f18ea3d..cd69ef1b08ec 100644 --- a/tests/compile-fail/missing-doc.rs +++ b/tests/ui/missing-doc.rs @@ -23,17 +23,17 @@ //! Some garbage docs for the crate here #![doc="More garbage"] -type Typedef = String; //~ ERROR: missing documentation for a type alias -pub type PubTypedef = String; //~ ERROR: missing documentation for a type alias +type Typedef = String; +pub type PubTypedef = String; -struct Foo { //~ ERROR: missing documentation for a struct - a: isize, //~ ERROR: missing documentation for a struct field - b: isize, //~ ERROR: missing documentation for a struct field +struct Foo { + a: isize, + b: isize, } -pub struct PubFoo { //~ ERROR: missing documentation for a struct - pub a: isize, //~ ERROR: missing documentation for a struct field - b: isize, //~ ERROR: missing documentation for a struct field +pub struct PubFoo { + pub a: isize, + b: isize, } #[allow(missing_docs_in_private_items)] @@ -42,13 +42,13 @@ pub struct PubFoo2 { pub c: isize, } -mod module_no_dox {} //~ ERROR: missing documentation for a module -pub mod pub_module_no_dox {} //~ ERROR: missing documentation for a module +mod module_no_dox {} +pub mod pub_module_no_dox {} /// dox pub fn foo() {} -pub fn foo2() {} //~ ERROR: missing documentation for a function -fn foo3() {} //~ ERROR: missing documentation for a function +pub fn foo2() {} +fn foo3() {} #[allow(missing_docs_in_private_items)] pub fn foo4() {} /// dox @@ -65,9 +65,9 @@ trait B { fn foo_with_impl(&self) {} } -pub trait C { //~ ERROR: missing documentation for a trait - fn foo(&self); //~ ERROR: missing documentation for a trait method - fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a trait method +pub trait C { + fn foo(&self); + fn foo_with_impl(&self) {} } #[allow(missing_docs_in_private_items)] @@ -77,8 +77,8 @@ pub trait D { /// dox pub trait E { - type AssociatedType; //~ ERROR: missing documentation for an associated type - type AssociatedTypeDef = Self; //~ ERROR: missing documentation for an associated type + type AssociatedType; + type AssociatedTypeDef = Self; /// dox type DocumentedType; @@ -89,15 +89,15 @@ pub trait E { } impl Foo { - pub fn foo() {} //~ ERROR: missing documentation for a method - fn bar() {} //~ ERROR: missing documentation for a method + pub fn foo() {} + fn bar() {} } impl PubFoo { - pub fn foo() {} //~ ERROR: missing documentation for a method + pub fn foo() {} /// dox pub fn foo1() {} - fn foo2() {} //~ ERROR: missing documentation for a method + fn foo2() {} #[allow(missing_docs_in_private_items)] pub fn foo3() {} } @@ -123,17 +123,17 @@ mod a { } } -enum Baz { //~ ERROR: missing documentation for an enum - BazA { //~ ERROR: missing documentation for a variant - a: isize, //~ ERROR: missing documentation for a struct field - b: isize //~ ERROR: missing documentation for a struct field +enum Baz { + BazA { + a: isize, + b: isize }, - BarB //~ ERROR: missing documentation for a variant + BarB } -pub enum PubBaz { //~ ERROR: missing documentation for an enum - PubBazA { //~ ERROR: missing documentation for a variant - a: isize, //~ ERROR: missing documentation for a struct field +pub enum PubBaz { + PubBazA { + a: isize, }, } @@ -157,38 +157,38 @@ pub enum PubBaz3 { pub fn baz() {} -const FOO: u32 = 0; //~ ERROR: missing documentation for a const +const FOO: u32 = 0; /// dox pub const FOO1: u32 = 0; #[allow(missing_docs_in_private_items)] pub const FOO2: u32 = 0; #[doc(hidden)] pub const FOO3: u32 = 0; -pub const FOO4: u32 = 0; //~ ERROR: missing documentation for a const +pub const FOO4: u32 = 0; -static BAR: u32 = 0; //~ ERROR: missing documentation for a static +static BAR: u32 = 0; /// dox pub static BAR1: u32 = 0; #[allow(missing_docs_in_private_items)] pub static BAR2: u32 = 0; #[doc(hidden)] pub static BAR3: u32 = 0; -pub static BAR4: u32 = 0; //~ ERROR: missing documentation for a static +pub static BAR4: u32 = 0; -mod internal_impl { //~ ERROR: missing documentation for a module +mod internal_impl { /// dox pub fn documented() {} - pub fn undocumented1() {} //~ ERROR: missing documentation for a function - pub fn undocumented2() {} //~ ERROR: missing documentation for a function - fn undocumented3() {} //~ ERROR: missing documentation for a function + pub fn undocumented1() {} + pub fn undocumented2() {} + fn undocumented3() {} /// dox pub mod globbed { /// dox pub fn also_documented() {} - pub fn also_undocumented1() {} //~ ERROR: missing documentation for a function - fn also_undocumented2() {} //~ ERROR: missing documentation for a function + pub fn also_undocumented1() {} + fn also_undocumented2() {} } } /// dox @@ -199,4 +199,4 @@ pub mod public_interface { pub use internal_impl::globbed::*; } -fn main() {} //~ ERROR: missing documentation for a function +fn main() {} diff --git a/tests/ui/missing-doc.stderr b/tests/ui/missing-doc.stderr new file mode 100644 index 000000000000..6e3a146ee2d3 --- /dev/null +++ b/tests/ui/missing-doc.stderr @@ -0,0 +1,279 @@ +error: missing documentation for a type alias + --> $DIR/missing-doc.rs:26:1 + | +26 | type Typedef = String; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/missing-doc.rs:16:9 + | +16 | #![deny(missing_docs_in_private_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a type alias + --> $DIR/missing-doc.rs:27:1 + | +27 | pub type PubTypedef = String; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a struct + --> $DIR/missing-doc.rs:29:1 + | +29 | struct Foo { + | _^ starting here... +30 | | a: isize, +31 | | b: isize, +32 | | } + | |_^ ...ending here + +error: missing documentation for a struct field + --> $DIR/missing-doc.rs:30:5 + | +30 | a: isize, + | ^^^^^^^^ + +error: missing documentation for a struct field + --> $DIR/missing-doc.rs:31:5 + | +31 | b: isize, + | ^^^^^^^^ + +error: missing documentation for a struct + --> $DIR/missing-doc.rs:34:1 + | +34 | pub struct PubFoo { + | _^ starting here... +35 | | pub a: isize, +36 | | b: isize, +37 | | } + | |_^ ...ending here + +error: missing documentation for a struct field + --> $DIR/missing-doc.rs:35:5 + | +35 | pub a: isize, + | ^^^^^^^^^^^^ + +error: missing documentation for a struct field + --> $DIR/missing-doc.rs:36:5 + | +36 | b: isize, + | ^^^^^^^^ + +error: missing documentation for a module + --> $DIR/missing-doc.rs:45:1 + | +45 | mod module_no_dox {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a module + --> $DIR/missing-doc.rs:46:1 + | +46 | pub mod pub_module_no_dox {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:50:1 + | +50 | pub fn foo2() {} + | ^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:51:1 + | +51 | fn foo3() {} + | ^^^^^^^^^^^^ + +error: missing documentation for a trait + --> $DIR/missing-doc.rs:68:1 + | +68 | pub trait C { + | _^ starting here... +69 | | fn foo(&self); +70 | | fn foo_with_impl(&self) {} +71 | | } + | |_^ ...ending here + +error: missing documentation for a trait method + --> $DIR/missing-doc.rs:69:5 + | +69 | fn foo(&self); + | ^^^^^^^^^^^^^^ + +error: missing documentation for a trait method + --> $DIR/missing-doc.rs:70:5 + | +70 | fn foo_with_impl(&self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for an associated type + --> $DIR/missing-doc.rs:80:5 + | +80 | type AssociatedType; + | ^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for an associated type + --> $DIR/missing-doc.rs:81:5 + | +81 | type AssociatedTypeDef = Self; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a method + --> $DIR/missing-doc.rs:92:5 + | +92 | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a method + --> $DIR/missing-doc.rs:93:5 + | +93 | fn bar() {} + | ^^^^^^^^^^^ + +error: missing documentation for a method + --> $DIR/missing-doc.rs:97:5 + | +97 | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + +error: missing documentation for a method + --> $DIR/missing-doc.rs:100:5 + | +100 | fn foo2() {} + | ^^^^^^^^^^^^ + +error: missing documentation for an enum + --> $DIR/missing-doc.rs:126:1 + | +126 | enum Baz { + | _^ starting here... +127 | | BazA { +128 | | a: isize, +129 | | b: isize +130 | | }, +131 | | BarB +132 | | } + | |_^ ...ending here + +error: missing documentation for a variant + --> $DIR/missing-doc.rs:127:5 + | +127 | BazA { + | _____^ starting here... +128 | | a: isize, +129 | | b: isize +130 | | }, + | |_____^ ...ending here + +error: missing documentation for a struct field + --> $DIR/missing-doc.rs:128:9 + | +128 | a: isize, + | ^^^^^^^^ + +error: missing documentation for a struct field + --> $DIR/missing-doc.rs:129:9 + | +129 | b: isize + | ^^^^^^^^ + +error: missing documentation for a variant + --> $DIR/missing-doc.rs:131:5 + | +131 | BarB + | ^^^^ + +error: missing documentation for an enum + --> $DIR/missing-doc.rs:134:1 + | +134 | pub enum PubBaz { + | _^ starting here... +135 | | PubBazA { +136 | | a: isize, +137 | | }, +138 | | } + | |_^ ...ending here + +error: missing documentation for a variant + --> $DIR/missing-doc.rs:135:5 + | +135 | PubBazA { + | _____^ starting here... +136 | | a: isize, +137 | | }, + | |_____^ ...ending here + +error: missing documentation for a struct field + --> $DIR/missing-doc.rs:136:9 + | +136 | a: isize, + | ^^^^^^^^ + +error: missing documentation for a constant + --> $DIR/missing-doc.rs:160:1 + | +160 | const FOO: u32 = 0; + | ^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a constant + --> $DIR/missing-doc.rs:167:1 + | +167 | pub const FOO4: u32 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a static + --> $DIR/missing-doc.rs:170:1 + | +170 | static BAR: u32 = 0; + | ^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a static + --> $DIR/missing-doc.rs:177:1 + | +177 | pub static BAR4: u32 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a module + --> $DIR/missing-doc.rs:180:1 + | +180 | mod internal_impl { + | ^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:183:5 + | +183 | pub fn undocumented1() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:184:5 + | +184 | pub fn undocumented2() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:185:5 + | +185 | fn undocumented3() {} + | ^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:190:9 + | +190 | pub fn also_undocumented1() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:191:9 + | +191 | fn also_undocumented2() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing documentation for a function + --> $DIR/missing-doc.rs:202:1 + | +202 | fn main() {} + | ^^^^^^^^^^^^ + +error: aborting due to 40 previous errors + diff --git a/tests/compile-fail/module_inception.rs b/tests/ui/module_inception.rs similarity index 68% rename from tests/compile-fail/module_inception.rs rename to tests/ui/module_inception.rs index 861ed504c86e..f102057c1daf 100644 --- a/tests/compile-fail/module_inception.rs +++ b/tests/ui/module_inception.rs @@ -4,12 +4,12 @@ mod foo { mod bar { - mod bar { //~ ERROR module has the same name as its containing module + mod bar { mod foo {} } mod foo {} } - mod foo { //~ ERROR module has the same name as its containing module + mod foo { mod bar {} } } diff --git a/tests/ui/module_inception.stderr b/tests/ui/module_inception.stderr new file mode 100644 index 000000000000..b61b8557ac01 --- /dev/null +++ b/tests/ui/module_inception.stderr @@ -0,0 +1,26 @@ +error: module has the same name as its containing module + --> $DIR/module_inception.rs:7:9 + | +7 | mod bar { + | _________^ starting here... +8 | | mod foo {} +9 | | } + | |_________^ ...ending here + | +note: lint level defined here + --> $DIR/module_inception.rs:3:9 + | +3 | #![deny(module_inception)] + | ^^^^^^^^^^^^^^^^ + +error: module has the same name as its containing module + --> $DIR/module_inception.rs:12:5 + | +12 | mod foo { + | _____^ starting here... +13 | | mod bar {} +14 | | } + | |_____^ ...ending here + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/modulo_one.rs b/tests/ui/modulo_one.rs similarity index 71% rename from tests/compile-fail/modulo_one.rs rename to tests/ui/modulo_one.rs index 496c1c60d5f1..d9ab7492eadc 100644 --- a/tests/compile-fail/modulo_one.rs +++ b/tests/ui/modulo_one.rs @@ -4,6 +4,6 @@ #![allow(no_effect, unnecessary_operation)] fn main() { - 10 % 1; //~ERROR any number modulo 1 will be 0 + 10 % 1; 10 % 2; } diff --git a/tests/ui/modulo_one.stderr b/tests/ui/modulo_one.stderr new file mode 100644 index 000000000000..2e5aef675743 --- /dev/null +++ b/tests/ui/modulo_one.stderr @@ -0,0 +1,14 @@ +error: any number modulo 1 will be 0 + --> $DIR/modulo_one.rs:7:5 + | +7 | 10 % 1; + | ^^^^^^ + | +note: lint level defined here + --> $DIR/modulo_one.rs:3:9 + | +3 | #![deny(modulo_one)] + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/mut_mut.rs b/tests/ui/mut_mut.rs new file mode 100644 index 000000000000..457a79152efd --- /dev/null +++ b/tests/ui/mut_mut.rs @@ -0,0 +1,64 @@ +#![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 { + **x > 0 +} + +fn less_fun(x : *mut *mut u32) { + let y = x; +} + +macro_rules! mut_ptr { + ($p:expr) => { &mut $p } + +} + +#[allow(unused_mut, unused_variables)] +fn main() { + let mut x = &mut &mut 1u32; + { + let mut y = &mut x; + } + + if fun(x) { + let y : &mut &mut u32 = &mut &mut 2; + + + + **y + **x; + } + + if fun(x) { + let y : &mut &mut &mut u32 = &mut &mut &mut 2; + + + + + + + ***y + **x; + } + + let mut z = mut_ptr!(&mut 3u32); + +} + +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); + } +} diff --git a/tests/ui/mut_mut.stderr b/tests/ui/mut_mut.stderr new file mode 100644 index 000000000000..2149d3d88240 --- /dev/null +++ b/tests/ui/mut_mut.stderr @@ -0,0 +1,89 @@ +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:10:12 + | +10 | fn fun(x : &mut &mut u32) -> bool { + | ^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/mut_mut.rs:5:9 + | +5 | #![deny(mut_mut)] + | ^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:25:17 + | +25 | let mut x = &mut &mut 1u32; + | ^^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:19:20 + | +19 | ($p:expr) => { &mut $p } + | ^^^^^^^ +... +49 | let mut z = mut_ptr!(&mut 3u32); + | ------------------- in this macro invocation + +error: this expression mutably borrows a mutable reference. Consider reborrowing + --> $DIR/mut_mut.rs:27:21 + | +27 | let mut y = &mut x; + | ^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:31:17 + | +31 | let y : &mut &mut u32 = &mut &mut 2; + | ^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:31:33 + | +31 | let y : &mut &mut u32 = &mut &mut 2; + | ^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:31:17 + | +31 | let y : &mut &mut u32 = &mut &mut 2; + | ^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:39:17 + | +39 | let y : &mut &mut &mut u32 = &mut &mut &mut 2; + | ^^^^^^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:39:22 + | +39 | let y : &mut &mut &mut u32 = &mut &mut &mut 2; + | ^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:39:38 + | +39 | let y : &mut &mut &mut u32 = &mut &mut &mut 2; + | ^^^^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:39:17 + | +39 | let y : &mut &mut &mut u32 = &mut &mut &mut 2; + | ^^^^^^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:39:22 + | +39 | let y : &mut &mut &mut u32 = &mut &mut &mut 2; + | ^^^^^^^^^^^^^ + +error: generally you want to avoid `&mut &mut _` if possible + --> $DIR/mut_mut.rs:39:22 + | +39 | let y : &mut &mut &mut u32 = &mut &mut &mut 2; + | ^^^^^^^^^^^^^ + +error: aborting due to 13 previous errors + diff --git a/tests/compile-fail/mut_reference.rs b/tests/ui/mut_reference.rs similarity index 72% rename from tests/compile-fail/mut_reference.rs rename to tests/ui/mut_reference.rs index 0bb59a318b83..a3b9a965ec4c 100644 --- a/tests/compile-fail/mut_reference.rs +++ b/tests/ui/mut_reference.rs @@ -19,13 +19,13 @@ impl MyStruct { #[deny(unnecessary_mut_passed)] fn main() { // Functions - takes_an_immutable_reference(&mut 42); //~ERROR The function/method "takes_an_immutable_reference" doesn't need a mutable reference + takes_an_immutable_reference(&mut 42); let as_ptr: fn(&i32) = takes_an_immutable_reference; - as_ptr(&mut 42); //~ERROR The function/method "as_ptr" doesn't need a mutable reference + as_ptr(&mut 42); // Methods let my_struct = MyStruct; - my_struct.takes_an_immutable_reference(&mut 42); //~ERROR The function/method "takes_an_immutable_reference" doesn't need a mutable reference + my_struct.takes_an_immutable_reference(&mut 42); // No error diff --git a/tests/ui/mut_reference.stderr b/tests/ui/mut_reference.stderr new file mode 100644 index 000000000000..f4c2b60746ea --- /dev/null +++ b/tests/ui/mut_reference.stderr @@ -0,0 +1,26 @@ +error: The function/method "takes_an_immutable_reference" doesn't need a mutable reference + --> $DIR/mut_reference.rs:22:34 + | +22 | takes_an_immutable_reference(&mut 42); + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/mut_reference.rs:19:8 + | +19 | #[deny(unnecessary_mut_passed)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: The function/method "as_ptr" doesn't need a mutable reference + --> $DIR/mut_reference.rs:24:12 + | +24 | as_ptr(&mut 42); + | ^^^^^^^ + +error: The function/method "takes_an_immutable_reference" doesn't need a mutable reference + --> $DIR/mut_reference.rs:28:44 + | +28 | my_struct.takes_an_immutable_reference(&mut 42); + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/mutex_atomic.rs b/tests/ui/mutex_atomic.rs new file mode 100644 index 000000000000..5a5289c2cf48 --- /dev/null +++ b/tests/ui/mutex_atomic.rs @@ -0,0 +1,18 @@ +#![feature(plugin)] + +#![plugin(clippy)] +#![deny(clippy)] +#![deny(mutex_integer)] + +fn main() { + use std::sync::Mutex; + Mutex::new(true); + Mutex::new(5usize); + Mutex::new(9isize); + let mut x = 4u32; + Mutex::new(&x as *const u32); + Mutex::new(&mut x as *mut u32); + Mutex::new(0u32); + Mutex::new(0i32); + Mutex::new(0f32); // there are no float atomics, so this should not lint +} diff --git a/tests/ui/mutex_atomic.stderr b/tests/ui/mutex_atomic.stderr new file mode 100644 index 000000000000..6a61c42cbe2d --- /dev/null +++ b/tests/ui/mutex_atomic.stderr @@ -0,0 +1,65 @@ +error: Consider using an AtomicBool instead of a Mutex here. If you just want the locking behaviour and not the internal type, consider using Mutex<()>. + --> $DIR/mutex_atomic.rs:9:5 + | +9 | Mutex::new(true); + | ^^^^^^^^^^^^^^^^ + | + = note: #[deny(mutex_atomic)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/mutex_atomic.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + +error: Consider using an AtomicUsize instead of a Mutex here. If you just want the locking behaviour and not the internal type, consider using Mutex<()>. + --> $DIR/mutex_atomic.rs:10:5 + | +10 | Mutex::new(5usize); + | ^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(mutex_atomic)] implied by #[deny(clippy)] + +error: Consider using an AtomicIsize instead of a Mutex here. If you just want the locking behaviour and not the internal type, consider using Mutex<()>. + --> $DIR/mutex_atomic.rs:11:5 + | +11 | Mutex::new(9isize); + | ^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(mutex_atomic)] implied by #[deny(clippy)] + +error: Consider using an AtomicPtr instead of a Mutex here. If you just want the locking behaviour and not the internal type, consider using Mutex<()>. + --> $DIR/mutex_atomic.rs:13:5 + | +13 | Mutex::new(&x as *const u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(mutex_atomic)] implied by #[deny(clippy)] + +error: Consider using an AtomicPtr instead of a Mutex here. If you just want the locking behaviour and not the internal type, consider using Mutex<()>. + --> $DIR/mutex_atomic.rs:14:5 + | +14 | Mutex::new(&mut x as *mut u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(mutex_atomic)] implied by #[deny(clippy)] + +error: Consider using an AtomicUsize instead of a Mutex here. If you just want the locking behaviour and not the internal type, consider using Mutex<()>. + --> $DIR/mutex_atomic.rs:15:5 + | +15 | Mutex::new(0u32); + | ^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/mutex_atomic.rs:5:9 + | +5 | #![deny(mutex_integer)] + | ^^^^^^^^^^^^^ + +error: Consider using an AtomicIsize instead of a Mutex here. If you just want the locking behaviour and not the internal type, consider using Mutex<()>. + --> $DIR/mutex_atomic.rs:16:5 + | +16 | Mutex::new(0i32); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/tests/ui/needless_bool.rs b/tests/ui/needless_bool.rs new file mode 100644 index 000000000000..ebbff1454822 --- /dev/null +++ b/tests/ui/needless_bool.rs @@ -0,0 +1,74 @@ +#![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 }; + if x { false } else { false }; + if x { true } else { false }; + + + + if x { false } else { true }; + + + + if x && y { false } else { true }; + + + + 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 }; + +} + +#[allow(if_same_then_else, needless_return)] +fn bool_ret2(x: bool) -> bool { + if x { return false } else { return false }; + +} + +#[allow(needless_return)] +fn bool_ret3(x: bool) -> bool { + if x { return true } else { return false }; + + + +} + +#[allow(needless_return)] +fn bool_ret5(x: bool, y: bool) -> bool { + if x && y { return true } else { return false }; + + + +} + +#[allow(needless_return)] +fn bool_ret4(x: bool) -> bool { + if x { return false } else { return true }; + + + +} + +#[allow(needless_return)] +fn bool_ret6(x: bool, y: bool) -> bool { + if x && y { return false } else { return true }; + + + +} diff --git a/tests/ui/needless_bool.stderr b/tests/ui/needless_bool.stderr new file mode 100644 index 000000000000..930a3cba514d --- /dev/null +++ b/tests/ui/needless_bool.stderr @@ -0,0 +1,95 @@ +error: this if-then-else expression will always return true + --> $DIR/needless_bool.rs:9:5 + | +9 | if x { true } else { true }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/needless_bool.rs:3:9 + | +3 | #![deny(needless_bool)] + | ^^^^^^^^^^^^^ + +error: this if-then-else expression will always return false + --> $DIR/needless_bool.rs:10:5 + | +10 | if x { false } else { false }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this if-then-else expression returns a bool literal + --> $DIR/needless_bool.rs:11:5 + | +11 | if x { true } else { false }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can reduce it to + | x; + +error: this if-then-else expression returns a bool literal + --> $DIR/needless_bool.rs:15:5 + | +15 | if x { false } else { true }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can reduce it to + | !x; + +error: this if-then-else expression returns a bool literal + --> $DIR/needless_bool.rs:19:5 + | +19 | if x && y { false } else { true }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can reduce it to + | !(x && y); + +error: this if-then-else expression will always return true + --> $DIR/needless_bool.rs:34:5 + | +34 | if x { return true } else { return true }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this if-then-else expression will always return false + --> $DIR/needless_bool.rs:40:5 + | +40 | if x { return false } else { return false }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this if-then-else expression returns a bool literal + --> $DIR/needless_bool.rs:46:5 + | +46 | if x { return true } else { return false }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can reduce it to + | return x; + +error: this if-then-else expression returns a bool literal + --> $DIR/needless_bool.rs:54:5 + | +54 | if x && y { return true } else { return false }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can reduce it to + | return x && y; + +error: this if-then-else expression returns a bool literal + --> $DIR/needless_bool.rs:62:5 + | +62 | if x { return false } else { return true }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can reduce it to + | return !x; + +error: this if-then-else expression returns a bool literal + --> $DIR/needless_bool.rs:70:5 + | +70 | if x && y { return false } else { return true }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can reduce it to + | return !(x && y); + +error: aborting due to 11 previous errors + diff --git a/tests/compile-fail/needless_borrow.rs b/tests/ui/needless_borrow.rs similarity index 77% rename from tests/compile-fail/needless_borrow.rs rename to tests/ui/needless_borrow.rs index 77992252e102..1fc36c0be185 100644 --- a/tests/compile-fail/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -10,14 +10,14 @@ fn x(y: &i32) -> i32 { fn main() { let a = 5; let b = x(&a); - let c = x(&&a); //~ ERROR: this expression borrows a reference that is immediately dereferenced by the compiler + let c = x(&&a); let s = &String::from("hi"); let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not let g_val = g(&Vec::new()); // should not error, because `&Vec` derefs to `&[T]` let vec = Vec::new(); let vec_val = g(&vec); // should not error, because `&Vec` derefs to `&[T]` h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait` - if let Some(ref cake) = Some(&5) {} //~ ERROR: this pattern creates a reference to a reference + if let Some(ref cake) = Some(&5) {} } fn f(y: &T) -> T { @@ -39,6 +39,6 @@ fn issue_1432() { let mut v = Vec::::new(); let _ = v.iter_mut().filter(|&ref a| a.is_empty()); let _ = v.iter().filter(|&ref a| a.is_empty()); - //~^WARNING this pattern creates a reference to a reference + let _ = v.iter().filter(|&a| a.is_empty()); } diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr new file mode 100644 index 000000000000..a5d549c986b5 --- /dev/null +++ b/tests/ui/needless_borrow.stderr @@ -0,0 +1,31 @@ +error: this expression borrows a reference that is immediately dereferenced by the compiler + --> $DIR/needless_borrow.rs:13:15 + | +13 | let c = x(&&a); + | ^^^ + | + = note: #[deny(needless_borrow)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/needless_borrow.rs:8:8 + | +8 | #[deny(clippy)] + | ^^^^^^ + +error: this pattern creates a reference to a reference + --> $DIR/needless_borrow.rs:20:17 + | +20 | if let Some(ref cake) = Some(&5) {} + | ^^^^^^^^ + | + = note: #[deny(needless_borrow)] implied by #[deny(clippy)] + +warning: this pattern creates a reference to a reference + --> $DIR/needless_borrow.rs:41:31 + | +41 | let _ = v.iter().filter(|&ref a| a.is_empty()); + | ^^^^^ + | + = note: #[warn(needless_borrow)] on by default + +error: aborting due to 2 previous errors + diff --git a/tests/ui/needless_return.rs b/tests/ui/needless_return.rs new file mode 100644 index 000000000000..2751089bddad --- /dev/null +++ b/tests/ui/needless_return.rs @@ -0,0 +1,73 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#![deny(needless_return)] + +fn test_end_of_fn() -> bool { + if true { + // no error! + return true; + } + return true; + + + +} + +fn test_no_semicolon() -> bool { + return true + + + +} + +fn test_if_block() -> bool { + if true { + return true; + + + + } else { + return false; + + + + } +} + +fn test_match(x: bool) -> bool { + match x { + true => return false, + + + + + false => { + return true; + + + + } + } +} + +fn test_closure() { + let _ = || { + return true; + + + + }; + let _ = || return true; + + + +} + +fn main() { + let _ = test_end_of_fn(); + let _ = test_no_semicolon(); + let _ = test_if_block(); + let _ = test_match(true); + test_closure(); +} diff --git a/tests/ui/needless_return.stderr b/tests/ui/needless_return.stderr new file mode 100644 index 000000000000..0d9f5f9a57da --- /dev/null +++ b/tests/ui/needless_return.stderr @@ -0,0 +1,79 @@ +error: unneeded return statement + --> $DIR/needless_return.rs:11:5 + | +11 | return true; + | ^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/needless_return.rs:4:9 + | +4 | #![deny(needless_return)] + | ^^^^^^^^^^^^^^^ +help: remove `return` as shown: + | true + +error: unneeded return statement + --> $DIR/needless_return.rs:18:5 + | +18 | return true + | ^^^^^^^^^^^ + | +help: remove `return` as shown: + | true + +error: unneeded return statement + --> $DIR/needless_return.rs:26:9 + | +26 | return true; + | ^^^^^^^^^^^^ + | +help: remove `return` as shown: + | true + +error: unneeded return statement + --> $DIR/needless_return.rs:31:9 + | +31 | return false; + | ^^^^^^^^^^^^^ + | +help: remove `return` as shown: + | false + +error: unneeded return statement + --> $DIR/needless_return.rs:40:17 + | +40 | true => return false, + | ^^^^^^^^^^^^ + | +help: remove `return` as shown: + | true => false, + +error: unneeded return statement + --> $DIR/needless_return.rs:46:13 + | +46 | return true; + | ^^^^^^^^^^^^ + | +help: remove `return` as shown: + | true + +error: unneeded return statement + --> $DIR/needless_return.rs:56:9 + | +56 | return true; + | ^^^^^^^^^^^^ + | +help: remove `return` as shown: + | true + +error: unneeded return statement + --> $DIR/needless_return.rs:61:16 + | +61 | let _ = || return true; + | ^^^^^^^^^^^ + | +help: remove `return` as shown: + | let _ = || true; + +error: aborting due to 8 previous errors + diff --git a/tests/compile-fail/needless_update.rs b/tests/ui/needless_update.rs similarity index 78% rename from tests/compile-fail/needless_update.rs rename to tests/ui/needless_update.rs index 55cfed76d5d3..a8eb232f0602 100644 --- a/tests/compile-fail/needless_update.rs +++ b/tests/ui/needless_update.rs @@ -13,5 +13,5 @@ fn main() { let base = S { a: 0, b: 0 }; S { ..base }; // no error S { a: 1, ..base }; // no error - S { a: 1, b: 1, ..base }; //~ERROR struct update has no effect + S { a: 1, b: 1, ..base }; } diff --git a/tests/ui/needless_update.stderr b/tests/ui/needless_update.stderr new file mode 100644 index 000000000000..ab1441508d4c --- /dev/null +++ b/tests/ui/needless_update.stderr @@ -0,0 +1,14 @@ +error: struct update has no effect, all the fields in the struct have already been specified + --> $DIR/needless_update.rs:16:23 + | +16 | S { a: 1, b: 1, ..base }; + | ^^^^ + | +note: lint level defined here + --> $DIR/needless_update.rs:4:9 + | +4 | #![deny(needless_update)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/compile-fail/neg_multiply.rs b/tests/ui/neg_multiply.rs similarity index 83% rename from tests/compile-fail/neg_multiply.rs rename to tests/ui/neg_multiply.rs index 90c63c5f2632..748a2e536098 100644 --- a/tests/compile-fail/neg_multiply.rs +++ b/tests/ui/neg_multiply.rs @@ -28,10 +28,10 @@ fn main() { let x = 0; x * -1; - //~^ ERROR Negation by multiplying with -1 + -1 * x; - //~^ ERROR Negation by multiplying with -1 + -1 * -1; // should be ok diff --git a/tests/ui/neg_multiply.stderr b/tests/ui/neg_multiply.stderr new file mode 100644 index 000000000000..11460a5583fa --- /dev/null +++ b/tests/ui/neg_multiply.stderr @@ -0,0 +1,20 @@ +error: Negation by multiplying with -1 + --> $DIR/neg_multiply.rs:30:5 + | +30 | x * -1; + | ^^^^^^ + | +note: lint level defined here + --> $DIR/neg_multiply.rs:4:9 + | +4 | #![deny(neg_multiply)] + | ^^^^^^^^^^^^ + +error: Negation by multiplying with -1 + --> $DIR/neg_multiply.rs:33:5 + | +33 | -1 * x; + | ^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/new_without_default.rs b/tests/ui/new_without_default.rs similarity index 67% rename from tests/compile-fail/new_without_default.rs rename to tests/ui/new_without_default.rs index 65f6805e1214..a5673b622ba1 100644 --- a/tests/compile-fail/new_without_default.rs +++ b/tests/ui/new_without_default.rs @@ -5,23 +5,23 @@ #![deny(new_without_default, new_without_default_derive)] pub struct Foo; -//~^HELP try this -//~^^SUGGESTION #[derive(Default)] -//~^^SUGGESTION pub struct Foo + + + impl Foo { pub fn new() -> Foo { Foo } - //~^ERROR: you should consider deriving a `Default` implementation for `Foo` + } pub struct Bar; -//~^HELP try this -//~^^SUGGESTION #[derive(Default)] -//~^^SUGGESTION pub struct Bar + + + impl Bar { pub fn new() -> Self { Bar } - //~^ERROR: you should consider deriving a `Default` implementation for `Bar` + } pub struct Ok; @@ -70,13 +70,13 @@ pub struct LtKo<'a> { impl<'c> LtKo<'c> { pub fn new() -> LtKo<'c> { unimplemented!() } - //~^ERROR: you should consider adding a `Default` implementation for - //~^^HELP try - //~^^^SUGGESTION impl Default for LtKo<'c> { - //~^^^SUGGESTION fn default() -> Self { - //~^^^SUGGESTION Self::new() - //~^^^SUGGESTION } - //~^^^SUGGESTION } + + + + + + + // FIXME: that suggestion is missing lifetimes } diff --git a/tests/ui/new_without_default.stderr b/tests/ui/new_without_default.stderr new file mode 100644 index 000000000000..e2b10894af8d --- /dev/null +++ b/tests/ui/new_without_default.stderr @@ -0,0 +1,47 @@ +error: you should consider deriving a `Default` implementation for `Foo` + --> $DIR/new_without_default.rs:13:5 + | +13 | pub fn new() -> Foo { Foo } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/new_without_default.rs:5:30 + | +5 | #![deny(new_without_default, new_without_default_derive)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: try this + | #[derive(Default)] + | pub struct Foo; + +error: you should consider deriving a `Default` implementation for `Bar` + --> $DIR/new_without_default.rs:23:5 + | +23 | pub fn new() -> Self { Bar } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try this + | #[derive(Default)] + | pub struct Bar; + +error: you should consider adding a `Default` implementation for `LtKo<'c>` + --> $DIR/new_without_default.rs:72:5 + | +72 | pub fn new() -> LtKo<'c> { unimplemented!() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/new_without_default.rs:5:9 + | +5 | #![deny(new_without_default, new_without_default_derive)] + | ^^^^^^^^^^^^^^^^^^^ +help: try this + | impl Default for LtKo<'c> { + | fn default() -> Self { + | Self::new() + | } + | } + | +... + +error: aborting due to 3 previous errors + diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs new file mode 100644 index 000000000000..3759986ae9d3 --- /dev/null +++ b/tests/ui/no_effect.rs @@ -0,0 +1,122 @@ +#![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; + s2; + Unit; + Tuple(0); + Struct { field: 0 }; + Struct { ..s }; + Union { a: 0 }; + Enum::Tuple(0); + Enum::Struct { field: 0 }; + 5 + 6; + *&42; + &6; + (5, 6, 7); + box 42; + ..; + 5..; + ..5; + 5..6; + 5...6; + [42, 55]; + [42, 55][1]; + (42, 55).1; + [42; 55]; + [42; 55][13]; + let mut x = 0; + || x += 5; + + // Do not warn + get_number(); + unsafe { unsafe_fn() }; + + Tuple(get_number()); + + + Struct { field: get_number() }; + + + Struct { ..get_struct() }; + + + Enum::Tuple(get_number()); + + + Enum::Struct { field: get_number() }; + + + 5 + get_number(); + + + *&get_number(); + + + &get_number(); + + + (5, 6, get_number()); + + + box get_number(); + + + get_number()..; + + + ..get_number(); + + + 5..get_number(); + + + [42, get_number()]; + + + [42, 55][get_number() as usize]; + + + (42, get_number()).1; + + + [get_number(); 55]; + + + [42; 55][get_number() as usize]; + + + {get_number()}; + + +} diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr new file mode 100644 index 000000000000..5fd1d7c425b7 --- /dev/null +++ b/tests/ui/no_effect.stderr @@ -0,0 +1,334 @@ +error: statement with no effect + --> $DIR/no_effect.rs:34:5 + | +34 | 0; + | ^^ + | +note: lint level defined here + --> $DIR/no_effect.rs:4:9 + | +4 | #![deny(no_effect, unnecessary_operation)] + | ^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:35:5 + | +35 | s2; + | ^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:36:5 + | +36 | Unit; + | ^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:37:5 + | +37 | Tuple(0); + | ^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:38:5 + | +38 | Struct { field: 0 }; + | ^^^^^^^^^^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:39:5 + | +39 | Struct { ..s }; + | ^^^^^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:40:5 + | +40 | Union { a: 0 }; + | ^^^^^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:41:5 + | +41 | Enum::Tuple(0); + | ^^^^^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:42:5 + | +42 | Enum::Struct { field: 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:43:5 + | +43 | 5 + 6; + | ^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:44:5 + | +44 | *&42; + | ^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:45:5 + | +45 | &6; + | ^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:46:5 + | +46 | (5, 6, 7); + | ^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:47:5 + | +47 | box 42; + | ^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:48:5 + | +48 | ..; + | ^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:49:5 + | +49 | 5..; + | ^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:50:5 + | +50 | ..5; + | ^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:51:5 + | +51 | 5..6; + | ^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:52:5 + | +52 | 5...6; + | ^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:53:5 + | +53 | [42, 55]; + | ^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:54:5 + | +54 | [42, 55][1]; + | ^^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:55:5 + | +55 | (42, 55).1; + | ^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:56:5 + | +56 | [42; 55]; + | ^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:57:5 + | +57 | [42; 55][13]; + | ^^^^^^^^^^^^^ + +error: statement with no effect + --> $DIR/no_effect.rs:59:5 + | +59 | || x += 5; + | ^^^^^^^^^^ + +error: statement can be reduced + --> $DIR/no_effect.rs:65:5 + | +65 | Tuple(get_number()); + | ^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/no_effect.rs:4:20 + | +4 | #![deny(no_effect, unnecessary_operation)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:68:5 + | +68 | Struct { field: get_number() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:71:5 + | +71 | Struct { ..get_struct() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | get_struct(); + +error: statement can be reduced + --> $DIR/no_effect.rs:74:5 + | +74 | Enum::Tuple(get_number()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:77:5 + | +77 | Enum::Struct { field: get_number() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:80:5 + | +80 | 5 + get_number(); + | ^^^^^^^^^^^^^^^^^ + | +help: replace it with + | 5;get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:83:5 + | +83 | *&get_number(); + | ^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:86:5 + | +86 | &get_number(); + | ^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:89:5 + | +89 | (5, 6, get_number()); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | 5;6;get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:92:5 + | +92 | box get_number(); + | ^^^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:95:5 + | +95 | get_number()..; + | ^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:98:5 + | +98 | ..get_number(); + | ^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:101:5 + | +101 | 5..get_number(); + | ^^^^^^^^^^^^^^^^ + | +help: replace it with + | 5;get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:104:5 + | +104 | [42, get_number()]; + | ^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | 42;get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:107:5 + | +107 | [42, 55][get_number() as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | [42, 55];get_number() as usize; + +error: statement can be reduced + --> $DIR/no_effect.rs:110:5 + | +110 | (42, get_number()).1; + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | 42;get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:113:5 + | +113 | [get_number(); 55]; + | ^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: statement can be reduced + --> $DIR/no_effect.rs:116:5 + | +116 | [42; 55][get_number() as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace it with + | [42; 55];get_number() as usize; + +error: statement can be reduced + --> $DIR/no_effect.rs:119:5 + | +119 | {get_number()}; + | ^^^^^^^^^^^^^^^ + | +help: replace it with + | get_number(); + +error: aborting due to 44 previous errors + diff --git a/tests/ui/non_expressive_names.rs b/tests/ui/non_expressive_names.rs new file mode 100644 index 000000000000..649a5ecb812d --- /dev/null +++ b/tests/ui/non_expressive_names.rs @@ -0,0 +1,150 @@ +#![feature(plugin)] +#![plugin(clippy)] +#![deny(clippy,similar_names)] + + + + + + + + + + + +#![allow(unused)] + + +struct Foo { + apple: i32, + bpple: i32, +} + +fn main() { + let specter: i32; + let spectre: i32; + + let apple: i32; + + let bpple: i32; + + let cpple: i32; + + + let a_bar: i32; + let b_bar: i32; + let c_bar: i32; + + let items = [5]; + for item in &items { + loop {} + } + + let foo_x: i32; + let foo_y: i32; + + let rhs: i32; + let lhs: i32; + + let bla_rhs: i32; + let bla_lhs: i32; + + let blubrhs: i32; + let blublhs: i32; + + let blubx: i32; + let bluby: i32; + + + let cake: i32; + let cakes: i32; + let coke: i32; + + match 5 { + cheese @ 1 => {}, + rabbit => panic!(), + } + let cheese: i32; + match (42, 43) { + (cheese1, 1) => {}, + (cheese2, 2) => panic!(), + _ => println!(""), + } + let ipv4: i32; + let ipv6: i32; + let abcd1: i32; + let abdc2: i32; + let xyz1abc: i32; + let xyz2abc: i32; + let xyzeabc: i32; + + let parser: i32; + let parsed: i32; + let parsee: i32; + + + let setter: i32; + let getter: i32; + let tx1: i32; + let rx1: i32; + let tx_cake: i32; + let rx_cake: i32; +} + +fn foo() { + let Foo { apple, bpple } = unimplemented!(); + let Foo { apple: spring, + bpple: sprang } = unimplemented!(); +} + +#[derive(Clone, Debug)] +enum MaybeInst { + Split, + Split1(usize), + Split2(usize), +} + +struct InstSplit { + uiae: usize, +} + +impl MaybeInst { + fn fill(&mut self) { + let filled = match *self { + MaybeInst::Split1(goto1) => panic!(1), + MaybeInst::Split2(goto2) => panic!(2), + _ => unimplemented!(), + }; + unimplemented!() + } +} + +fn bla() { + let a: i32; + let (b, c, d): (i32, i64, i16); + { + { + let cdefg: i32; + let blar: i32; + } + { + let e: i32; + + } + { + let e: i32; + + let f: i32; + + } + match 5 { + 1 => println!(""), + e => panic!(), + + } + match 5 { + 1 => println!(""), + _ => panic!(), + } + } +} diff --git a/tests/ui/non_expressive_names.stderr b/tests/ui/non_expressive_names.stderr new file mode 100644 index 000000000000..c47f5a449a23 --- /dev/null +++ b/tests/ui/non_expressive_names.stderr @@ -0,0 +1,148 @@ +error: binding's name is too similar to existing binding + --> $DIR/non_expressive_names.rs:29:9 + | +29 | let bpple: i32; + | ^^^^^ + | +note: lint level defined here + --> $DIR/non_expressive_names.rs:3:16 + | +3 | #![deny(clippy,similar_names)] + | ^^^^^^^^^^^^^ +note: existing binding defined here + --> $DIR/non_expressive_names.rs:27:9 + | +27 | let apple: i32; + | ^^^^^ +help: separate the discriminating character by an underscore like: `b_pple` + --> $DIR/non_expressive_names.rs:29:9 + | +29 | let bpple: i32; + | ^^^^^ + +error: binding's name is too similar to existing binding + --> $DIR/non_expressive_names.rs:31:9 + | +31 | let cpple: i32; + | ^^^^^ + | +note: existing binding defined here + --> $DIR/non_expressive_names.rs:27:9 + | +27 | let apple: i32; + | ^^^^^ +help: separate the discriminating character by an underscore like: `c_pple` + --> $DIR/non_expressive_names.rs:31:9 + | +31 | let cpple: i32; + | ^^^^^ + +error: binding's name is too similar to existing binding + --> $DIR/non_expressive_names.rs:56:9 + | +56 | let bluby: i32; + | ^^^^^ + | +note: existing binding defined here + --> $DIR/non_expressive_names.rs:55:9 + | +55 | let blubx: i32; + | ^^^^^ +help: separate the discriminating character by an underscore like: `blub_y` + --> $DIR/non_expressive_names.rs:56:9 + | +56 | let bluby: i32; + | ^^^^^ + +error: binding's name is too similar to existing binding + --> $DIR/non_expressive_names.rs:61:9 + | +61 | let coke: i32; + | ^^^^ + | +note: existing binding defined here + --> $DIR/non_expressive_names.rs:59:9 + | +59 | let cake: i32; + | ^^^^ + +error: binding's name is too similar to existing binding + --> $DIR/non_expressive_names.rs:79:9 + | +79 | let xyzeabc: i32; + | ^^^^^^^ + | +note: existing binding defined here + --> $DIR/non_expressive_names.rs:77:9 + | +77 | let xyz1abc: i32; + | ^^^^^^^ + +error: binding's name is too similar to existing binding + --> $DIR/non_expressive_names.rs:83:9 + | +83 | let parsee: i32; + | ^^^^^^ + | +note: existing binding defined here + --> $DIR/non_expressive_names.rs:81:9 + | +81 | let parser: i32; + | ^^^^^^ +help: separate the discriminating character by an underscore like: `parse_e` + --> $DIR/non_expressive_names.rs:83:9 + | +83 | let parsee: i32; + | ^^^^^^ + +error: binding's name is too similar to existing binding + --> $DIR/non_expressive_names.rs:97:16 + | +97 | bpple: sprang } = unimplemented!(); + | ^^^^^^ + | +note: existing binding defined here + --> $DIR/non_expressive_names.rs:96:22 + | +96 | let Foo { apple: spring, + | ^^^^^^ + +error: 5th binding whose name is just one char + --> $DIR/non_expressive_names.rs:131:17 + | +131 | let e: i32; + | ^ + | + = note: #[deny(many_single_char_names)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/non_expressive_names.rs:3:9 + | +3 | #![deny(clippy,similar_names)] + | ^^^^^^ + +error: 5th binding whose name is just one char + --> $DIR/non_expressive_names.rs:135:17 + | +135 | let e: i32; + | ^ + | + = note: #[deny(many_single_char_names)] implied by #[deny(clippy)] + +error: 6th binding whose name is just one char + --> $DIR/non_expressive_names.rs:137:17 + | +137 | let f: i32; + | ^ + | + = note: #[deny(many_single_char_names)] implied by #[deny(clippy)] + +error: 5th binding whose name is just one char + --> $DIR/non_expressive_names.rs:142:13 + | +142 | e => panic!(), + | ^ + | + = note: #[deny(many_single_char_names)] implied by #[deny(clippy)] + +error: aborting due to 11 previous errors + diff --git a/tests/compile-fail/ok_if_let.rs b/tests/ui/ok_if_let.rs similarity index 87% rename from tests/compile-fail/ok_if_let.rs rename to tests/ui/ok_if_let.rs index 3676f473bcd0..414176f8d108 100644 --- a/tests/compile-fail/ok_if_let.rs +++ b/tests/ui/ok_if_let.rs @@ -5,7 +5,7 @@ fn str_to_int(x: &str) -> i32 { if let Some(y) = x.parse().ok() { - //~^ERROR Matching on `Some` with `ok()` is redundant + y } else { 0 diff --git a/tests/ui/ok_if_let.stderr b/tests/ui/ok_if_let.stderr new file mode 100644 index 000000000000..d3eaaddaefc8 --- /dev/null +++ b/tests/ui/ok_if_let.stderr @@ -0,0 +1,21 @@ +error: Matching on `Some` with `ok()` is redundant + --> $DIR/ok_if_let.rs:7:5 + | +7 | if let Some(y) = x.parse().ok() { + | _____^ starting here... +8 | | +9 | | y +10 | | } else { +11 | | 0 +12 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/ok_if_let.rs:4:9 + | +4 | #![deny(if_let_some_result)] + | ^^^^^^^^^^^^^^^^^^ + = help: Consider matching on `Ok(y)` and removing the call to `ok` instead + +error: aborting due to previous error + diff --git a/tests/compile-fail/open_options.rs b/tests/ui/open_options.rs similarity index 53% rename from tests/compile-fail/open_options.rs rename to tests/ui/open_options.rs index 08024e37d4af..e1ce69af76e6 100644 --- a/tests/compile-fail/open_options.rs +++ b/tests/ui/open_options.rs @@ -5,12 +5,12 @@ use std::fs::OpenOptions; #[allow(unused_must_use)] #[deny(nonsensical_open_options)] fn main() { - OpenOptions::new().read(true).truncate(true).open("foo.txt"); //~ERROR file opened with "truncate" and "read" - OpenOptions::new().append(true).truncate(true).open("foo.txt"); //~ERROR file opened with "append" and "truncate" + OpenOptions::new().read(true).truncate(true).open("foo.txt"); + OpenOptions::new().append(true).truncate(true).open("foo.txt"); - OpenOptions::new().read(true).read(false).open("foo.txt"); //~ERROR the method "read" is called more than once - OpenOptions::new().create(true).create(false).open("foo.txt"); //~ERROR the method "create" is called more than once - OpenOptions::new().write(true).write(false).open("foo.txt"); //~ERROR the method "write" is called more than once - OpenOptions::new().append(true).append(false).open("foo.txt"); //~ERROR the method "append" is called more than once - OpenOptions::new().truncate(true).truncate(false).open("foo.txt"); //~ERROR the method "truncate" is called more than once + OpenOptions::new().read(true).read(false).open("foo.txt"); + OpenOptions::new().create(true).create(false).open("foo.txt"); + OpenOptions::new().write(true).write(false).open("foo.txt"); + OpenOptions::new().append(true).append(false).open("foo.txt"); + OpenOptions::new().truncate(true).truncate(false).open("foo.txt"); } diff --git a/tests/ui/open_options.stderr b/tests/ui/open_options.stderr new file mode 100644 index 000000000000..0f9779c27782 --- /dev/null +++ b/tests/ui/open_options.stderr @@ -0,0 +1,50 @@ +error: file opened with "truncate" and "read" + --> $DIR/open_options.rs:8:5 + | +8 | OpenOptions::new().read(true).truncate(true).open("foo.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/open_options.rs:6:8 + | +6 | #[deny(nonsensical_open_options)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: file opened with "append" and "truncate" + --> $DIR/open_options.rs:9:5 + | +9 | OpenOptions::new().append(true).truncate(true).open("foo.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the method "read" is called more than once + --> $DIR/open_options.rs:11:5 + | +11 | OpenOptions::new().read(true).read(false).open("foo.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the method "create" is called more than once + --> $DIR/open_options.rs:12:5 + | +12 | OpenOptions::new().create(true).create(false).open("foo.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the method "write" is called more than once + --> $DIR/open_options.rs:13:5 + | +13 | OpenOptions::new().write(true).write(false).open("foo.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the method "append" is called more than once + --> $DIR/open_options.rs:14:5 + | +14 | OpenOptions::new().append(true).append(false).open("foo.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the method "truncate" is called more than once + --> $DIR/open_options.rs:15:5 + | +15 | OpenOptions::new().truncate(true).truncate(false).open("foo.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/tests/ui/overflow_check_conditional.rs b/tests/ui/overflow_check_conditional.rs new file mode 100644 index 000000000000..51503003be41 --- /dev/null +++ b/tests/ui/overflow_check_conditional.rs @@ -0,0 +1,61 @@ +#![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 { + + } + if a > a + b { + + } + if a + b < b { + + } + if b > a + b { + + } + if a - b > b { + + } + if b < a - b { + + } + if a - b > a { + + } + if a < a - b { + + } + 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 { + + } +} diff --git a/tests/ui/overflow_check_conditional.stderr b/tests/ui/overflow_check_conditional.stderr new file mode 100644 index 000000000000..8705f3d72038 --- /dev/null +++ b/tests/ui/overflow_check_conditional.stderr @@ -0,0 +1,56 @@ +error: You are trying to use classic C overflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:11:5 + | +11 | \tif a + b < a { + | \t ^^^^^^^^^ + | +note: lint level defined here + --> $DIR/overflow_check_conditional.rs:5:9 + | +5 | #![deny(overflow_check_conditional)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: You are trying to use classic C overflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:14:5 + | +14 | \tif a > a + b { + | \t ^^^^^^^^^ + +error: You are trying to use classic C overflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:17:5 + | +17 | \tif a + b < b { + | \t ^^^^^^^^^ + +error: You are trying to use classic C overflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:20:5 + | +20 | \tif b > a + b { + | \t ^^^^^^^^^ + +error: You are trying to use classic C underflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:23:5 + | +23 | \tif a - b > b { + | \t ^^^^^^^^^ + +error: You are trying to use classic C underflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:26:5 + | +26 | \tif b < a - b { + | \t ^^^^^^^^^ + +error: You are trying to use classic C underflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:29:5 + | +29 | \tif a - b > a { + | \t ^^^^^^^^^ + +error: You are trying to use classic C underflow conditions that will fail in Rust. + --> $DIR/overflow_check_conditional.rs:32:5 + | +32 | \tif a < a - b { + | \t ^^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/compile-fail/panic.rs b/tests/ui/panic.rs similarity index 70% rename from tests/compile-fail/panic.rs rename to tests/ui/panic.rs index 7e535d69b698..741c80903562 100644 --- a/tests/compile-fail/panic.rs +++ b/tests/ui/panic.rs @@ -5,11 +5,11 @@ fn missing() { if true { - panic!("{}"); //~ERROR: you probably are missing some parameter + panic!("{}"); } else if false { - panic!("{:?}"); //~ERROR: you probably are missing some parameter + panic!("{:?}"); } else { - assert!(true, "here be missing values: {}"); //~ERROR you probably are missing some parameter + assert!(true, "here be missing values: {}"); } } diff --git a/tests/ui/panic.stderr b/tests/ui/panic.stderr new file mode 100644 index 000000000000..e77add7a32ae --- /dev/null +++ b/tests/ui/panic.stderr @@ -0,0 +1,26 @@ +error: you probably are missing some parameter in your format string + --> $DIR/panic.rs:8:16 + | +8 | panic!("{}"); + | ^^^^ + | +note: lint level defined here + --> $DIR/panic.rs:4:9 + | +4 | #![deny(panic_params)] + | ^^^^^^^^^^^^ + +error: you probably are missing some parameter in your format string + --> $DIR/panic.rs:10:16 + | +10 | panic!("{:?}"); + | ^^^^^^ + +error: you probably are missing some parameter in your format string + --> $DIR/panic.rs:12:23 + | +12 | assert!(true, "here be missing values: {}"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/compile-fail/partialeq_ne_impl.rs b/tests/ui/partialeq_ne_impl.rs similarity index 78% rename from tests/compile-fail/partialeq_ne_impl.rs rename to tests/ui/partialeq_ne_impl.rs index f4ecdd4261a2..9ee1f48b01c5 100644 --- a/tests/compile-fail/partialeq_ne_impl.rs +++ b/tests/ui/partialeq_ne_impl.rs @@ -9,7 +9,7 @@ struct Foo; impl PartialEq for Foo { fn eq(&self, _: &Foo) -> bool { true } fn ne(&self, _: &Foo) -> bool { false } - //~^ ERROR re-implementing `PartialEq::ne` is unnecessary + } fn main() {} diff --git a/tests/ui/partialeq_ne_impl.stderr b/tests/ui/partialeq_ne_impl.stderr new file mode 100644 index 000000000000..dd1e4099e4ca --- /dev/null +++ b/tests/ui/partialeq_ne_impl.stderr @@ -0,0 +1,15 @@ +error: re-implementing `PartialEq::ne` is unnecessary + --> $DIR/partialeq_ne_impl.rs:11:5 + | +11 | fn ne(&self, _: &Foo) -> bool { false } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(partialeq_ne_impl)] implied by #[deny(warnings)] +note: lint level defined here + --> $DIR/partialeq_ne_impl.rs:4:9 + | +4 | #![deny(warnings)] + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/compile-fail/patterns.rs b/tests/ui/patterns.rs similarity index 74% rename from tests/compile-fail/patterns.rs rename to tests/ui/patterns.rs index 62bd2c43cc14..d4aa513ea062 100644 --- a/tests/compile-fail/patterns.rs +++ b/tests/ui/patterns.rs @@ -7,7 +7,7 @@ fn main() { let v = Some(true); match v { Some(x) => (), - y @ _ => (), //~ERROR the `y @ _` pattern can be written as just `y` + y @ _ => (), } match v { Some(x) => (), diff --git a/tests/ui/patterns.stderr b/tests/ui/patterns.stderr new file mode 100644 index 000000000000..515ae4cae6ee --- /dev/null +++ b/tests/ui/patterns.stderr @@ -0,0 +1,15 @@ +error: the `y @ _` pattern can be written as just `y` + --> $DIR/patterns.rs:10:9 + | +10 | y @ _ => (), + | ^^^^^ + | + = note: #[deny(redundant_pattern)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/patterns.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/precedence.rs b/tests/ui/precedence.rs new file mode 100644 index 000000000000..1c6019fdecf1 --- /dev/null +++ b/tests/ui/precedence.rs @@ -0,0 +1,44 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#[deny(precedence)] +#[allow(identity_op)] +#[allow(eq_op)] +fn main() { + 1 << 2 + 3; + + + 1 + 2 << 3; + + + 4 >> 1 + 1; + + + 1 + 3 >> 2; + + + 1 ^ 1 - 1; + + + 3 | 2 - 1; + + + 3 & 5 - 2; + + + + -1i32.abs(); + + + -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()); +} diff --git a/tests/ui/precedence.stderr b/tests/ui/precedence.stderr new file mode 100644 index 000000000000..5eb8d91ec211 --- /dev/null +++ b/tests/ui/precedence.stderr @@ -0,0 +1,88 @@ +error: operator precedence can trip the unwary + --> $DIR/precedence.rs:8:5 + | +8 | 1 << 2 + 3; + | ^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/precedence.rs:4:8 + | +4 | #[deny(precedence)] + | ^^^^^^^^^^ +help: consider parenthesizing your expression + | 1 << (2 + 3); + +error: operator precedence can trip the unwary + --> $DIR/precedence.rs:11:5 + | +11 | 1 + 2 << 3; + | ^^^^^^^^^^ + | +help: consider parenthesizing your expression + | (1 + 2) << 3; + +error: operator precedence can trip the unwary + --> $DIR/precedence.rs:14:5 + | +14 | 4 >> 1 + 1; + | ^^^^^^^^^^ + | +help: consider parenthesizing your expression + | 4 >> (1 + 1); + +error: operator precedence can trip the unwary + --> $DIR/precedence.rs:17:5 + | +17 | 1 + 3 >> 2; + | ^^^^^^^^^^ + | +help: consider parenthesizing your expression + | (1 + 3) >> 2; + +error: operator precedence can trip the unwary + --> $DIR/precedence.rs:20:5 + | +20 | 1 ^ 1 - 1; + | ^^^^^^^^^ + | +help: consider parenthesizing your expression + | 1 ^ (1 - 1); + +error: operator precedence can trip the unwary + --> $DIR/precedence.rs:23:5 + | +23 | 3 | 2 - 1; + | ^^^^^^^^^ + | +help: consider parenthesizing your expression + | 3 | (2 - 1); + +error: operator precedence can trip the unwary + --> $DIR/precedence.rs:26:5 + | +26 | 3 & 5 - 2; + | ^^^^^^^^^ + | +help: consider parenthesizing your expression + | 3 & (5 - 2); + +error: unary minus has lower precedence than method call + --> $DIR/precedence.rs:30:5 + | +30 | -1i32.abs(); + | ^^^^^^^^^^^ + | +help: consider adding parentheses to clarify your intent + | -(1i32.abs()); + +error: unary minus has lower precedence than method call + --> $DIR/precedence.rs:33:5 + | +33 | -1f32.abs(); + | ^^^^^^^^^^^ + | +help: consider adding parentheses to clarify your intent + | -(1f32.abs()); + +error: aborting due to 9 previous errors + diff --git a/tests/compile-fail/print.rs b/tests/ui/print.rs similarity index 62% rename from tests/compile-fail/print.rs rename to tests/ui/print.rs index 34c38dca2861..e6b114b897b8 100644 --- a/tests/compile-fail/print.rs +++ b/tests/ui/print.rs @@ -10,7 +10,7 @@ struct Foo; impl Display for Foo { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "{:?}", 43.1415) - //~^ ERROR use of `Debug`-based formatting + } } @@ -22,18 +22,18 @@ impl Debug for Foo { } fn main() { - println!("Hello"); //~ERROR use of `println!` - print!("Hello"); //~ERROR use of `print!` + println!("Hello"); + print!("Hello"); - print!("Hello {}", "World"); //~ERROR use of `print!` + print!("Hello {}", "World"); print!("Hello {:?}", "World"); - //~^ ERROR use of `print!` - //~| ERROR use of `Debug`-based formatting + + print!("Hello {:#?}", "#orld"); - //~^ ERROR use of `print!` - //~| ERROR use of `Debug`-based formatting + + assert_eq!(42, 1337); diff --git a/tests/ui/print.stderr b/tests/ui/print.stderr new file mode 100644 index 000000000000..5afb8ae504d4 --- /dev/null +++ b/tests/ui/print.stderr @@ -0,0 +1,62 @@ +error: use of `Debug`-based formatting + --> $DIR/print.rs:12:27 + | +12 | write!(f, "{:?}", 43.1415) + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/print.rs:3:23 + | +3 | #![deny(print_stdout, use_debug)] + | ^^^^^^^^^ + +error: use of `println!` + --> $DIR/print.rs:25:5 + | +25 | println!("Hello"); + | ^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/print.rs:3:9 + | +3 | #![deny(print_stdout, use_debug)] + | ^^^^^^^^^^^^ + +error: use of `print!` + --> $DIR/print.rs:26:5 + | +26 | print!("Hello"); + | ^^^^^^^^^^^^^^^^ + +error: use of `print!` + --> $DIR/print.rs:28:5 + | +28 | print!("Hello {}", "World"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: use of `print!` + --> $DIR/print.rs:30:5 + | +30 | print!("Hello {:?}", "World"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: use of `Debug`-based formatting + --> $DIR/print.rs:30:26 + | +30 | print!("Hello {:?}", "World"); + | ^^^^^^^ + +error: use of `print!` + --> $DIR/print.rs:34:5 + | +34 | print!("Hello {:#?}", "#orld"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: use of `Debug`-based formatting + --> $DIR/print.rs:34:27 + | +34 | print!("Hello {:#?}", "#orld"); + | ^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/ui/print_with_newline.rs b/tests/ui/print_with_newline.rs new file mode 100644 index 000000000000..3e2b31a528fd --- /dev/null +++ b/tests/ui/print_with_newline.rs @@ -0,0 +1,20 @@ +#![feature(plugin)] +#![plugin(clippy)] +#![deny(print_with_newline)] + +fn main() { + print!("Hello\n"); + print!("Hello {}\n", "world"); + print!("Hello {} {}\n\n", "world", "#2"); + print!("{}\n", 1265); + + // 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); +} diff --git a/tests/ui/print_with_newline.stderr b/tests/ui/print_with_newline.stderr new file mode 100644 index 000000000000..44beb530277b --- /dev/null +++ b/tests/ui/print_with_newline.stderr @@ -0,0 +1,32 @@ +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:6:5 + | +6 | print!("Hello/n"); + | ^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/print_with_newline.rs:3:9 + | +3 | #![deny(print_with_newline)] + | ^^^^^^^^^^^^^^^^^^ + +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:7:5 + | +7 | print!("Hello {}/n", "world"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:8:5 + | +8 | print!("Hello {} {}/n/n", "world", "#2"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:9:5 + | +9 | print!("{}/n", 1265); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/compile-fail/ptr_arg.rs b/tests/ui/ptr_arg.rs similarity index 72% rename from tests/compile-fail/ptr_arg.rs rename to tests/ui/ptr_arg.rs index e4971208747a..f262d2a8dba1 100644 --- a/tests/compile-fail/ptr_arg.rs +++ b/tests/ui/ptr_arg.rs @@ -3,7 +3,7 @@ #![allow(unused)] #![deny(ptr_arg)] -fn do_vec(x: &Vec) { //~ERROR writing `&Vec<_>` instead of `&[_]` +fn do_vec(x: &Vec) { //Nothing here } @@ -11,7 +11,7 @@ fn do_vec_mut(x: &mut Vec) { // no error here //Nothing here } -fn do_str(x: &String) { //~ERROR writing `&String` instead of `&str` +fn do_str(x: &String) { //Nothing here either } @@ -24,7 +24,7 @@ fn main() { trait Foo { type Item; - fn do_vec(x: &Vec); //~ERROR writing `&Vec<_>` + fn do_vec(x: &Vec); fn do_item(x: &Self::Item); } diff --git a/tests/ui/ptr_arg.stderr b/tests/ui/ptr_arg.stderr new file mode 100644 index 000000000000..ce9c1e856fd6 --- /dev/null +++ b/tests/ui/ptr_arg.stderr @@ -0,0 +1,26 @@ +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. Consider changing the type to `&[...]` + --> $DIR/ptr_arg.rs:6:14 + | +6 | fn do_vec(x: &Vec) { + | ^^^^^^^^^ + | +note: lint level defined here + --> $DIR/ptr_arg.rs:4:9 + | +4 | #![deny(ptr_arg)] + | ^^^^^^^ + +error: writing `&String` instead of `&str` involves a new object where a slice will do. Consider changing the type to `&str` + --> $DIR/ptr_arg.rs:14:14 + | +14 | fn do_str(x: &String) { + | ^^^^^^^ + +error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. Consider changing the type to `&[...]` + --> $DIR/ptr_arg.rs:27:18 + | +27 | fn do_vec(x: &Vec); + | ^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/compile-fail/range.rs b/tests/ui/range.rs similarity index 53% rename from tests/compile-fail/range.rs rename to tests/ui/range.rs index fc12155ce9cb..8e2bf6a7e69d 100644 --- a/tests/compile-fail/range.rs +++ b/tests/ui/range.rs @@ -10,15 +10,15 @@ impl NotARange { #[deny(range_step_by_zero, range_zip_with_len)] fn main() { - (0..1).step_by(0); //~ERROR Range::step_by(0) produces an infinite iterator + (0..1).step_by(0); // No warning for non-zero step (0..1).step_by(1); - (1..).step_by(0); //~ERROR Range::step_by(0) produces an infinite iterator - (1...2).step_by(0); //~ERROR Range::step_by(0) produces an infinite iterator + (1..).step_by(0); + (1...2).step_by(0); let x = 0..1; - x.step_by(0); //~ERROR Range::step_by(0) produces an infinite iterator + x.step_by(0); // No error, not a range. let y = NotARange; @@ -26,6 +26,6 @@ fn main() { let v1 = vec![1,2,3]; let v2 = vec![4,5]; - let _x = v1.iter().zip(0..v1.len()); //~ERROR It is more idiomatic to use v1.iter().enumerate() + let _x = v1.iter().zip(0..v1.len()); let _y = v1.iter().zip(0..v2.len()); // No error } diff --git a/tests/ui/range.stderr b/tests/ui/range.stderr new file mode 100644 index 000000000000..09e9f8a47514 --- /dev/null +++ b/tests/ui/range.stderr @@ -0,0 +1,44 @@ +error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead + --> $DIR/range.rs:13:5 + | +13 | (0..1).step_by(0); + | ^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/range.rs:11:8 + | +11 | #[deny(range_step_by_zero, range_zip_with_len)] + | ^^^^^^^^^^^^^^^^^^ + +error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead + --> $DIR/range.rs:17:5 + | +17 | (1..).step_by(0); + | ^^^^^^^^^^^^^^^^ + +error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead + --> $DIR/range.rs:18:5 + | +18 | (1...2).step_by(0); + | ^^^^^^^^^^^^^^^^^^ + +error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead + --> $DIR/range.rs:21:5 + | +21 | x.step_by(0); + | ^^^^^^^^^^^^ + +error: It is more idiomatic to use v1.iter().enumerate() + --> $DIR/range.rs:29:14 + | +29 | let _x = v1.iter().zip(0..v1.len()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/range.rs:11:28 + | +11 | #[deny(range_step_by_zero, range_zip_with_len)] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/redundant_closure_call.rs b/tests/ui/redundant_closure_call.rs new file mode 100644 index 000000000000..a431e05e72fd --- /dev/null +++ b/tests/ui/redundant_closure_call.rs @@ -0,0 +1,25 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#![deny(redundant_closure_call)] + +fn main() { + let a = (|| 42)(); + + + + + let mut i = 1; + let k = (|m| m+1)(i); + + k = (|a,b| a*b)(1,5); + + let closure = || 32; + i = closure(); + + let closure = |i| i+1; + i = closure(3); + + i = closure(4); +} + diff --git a/tests/ui/redundant_closure_call.stderr b/tests/ui/redundant_closure_call.stderr new file mode 100644 index 000000000000..287f465bb4ad --- /dev/null +++ b/tests/ui/redundant_closure_call.stderr @@ -0,0 +1,41 @@ +error: Closure called just once immediately after it was declared + --> $DIR/redundant_closure_call.rs:18:2 + | +18 | \ti = closure(); + | \t^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/redundant_closure_call.rs:4:9 + | +4 | #![deny(redundant_closure_call)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: Closure called just once immediately after it was declared + --> $DIR/redundant_closure_call.rs:21:2 + | +21 | \ti = closure(3); + | \t^^^^^^^^^^^^^^ + +error: Try not to call a closure in the expression where it is declared. + --> $DIR/redundant_closure_call.rs:7:10 + | +7 | \tlet a = (|| 42)(); + | \t ^^^^^^^^^ + | +help: Try doing something like: + | \tlet a = 42; + +error: Try not to call a closure in the expression where it is declared. + --> $DIR/redundant_closure_call.rs:13:10 + | +13 | \tlet k = (|m| m+1)(i); + | \t ^^^^^^^^^^^^ + +error: Try not to call a closure in the expression where it is declared. + --> $DIR/redundant_closure_call.rs:15:6 + | +15 | \tk = (|a,b| a*b)(1,5); + | \t ^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/reference.rs b/tests/ui/reference.rs new file mode 100644 index 000000000000..d1160df9e128 --- /dev/null +++ b/tests/ui/reference.rs @@ -0,0 +1,88 @@ +#![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; + + + + + let b = *&get_number(); + + + + + let b = *get_reference(&a); + + let bytes : Vec = vec![1, 2, 3, 4]; + let b = *&bytes[1..2][0]; + + + + + //This produces a suggestion of 'let b = (a);' which + //will trigger the 'unused_parens' lint + let b = *&(a); + + + + + let b = *(&a); + + + + + let b = *((&a)); + + + + + let b = *&&a; + + + + + let b = **&aref; + + + + + //This produces a suggestion of 'let b = *&a;' which + //will trigger the 'deref_addrof' lint again + let b = **&&a; + + + + + { + let mut x = 10; + let y = *&mut 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; + + + + } +} diff --git a/tests/ui/reference.stderr b/tests/ui/reference.stderr new file mode 100644 index 000000000000..6701016b3bed --- /dev/null +++ b/tests/ui/reference.stderr @@ -0,0 +1,106 @@ +error: immediately dereferencing a reference + --> $DIR/reference.rs:19:13 + | +19 | let b = *&a; + | ^^^ + | +note: lint level defined here + --> $DIR/reference.rs:14:8 + | +14 | #[deny(deref_addrof)] + | ^^^^^^^^^^^^ +help: try this + | let b = a; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:24:13 + | +24 | let b = *&get_number(); + | ^^^^^^^^^^^^^^ + | +help: try this + | let b = get_number(); + +error: immediately dereferencing a reference + --> $DIR/reference.rs:32:13 + | +32 | let b = *&bytes[1..2][0]; + | ^^^^^^^^^^^^^^^^ + | +help: try this + | let b = bytes[1..2][0]; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:39:13 + | +39 | let b = *&(a); + | ^^^^^ + | +help: try this + | let b = (a); + +error: immediately dereferencing a reference + --> $DIR/reference.rs:44:13 + | +44 | let b = *(&a); + | ^^^^^ + | +help: try this + | let b = a; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:49:13 + | +49 | let b = *((&a)); + | ^^^^^^^ + | +help: try this + | let b = a; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:54:13 + | +54 | let b = *&&a; + | ^^^^ + | +help: try this + | let b = &a; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:59:14 + | +59 | let b = **&aref; + | ^^^^^^ + | +help: try this + | let b = *aref; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:66:14 + | +66 | let b = **&&a; + | ^^^^ + | +help: try this + | let b = *&a; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:73:17 + | +73 | let y = *&mut x; + | ^^^^^^^ + | +help: try this + | let y = x; + +error: immediately dereferencing a reference + --> $DIR/reference.rs:83:18 + | +83 | let y = **&mut &mut x; + | ^^^^^^^^^^^^ + | +help: try this + | let y = *&mut x; + +error: aborting due to 11 previous errors + diff --git a/tests/compile-fail/regex.rs b/tests/ui/regex.rs similarity index 64% rename from tests/compile-fail/regex.rs rename to tests/ui/regex.rs index d6287b881a19..245ceb835617 100644 --- a/tests/compile-fail/regex.rs +++ b/tests/ui/regex.rs @@ -14,23 +14,23 @@ const NOT_A_REAL_REGEX : &'static str = "foobar"; fn syntax_error() { let pipe_in_wrong_position = Regex::new("|"); - //~^ERROR: regex syntax error: empty alternate + let pipe_in_wrong_position_builder = RegexBuilder::new("|"); - //~^ERROR: regex syntax error: empty alternate + let wrong_char_ranice = Regex::new("[z-a]"); - //~^ERROR: regex syntax error: invalid character class range + let some_unicode = Regex::new("[é-è]"); - //~^ERROR: regex syntax error: invalid character class range + let some_regex = Regex::new(OPENING_PAREN); - //~^ERROR: regex syntax error on position 0: unclosed + let binary_pipe_in_wrong_position = BRegex::new("|"); - //~^ERROR: regex syntax error: empty alternate + let some_binary_regex = BRegex::new(OPENING_PAREN); - //~^ERROR: regex syntax error on position 0: unclosed + let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); - //~^ERROR: regex syntax error on position 0: unclosed + let closing_paren = ")"; let not_linted = Regex::new(closing_paren); @@ -46,61 +46,61 @@ fn syntax_error() { let set_error = RegexSet::new(&[ OPENING_PAREN, - //~^ERROR: regex syntax error on position 0: unclosed + r"[a-z]+\.(com|org|net)", ]); let bset_error = BRegexSet::new(&[ OPENING_PAREN, - //~^ERROR: regex syntax error on position 0: unclosed + r"[a-z]+\.(com|org|net)", ]); } fn trivial_regex() { let trivial_eq = Regex::new("^foobar$"); - //~^ERROR: trivial regex - //~|HELP consider using `==` on `str`s + + let trivial_eq_builder = RegexBuilder::new("^foobar$"); - //~^ERROR: trivial regex - //~|HELP consider using `==` on `str`s + + let trivial_starts_with = Regex::new("^foobar"); - //~^ERROR: trivial regex - //~|HELP consider using `str::starts_with` + + let trivial_ends_with = Regex::new("foobar$"); - //~^ERROR: trivial regex - //~|HELP consider using `str::ends_with` + + let trivial_contains = Regex::new("foobar"); - //~^ERROR: trivial regex - //~|HELP consider using `str::contains` + + let trivial_contains = Regex::new(NOT_A_REAL_REGEX); - //~^ERROR: trivial regex - //~|HELP consider using `str::contains` + + let trivial_backslash = Regex::new("a\\.b"); - //~^ERROR: trivial regex - //~|HELP consider using `str::contains` + + // unlikely corner cases let trivial_empty = Regex::new(""); - //~^ERROR: trivial regex - //~|HELP the regex is unlikely to be useful + + let trivial_empty = Regex::new("^"); - //~^ERROR: trivial regex - //~|HELP the regex is unlikely to be useful + + let trivial_empty = Regex::new("^$"); - //~^ERROR: trivial regex - //~|HELP consider using `str::is_empty` + + let binary_trivial_empty = BRegex::new("^$"); - //~^ERROR: trivial regex - //~|HELP consider using `str::is_empty` + + // non-trivial regexes let non_trivial_dot = Regex::new("a.b"); diff --git a/tests/ui/regex.stderr b/tests/ui/regex.stderr new file mode 100644 index 000000000000..f59d0c6b5dc7 --- /dev/null +++ b/tests/ui/regex.stderr @@ -0,0 +1,175 @@ +error: regex syntax error: empty alternate + --> $DIR/regex.rs:16:45 + | +16 | let pipe_in_wrong_position = Regex::new("|"); + | ^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error: empty alternate + --> $DIR/regex.rs:18:60 + | +18 | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); + | ^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error: invalid character class range + --> $DIR/regex.rs:20:40 + | +20 | let wrong_char_ranice = Regex::new("[z-a]"); + | ^^^^^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error: invalid character class range + --> $DIR/regex.rs:22:35 + | +22 | let some_unicode = Regex::new("[é-è]"); + | ^^^^^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error on position 0: unclosed parenthesis + --> $DIR/regex.rs:25:33 + | +25 | let some_regex = Regex::new(OPENING_PAREN); + | ^^^^^^^^^^^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error: empty alternate + --> $DIR/regex.rs:28:53 + | +28 | let binary_pipe_in_wrong_position = BRegex::new("|"); + | ^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error on position 0: unclosed parenthesis + --> $DIR/regex.rs:30:41 + | +30 | let some_binary_regex = BRegex::new(OPENING_PAREN); + | ^^^^^^^^^^^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error on position 0: unclosed parenthesis + --> $DIR/regex.rs:32:56 + | +32 | let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); + | ^^^^^^^^^^^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error on position 0: unclosed parenthesis + --> $DIR/regex.rs:48:9 + | +48 | OPENING_PAREN, + | ^^^^^^^^^^^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: regex syntax error on position 0: unclosed parenthesis + --> $DIR/regex.rs:53:9 + | +53 | OPENING_PAREN, + | ^^^^^^^^^^^^^ + | + = note: #[deny(invalid_regex)] on by default + +error: trivial regex + --> $DIR/regex.rs:60:33 + | +60 | let trivial_eq = Regex::new("^foobar$"); + | ^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/regex.rs:5:24 + | +5 | #![deny(invalid_regex, trivial_regex, regex_macro)] + | ^^^^^^^^^^^^^ + = help: consider using consider using `==` on `str`s + +error: trivial regex + --> $DIR/regex.rs:64:48 + | +64 | let trivial_eq_builder = RegexBuilder::new("^foobar$"); + | ^^^^^^^^^^ + | + = help: consider using consider using `==` on `str`s + +error: trivial regex + --> $DIR/regex.rs:68:42 + | +68 | let trivial_starts_with = Regex::new("^foobar"); + | ^^^^^^^^^ + | + = help: consider using consider using `str::starts_with` + +error: trivial regex + --> $DIR/regex.rs:72:40 + | +72 | let trivial_ends_with = Regex::new("foobar$"); + | ^^^^^^^^^ + | + = help: consider using consider using `str::ends_with` + +error: trivial regex + --> $DIR/regex.rs:76:39 + | +76 | let trivial_contains = Regex::new("foobar"); + | ^^^^^^^^ + | + = help: consider using consider using `str::contains` + +error: trivial regex + --> $DIR/regex.rs:80:39 + | +80 | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); + | ^^^^^^^^^^^^^^^^ + | + = help: consider using consider using `str::contains` + +error: trivial regex + --> $DIR/regex.rs:84:40 + | +84 | let trivial_backslash = Regex::new("a//.b"); + | ^^^^^^^ + | + = help: consider using consider using `str::contains` + +error: trivial regex + --> $DIR/regex.rs:89:36 + | +89 | let trivial_empty = Regex::new(""); + | ^^ + | + = help: consider using the regex is unlikely to be useful as it is + +error: trivial regex + --> $DIR/regex.rs:93:36 + | +93 | let trivial_empty = Regex::new("^"); + | ^^^ + | + = help: consider using the regex is unlikely to be useful as it is + +error: trivial regex + --> $DIR/regex.rs:97:36 + | +97 | let trivial_empty = Regex::new("^$"); + | ^^^^ + | + = help: consider using consider using `str::is_empty` + +error: trivial regex + --> $DIR/regex.rs:101:44 + | +101 | let binary_trivial_empty = BRegex::new("^$"); + | ^^^^ + | + = help: consider using consider using `str::is_empty` + +error: aborting due to 21 previous errors + diff --git a/tests/compile-fail/serde.rs b/tests/ui/serde.rs similarity index 90% rename from tests/compile-fail/serde.rs rename to tests/ui/serde.rs index a0671f07101d..78aabf352bb0 100644 --- a/tests/compile-fail/serde.rs +++ b/tests/ui/serde.rs @@ -37,7 +37,7 @@ impl serde::de::Visitor for B { } fn visit_string(self, _v: String) -> Result - //~^ ERROR you should not implement `visit_string` without also implementing `visit_str` + where E: serde::de::Error, { unimplemented!() diff --git a/tests/ui/serde.stderr b/tests/ui/serde.stderr new file mode 100644 index 000000000000..6aa5adabe787 --- /dev/null +++ b/tests/ui/serde.stderr @@ -0,0 +1,20 @@ +error: you should not implement `visit_string` without also implementing `visit_str` + --> $DIR/serde.rs:39:5 + | +39 | fn visit_string(self, _v: String) -> Result + | _____^ starting here... +40 | | +41 | | where E: serde::de::Error, +42 | | { +43 | | unimplemented!() +44 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/serde.rs:3:9 + | +3 | #![deny(serde_api_misuse)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/compile-fail/shadow.rs b/tests/ui/shadow.rs similarity index 50% rename from tests/compile-fail/shadow.rs rename to tests/ui/shadow.rs index bf0bdd818632..5a2c9ba663e0 100644 --- a/tests/compile-fail/shadow.rs +++ b/tests/ui/shadow.rs @@ -10,17 +10,17 @@ fn first(x: (isize, isize)) -> isize { x.0 } fn main() { let mut x = 1; - let x = &mut x; //~ERROR `x` is shadowed by itself in `&mut x` - let x = { x }; //~ERROR `x` is shadowed by itself in `{ x }` - let x = (&*x); //~ERROR `x` is shadowed by itself in `(&*x)` - let x = { *x + 1 }; //~ERROR `x` is shadowed by `{ *x + 1 }` which reuses - let x = id(x); //~ERROR `x` is shadowed by `id(x)` which reuses - let x = (1, x); //~ERROR `x` is shadowed by `(1, x)` which reuses - let x = first(x); //~ERROR `x` is shadowed by `first(x)` which reuses + let x = &mut x; + let x = { x }; + let x = (&*x); + let x = { *x + 1 }; + let x = id(x); + let x = (1, x); + let x = first(x); let y = 1; - let x = y; //~ERROR `x` is shadowed by `y` + let x = y; - let x; //~ERROR `x` shadows a previous declaration + let x; x = 42; let o = Some(1_u8); diff --git a/tests/ui/shadow.stderr b/tests/ui/shadow.stderr new file mode 100644 index 000000000000..212192a28da6 --- /dev/null +++ b/tests/ui/shadow.stderr @@ -0,0 +1,159 @@ +error: `x` is shadowed by itself in `&mut x` + --> $DIR/shadow.rs:13:9 + | +13 | let x = &mut x; + | ^^^^^^^^^^ + | + = note: #[deny(shadow_same)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/shadow.rs:4:17 + | +4 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ +note: previous binding is here + --> $DIR/shadow.rs:12:13 + | +12 | let mut x = 1; + | ^ + +error: `x` is shadowed by itself in `{ x }` + --> $DIR/shadow.rs:14:9 + | +14 | let x = { x }; + | ^^^^^^^^^ + | + = note: #[deny(shadow_same)] implied by #[deny(clippy_pedantic)] +note: previous binding is here + --> $DIR/shadow.rs:13:9 + | +13 | let x = &mut x; + | ^ + +error: `x` is shadowed by itself in `(&*x)` + --> $DIR/shadow.rs:15:9 + | +15 | let x = (&*x); + | ^^^^^^^^^ + | + = note: #[deny(shadow_same)] implied by #[deny(clippy_pedantic)] +note: previous binding is here + --> $DIR/shadow.rs:14:9 + | +14 | let x = { x }; + | ^ + +error: `x` is shadowed by `{ *x + 1 }` which reuses the original value + --> $DIR/shadow.rs:16:9 + | +16 | let x = { *x + 1 }; + | ^ + | + = note: #[deny(shadow_reuse)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/shadow.rs:4:17 + | +4 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ +note: initialization happens here + --> $DIR/shadow.rs:16:13 + | +16 | let x = { *x + 1 }; + | ^^^^^^^^^^ +note: previous binding is here + --> $DIR/shadow.rs:15:9 + | +15 | let x = (&*x); + | ^ + +error: `x` is shadowed by `id(x)` which reuses the original value + --> $DIR/shadow.rs:17:9 + | +17 | let x = id(x); + | ^ + | + = note: #[deny(shadow_reuse)] implied by #[deny(clippy_pedantic)] +note: initialization happens here + --> $DIR/shadow.rs:17:13 + | +17 | let x = id(x); + | ^^^^^ +note: previous binding is here + --> $DIR/shadow.rs:16:9 + | +16 | let x = { *x + 1 }; + | ^ + +error: `x` is shadowed by `(1, x)` which reuses the original value + --> $DIR/shadow.rs:18:9 + | +18 | let x = (1, x); + | ^ + | + = note: #[deny(shadow_reuse)] implied by #[deny(clippy_pedantic)] +note: initialization happens here + --> $DIR/shadow.rs:18:13 + | +18 | let x = (1, x); + | ^^^^^^ +note: previous binding is here + --> $DIR/shadow.rs:17:9 + | +17 | let x = id(x); + | ^ + +error: `x` is shadowed by `first(x)` which reuses the original value + --> $DIR/shadow.rs:19:9 + | +19 | let x = first(x); + | ^ + | + = note: #[deny(shadow_reuse)] implied by #[deny(clippy_pedantic)] +note: initialization happens here + --> $DIR/shadow.rs:19:13 + | +19 | let x = first(x); + | ^^^^^^^^ +note: previous binding is here + --> $DIR/shadow.rs:18:9 + | +18 | let x = (1, x); + | ^ + +error: `x` is shadowed by `y` + --> $DIR/shadow.rs:21:9 + | +21 | let x = y; + | ^ + | + = note: #[deny(shadow_unrelated)] implied by #[deny(clippy_pedantic)] +note: lint level defined here + --> $DIR/shadow.rs:4:17 + | +4 | #![deny(clippy, clippy_pedantic)] + | ^^^^^^^^^^^^^^^ +note: initialization happens here + --> $DIR/shadow.rs:21:13 + | +21 | let x = y; + | ^ +note: previous binding is here + --> $DIR/shadow.rs:19:9 + | +19 | let x = first(x); + | ^ + +error: `x` shadows a previous declaration + --> $DIR/shadow.rs:23:9 + | +23 | let x; + | ^ + | + = note: #[deny(shadow_unrelated)] implied by #[deny(clippy_pedantic)] +note: previous binding is here + --> $DIR/shadow.rs:21:9 + | +21 | let x = y; + | ^ + +error: aborting due to 9 previous errors + diff --git a/tests/ui/short_circuit_statement.rs b/tests/ui/short_circuit_statement.rs new file mode 100644 index 000000000000..55ff4a83b87a --- /dev/null +++ b/tests/ui/short_circuit_statement.rs @@ -0,0 +1,27 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#![deny(short_circuit_statement)] + +fn main() { + f() && g(); + + + + f() || g(); + + + + 1 == 2 || g(); + + + +} + +fn f() -> bool { + true +} + +fn g() -> bool { + false +} diff --git a/tests/ui/short_circuit_statement.stderr b/tests/ui/short_circuit_statement.stderr new file mode 100644 index 000000000000..4c865ebeb19f --- /dev/null +++ b/tests/ui/short_circuit_statement.stderr @@ -0,0 +1,34 @@ +error: boolean short circuit operator in statement may be clearer using an explicit test + --> $DIR/short_circuit_statement.rs:7:5 + | +7 | f() && g(); + | ^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/short_circuit_statement.rs:4:9 + | +4 | #![deny(short_circuit_statement)] + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: replace it with + | if f() { g(); } + +error: boolean short circuit operator in statement may be clearer using an explicit test + --> $DIR/short_circuit_statement.rs:11:5 + | +11 | f() || g(); + | ^^^^^^^^^^^ + | +help: replace it with + | if !f() { g(); } + +error: boolean short circuit operator in statement may be clearer using an explicit test + --> $DIR/short_circuit_statement.rs:15:5 + | +15 | 1 == 2 || g(); + | ^^^^^^^^^^^^^^ + | +help: replace it with + | if !(1 == 2) { g(); } + +error: aborting due to 3 previous errors + diff --git a/tests/ui/strings.rs b/tests/ui/strings.rs new file mode 100644 index 000000000000..f893d99491be --- /dev/null +++ b/tests/ui/strings.rs @@ -0,0 +1,73 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#[deny(string_add)] +#[allow(string_add_assign)] +fn add_only() { // ignores assignment distinction + let mut x = "".to_owned(); + + for _ in 1..3 { + x = x + "."; + } + + let y = "".to_owned(); + let z = y + "..."; + + assert_eq!(&x, &z); +} + +#[deny(string_add_assign)] +fn add_assign_only() { + let mut x = "".to_owned(); + + for _ in 1..3 { + x = x + "."; + } + + let y = "".to_owned(); + let z = y + "..."; + + assert_eq!(&x, &z); +} + +#[deny(string_add, string_add_assign)] +fn both() { + let mut x = "".to_owned(); + + for _ in 1..3 { + x = x + "."; + } + + let y = "".to_owned(); + let z = y + "..."; + + assert_eq!(&x, &z); +} + +#[allow(dead_code, unused_variables)] +#[deny(string_lit_as_bytes)] +fn str_lit_as_bytes() { + let bs = "hello there".as_bytes(); + + + + + // no warning, because this cannot be written as a byte string literal: + let ubs = "☃".as_bytes(); + + let strify = stringify!(foobar).as_bytes(); +} + +fn main() { + add_only(); + add_assign_only(); + both(); + + // the add is only caught for `String` + let mut x = 1; + ; x = x + 1; + + + + assert_eq!(2, x); +} diff --git a/tests/ui/strings.stderr b/tests/ui/strings.stderr new file mode 100644 index 000000000000..b16724261d87 --- /dev/null +++ b/tests/ui/strings.stderr @@ -0,0 +1,80 @@ +error: you added something to a string. Consider using `String::push_str()` instead + --> $DIR/strings.rs:10:13 + | +10 | x = x + "."; + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/strings.rs:4:8 + | +4 | #[deny(string_add)] + | ^^^^^^^^^^ + +error: you added something to a string. Consider using `String::push_str()` instead + --> $DIR/strings.rs:14:13 + | +14 | let z = y + "..."; + | ^^^^^^^^^ + +error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead + --> $DIR/strings.rs:24:9 + | +24 | x = x + "."; + | ^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/strings.rs:19:8 + | +19 | #[deny(string_add_assign)] + | ^^^^^^^^^^^^^^^^^ + +error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead + --> $DIR/strings.rs:38:9 + | +38 | x = x + "."; + | ^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/strings.rs:33:20 + | +33 | #[deny(string_add, string_add_assign)] + | ^^^^^^^^^^^^^^^^^ + +error: you added something to a string. Consider using `String::push_str()` instead + --> $DIR/strings.rs:42:13 + | +42 | let z = y + "..."; + | ^^^^^^^^^ + | +note: lint level defined here + --> $DIR/strings.rs:33:8 + | +33 | #[deny(string_add, string_add_assign)] + | ^^^^^^^^^^ + +error: calling `as_bytes()` on a string literal + --> $DIR/strings.rs:50:14 + | +50 | let bs = "hello there".as_bytes(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/strings.rs:48:8 + | +48 | #[deny(string_lit_as_bytes)] + | ^^^^^^^^^^^^^^^^^^^ +help: consider using a byte string literal instead + | let bs = b"hello there"; + +warning: manual implementation of an assign operation + --> $DIR/strings.rs:68:7 + | +68 | ; x = x + 1; + | ^^^^^^^^^ + | + = note: #[warn(assign_op_pattern)] on by default +help: replace it with + | ; x += 1; + +error: aborting due to 6 previous errors + diff --git a/tests/ui/stutter.rs b/tests/ui/stutter.rs new file mode 100644 index 000000000000..922ab080d73c --- /dev/null +++ b/tests/ui/stutter.rs @@ -0,0 +1,14 @@ +#![feature(plugin)] +#![plugin(clippy)] +#![deny(stutter)] +#![allow(dead_code)] + +mod foo { + pub fn foo() {} + pub fn foo_bar() {} + pub fn bar_foo() {} + pub struct FooCake {} + pub enum CakeFoo {} +} + +fn main() {} diff --git a/tests/ui/stutter.stderr b/tests/ui/stutter.stderr new file mode 100644 index 000000000000..03f4c7396b40 --- /dev/null +++ b/tests/ui/stutter.stderr @@ -0,0 +1,32 @@ +error: item name starts with its containing module's name + --> $DIR/stutter.rs:8:5 + | +8 | pub fn foo_bar() {} + | ^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/stutter.rs:3:9 + | +3 | #![deny(stutter)] + | ^^^^^^^ + +error: item name ends with its containing module's name + --> $DIR/stutter.rs:9:5 + | +9 | pub fn bar_foo() {} + | ^^^^^^^^^^^^^^^^^^^ + +error: item name starts with its containing module's name + --> $DIR/stutter.rs:10:5 + | +10 | pub struct FooCake {} + | ^^^^^^^^^^^^^^^^^^^^^ + +error: item name ends with its containing module's name + --> $DIR/stutter.rs:11:5 + | +11 | pub enum CakeFoo {} + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/swap.rs b/tests/ui/swap.rs new file mode 100644 index 000000000000..95478dda0d32 --- /dev/null +++ b/tests/ui/swap.rs @@ -0,0 +1,84 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#![deny(clippy)] +#![allow(blacklisted_name, unused_assignments)] + +struct Foo(u32); + +fn array() { + let mut foo = [1, 2]; + let temp = foo[0]; + foo[0] = foo[1]; + foo[1] = temp; + + + + + foo.swap(0, 1); +} + +fn slice() { + let foo = &mut [1, 2]; + let temp = foo[0]; + foo[0] = foo[1]; + foo[1] = temp; + + + + + foo.swap(0, 1); +} + +fn vec() { + let mut foo = vec![1, 2]; + let temp = foo[0]; + foo[0] = foo[1]; + foo[1] = temp; + + + + + foo.swap(0, 1); +} + +fn main() { + array(); + slice(); + vec(); + + let mut a = 42; + let mut b = 1337; + + a = b; + b = a; + + + + + + ; let t = a; + a = b; + b = t; + + + + + + let mut c = Foo(42); + + c.0 = a; + a = c.0; + + + + + + ; let t = c.0; + c.0 = a; + a = t; + + + + +} diff --git a/tests/ui/swap.stderr b/tests/ui/swap.stderr new file mode 100644 index 000000000000..714b6859ffd1 --- /dev/null +++ b/tests/ui/swap.stderr @@ -0,0 +1,105 @@ +error: this looks like you are swapping elements of `foo` manually + --> $DIR/swap.rs:11:5 + | +11 | let temp = foo[0]; + | _____^ starting here... +12 | | foo[0] = foo[1]; +13 | | foo[1] = temp; + | |_________________^ ...ending here + | + = note: #[deny(manual_swap)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/swap.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ +help: try + | foo.swap(0, 1); + +error: this looks like you are swapping elements of `foo` manually + --> $DIR/swap.rs:23:5 + | +23 | let temp = foo[0]; + | _____^ starting here... +24 | | foo[0] = foo[1]; +25 | | foo[1] = temp; + | |_________________^ ...ending here + | + = note: #[deny(manual_swap)] implied by #[deny(clippy)] +help: try + | foo.swap(0, 1); + +error: this looks like you are swapping elements of `foo` manually + --> $DIR/swap.rs:35:5 + | +35 | let temp = foo[0]; + | _____^ starting here... +36 | | foo[0] = foo[1]; +37 | | foo[1] = temp; + | |_________________^ ...ending here + | + = note: #[deny(manual_swap)] implied by #[deny(clippy)] +help: try + | foo.swap(0, 1); + +error: this looks like you are swapping `a` and `b` manually + --> $DIR/swap.rs:60:7 + | +60 | ; let t = a; + | _______^ starting here... +61 | | a = b; +62 | | b = t; + | |_________^ ...ending here + | + = note: #[deny(manual_swap)] implied by #[deny(clippy)] +help: try + | ; std::mem::swap(&mut a, &mut b); + = note: or maybe you should use `std::mem::replace`? + +error: this looks like you are swapping `c.0` and `a` manually + --> $DIR/swap.rs:77:7 + | +77 | ; let t = c.0; + | _______^ starting here... +78 | | c.0 = a; +79 | | a = t; + | |_________^ ...ending here + | + = note: #[deny(manual_swap)] implied by #[deny(clippy)] +help: try + | ; std::mem::swap(&mut c.0, &mut a); + = note: or maybe you should use `std::mem::replace`? + +error: this looks like you are trying to swap `a` and `b` + --> $DIR/swap.rs:53:5 + | +53 | a = b; + | _____^ starting here... +54 | | b = a; + | |_________^ ...ending here + | + = note: #[deny(almost_swapped)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/swap.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ +help: try + | std::mem::swap(&mut a, &mut b); + = note: or maybe you should use `std::mem::replace`? + +error: this looks like you are trying to swap `c.0` and `a` + --> $DIR/swap.rs:70:5 + | +70 | c.0 = a; + | _____^ starting here... +71 | | a = c.0; + | |___________^ ...ending here + | + = note: #[deny(almost_swapped)] implied by #[deny(clippy)] +help: try + | std::mem::swap(&mut c.0, &mut a); + = note: or maybe you should use `std::mem::replace`? + +error: aborting due to 7 previous errors + diff --git a/tests/compile-fail/temporary_assignment.rs b/tests/ui/temporary_assignment.rs similarity index 82% rename from tests/compile-fail/temporary_assignment.rs rename to tests/ui/temporary_assignment.rs index b1c2b990024f..752d897d0144 100644 --- a/tests/compile-fail/temporary_assignment.rs +++ b/tests/ui/temporary_assignment.rs @@ -26,8 +26,8 @@ fn main() { let mut s = Struct { field: 0 }; let mut t = (0, 0); - Struct { field: 0 }.field = 1; //~ERROR assignment to temporary - (0, 0).0 = 1; //~ERROR assignment to temporary + Struct { field: 0 }.field = 1; + (0, 0).0 = 1; // no error s.field = 1; diff --git a/tests/ui/temporary_assignment.stderr b/tests/ui/temporary_assignment.stderr new file mode 100644 index 000000000000..ea39d798e2d8 --- /dev/null +++ b/tests/ui/temporary_assignment.stderr @@ -0,0 +1,20 @@ +error: assignment to temporary + --> $DIR/temporary_assignment.rs:29:5 + | +29 | Struct { field: 0 }.field = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/temporary_assignment.rs:4:9 + | +4 | #![deny(temporary_assignment)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: assignment to temporary + --> $DIR/temporary_assignment.rs:30:5 + | +30 | (0, 0).0 = 1; + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/toplevel_ref_arg.rs b/tests/ui/toplevel_ref_arg.rs new file mode 100644 index 000000000000..a69600899afa --- /dev/null +++ b/tests/ui/toplevel_ref_arg.rs @@ -0,0 +1,40 @@ +#![feature(plugin)] + +#![plugin(clippy)] +#![deny(clippy)] +#![allow(unused)] + +fn the_answer(ref mut x: u8) { + *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; + + + + + let ref y: (&_, u8) = (&1, 2); + + + + + let ref z = 1 + 2; + + + + + let ref mut z = 1 + 2; + + + + + let (ref x, _) = (1,2); // okay, not top level + println!("The answer is {}.", x); +} diff --git a/tests/ui/toplevel_ref_arg.stderr b/tests/ui/toplevel_ref_arg.stderr new file mode 100644 index 000000000000..86dd880ed127 --- /dev/null +++ b/tests/ui/toplevel_ref_arg.stderr @@ -0,0 +1,55 @@ +error: `ref` directly on a function argument is ignored. Consider using a reference type instead. + --> $DIR/toplevel_ref_arg.rs:7:15 + | +7 | fn the_answer(ref mut x: u8) { + | ^^^^^^^^^ + | + = note: #[deny(toplevel_ref_arg)] implied by #[deny(clippy)] +note: lint level defined here + --> $DIR/toplevel_ref_arg.rs:4:9 + | +4 | #![deny(clippy)] + | ^^^^^^ + +error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead + --> $DIR/toplevel_ref_arg.rs:18:7 + | +18 | let ref x = 1; + | ^^^^^ + | + = note: #[deny(toplevel_ref_arg)] implied by #[deny(clippy)] +help: try + | let x = &1; + +error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead + --> $DIR/toplevel_ref_arg.rs:23:7 + | +23 | let ref y: (&_, u8) = (&1, 2); + | ^^^^^ + | + = note: #[deny(toplevel_ref_arg)] implied by #[deny(clippy)] +help: try + | let y: &(&_, u8) = &(&1, 2); + +error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead + --> $DIR/toplevel_ref_arg.rs:28:7 + | +28 | let ref z = 1 + 2; + | ^^^^^ + | + = note: #[deny(toplevel_ref_arg)] implied by #[deny(clippy)] +help: try + | let z = &(1 + 2); + +error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead + --> $DIR/toplevel_ref_arg.rs:33:7 + | +33 | let ref mut z = 1 + 2; + | ^^^^^^^^^ + | + = note: #[deny(toplevel_ref_arg)] implied by #[deny(clippy)] +help: try + | let z = &mut (1 + 2); + +error: aborting due to 5 previous errors + diff --git a/tests/compile-fail/transmute.rs b/tests/ui/transmute.rs similarity index 52% rename from tests/compile-fail/transmute.rs rename to tests/ui/transmute.rs index c5ab854b05ae..1fae47c8aa04 100644 --- a/tests/compile-fail/transmute.rs +++ b/tests/ui/transmute.rs @@ -20,68 +20,68 @@ fn my_vec() -> MyVec { #[deny(useless_transmute)] unsafe fn _generic<'a, T, U: 'a>(t: &'a T) { let _: &'a T = core::intrinsics::transmute(t); - //~^ ERROR transmute from a type (`&'a T`) to itself + let _: &'a U = core::intrinsics::transmute(t); let _: *const T = core::intrinsics::transmute(t); - //~^ ERROR transmute from a reference to a pointer - //~| HELP try - //~| SUGGESTION = t as *const T + + + let _: *mut T = core::intrinsics::transmute(t); - //~^ ERROR transmute from a reference to a pointer - //~| HELP try - //~| SUGGESTION = t as *const T as *mut T + + + let _: *const U = core::intrinsics::transmute(t); - //~^ ERROR transmute from a reference to a pointer - //~| HELP try - //~| SUGGESTION = t as *const T as *const U + + + } #[deny(transmute_ptr_to_ref)] unsafe fn _ptr_to_ref(p: *const T, m: *mut T, o: *const U, om: *mut U) { let _: &T = std::mem::transmute(p); - //~^ ERROR transmute from a pointer type (`*const T`) to a reference type (`&T`) - //~| HELP try - //~| SUGGESTION = &*p; + + + let _: &T = &*p; let _: &mut T = std::mem::transmute(m); - //~^ ERROR transmute from a pointer type (`*mut T`) to a reference type (`&mut T`) - //~| HELP try - //~| SUGGESTION = &mut *m; + + + let _: &mut T = &mut *m; let _: &T = std::mem::transmute(m); - //~^ ERROR transmute from a pointer type (`*mut T`) to a reference type (`&T`) - //~| HELP try - //~| SUGGESTION = &*m; + + + let _: &T = &*m; let _: &mut T = std::mem::transmute(p as *mut T); - //~^ ERROR transmute from a pointer type (`*mut T`) to a reference type (`&mut T`) - //~| HELP try - //~| SUGGESTION = &mut *(p as *mut T); + + + let _ = &mut *(p as *mut T); let _: &T = std::mem::transmute(o); - //~^ ERROR transmute from a pointer type (`*const U`) to a reference type (`&T`) - //~| HELP try - //~| SUGGESTION = &*(o as *const T); + + + let _: &T = &*(o as *const T); let _: &mut T = std::mem::transmute(om); - //~^ ERROR transmute from a pointer type (`*mut U`) to a reference type (`&mut T`) - //~| HELP try - //~| SUGGESTION = &mut *(om as *mut T); + + + let _: &mut T = &mut *(om as *mut T); let _: &T = std::mem::transmute(om); - //~^ ERROR transmute from a pointer type (`*mut U`) to a reference type (`&T`) - //~| HELP try - //~| SUGGESTION = &*(om as *const T); + + + let _: &T = &*(om as *const T); } @@ -93,40 +93,40 @@ fn issue1231() { let raw = 0 as *const i32; let _: &Foo = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) }; - //~^ ERROR transmute from a pointer type - //~| HELP try - //~| SUGGESTION unsafe { &*(raw as *const Foo<_>) }; + + + let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) }; - //~^ ERROR transmute from a pointer type - //~| HELP try - //~| SUGGESTION unsafe { &*(raw as *const Foo<&_>) }; + + + type Bar<'a> = &'a u8; let raw = 0 as *const i32; unsafe { std::mem::transmute::<_, Bar>(raw) }; - //~^ ERROR transmute from a pointer type - //~| HELP try - //~| SUGGESTION unsafe { &*(raw as *const u8) }; + + + } #[deny(useless_transmute)] fn useless() { unsafe { let _: Vec = core::intrinsics::transmute(my_vec()); - //~^ ERROR transmute from a type (`std::vec::Vec`) to itself + let _: Vec = core::mem::transmute(my_vec()); - //~^ ERROR transmute from a type (`std::vec::Vec`) to itself + let _: Vec = std::intrinsics::transmute(my_vec()); - //~^ ERROR transmute from a type (`std::vec::Vec`) to itself + let _: Vec = std::mem::transmute(my_vec()); - //~^ ERROR transmute from a type (`std::vec::Vec`) to itself + let _: Vec = my_transmute(my_vec()); - //~^ ERROR transmute from a type (`std::vec::Vec`) to itself + let _: Vec = core::intrinsics::transmute(my_vec()); let _: Vec = core::mem::transmute(my_vec()); @@ -135,15 +135,15 @@ fn useless() { let _: Vec = my_transmute(my_vec()); let _: *const usize = std::mem::transmute(5_isize); - //~^ ERROR transmute from an integer to a pointer - //~| HELP try - //~| SUGGESTION 5_isize as *const usize + + + let _ = 5_isize as *const usize; let _: *const usize = std::mem::transmute(1+1usize); - //~^ ERROR transmute from an integer to a pointer - //~| HELP try - //~| SUGGESTION (1+1usize) as *const usize + + + let _ = (1+1_usize) as *const usize; } } @@ -158,16 +158,16 @@ fn crosspointer() { unsafe { let _: Usize = core::intrinsics::transmute(int_const_ptr); - //~^ ERROR transmute from a type (`*const Usize`) to the type that it points to (`Usize`) + let _: Usize = core::intrinsics::transmute(int_mut_ptr); - //~^ ERROR transmute from a type (`*mut Usize`) to the type that it points to (`Usize`) + let _: *const Usize = core::intrinsics::transmute(my_int()); - //~^ ERROR transmute from a type (`Usize`) to a pointer to that type (`*const Usize`) + let _: *mut Usize = core::intrinsics::transmute(my_int()); - //~^ ERROR transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`) + } } diff --git a/tests/ui/transmute.stderr b/tests/ui/transmute.stderr new file mode 100644 index 000000000000..ec9e79418550 --- /dev/null +++ b/tests/ui/transmute.stderr @@ -0,0 +1,225 @@ +error: transmute from a type (`&'a T`) to itself + --> $DIR/transmute.rs:22:20 + | +22 | let _: &'a T = core::intrinsics::transmute(t); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/transmute.rs:20:8 + | +20 | #[deny(useless_transmute)] + | ^^^^^^^^^^^^^^^^^ + +error: transmute from a reference to a pointer + --> $DIR/transmute.rs:27:23 + | +27 | let _: *const T = core::intrinsics::transmute(t); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: *const T = t as *const T; + +error: transmute from a reference to a pointer + --> $DIR/transmute.rs:32:21 + | +32 | let _: *mut T = core::intrinsics::transmute(t); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: *mut T = t as *const T as *mut T; + +error: transmute from a reference to a pointer + --> $DIR/transmute.rs:37:23 + | +37 | let _: *const U = core::intrinsics::transmute(t); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: *const U = t as *const T as *const U; + +error: transmute from a pointer type (`*const T`) to a reference type (`&T`) + --> $DIR/transmute.rs:45:17 + | +45 | let _: &T = std::mem::transmute(p); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/transmute.rs:43:8 + | +43 | #[deny(transmute_ptr_to_ref)] + | ^^^^^^^^^^^^^^^^^^^^ +help: try + | let _: &T = &*p; + +error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`) + --> $DIR/transmute.rs:51:21 + | +51 | let _: &mut T = std::mem::transmute(m); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: &mut T = &mut *m; + +error: transmute from a pointer type (`*mut T`) to a reference type (`&T`) + --> $DIR/transmute.rs:57:17 + | +57 | let _: &T = std::mem::transmute(m); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: &T = &*m; + +error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`) + --> $DIR/transmute.rs:63:21 + | +63 | let _: &mut T = std::mem::transmute(p as *mut T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: &mut T = &mut *(p as *mut T); + +error: transmute from a pointer type (`*const U`) to a reference type (`&T`) + --> $DIR/transmute.rs:69:17 + | +69 | let _: &T = std::mem::transmute(o); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: &T = &*(o as *const T); + +error: transmute from a pointer type (`*mut U`) to a reference type (`&mut T`) + --> $DIR/transmute.rs:75:21 + | +75 | let _: &mut T = std::mem::transmute(om); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: &mut T = &mut *(om as *mut T); + +error: transmute from a pointer type (`*mut U`) to a reference type (`&T`) + --> $DIR/transmute.rs:81:17 + | +81 | let _: &T = std::mem::transmute(om); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: &T = &*(om as *const T); + +error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<'_, u8>`) + --> $DIR/transmute.rs:95:32 + | +95 | let _: &Foo = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/transmute.rs:88:8 + | +88 | #[deny(transmute_ptr_to_ref)] + | ^^^^^^^^^^^^^^^^^^^^ +help: try + | let _: &Foo = unsafe { &*(raw as *const Foo<_>) }; + +error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<'_, &u8>`) + --> $DIR/transmute.rs:100:33 + | +100 | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: &Foo<&u8> = unsafe { &*(raw as *const Foo<&_>) }; + +error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`) + --> $DIR/transmute.rs:107:14 + | +107 | unsafe { std::mem::transmute::<_, Bar>(raw) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | unsafe { &*(raw as *const u8) }; + +error: transmute from a type (`std::vec::Vec`) to itself + --> $DIR/transmute.rs:116:27 + | +116 | let _: Vec = core::intrinsics::transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/transmute.rs:113:8 + | +113 | #[deny(useless_transmute)] + | ^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`std::vec::Vec`) to itself + --> $DIR/transmute.rs:119:27 + | +119 | let _: Vec = core::mem::transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`std::vec::Vec`) to itself + --> $DIR/transmute.rs:122:27 + | +122 | let _: Vec = std::intrinsics::transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`std::vec::Vec`) to itself + --> $DIR/transmute.rs:125:27 + | +125 | let _: Vec = std::mem::transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`std::vec::Vec`) to itself + --> $DIR/transmute.rs:128:27 + | +128 | let _: Vec = my_transmute(my_vec()); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from an integer to a pointer + --> $DIR/transmute.rs:137:31 + | +137 | let _: *const usize = std::mem::transmute(5_isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: *const usize = 5_isize as *const usize; + +error: transmute from an integer to a pointer + --> $DIR/transmute.rs:143:31 + | +143 | let _: *const usize = std::mem::transmute(1+1usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | let _: *const usize = (1+1usize) as *const usize; + +error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`) + --> $DIR/transmute.rs:160:24 + | +160 | let _: Usize = core::intrinsics::transmute(int_const_ptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/transmute.rs:153:8 + | +153 | #[deny(crosspointer_transmute)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`) + --> $DIR/transmute.rs:163:24 + | +163 | let _: Usize = core::intrinsics::transmute(int_mut_ptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`) + --> $DIR/transmute.rs:166:31 + | +166 | let _: *const Usize = core::intrinsics::transmute(my_int()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`) + --> $DIR/transmute.rs:169:29 + | +169 | let _: *mut Usize = core::intrinsics::transmute(my_int()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 25 previous errors + diff --git a/tests/compile-fail/transmute_32bit.rs b/tests/ui/transmute_32bit.rs similarity index 60% rename from tests/compile-fail/transmute_32bit.rs rename to tests/ui/transmute_32bit.rs index 1368ab5015d8..9c63a6fe0d90 100644 --- a/tests/compile-fail/transmute_32bit.rs +++ b/tests/ui/transmute_32bit.rs @@ -6,15 +6,15 @@ fn main() { unsafe { let _: *const usize = std::mem::transmute(6.0f32); - //~^ ERROR transmute from a `f32` to a pointer + let _: *mut usize = std::mem::transmute(6.0f32); - //~^ ERROR transmute from a `f32` to a pointer + let _: *const usize = std::mem::transmute('x'); - //~^ ERROR transmute from a `char` to a pointer + let _: *mut usize = std::mem::transmute('x'); - //~^ ERROR transmute from a `char` to a pointer + } } diff --git a/tests/compile-fail/transmute_64bit.rs b/tests/ui/transmute_64bit.rs similarity index 69% rename from tests/compile-fail/transmute_64bit.rs rename to tests/ui/transmute_64bit.rs index 8bc6a2367b91..bf7066245a1f 100644 --- a/tests/compile-fail/transmute_64bit.rs +++ b/tests/ui/transmute_64bit.rs @@ -7,9 +7,9 @@ fn main() { unsafe { let _: *const usize = std::mem::transmute(6.0f64); - //~^ ERROR transmute from a `f64` to a pointer + let _: *mut usize = std::mem::transmute(6.0f64); - //~^ ERROR transmute from a `f64` to a pointer + } } diff --git a/tests/ui/transmute_64bit.stderr b/tests/ui/transmute_64bit.stderr new file mode 100644 index 000000000000..1559809eb836 --- /dev/null +++ b/tests/ui/transmute_64bit.stderr @@ -0,0 +1,20 @@ +error: transmute from a `f64` to a pointer + --> $DIR/transmute_64bit.rs:9:31 + | +9 | let _: *const usize = std::mem::transmute(6.0f64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/transmute_64bit.rs:6:8 + | +6 | #[deny(wrong_transmute)] + | ^^^^^^^^^^^^^^^ + +error: transmute from a `f64` to a pointer + --> $DIR/transmute_64bit.rs:12:29 + | +12 | let _: *mut usize = std::mem::transmute(6.0f64); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/unicode.rs b/tests/ui/unicode.rs similarity index 67% rename from tests/compile-fail/unicode.rs rename to tests/ui/unicode.rs index e55a0390ff32..a12276b9851e 100644 --- a/tests/compile-fail/unicode.rs +++ b/tests/ui/unicode.rs @@ -4,19 +4,19 @@ #[deny(zero_width_space)] fn zero() { print!("Here >​< is a ZWS, and ​another"); - //~^ ERROR zero-width space detected + print!("This\u{200B}is\u{200B}fine"); } #[deny(unicode_not_nfc)] fn canon() { - print!("̀àh?"); //~ERROR non-nfc unicode sequence detected + print!("̀àh?"); print!("a\u{0300}h?"); // also okay } #[deny(non_ascii_literal)] fn uni() { - print!("Üben!"); //~ERROR literal non-ASCII character detected + print!("Üben!"); print!("\u{DC}ben!"); // this is okay } diff --git a/tests/ui/unicode.stderr b/tests/ui/unicode.stderr new file mode 100644 index 000000000000..407220d1ae07 --- /dev/null +++ b/tests/ui/unicode.stderr @@ -0,0 +1,40 @@ +error: zero-width space detected + --> $DIR/unicode.rs:6:12 + | +6 | print!("Here >​< is a ZWS, and ​another"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(zero_width_space)] on by default + = help: Consider replacing the string with: + ""Here >/u{200B}< is a ZWS, and /u{200B}another"" + +error: non-nfc unicode sequence detected + --> $DIR/unicode.rs:13:12 + | +13 | print!("̀àh?"); + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/unicode.rs:11:8 + | +11 | #[deny(unicode_not_nfc)] + | ^^^^^^^^^^^^^^^ + = help: Consider replacing the string with: + ""̀àh?"" + +error: literal non-ASCII character detected + --> $DIR/unicode.rs:19:12 + | +19 | print!("Üben!"); + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/unicode.rs:17:8 + | +17 | #[deny(non_ascii_literal)] + | ^^^^^^^^^^^^^^^^^ + = help: Consider replacing the string with: + ""/u{dc}ben!"" + +error: aborting due to 3 previous errors + diff --git a/tests/compile-fail/unit_cmp.rs b/tests/ui/unit_cmp.rs similarity index 55% rename from tests/compile-fail/unit_cmp.rs rename to tests/ui/unit_cmp.rs index 13095ee6bfb4..d5176a5eaca5 100644 --- a/tests/compile-fail/unit_cmp.rs +++ b/tests/ui/unit_cmp.rs @@ -13,9 +13,9 @@ fn main() { } // this warns - if { true; } == { false; } { //~ERROR ==-comparison of unit values detected. This will always be true + if { true; } == { false; } { } - if { true; } > { false; } { //~ERROR >-comparison of unit values detected. This will always be false + if { true; } > { false; } { } } diff --git a/tests/ui/unit_cmp.stderr b/tests/ui/unit_cmp.stderr new file mode 100644 index 000000000000..fa5f108fad8c --- /dev/null +++ b/tests/ui/unit_cmp.stderr @@ -0,0 +1,20 @@ +error: ==-comparison of unit values detected. This will always be true + --> $DIR/unit_cmp.rs:16:8 + | +16 | if { true; } == { false; } { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/unit_cmp.rs:4:9 + | +4 | #![deny(unit_cmp)] + | ^^^^^^^^ + +error: >-comparison of unit values detected. This will always be false + --> $DIR/unit_cmp.rs:19:8 + | +19 | if { true; } > { false; } { + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/unneeded_field_pattern.rs b/tests/ui/unneeded_field_pattern.rs similarity index 52% rename from tests/compile-fail/unneeded_field_pattern.rs rename to tests/ui/unneeded_field_pattern.rs index 9c7623d85b71..9c1661e99ce7 100644 --- a/tests/compile-fail/unneeded_field_pattern.rs +++ b/tests/ui/unneeded_field_pattern.rs @@ -14,10 +14,10 @@ fn main() { let f = Foo { a: 0, b: 0, c: 0 }; match f { - Foo { a: _, b: 0, .. } => {} //~ERROR You matched a field with a wildcard pattern - //~^ HELP Try with `Foo { b: 0, .. }` - Foo { a: _, b: _, c: _ } => {} //~ERROR All the struct fields are matched to a - //~^ HELP Try with `Foo { .. }` + Foo { a: _, b: 0, .. } => {} + + Foo { a: _, b: _, c: _ } => {} + } match f { Foo { b: 0, .. } => {} // should be OK diff --git a/tests/ui/unneeded_field_pattern.stderr b/tests/ui/unneeded_field_pattern.stderr new file mode 100644 index 000000000000..fdf976fd5194 --- /dev/null +++ b/tests/ui/unneeded_field_pattern.stderr @@ -0,0 +1,23 @@ +error: You matched a field with a wildcard pattern. Consider using `..` instead + --> $DIR/unneeded_field_pattern.rs:17:15 + | +17 | Foo { a: _, b: 0, .. } => {} + | ^^^^ + | +note: lint level defined here + --> $DIR/unneeded_field_pattern.rs:4:9 + | +4 | #![deny(unneeded_field_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = help: Try with `Foo { b: 0, .. }` + +error: All the struct fields are matched to a wildcard pattern, consider using `..`. + --> $DIR/unneeded_field_pattern.rs:19:9 + | +19 | Foo { a: _, b: _, c: _ } => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: Try with `Foo { .. }` instead + +error: aborting due to 2 previous errors + diff --git a/tests/compile-fail/unsafe_removed_from_name.rs b/tests/ui/unsafe_removed_from_name.rs similarity index 75% rename from tests/compile-fail/unsafe_removed_from_name.rs rename to tests/ui/unsafe_removed_from_name.rs index 3e5f6e58c90a..7ff20223bd2c 100644 --- a/tests/compile-fail/unsafe_removed_from_name.rs +++ b/tests/ui/unsafe_removed_from_name.rs @@ -5,10 +5,10 @@ #![deny(unsafe_removed_from_name)] use std::cell::{UnsafeCell as TotallySafeCell}; -//~^ ERROR removed "unsafe" from the name of `UnsafeCell` in use as `TotallySafeCell` + use std::cell::UnsafeCell as TotallySafeCellAgain; -//~^ ERROR removed "unsafe" from the name of `UnsafeCell` in use as `TotallySafeCellAgain` + // Shouldn't error use std::cell::{UnsafeCell as SuperDangerousUnsafeCell}; @@ -23,7 +23,7 @@ mod mod_with_some_unsafe_things { } use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; -//~^ ERROR removed "unsafe" from the name of `Unsafe` in use as `LieAboutModSafety` + // Shouldn't error use mod_with_some_unsafe_things::Safe as IPromiseItsSafeThisTime; diff --git a/tests/ui/unsafe_removed_from_name.stderr b/tests/ui/unsafe_removed_from_name.stderr new file mode 100644 index 000000000000..4080353efbd7 --- /dev/null +++ b/tests/ui/unsafe_removed_from_name.stderr @@ -0,0 +1,26 @@ +error: removed "unsafe" from the name of `UnsafeCell` in use as `TotallySafeCell` + --> $DIR/unsafe_removed_from_name.rs:7:1 + | +7 | use std::cell::{UnsafeCell as TotallySafeCell}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/unsafe_removed_from_name.rs:5:9 + | +5 | #![deny(unsafe_removed_from_name)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: removed "unsafe" from the name of `UnsafeCell` in use as `TotallySafeCellAgain` + --> $DIR/unsafe_removed_from_name.rs:10:1 + | +10 | use std::cell::UnsafeCell as TotallySafeCellAgain; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: removed "unsafe" from the name of `Unsafe` in use as `LieAboutModSafety` + --> $DIR/unsafe_removed_from_name.rs:25:1 + | +25 | use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/compile-fail/unused_io_amount.rs b/tests/ui/unused_io_amount.rs similarity index 78% rename from tests/compile-fail/unused_io_amount.rs rename to tests/ui/unused_io_amount.rs index 2e63705c5107..7456a3602d66 100644 --- a/tests/compile-fail/unused_io_amount.rs +++ b/tests/ui/unused_io_amount.rs @@ -15,19 +15,19 @@ fn try_macro(s: &mut T) -> io::Result<()> { fn question_mark(s: &mut T) -> io::Result<()> { s.write(b"test")?; - //~^ ERROR handle written amount returned + let mut buf = [0u8; 4]; s.read(&mut buf)?; - //~^ ERROR handle read amount returned + Ok(()) } fn unwrap(s: &mut T) { s.write(b"test").unwrap(); - //~^ ERROR handle written amount returned + let mut buf = [0u8; 4]; s.read(&mut buf).unwrap(); - //~^ ERROR handle read amount returned + } fn main() { diff --git a/tests/ui/unused_io_amount.stderr b/tests/ui/unused_io_amount.stderr new file mode 100644 index 000000000000..54d8158908fa --- /dev/null +++ b/tests/ui/unused_io_amount.stderr @@ -0,0 +1,52 @@ +error: handle written amount returned or use `Write::write_all` instead + --> $DIR/unused_io_amount.rs:10:5 + | +10 | try!(s.write(b"test")); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(unused_io_amount)] on by default + = note: this error originates in a macro outside of the current crate + +error: handle read amount returned or use `Read::read_exact` instead + --> $DIR/unused_io_amount.rs:12:5 + | +12 | try!(s.read(&mut buf)); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(unused_io_amount)] on by default + = note: this error originates in a macro outside of the current crate + +error: handle written amount returned or use `Write::write_all` instead + --> $DIR/unused_io_amount.rs:17:5 + | +17 | s.write(b"test")?; + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(unused_io_amount)] on by default + +error: handle read amount returned or use `Read::read_exact` instead + --> $DIR/unused_io_amount.rs:20:5 + | +20 | s.read(&mut buf)?; + | ^^^^^^^^^^^^^^^^^ + | + = note: #[deny(unused_io_amount)] on by default + +error: handle written amount returned or use `Write::write_all` instead + --> $DIR/unused_io_amount.rs:26:5 + | +26 | s.write(b"test").unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(unused_io_amount)] on by default + +error: handle read amount returned or use `Read::read_exact` instead + --> $DIR/unused_io_amount.rs:29:5 + | +29 | s.read(&mut buf).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(unused_io_amount)] on by default + +error: aborting due to 6 previous errors + diff --git a/tests/compile-fail/unused_labels.rs b/tests/ui/unused_labels.rs similarity index 69% rename from tests/compile-fail/unused_labels.rs rename to tests/ui/unused_labels.rs index 26b4d4a2f3b2..ce718c4903a1 100644 --- a/tests/compile-fail/unused_labels.rs +++ b/tests/ui/unused_labels.rs @@ -5,7 +5,7 @@ #![deny(unused_label)] fn unused_label() { - 'label: for i in 1..2 { //~ERROR: unused label `'label` + 'label: for i in 1..2 { if i > 4 { continue } } } @@ -18,7 +18,7 @@ fn foo() { fn bla() { - 'a: loop { break } //~ERROR: unused label `'a` + 'a: loop { break } fn blub() {} } @@ -29,7 +29,7 @@ fn main() { } } - 'same_label_in_two_fns: loop { //~ERROR: unused label `'same_label_in_two_fns` + 'same_label_in_two_fns: loop { let _ = 1; } } diff --git a/tests/ui/unused_labels.stderr b/tests/ui/unused_labels.stderr new file mode 100644 index 000000000000..7b124477ded0 --- /dev/null +++ b/tests/ui/unused_labels.stderr @@ -0,0 +1,32 @@ +error: unused label `'label` + --> $DIR/unused_labels.rs:8:5 + | +8 | 'label: for i in 1..2 { + | _____^ starting here... +9 | | if i > 4 { continue } +10 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/unused_labels.rs:5:9 + | +5 | #![deny(unused_label)] + | ^^^^^^^^^^^^ + +error: unused label `'a` + --> $DIR/unused_labels.rs:21:5 + | +21 | 'a: loop { break } + | ^^^^^^^^^^^^^^^^^^ + +error: unused label `'same_label_in_two_fns` + --> $DIR/unused_labels.rs:32:5 + | +32 | 'same_label_in_two_fns: loop { + | _____^ starting here... +33 | | let _ = 1; +34 | | } + | |_____^ ...ending here + +error: aborting due to 3 previous errors + diff --git a/tests/compile-fail/unused_lt.rs b/tests/ui/unused_lt.rs similarity index 84% rename from tests/compile-fail/unused_lt.rs rename to tests/ui/unused_lt.rs index 19502720993b..ec44420a376e 100644 --- a/tests/compile-fail/unused_lt.rs +++ b/tests/ui/unused_lt.rs @@ -13,11 +13,11 @@ fn used_lt<'a>(x: &'a u8) { } -fn unused_lt<'a>(x: u8) { //~ ERROR this lifetime +fn unused_lt<'a>(x: u8) { } -fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) { //~ ERROR this lifetime +fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) { // 'a is useless here since it's not directly bound } @@ -47,7 +47,7 @@ impl<'a> Foo<'a> for u8 { struct Bar; impl Bar { - fn x<'a>(&self) {} //~ ERROR this lifetime + fn x<'a>(&self) {} } // test for #489 (used lifetimes in bounds) diff --git a/tests/ui/unused_lt.stderr b/tests/ui/unused_lt.stderr new file mode 100644 index 000000000000..1e13f4c80b4f --- /dev/null +++ b/tests/ui/unused_lt.stderr @@ -0,0 +1,26 @@ +error: this lifetime isn't used in the function definition + --> $DIR/unused_lt.rs:16:14 + | +16 | fn unused_lt<'a>(x: u8) { + | ^^ + | +note: lint level defined here + --> $DIR/unused_lt.rs:4:9 + | +4 | #![deny(unused_lifetimes)] + | ^^^^^^^^^^^^^^^^ + +error: this lifetime isn't used in the function definition + --> $DIR/unused_lt.rs:20:25 + | +20 | fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) { + | ^^ + +error: this lifetime isn't used in the function definition + --> $DIR/unused_lt.rs:50:10 + | +50 | fn x<'a>(&self) {} + | ^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/update-all-references.sh b/tests/ui/update-all-references.sh new file mode 100755 index 000000000000..ddd69c399a5c --- /dev/null +++ b/tests/ui/update-all-references.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright 2015 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +# A script to update the references for all tests. The idea is that +# you do a run, which will generate files in the build directory +# containing the (normalized) actual output of the compiler. You then +# run this script, which will copy those files over. If you find +# yourself manually editing a foo.stderr file, you're doing it wrong. +# +# See all `update-references.sh`, if you just want to update a single test. + +if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" != "" ]]; then + echo "usage: $0 " + echo "" + echo "For example:" + echo " $0 ../../../build/x86_64-apple-darwin/test/ui" +fi + +BUILD_DIR=$PWD/$1 +MY_DIR=$(dirname $0) +cd $MY_DIR +find . -name '*.rs' | xargs ./update-references.sh $BUILD_DIR diff --git a/tests/ui/update-references.sh b/tests/ui/update-references.sh new file mode 100755 index 000000000000..aa99d35f7aa7 --- /dev/null +++ b/tests/ui/update-references.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Copyright 2015 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +# A script to update the references for particular tests. The idea is +# that you do a run, which will generate files in the build directory +# containing the (normalized) actual output of the compiler. This +# script will then copy that output and replace the "expected output" +# files. You can then commit the changes. +# +# If you find yourself manually editing a foo.stderr file, you're +# doing it wrong. + +if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then + echo "usage: $0 " + echo "" + echo "For example:" + echo " $0 ../../../build/x86_64-apple-darwin/test/ui *.rs */*.rs" +fi + +MYDIR=$(dirname $0) + +BUILD_DIR="$1" +shift + +while [[ "$1" != "" ]]; do + STDERR_NAME="${1/%.rs/.stderr}" + STDOUT_NAME="${1/%.rs/.stdout}" + shift + if [ -f $BUILD_DIR/$STDOUT_NAME ] && \ + ! (diff $BUILD_DIR/$STDOUT_NAME $MYDIR/$STDOUT_NAME >& /dev/null); then + echo updating $MYDIR/$STDOUT_NAME + cp $BUILD_DIR/$STDOUT_NAME $MYDIR/$STDOUT_NAME + fi + if [ -f $BUILD_DIR/$STDERR_NAME ] && \ + ! (diff $BUILD_DIR/$STDERR_NAME $MYDIR/$STDERR_NAME >& /dev/null); then + echo updating $MYDIR/$STDERR_NAME + cp $BUILD_DIR/$STDERR_NAME $MYDIR/$STDERR_NAME + fi +done + + diff --git a/tests/compile-fail/used_underscore_binding.rs b/tests/ui/used_underscore_binding.rs similarity index 84% rename from tests/compile-fail/used_underscore_binding.rs rename to tests/ui/used_underscore_binding.rs index c3700d1b1cd4..fe0db6346ca3 100644 --- a/tests/compile-fail/used_underscore_binding.rs +++ b/tests/ui/used_underscore_binding.rs @@ -14,16 +14,16 @@ macro_rules! test_macro { /// Test that we lint if we use a binding with a single leading underscore fn prefix_underscore(_foo: u32) -> u32 { - _foo + 1 //~ ERROR used binding `_foo` which is prefixed with an underscore + _foo + 1 } /// Test that we lint if we use a `_`-variable defined outside within a macro expansion fn in_macro(_foo: u32) { println!("{}", _foo); - //~^ ERROR used binding `_foo` which is prefixed with an underscore + assert_eq!(_foo, _foo); - //~^ ERROR used binding `_foo` which is prefixed with an underscore - //~| ERROR used binding `_foo` which is prefixed with an underscore + + test_macro!() + 1; } @@ -36,7 +36,7 @@ struct StructFieldTest { /// Test that we lint the use of a struct field which is prefixed with an underscore fn in_struct_field() { let mut s = StructFieldTest { _underscore_field: 0 }; - s._underscore_field += 1; //~ Error used binding `_underscore_field` which is prefixed with an underscore + s._underscore_field += 1; } /// Test that we do not lint if the underscore is not a prefix diff --git a/tests/ui/used_underscore_binding.stderr b/tests/ui/used_underscore_binding.stderr new file mode 100644 index 000000000000..35179ac37035 --- /dev/null +++ b/tests/ui/used_underscore_binding.stderr @@ -0,0 +1,38 @@ +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. + --> $DIR/used_underscore_binding.rs:17:5 + | +17 | _foo + 1 + | ^^^^ + | +note: lint level defined here + --> $DIR/used_underscore_binding.rs:6:9 + | +6 | #![deny(used_underscore_binding)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. + --> $DIR/used_underscore_binding.rs:22:20 + | +22 | println!("{}", _foo); + | ^^^^ + +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. + --> $DIR/used_underscore_binding.rs:24:16 + | +24 | assert_eq!(_foo, _foo); + | ^^^^ + +error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. + --> $DIR/used_underscore_binding.rs:24:22 + | +24 | assert_eq!(_foo, _foo); + | ^^^^ + +error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used. + --> $DIR/used_underscore_binding.rs:39:5 + | +39 | s._underscore_field += 1; + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/compile-fail/useless_attribute.rs b/tests/ui/useless_attribute.rs similarity index 71% rename from tests/compile-fail/useless_attribute.rs rename to tests/ui/useless_attribute.rs index de3896f091b4..2b8a4cf56d7f 100644 --- a/tests/compile-fail/useless_attribute.rs +++ b/tests/ui/useless_attribute.rs @@ -2,9 +2,9 @@ #![plugin(clippy)] #![deny(useless_attribute)] -#[allow(dead_code)] //~ ERROR useless lint attribute -//~| HELP if you just forgot a `!`, use -//~| SUGGESTION #![allow(dead_code)] +#[allow(dead_code)] + + extern crate clippy_lints; // don't lint on unused_import for `use` items diff --git a/tests/ui/useless_attribute.stderr b/tests/ui/useless_attribute.stderr new file mode 100644 index 000000000000..05d3da4ca3ff --- /dev/null +++ b/tests/ui/useless_attribute.stderr @@ -0,0 +1,16 @@ +error: useless lint attribute + --> $DIR/useless_attribute.rs:5:1 + | +5 | #[allow(dead_code)] + | ^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/useless_attribute.rs:3:9 + | +3 | #![deny(useless_attribute)] + | ^^^^^^^^^^^^^^^^^ +help: if you just forgot a `!`, use + | #![allow(dead_code)] + +error: aborting due to previous error + diff --git a/tests/compile-fail/vec.rs b/tests/ui/vec.rs similarity index 59% rename from tests/compile-fail/vec.rs rename to tests/ui/vec.rs index 7a790e621161..3717192fb981 100644 --- a/tests/compile-fail/vec.rs +++ b/tests/ui/vec.rs @@ -22,33 +22,33 @@ impl Line { fn main() { on_slice(&vec![]); - //~^ ERROR useless use of `vec!` - //~| HELP you can use - //~| SUGGESTION on_slice(&[]) + + + on_slice(&[]); on_slice(&vec![1, 2]); - //~^ ERROR useless use of `vec!` - //~| HELP you can use - //~| SUGGESTION on_slice(&[1, 2]) + + + on_slice(&[1, 2]); on_slice(&vec ![1, 2]); - //~^ ERROR useless use of `vec!` - //~| HELP you can use - //~| SUGGESTION on_slice(&[1, 2]) + + + on_slice(&[1, 2]); on_slice(&vec!(1, 2)); - //~^ ERROR useless use of `vec!` - //~| HELP you can use - //~| SUGGESTION on_slice(&[1, 2]) + + + on_slice(&[1, 2]); on_slice(&vec![1; 2]); - //~^ ERROR useless use of `vec!` - //~| HELP you can use - //~| SUGGESTION on_slice(&[1; 2]) + + + on_slice(&[1; 2]); on_vec(&vec![]); @@ -62,9 +62,9 @@ fn main() { on_slice(&vec![2; line.length()]); for a in vec![1, 2, 3] { - //~^ ERROR useless use of `vec!` - //~| HELP you can use - //~| SUGGESTION for a in &[1, 2, 3] { + + + println!("{:?}", a); } diff --git a/tests/ui/vec.stderr b/tests/ui/vec.stderr new file mode 100644 index 000000000000..c42b156fced1 --- /dev/null +++ b/tests/ui/vec.stderr @@ -0,0 +1,61 @@ +error: useless use of `vec!` + --> $DIR/vec.rs:24:14 + | +24 | on_slice(&vec![]); + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/vec.rs:4:9 + | +4 | #![deny(useless_vec)] + | ^^^^^^^^^^^ +help: you can use a slice directly + | on_slice(&[]); + +error: useless use of `vec!` + --> $DIR/vec.rs:30:14 + | +30 | on_slice(&vec![1, 2]); + | ^^^^^^^^^^^ + | +help: you can use a slice directly + | on_slice(&[1, 2]); + +error: useless use of `vec!` + --> $DIR/vec.rs:36:14 + | +36 | on_slice(&vec ![1, 2]); + | ^^^^^^^^^^^^ + | +help: you can use a slice directly + | on_slice(&[1, 2]); + +error: useless use of `vec!` + --> $DIR/vec.rs:42:14 + | +42 | on_slice(&vec!(1, 2)); + | ^^^^^^^^^^^ + | +help: you can use a slice directly + | on_slice(&[1, 2]); + +error: useless use of `vec!` + --> $DIR/vec.rs:48:14 + | +48 | on_slice(&vec![1; 2]); + | ^^^^^^^^^^^ + | +help: you can use a slice directly + | on_slice(&[1; 2]); + +error: useless use of `vec!` + --> $DIR/vec.rs:64:14 + | +64 | for a in vec![1, 2, 3] { + | ^^^^^^^^^^^^^ + | +help: you can use a slice directly + | for a in &[1, 2, 3] { + +error: aborting due to 6 previous errors + diff --git a/tests/compile-fail/while_loop.rs b/tests/ui/while_loop.rs similarity index 75% rename from tests/compile-fail/while_loop.rs rename to tests/ui/while_loop.rs index 7b0fb43575ee..2b75e5b83e8f 100644 --- a/tests/compile-fail/while_loop.rs +++ b/tests/ui/while_loop.rs @@ -7,9 +7,9 @@ fn main() { let y = Some(true); loop { - //~^ERROR this loop could be written as a `while let` loop - //~|HELP try - //~|SUGGESTION while let Some(_x) = y { + + + if let Some(_x) = y { let _v = 1; } else { @@ -23,18 +23,18 @@ fn main() { break; } loop { - //~^ERROR this loop could be written as a `while let` loop - //~|HELP try - //~|SUGGESTION while let Some(_x) = y { + + + match y { Some(_x) => true, None => break }; } loop { - //~^ERROR this loop could be written as a `while let` loop - //~|HELP try - //~|SUGGESTION while let Some(x) = y { + + + let x = match y { Some(x) => x, None => break @@ -43,9 +43,9 @@ fn main() { let _str = "foo"; } loop { - //~^ERROR this loop could be written as a `while let` loop - //~|HELP try - //~|SUGGESTION while let Some(x) = y { + + + let x = match y { Some(x) => x, None => break, @@ -68,9 +68,9 @@ fn main() { // #675, this used to have a wrong suggestion loop { - //~^ERROR this loop could be written as a `while let` loop - //~|HELP try - //~|SUGGESTION while let Some(word) = "".split_whitespace().next() { .. } + + + let (e, l) = match "".split_whitespace().next() { Some(word) => (word.is_empty(), word.len()), None => break @@ -81,25 +81,25 @@ fn main() { let mut iter = 1..20; while let Option::Some(x) = iter.next() { - //~^ ERROR this loop could be written as a `for` loop - //~| HELP try - //~| SUGGESTION for x in iter { + + + println!("{}", x); } let mut iter = 1..20; while let Some(x) = iter.next() { - //~^ ERROR this loop could be written as a `for` loop - //~| HELP try - //~| SUGGESTION for x in iter { + + + println!("{}", x); } let mut iter = 1..20; while let Some(_) = iter.next() {} - //~^ ERROR this loop could be written as a `for` loop - //~| HELP try - //~| SUGGESTION for _ in iter { + + + let mut iter = 1..20; while let None = iter.next() {} // this is fine (if nonsensical) @@ -140,14 +140,14 @@ fn main() { fn no_panic(slice: &[T]) { let mut iter = slice.iter(); loop { - //~^ ERROR - //~| HELP try - //~| SUGGESTION while let Some(ele) = iter.next() { .. } + + + let _ = match iter.next() { Some(ele) => ele, None => break }; - loop {} //~ERROR empty `loop {}` detected. + loop {} } } diff --git a/tests/ui/while_loop.stderr b/tests/ui/while_loop.stderr new file mode 100644 index 000000000000..a3bb0c34f312 --- /dev/null +++ b/tests/ui/while_loop.stderr @@ -0,0 +1,126 @@ +error: this loop could be written as a `while let` loop + --> $DIR/while_loop.rs:9:5 + | +9 | loop { + | ^ + | +note: lint level defined here + --> $DIR/while_loop.rs:4:9 + | +4 | #![deny(while_let_loop, empty_loop, while_let_on_iterator)] + | ^^^^^^^^^^^^^^ +help: try + | while let Some(_x) = y { .. } + +error: this loop could be written as a `while let` loop + --> $DIR/while_loop.rs:25:5 + | +25 | loop { + | _____^ starting here... +26 | | +27 | | +28 | | +29 | | match y { +30 | | Some(_x) => true, +31 | | None => break +32 | | }; +33 | | } + | |_____^ ...ending here + | +help: try + | while let Some(_x) = y { .. } + +error: this loop could be written as a `while let` loop + --> $DIR/while_loop.rs:34:5 + | +34 | loop { + | ^ + | +help: try + | while let Some(x) = y { .. } + +error: this loop could be written as a `while let` loop + --> $DIR/while_loop.rs:45:5 + | +45 | loop { + | ^ + | +help: try + | while let Some(x) = y { .. } + +error: this loop could be written as a `while let` loop + --> $DIR/while_loop.rs:70:5 + | +70 | loop { + | ^ + | +help: try + | while let Some(word) = "".split_whitespace().next() { .. } + +error: this loop could be written as a `for` loop + --> $DIR/while_loop.rs:83:5 + | +83 | while let Option::Some(x) = iter.next() { + | _____^ starting here... +84 | | +85 | | +86 | | +87 | | println!("{}", x); +88 | | } + | |_____^ ...ending here + | +note: lint level defined here + --> $DIR/while_loop.rs:4:37 + | +4 | #![deny(while_let_loop, empty_loop, while_let_on_iterator)] + | ^^^^^^^^^^^^^^^^^^^^^ +help: try + | for x in iter { .. } + +error: this loop could be written as a `for` loop + --> $DIR/while_loop.rs:91:5 + | +91 | while let Some(x) = iter.next() { + | _____^ starting here... +92 | | +93 | | +94 | | +95 | | println!("{}", x); +96 | | } + | |_____^ ...ending here + | +help: try + | for x in iter { .. } + +error: this loop could be written as a `for` loop + --> $DIR/while_loop.rs:99:5 + | +99 | while let Some(_) = iter.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | for _ in iter { .. } + +error: this loop could be written as a `while let` loop + --> $DIR/while_loop.rs:142:5 + | +142 | loop { + | ^ + | +help: try + | while let Some(ele) = iter.next() { .. } + +error: empty `loop {}` detected. You may want to either use `panic!()` or add `std::thread::sleep(..);` to the loop body. + --> $DIR/while_loop.rs:150:9 + | +150 | loop {} + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/while_loop.rs:4:25 + | +4 | #![deny(while_let_loop, empty_loop, while_let_on_iterator)] + | ^^^^^^^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui/wrong_macro_span.rs_ b/tests/ui/wrong_macro_span.rs_ new file mode 100644 index 000000000000..fcacb030b850 --- /dev/null +++ b/tests/ui/wrong_macro_span.rs_ @@ -0,0 +1,29 @@ +#![feature(plugin)] + +#![plugin(clippy)] +#![deny(clippy)] +#![allow(unused, if_let_redundant_pattern_matching)] + +fn main() { + #[derive(Debug)] + enum Foo { + A(String), + B, + } + + struct Thingy(Foo); + + macro_rules! issue_1404 { + ($idx:tt) => {{ + let thingy = Thingy(Foo::A("Foo".into())); + let t = &thingy; + + match t.$idx { Foo::A(ref val) => { println!("42"); }, _ => {} } + + + + }} + } + + issue_1404!(0) +} diff --git a/tests/ui/wrong_self_convention.rs b/tests/ui/wrong_self_convention.rs new file mode 100644 index 000000000000..8e81679aaab2 --- /dev/null +++ b/tests/ui/wrong_self_convention.rs @@ -0,0 +1,60 @@ +#![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) {} + + 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) {} + // 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) {} + fn as_u32(&self) {} + fn into_i32(&self) {} + fn into_u32(self) {} + fn is_i32(self) {} + fn is_u32(&self) {} + fn to_i32(self) {} + fn to_u32(&self) {} + fn from_i32(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) {} + + // test for false positives + fn as_(self) {} + fn into_(&self) {} + fn is_(self) {} + fn to_(self) {} + fn from_(self) {} +} diff --git a/tests/ui/wrong_self_convention.stderr b/tests/ui/wrong_self_convention.stderr new file mode 100644 index 000000000000..cbee5bd45a26 --- /dev/null +++ b/tests/ui/wrong_self_convention.stderr @@ -0,0 +1,80 @@ +error: methods called `from_*` usually take no self; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:21:17 + | +21 | fn from_i32(self) {} + | ^^^^ + | +note: lint level defined here + --> $DIR/wrong_self_convention.rs:4:9 + | +4 | #![deny(wrong_self_convention)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: methods called `from_*` usually take no self; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:27:21 + | +27 | pub fn from_i64(self) {} + | ^^^^ + +error: methods called `as_*` usually take self by reference or self by mutable reference; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:38:15 + | +38 | fn as_i32(self) {} + | ^^^^ + +error: methods called `into_*` usually take self by value; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:40:17 + | +40 | fn into_i32(&self) {} + | ^^^^^ + +error: methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:42:15 + | +42 | fn is_i32(self) {} + | ^^^^ + +error: methods called `to_*` usually take self by reference; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:44:15 + | +44 | fn to_i32(self) {} + | ^^^^ + +error: methods called `from_*` usually take no self; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:46:17 + | +46 | fn from_i32(self) {} + | ^^^^ + +error: methods called `as_*` usually take self by reference or self by mutable reference; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:48:19 + | +48 | pub fn as_i64(self) {} + | ^^^^ + +error: methods called `into_*` usually take self by value; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:49:21 + | +49 | pub fn into_i64(&self) {} + | ^^^^^ + +error: methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:50:19 + | +50 | pub fn is_i64(self) {} + | ^^^^ + +error: methods called `to_*` usually take self by reference; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:51:19 + | +51 | pub fn to_i64(self) {} + | ^^^^ + +error: methods called `from_*` usually take no self; consider choosing a less ambiguous name + --> $DIR/wrong_self_convention.rs:52:21 + | +52 | pub fn from_i64(self) {} + | ^^^^ + +error: aborting due to 12 previous errors + diff --git a/tests/ui/zero_div_zero.rs b/tests/ui/zero_div_zero.rs new file mode 100644 index 000000000000..6f1263372467 --- /dev/null +++ b/tests/ui/zero_div_zero.rs @@ -0,0 +1,20 @@ +#![feature(plugin)] +#![plugin(clippy)] + +#[allow(unused_variables)] +#[deny(zero_divided_by_zero)] +fn main() { + let nan = 0.0 / 0.0; + + let f64_nan = 0.0 / 0.0f64; + + let other_f64_nan = 0.0f64 / 0.0; + + let one_more_f64_nan = 0.0f64/0.0f64; + + 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 +} diff --git a/tests/ui/zero_div_zero.stderr b/tests/ui/zero_div_zero.stderr new file mode 100644 index 000000000000..6b34e2da13ca --- /dev/null +++ b/tests/ui/zero_div_zero.stderr @@ -0,0 +1,71 @@ +warning: equal expressions as operands to `/` + --> $DIR/zero_div_zero.rs:7:15 + | +7 | let nan = 0.0 / 0.0; + | ^^^^^^^^^ + | + = note: #[warn(eq_op)] on by default + +error: constant division of 0.0 with 0.0 will always result in NaN + --> $DIR/zero_div_zero.rs:7:15 + | +7 | let nan = 0.0 / 0.0; + | ^^^^^^^^^ + | +note: lint level defined here + --> $DIR/zero_div_zero.rs:5:8 + | +5 | #[deny(zero_divided_by_zero)] + | ^^^^^^^^^^^^^^^^^^^^ + = help: Consider using `std::f32::NAN` if you would like a constant representing NaN + +warning: equal expressions as operands to `/` + --> $DIR/zero_div_zero.rs:9:19 + | +9 | let f64_nan = 0.0 / 0.0f64; + | ^^^^^^^^^^^^ + | + = note: #[warn(eq_op)] on by default + +error: constant division of 0.0 with 0.0 will always result in NaN + --> $DIR/zero_div_zero.rs:9:19 + | +9 | let f64_nan = 0.0 / 0.0f64; + | ^^^^^^^^^^^^ + | + = help: Consider using `std::f64::NAN` if you would like a constant representing NaN + +warning: equal expressions as operands to `/` + --> $DIR/zero_div_zero.rs:11:25 + | +11 | let other_f64_nan = 0.0f64 / 0.0; + | ^^^^^^^^^^^^ + | + = note: #[warn(eq_op)] on by default + +error: constant division of 0.0 with 0.0 will always result in NaN + --> $DIR/zero_div_zero.rs:11:25 + | +11 | let other_f64_nan = 0.0f64 / 0.0; + | ^^^^^^^^^^^^ + | + = help: Consider using `std::f64::NAN` if you would like a constant representing NaN + +warning: equal expressions as operands to `/` + --> $DIR/zero_div_zero.rs:13:28 + | +13 | let one_more_f64_nan = 0.0f64/0.0f64; + | ^^^^^^^^^^^^^ + | + = note: #[warn(eq_op)] on by default + +error: constant division of 0.0 with 0.0 will always result in NaN + --> $DIR/zero_div_zero.rs:13:28 + | +13 | let one_more_f64_nan = 0.0f64/0.0f64; + | ^^^^^^^^^^^^^ + | + = help: Consider using `std::f64::NAN` if you would like a constant representing NaN + +error: aborting due to 4 previous errors +