Skip to content

Commit d6182b3

Browse files
committed
Merge remote-tracking branch 'origin/rustup' into sugg
2 parents 28bd591 + 55b78ae commit d6182b3

18 files changed

+155
-110
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
All notable changes to this project will be documented in this file.
33

44
## 0.0.78 - TBA
5-
* New lints: [`wrong_transmute`]
5+
* New lints: [`wrong_transmute`, `double_neg`]
66
* For compatibility, `cargo clippy` does not defines the `clippy` feature
77
introduced in 0.0.76 anymore
88
* [`collapsible_if`] now considers `if let`
@@ -153,6 +153,7 @@ All notable changes to this project will be documented in this file.
153153
[`deprecated_semver`]: https://github.com/Manishearth/rust-clippy/wiki#deprecated_semver
154154
[`derive_hash_xor_eq`]: https://github.com/Manishearth/rust-clippy/wiki#derive_hash_xor_eq
155155
[`doc_markdown`]: https://github.com/Manishearth/rust-clippy/wiki#doc_markdown
156+
[`double_neg`]: https://github.com/Manishearth/rust-clippy/wiki#double_neg
156157
[`drop_ref`]: https://github.com/Manishearth/rust-clippy/wiki#drop_ref
157158
[`duplicate_underscore_argument`]: https://github.com/Manishearth/rust-clippy/wiki#duplicate_underscore_argument
158159
[`empty_loop`]: https://github.com/Manishearth/rust-clippy/wiki#empty_loop

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Table of contents:
1717

1818
## Lints
1919

20-
There are 156 lints included in this crate:
20+
There are 157 lints included in this crate:
2121

