Skip to content

Commit 542685d

Browse files
committed
2 parents 0fa8481 + ec5d962 commit 542685d

32 files changed

+606
-224
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "clippy"
3-
version = "0.0.32"
3+
version = "0.0.35"
44
authors = [
55
"Manish Goregaokar <[email protected]>",
66
"Andre Bogus <[email protected]>",
@@ -17,7 +17,7 @@ name = "clippy"
1717
plugin = true
1818

1919
[dependencies]
20-
unicode-normalization = "*"
20+
unicode-normalization = "0.1"
2121

2222
[dev-dependencies]
2323
compiletest_rs = "0.0.11"

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your Rust code.
66
[Jump to usage instructions](#usage)
77

88
##Lints
9-
There are 86 lints included in this crate:
9+
There are 89 lints included in this crate:
1010

1111
name | default | meaning
1212
---------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -28,6 +28,7 @@ name
2828
[eq_op](https://github.com/Manishearth/rust-clippy/wiki#eq_op) | warn | equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)
2929
[explicit_counter_loop](https://github.com/Manishearth/rust-clippy/wiki#explicit_counter_loop) | warn | for-looping with an explicit counter when `_.enumerate()` would do
3030
[explicit_iter_loop](https://github.com/Manishearth/rust-clippy/wiki#explicit_iter_loop) | warn | for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do
31+
[filter_next](https://github.com/Manishearth/rust-clippy/wiki#filter_next) | warn | using `filter(p).next()`, which is more succinctly expressed as `.find(p)`
3132
[float_cmp](https://github.com/Manishearth/rust-clippy/wiki#float_cmp) | warn | using `==` or `!=` on float values (as floating-point operations usually involve rounding errors, it is always better to check for approximate equality within small bounds)
3233
[identity_op](https://github.com/Manishearth/rust-clippy/wiki#identity_op) | warn | using identity operations, e.g. `x + 0` or `y / 1`
3334
[ineffective_bit_mask](https://github.com/Manishearth/rust-clippy/wiki#ineffective_bit_mask) | warn | expressions where a bit mask will be rendered useless by a comparison, e.g. `(x | 1) > 2`
@@ -41,7 +42,7 @@ name
4142
[map_clone](https://github.com/Manishearth/rust-clippy/wiki#map_clone) | warn | using `.map(|x| x.clone())` to clone an iterator or option's contents (recommends `.cloned()` instead)
4243
[match_bool](https://github.com/Manishearth/rust-clippy/wiki#match_bool) | warn | a match on boolean expression; recommends `if..else` block instead
4344
[match_overlapping_arm](https://github.com/Manishearth/rust-clippy/wiki#match_overlapping_arm) | warn | a match has overlapping arms
44-
[match_ref_pats](https://github.com/Manishearth/rust-clippy/wiki#match_ref_pats) | warn | a match has all arms prefixed with `&`; the match expression can be dereferenced instead
45+
[match_ref_pats](https://github.com/Manishearth/rust-clippy/wiki#match_ref_pats) | warn | a match or `if let` has all arms prefixed with `&`; the match expression can be dereferenced instead
4546
[min_max](https://github.com/Manishearth/rust-clippy/wiki#min_max) | warn | `min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant
4647
[modulo_one](https://github.com/Manishearth/rust-clippy/wiki#modulo_one) | warn | taking a number modulo 1, which always returns 0
4748
[mut_mut](https://github.com/Manishearth/rust-clippy/wiki#mut_mut) | allow | usage of double-mut refs, e.g. `&mut &mut ...` (either copy'n'paste error, or shows a fundamental misunderstanding of references)
@@ -56,10 +57,11 @@ name
5657
[non_ascii_literal](https://github.com/Manishearth/rust-clippy/wiki#non_ascii_literal) | allow | using any literal non-ASCII chars in a string literal; suggests using the \\u escape instead
5758
[nonsensical_open_options](https://github.com/Manishearth/rust-clippy/wiki#nonsensical_open_options) | warn | nonsensical combination of options for opening a file
5859
[ok_expect](https://github.com/Manishearth/rust-clippy/wiki#ok_expect) | warn | using `ok().expect()`, which gives worse error messages than calling `expect` directly on the Result
59-
[option_map_unwrap_or](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or) | warn | using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as `map_or(a, f)`)
60-
[option_map_unwrap_or_else](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or_else) | warn | using `Option.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `map_or_else(g, f)`)
60+
[option_map_unwrap_or](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or) | warn | using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as `map_or(a, f)`
61+
[option_map_unwrap_or_else](https://github.com/Manishearth/rust-clippy/wiki#option_map_unwrap_or_else) | warn | using `Option.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `map_or_else(g, f)`
6162
[option_unwrap_used](https://github.com/Manishearth/rust-clippy/wiki#option_unwrap_used) | allow | using `Option.unwrap()`, which should at least get a better message using `expect()`
6263
[out_of_bounds_indexing](https://github.com/Manishearth/rust-clippy/wiki#out_of_bounds_indexing) | deny | out of bound constant indexing
64+
[panic_params](https://github.com/Manishearth/rust-clippy/wiki#panic_params) | warn | missing parameters in `panic!`
6365
[precedence](https://github.com/Manishearth/rust-clippy/wiki#precedence) | warn | catches operations where precedence may be unclear. See the wiki for a list of cases caught
6466
[ptr_arg](https://github.com/Manishearth/rust-clippy/wiki#ptr_arg) | warn | fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively
6567
[range_step_by_zero](https://github.com/Manishearth/rust-clippy/wiki#range_step_by_zero) | warn | using Range::step_by(0), which produces an infinite iterator
@@ -68,6 +70,7 @@ name
6870
[redundant_pattern](https://github.com/Manishearth/rust-clippy/wiki#redundant_pattern) | warn | using `name @ _` in a pattern
6971
[result_unwrap_used](https://github.com/Manishearth/rust-clippy/wiki#result_unwrap_used) | allow | using `Result.unwrap()`, which might be better handled
7072
[reverse_range_loop](https://github.com/Manishearth/rust-clippy/wiki#reverse_range_loop) | warn | Iterating over an empty range, such as `10..0` or `5..5`
73+
[search_is_some](https://github.com/Manishearth/rust-clippy/wiki#search_is_some) | warn | using an iterator search followed by `is_some()`, which is more succinctly expressed as a call to `any()`
7174
[shadow_reuse](https://github.com/Manishearth/rust-clippy/wiki#shadow_reuse) | allow | rebinding a name to an expression that re-uses the original value, e.g. `let x = x + 1`
7275
[shadow_same](https://github.com/Manishearth/rust-clippy/wiki#shadow_same) | allow | rebinding a name to itself, e.g. `let mut x = &mut x`
7376
[shadow_unrelated](https://github.com/Manishearth/rust-clippy/wiki#shadow_unrelated) | allow | The name is re-bound without even using the original value

src/attrs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use reexport::*;
66
use syntax::codemap::Span;
77
use syntax::attr::*;
88
use syntax::ast::{Attribute, MetaList, MetaWord};
9-
use utils::{in_macro, match_path, span_lint};
9+
use utils::{in_macro, match_path, span_lint, BEGIN_UNWIND};
1010

11-
/// **What it does:** This lint warns on items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics.
11+
/// **What it does:** This lint `Warn`s on items annotated with `#[inline(always)]`, unless the annotated function is empty or simply panics.
1212
///
1313
/// **Why is this bad?** While there are valid uses of this annotation (and once you know when to use it, by all means `allow` this lint), it's a common newbie-mistake to pepper one's code with it.
1414
///
@@ -94,7 +94,7 @@ fn is_relevant_expr(expr: &Expr) -> bool {
9494
ExprRet(None) | ExprBreak(_) => false,
9595
ExprCall(ref path_expr, _) => {
9696
if let ExprPath(_, ref path) = path_expr.node {
97-
!match_path(path, &["std", "rt", "begin_unwind"])
97+
!match_path(path, &BEGIN_UNWIND)
9898
} else { true }
9999
}
100100
_ => true

src/block_in_if_condition.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc::lint::{LateLintPass, LateContext, LintArray, LintPass};
33
use rustc_front::intravisit::{Visitor, walk_expr};
44
use utils::*;
55

6-
/// **What it does:** This lint checks for `if` conditions that use blocks to contain an expression.
6+
/// **What it does:** This lint checks for `if` conditions that use blocks to contain an expression. It is `Warn` by default.
77
///
88
/// **Why is this bad?** It isn't really rust style, same as using parentheses to contain expressions.
99
///
@@ -15,7 +15,7 @@ declare_lint! {
1515
"braces can be eliminated in conditions that are expressions, e.g `if { true } ...`"
1616
}
1717

18-
/// **What it does:** This lint checks for `if` conditions that use blocks containing statements, or conditions that use closures with blocks.
18+
/// **What it does:** This lint checks for `if` conditions that use blocks containing statements, or conditions that use closures with blocks. It is `Warn` by default.
1919
///
2020
/// **Why is this bad?** Using blocks in the condition makes it hard to read.
2121
///
@@ -74,23 +74,30 @@ impl LateLintPass for BlockInIfCondition {
7474
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
7575
if let ExprIf(ref check, ref then, _) = expr.node {
7676
if let ExprBlock(ref block) = check.node {
77-
if block.stmts.is_empty() {
78-
if let Some(ref ex) = block.expr {
79-
// don't dig into the expression here, just suggest that they remove
80-
// the block
81-
82-
span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_EXPR, check.span,
83-
BRACED_EXPR_MESSAGE,
84-
&format!("try\nif {} {} ... ", snippet_block(cx, ex.span, ".."),
77+
if block.rules == DefaultBlock {
78+
if block.stmts.is_empty() {
79+
if let Some(ref ex) = block.expr {
80+
// don't dig into the expression here, just suggest that they remove
81+
// the block
82+
if differing_macro_contexts(expr.span, ex.span) {
83+
return;
84+
}
85+
span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_EXPR, check.span,
86+
BRACED_EXPR_MESSAGE,
87+
&format!("try\nif {} {} ... ", snippet_block(cx, ex.span, ".."),
88+
snippet_block(cx, then.span, "..")));
89+
}
90+
} else {
91+
if differing_macro_contexts(expr.span, block.stmts[0].span) {
92+
return;
93+
}
94+
// move block higher
95+
span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_STMT, check.span,
96+
COMPLEX_BLOCK_MESSAGE,
97+
&format!("try\nlet res = {};\nif res {} ... ",
98+
snippet_block(cx, block.span, ".."),
8599
snippet_block(cx, then.span, "..")));
86100
}
87-
} else {
88-
// move block higher
89-
span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_STMT, check.span,
90-
COMPLEX_BLOCK_MESSAGE,
91-
&format!("try\nlet res = {};\nif res {} ... ",
92-
snippet_block(cx, block.span, ".."),
93-
snippet_block(cx, then.span, "..")));
94101
}
95102
} else {
96103
let mut visitor = ExVisitor { found_block: None };

src/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl Constant {
7575
if let ConstantInt(val, _) = *self {
7676
val // TODO we may want to check the sign if any
7777
} else {
78-
panic!("Could not convert a {:?} to u64");
78+
panic!("Could not convert a {:?} to u64", self);
7979
}
8080
}
8181

src/cyclomatic_complexity.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use syntax::attr::*;
99
use syntax::ast::Attribute;
1010
use rustc_front::intravisit::{Visitor, walk_expr};
1111

12-
use utils::{in_macro, LimitStack};
12+
use utils::{in_macro, LimitStack, span_help_and_lint};
1313

1414
/// **What it does:** It `Warn`s on methods with high cyclomatic complexity
1515
///
@@ -59,8 +59,8 @@ impl CyclomaticComplexity {
5959
} else {
6060
let rust_cc = cc + divergence - narms;
6161
if rust_cc > self.limit.limit() {
62-
cx.span_lint_help(CYCLOMATIC_COMPLEXITY, span,
63-
&format!("The function has a cyclomatic complexity of {}.", rust_cc),
62+
span_help_and_lint(cx, CYCLOMATIC_COMPLEXITY, span,
63+
&format!("The function has a cyclomatic complexity of {}", rust_cc),
6464
"You could split it up into multiple smaller functions");
6565
}
6666
}
@@ -140,8 +140,9 @@ fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, span: Span) {
140140
#[cfg(not(feature="debugging"))]
141141
fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, span: Span) {
142142
if cx.current_level(CYCLOMATIC_COMPLEXITY) != Level::Allow {
143-
cx.sess().span_note(span, &format!("Clippy encountered a bug calculating cyclomatic complexity \
144-
(hide this message with `#[allow(cyclomatic_complexity)]`): \
145-
cc = {}, arms = {}, div = {}. Please file a bug report.", cc, narms, div));
143+
cx.sess().span_note_without_error(span,
144+
&format!("Clippy encountered a bug calculating cyclomatic complexity \
145+
(hide this message with `#[allow(cyclomatic_complexity)]`): \
146+
cc = {}, arms = {}, div = {}. Please file a bug report.", cc, narms, div));
146147
}
147148
}

src/escape.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use utils::span_lint;
1414

1515
pub struct EscapePass;
1616

17-
/// **What it does:** This lint checks for usage of `Box<T>` where an unboxed `T` would work fine
17+
/// **What it does:** This lint checks for usage of `Box<T>` where an unboxed `T` would work fine. It is `Warn` by default.
1818
///
19-
/// **Why is this bad?** This is an unnecessary allocation, and bad for performance
19+
/// **Why is this bad?** This is an unnecessary allocation, and bad for performance. It is only necessary to allocate if you wish to move the box into something.
2020
///
21-
/// It is only necessary to allocate if you wish to move the box into something.
21+
/// **Known problems:** None
2222
///
2323
/// **Example:**
2424
///

src/eta_reduction.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ fn check_closure(cx: &LateContext, expr: &Expr) {
8484
}
8585
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span,
8686
"redundant closure found",
87-
|| {
87+
|db| {
8888
if let Some(snippet) = snippet_opt(cx, caller.span) {
89-
cx.sess().span_suggestion(expr.span,
89+
db.span_suggestion(expr.span,
9090
"remove closure as shown:",
9191
snippet);
9292
}

src/len_zero.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ fn check_len_zero(cx: &LateContext, span: Span, name: &Name,
135135
has_is_empty(cx, &args[0]) {
136136
span_lint(cx, LEN_ZERO, span, &format!(
137137
"consider replacing the len comparison with `{}{}.is_empty()`",
138-
op, snippet(cx, args[0].span, "_")))
138+
op, snippet(cx, args[0].span, "_")));
139139
}
140140
}
141141
}

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub mod cyclomatic_complexity;
6767
pub mod escape;
6868
pub mod misc_early;
6969
pub mod array_indexing;
70+
pub mod panic;
7071

7172
mod reexport {
7273
pub use syntax::ast::{Name, NodeId};
@@ -123,6 +124,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
123124
reg.register_early_lint_pass(box misc_early::MiscEarly);
124125
reg.register_late_lint_pass(box misc::UsedUnderscoreBinding);
125126
reg.register_late_lint_pass(box array_indexing::ArrayIndexing);
127+
reg.register_late_lint_pass(box panic::PanicPass);
126128

127129
reg.register_lint_group("clippy_pedantic", vec![
128130
methods::OPTION_UNWRAP_USED,
@@ -175,9 +177,11 @@ pub fn plugin_registrar(reg: &mut Registry) {
175177
matches::MATCH_OVERLAPPING_ARM,
176178
matches::MATCH_REF_PATS,
177179
matches::SINGLE_MATCH,
180+
methods::FILTER_NEXT,
178181
methods::OK_EXPECT,
179182
methods::OPTION_MAP_UNWRAP_OR,
180183
methods::OPTION_MAP_UNWRAP_OR_ELSE,
184+
methods::SEARCH_IS_SOME,
181185
methods::SHOULD_IMPLEMENT_TRAIT,
182186
methods::STR_TO_STRING,
183187
methods::STRING_TO_STRING,
@@ -199,6 +203,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
199203
needless_update::NEEDLESS_UPDATE,
200204
no_effect::NO_EFFECT,
201205
open_options::NONSENSICAL_OPEN_OPTIONS,
206+
panic::PANIC_PARAMS,
202207
precedence::PRECEDENCE,
203208
ptr_arg::PTR_ARG,
204209
ranges::RANGE_STEP_BY_ZERO,

src/loops.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ declare_lint!{ pub EXPLICIT_ITER_LOOP, Warn,
5050
declare_lint!{ pub ITER_NEXT_LOOP, Warn,
5151
"for-looping over `_.next()` which is probably not intended" }
5252

53-
/// **What it does:** This lint detects `loop + match` combinations that are easier written as a `while let` loop.
53+
/// **What it does:** This lint detects `loop + match` combinations that are easier written as a `while let` loop. It is `Warn` by default.
5454
///
5555
/// **Why is this bad?** The `while let` loop is usually shorter and more readable
5656
///
@@ -85,7 +85,7 @@ declare_lint!{ pub UNUSED_COLLECT, Warn,
8585
"`collect()`ing an iterator without using the result; this is usually better \
8686
written as a for loop" }
8787

88-
/// **What it does:** This lint checks for loops over ranges `x..y` where both `x` and `y` are constant and `x` is greater or equal to `y`, unless the range is reversed or has a negative `.step_by(_)`.
88+
/// **What it does:** This lint checks for loops over ranges `x..y` where both `x` and `y` are constant and `x` is greater or equal to `y`, unless the range is reversed or has a negative `.step_by(_)`. It is `Warn` by default.
8989
///
9090
/// **Why is it bad?** Such loops will either be skipped or loop until wrap-around (in debug code, this may `panic!()`). Both options are probably not intended.
9191
///

src/map_clone.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use utils::{walk_ptrs_ty, walk_ptrs_ty_depth};
88
///
99
/// **Why is this bad?** It makes the code less readable.
1010
///
11-
/// **Known problems:** False negative: The lint currently misses mapping `Clone::clone` directly. Issue #436 is tracking this.
11+
/// **Known problems:** None
1212
///
1313
/// **Example:** `x.map(|e| e.clone());`
1414
declare_lint!(pub MAP_CLONE, Warn,

0 commit comments

Comments
 (0)