2222
name | default | meaning
2323
---------------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -49,6 +49,7 @@ name
4949
[deprecated_semver](https://github.com/Manishearth/rust-clippy/wiki#deprecated_semver) | warn | `Warn` on `#[deprecated(since = "x")]` where x is not semver
5050
[derive_hash_xor_eq](https://github.com/Manishearth/rust-clippy/wiki#derive_hash_xor_eq) | warn | deriving `Hash` but implementing `PartialEq` explicitly
5151
[doc_markdown](https://github.com/Manishearth/rust-clippy/wiki#doc_markdown) | warn | checks for the presence of `_`, `::` or camel-case outside ticks in documentation
52+
[double_neg](https://github.com/Manishearth/rust-clippy/wiki#double_neg) | warn | `--x` is a double negation of `x` and not a pre-decrement as in C or C++
5253
[drop_ref](https://github.com/Manishearth/rust-clippy/wiki#drop_ref) | warn | call to `std::mem::drop` with a reference instead of an owned value, which will not call the `Drop::drop` method on the underlying value
5354
[duplicate_underscore_argument](https://github.com/Manishearth/rust-clippy/wiki#duplicate_underscore_argument) | warn | Function arguments having names which only differ by an underscore
5455
[empty_loop](https://github.com/Manishearth/rust-clippy/wiki#empty_loop) | warn | empty `loop {}` detected

clippy_lints/src/booleans.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use rustc::hir::*;
33
use rustc::hir::intravisit::*;
44
use syntax::ast::{LitKind, DUMMY_NODE_ID};
55
use syntax::codemap::{DUMMY_SP, dummy_spanned};
6+
use syntax::util::ThinVec;
67
use utils::{span_lint_and_then, in_macro, snippet_opt, SpanlessEq};
78

89
/// **What it does:** This lint checks for boolean expressions that can be written more concisely
@@ -99,7 +100,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
99100
Expr {
100101
id: DUMMY_NODE_ID,
101102
span: DUMMY_SP,
102-
attrs: None,
103+
attrs: ThinVec::new(),
103104
node: ExprBinary(dummy_spanned(op), lhs.clone(), rhs.clone()),
104105
}
105106
};

clippy_lints/src/collapsible_if.rs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ fn check_if(cx: &EarlyContext, expr: &ast::Expr) {
7171
fn check_collapsible_maybe_if_let(cx: &EarlyContext, else_: &ast::Expr) {
7272
if_let_chain! {[
7373
let ast::ExprKind::Block(ref block) = else_.node,
74-
block.stmts.is_empty(),
75-
let Some(ref else_) = block.expr,
74+
let Some(ref else_) = expr_block(block),
75+
!in_macro(cx, else_.span),
7676
], {
7777
match else_.node {
7878
ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => {
@@ -95,7 +95,7 @@ fn check_collapsible_no_if_let(
9595
then: &ast::Block,
9696
) {
9797
if_let_chain! {[
98-
let Some(inner) = single_stmt_of_block(then),
98+
let Some(inner) = expr_block(then),
9999
let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node,
100100
], {
101101
if expr.span.expn_id != inner.span.expn_id {
@@ -113,28 +113,16 @@ fn check_collapsible_no_if_let(
113113
}}
114114
}
115115

116-
fn single_stmt_of_block(block: &ast::Block) -> Option<&ast::Expr> {
117-
if block.stmts.len() == 1 && block.expr.is_none() {
118-
if let ast::StmtKind::Expr(ref expr, _) = block.stmts[0].node {
119-
single_stmt_of_expr(expr)
120-
} else {
121-
None
122-
}
123-
} else if block.stmts.is_empty() {
124-
if let Some(ref p) = block.expr {
125-
Some(p)
126-
} else {
127-
None
116+
/// If the block contains only one expression, returns it.
117+
fn expr_block(block: &ast::Block) -> Option<&ast::Expr> {
118+
let mut it = block.stmts.iter();
119+
120+
if let (Some(stmt), None) = (it.next(), it.next()) {
121+
match stmt.node {
122+
ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => Some(expr),
123+
_ => None,
128124
}
129125
} else {
130126
None
131127
}
132128
}
133-
134-
fn single_stmt_of_expr(expr: &ast::Expr) -> Option<&ast::Expr> {
135-
if let ast::ExprKind::Block(ref block) = expr.node {
136-
single_stmt_of_block(block)
137-
} else {
138-
Some(expr)
139-
}
140-
}

clippy_lints/src/formatting.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,13 @@ impl EarlyLintPass for Formatting {
5959
fn check_block(&mut self, cx: &EarlyContext, block: &ast::Block) {
6060
for w in block.stmts.windows(2) {
6161
match (&w[0].node, &w[1].node) {
62-
(&ast::StmtKind::Expr(ref first, _), &ast::StmtKind::Expr(ref second, _)) |
63-
(&ast::StmtKind::Expr(ref first, _), &ast::StmtKind::Semi(ref second, _)) => {
62+
(&ast::StmtKind::Expr(ref first), &ast::StmtKind::Expr(ref second)) |
63+
(&ast::StmtKind::Expr(ref first), &ast::StmtKind::Semi(ref second)) => {
6464
check_consecutive_ifs(cx, first, second);
6565
}
6666
_ => (),
6767
}
6868
}
69-
70-
if let Some(ref expr) = block.expr {
71-
if let Some(ref stmt) = block.stmts.iter().last() {
72-
if let ast::StmtKind::Expr(ref first, _) = stmt.node {
73-
check_consecutive_ifs(cx, first, expr);
74-
}
75-
}
76-
}
7769
}
7870

7971
fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) {

clippy_lints/src/items_after_statements.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use rustc::lint::*;
44
use syntax::ast::*;
5-
use utils::in_macro;
5+
use utils::{in_macro, span_lint};
66

77
/// **What it does:** This lints checks for items declared after some statement in a block
88
///
@@ -44,26 +44,23 @@ impl EarlyLintPass for ItemsAfterStatements {
4444
if in_macro(cx, item.span) {
4545
return;
4646
}
47-
let mut stmts = item.stmts.iter().map(|stmt| &stmt.node);
47+
4848
// skip initial items
49-
while let Some(&StmtKind::Decl(ref decl, _)) = stmts.next() {
50-
if let DeclKind::Local(_) = decl.node {
51-
break;
52-
}
53-
}
49+
let stmts = item.stmts.iter()
50+
.map(|stmt| &stmt.node)
51+
.skip_while(|s| matches!(**s, StmtKind::Item(..)));
52+
5453
// lint on all further items
5554
for stmt in stmts {
56-
if let StmtKind::Decl(ref decl, _) = *stmt {
57-
if let DeclKind::Item(ref it) = decl.node {
58-
if in_macro(cx, it.span) {
59-
return;
60-
}
61-
cx.struct_span_lint(ITEMS_AFTER_STATEMENTS,
62-
it.span,
63-
"adding items after statements is confusing, since items exist from the \
64-
start of the scope")
65-
.emit();
55+
if let StmtKind::Item(ref it) = *stmt {
56+
if in_macro(cx, it.span) {
57+
return;
6658
}
59+
span_lint(cx,
60+
ITEMS_AFTER_STATEMENTS,
61+
it.span,
62+
"adding items after statements is confusing, since items exist from the \
63+
start of the scope");
6764
}
6865
}
6966
}

clippy_lints/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
370370
misc::MODULO_ONE,
371371
misc::REDUNDANT_PATTERN,
372372
misc::TOPLEVEL_REF_ARG,
373+
misc_early::DOUBLE_NEG,
373374
misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
374375
misc_early::REDUNDANT_CLOSURE_CALL,
375376
misc_early::UNNEEDED_FIELD_PATTERN,

clippy_lints/src/misc_early.rs

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,25 @@ declare_lint! {
4040
"Closures should not be called in the expression they are defined"
4141
}
4242

43+
/// **What it does:** This lint detects expressions of the form `--x`
44+
///
45+
/// **Why is this bad?** It can mislead C/C++ programmers to think `x` was decremented.
46+
///
47+
/// **Known problems:** None.
48+
///
49+
/// **Example:** `--x;`
50+
declare_lint! {
51+
pub DOUBLE_NEG, Warn,
52+
"`--x` is a double negation of `x` and not a pre-decrement as in C or C++"
53+
}
54+
55+
4356
#[derive(Copy, Clone)]
4457
pub struct MiscEarly;
4558

4659
impl LintPass for MiscEarly {
4760
fn get_lints(&self) -> LintArray {
48-
lint_array!(UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT, REDUNDANT_CLOSURE_CALL)
61+
lint_array!(UNNEEDED_FIELD_PATTERN, DUPLICATE_UNDERSCORE_ARGUMENT, REDUNDANT_CLOSURE_CALL, DOUBLE_NEG)
4962
}
5063
}
5164

@@ -126,36 +139,46 @@ impl EarlyLintPass for MiscEarly {
126139
}
127140

128141
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
129-
if let ExprKind::Call(ref paren, _) = expr.node {
130-
if let ExprKind::Paren(ref closure) = paren.node {
131-
if let ExprKind::Closure(_, ref decl, ref block, _) = closure.node {
132-
span_lint_and_then(cx,
133-
REDUNDANT_CLOSURE_CALL,
134-
expr.span,
135-
"Try not to call a closure in the expression where it is declared.",
136-
|db| {
137-
if decl.inputs.is_empty() {
138-
let hint = format!("{}", snippet(cx, block.span, ".."));
139-
db.span_suggestion(expr.span, "Try doing something like: ", hint);
140-
}
141-
});
142+
match expr.node {
143+
ExprKind::Call(ref paren, _) => {
144+
if let ExprKind::Paren(ref closure) = paren.node {
145+
if let ExprKind::Closure(_, ref decl, ref block, _) = closure.node {
146+
span_lint_and_then(cx,
147+
REDUNDANT_CLOSURE_CALL,
148+
expr.span,
149+
"Try not to call a closure in the expression where it is declared.",
150+
|db| {
151+
if decl.inputs.is_empty() {
152+
let hint = format!("{}", snippet(cx, block.span, ".."));
153+
db.span_suggestion(expr.span, "Try doing something like: ", hint);
154+
}
155+
});
156+
}
142157
}
143158
}
159+
ExprKind::Unary(UnOp::Neg, ref inner) => {
160+
if let ExprKind::Unary(UnOp::Neg, _) = inner.node {
161+
span_lint(cx,
162+
DOUBLE_NEG,
163+
expr.span,
164+
"`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op");
165+
}
166+
}
167+
_ => ()
144168
}
145169
}
146170

147171
fn check_block(&mut self, cx: &EarlyContext, block: &Block) {
148172
for w in block.stmts.windows(2) {
149173
if_let_chain! {[
150-
let StmtKind::Decl(ref first, _) = w[0].node,
151-
let DeclKind::Local(ref local) = first.node,
174+
let StmtKind::Local(ref local) = w[0].node,
152175
let Option::Some(ref t) = local.init,
153-
let ExprKind::Closure(_,_,_,_) = t.node,
154-
let PatKind::Ident(_,sp_ident,_) = local.pat.node,
155-
let StmtKind::Semi(ref second,_) = w[1].node,
156-
let ExprKind::Assign(_,ref call) = second.node,
157-
let ExprKind::Call(ref closure,_) = call.node,
158-
let ExprKind::Path(_,ref path) = closure.node
176+
let ExprKind::Closure(_, _, _, _) = t.node,
177+
let PatKind::Ident(_, sp_ident, _) = local.pat.node,
178+
let StmtKind::Semi(ref second) = w[1].node,
179+
let ExprKind::Assign(_, ref call) = second.node,
180+
let ExprKind::Call(ref closure, _) = call.node,
181+
let ExprKind::Path(_, ref path) = closure.node
159182
], {
160183
if sp_ident.node == (&path.segments[0]).identifier {
161184
span_lint(cx, REDUNDANT_CLOSURE_CALL, second.span, "Closure called just once immediately after it was declared");

clippy_lints/src/non_expressive_names.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ const WHITELIST: &'static [&'static [&'static str]] = &[
6868

6969
struct SimilarNamesNameVisitor<'a, 'b: 'a, 'c: 'b>(&'a mut SimilarNamesLocalVisitor<'b, 'c>);
7070

71-
impl<'v, 'a, 'b, 'c> Visitor<'v> for SimilarNamesNameVisitor<'a, 'b, 'c> {
72-
fn visit_pat(&mut self, pat: &'v Pat) {
71+
impl<'a, 'b, 'c> Visitor for SimilarNamesNameVisitor<'a, 'b, 'c> {
72+
fn visit_pat(&mut self, pat: &Pat) {
7373
match pat.node {
7474
PatKind::Ident(_, id, _) => self.check_name(id.span, id.node.name),
7575
PatKind::Struct(_, ref fields, _) => {
@@ -226,25 +226,25 @@ impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
226226
}
227227
}
228228

229-
impl<'v, 'a, 'b> Visitor<'v> for SimilarNamesLocalVisitor<'a, 'b> {
230-
fn visit_local(&mut self, local: &'v Local) {
229+
impl<'a, 'b> Visitor for SimilarNamesLocalVisitor<'a, 'b> {
230+
fn visit_local(&mut self, local: &Local) {
231231
if let Some(ref init) = local.init {
232232
self.apply(|this| walk_expr(this, &**init));
233233
}
234234
// add the pattern after the expression because the bindings aren't available yet in the init expression
235235
SimilarNamesNameVisitor(self).visit_pat(&*local.pat);
236236
}
237-
fn visit_block(&mut self, blk: &'v Block) {
237+
fn visit_block(&mut self, blk: &Block) {
238238
self.apply(|this| walk_block(this, blk));
239239
}
240-
fn visit_arm(&mut self, arm: &'v Arm) {
240+
fn visit_arm(&mut self, arm: &Arm) {
241241
self.apply(|this| {
242242
// just go through the first pattern, as either all patterns bind the same bindings or rustc would have errored much earlier
243243
SimilarNamesNameVisitor(this).visit_pat(&arm.pats[0]);
244244
this.apply(|this| walk_expr(this, &arm.body));
245245
});
246246
}
247-
fn visit_item(&mut self, _: &'v Item) {
247+
fn visit_item(&mut self, _: &Item) {
248248
// do not recurse into inner items
249249
}
250250
}

clippy_lints/src/returns.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,12 @@ pub struct ReturnPass;
3636
impl ReturnPass {
3737
// Check the final stmt or expr in a block for unnecessary return.
3838
fn check_block_return(&mut self, cx: &EarlyContext, block: &Block) {
39-
if let Some(ref expr) = block.expr {
40-
self.check_final_expr(cx, expr);
41-
} else if let Some(stmt) = block.stmts.last() {
42-
if let StmtKind::Semi(ref expr, _) = stmt.node {
43-
if let ExprKind::Ret(Some(ref inner)) = expr.node {
44-
self.emit_return_lint(cx, (stmt.span, inner.span));
39+
if let Some(stmt) = block.stmts.last() {
40+
match stmt.node {
41+
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => {
42+
self.check_final_expr(cx, expr);
4543
}
44+
_ => (),
4645
}
4746
}
4847
}
@@ -88,12 +87,14 @@ impl ReturnPass {
8887

8988
// Check for "let x = EXPR; x"
9089
fn check_let_return(&mut self, cx: &EarlyContext, block: &Block) {
90+
let mut it = block.stmts.iter();
91+
9192
// we need both a let-binding stmt and an expr
9293
if_let_chain! {[
93-
let Some(stmt) = block.stmts.last(),
94-
let Some(ref retexpr) = block.expr,
95-
let StmtKind::Decl(ref decl, _) = stmt.node,
96-
let DeclKind::Local(ref local) = decl.node,
94+
let Some(ref retexpr) = it.next_back(),
95+
let StmtKind::Expr(ref retexpr) = retexpr.node,
96+
let Some(stmt) = it.next_back(),
97+
let StmtKind::Local(ref local) = stmt.node,
9798
let Some(ref initexpr) = local.init,
9899
let PatKind::Ident(_, Spanned { node: id, .. }, _) = local.pat.node,
99100
let ExprKind::Path(_, ref path) = retexpr.node,

mini-macro/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ extern crate rustc;
55
extern crate rustc_plugin;
66

77
use syntax::codemap::Span;
8-
use syntax::ast::TokenTree;
8+
use syntax::tokenstream::TokenTree;
99
use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
1010
use syntax::ext::build::AstBuilder; // trait for expr_usize
1111
use rustc_plugin::Registry;

0 commit comments

Comments
 (0)