From 0e6bb725315cd8f2c8f37301d46ee6dcb33d1ade Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 1 Jul 2016 22:55:47 -0400 Subject: [PATCH 1/6] Expr: the `attrs` field is now a ThinVec --- clippy_lints/src/booleans.rs | 2 +- tests/consts.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index 8b7952b3746d..45dc24b8d08f 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -99,7 +99,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { Expr { id: DUMMY_NODE_ID, span: DUMMY_SP, - attrs: None, + attrs: vec![].into(), node: ExprBinary(dummy_spanned(op), lhs.clone(), rhs.clone()), } }; diff --git a/tests/consts.rs b/tests/consts.rs index 81500f9d3934..afbc89397048 100644 --- a/tests/consts.rs +++ b/tests/consts.rs @@ -27,7 +27,7 @@ fn expr(n: Expr_) -> Expr { id: 1, node: n, span: COMMAND_LINE_SP, - attrs: None, + attrs: vec![].into(), } } From 9b602dcca6038b7a5563f20becfdc1c979ccb3e7 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 1 Jul 2016 22:57:03 -0400 Subject: [PATCH 2/6] StmtKind, Block: update for changes in nightly Block::expr is now just the last entry in Block::stmts. Additionally, StmtKind variants are all now have arity 1. --- clippy_lints/src/collapsible_if.rs | 15 +++++--------- clippy_lints/src/formatting.rs | 12 ++--------- clippy_lints/src/items_after_statements.rs | 23 +++++++++++----------- clippy_lints/src/misc_early.rs | 5 ++--- clippy_lints/src/returns.rs | 16 +++++++-------- 5 files changed, 28 insertions(+), 43 deletions(-) diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 2921bc2769c2..263dff3433f0 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -72,8 +72,9 @@ fn check_if(cx: &EarlyContext, expr: &ast::Expr) { fn check_collapsible_maybe_if_let(cx: &EarlyContext, else_: &ast::Expr) { if_let_chain! {[ let ast::ExprKind::Block(ref block) = else_.node, - block.stmts.is_empty(), - let Some(ref else_) = block.expr, + block.stmts.len() == 1, + let Some(ref last_stmt) = block.stmts.last(), + let ast::StmtKind::Expr(ref else_) = last_stmt.node, ], { match else_.node { ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => { @@ -129,18 +130,12 @@ fn check_to_string(cx: &EarlyContext, e: &ast::Expr) -> Cow<'static, str> { } fn single_stmt_of_block(block: &ast::Block) -> Option<&ast::Expr> { - if block.stmts.len() == 1 && block.expr.is_none() { - if let ast::StmtKind::Expr(ref expr, _) = block.stmts[0].node { + if block.stmts.len() == 1 { + if let ast::StmtKind::Expr(ref expr) = block.stmts[0].node { single_stmt_of_expr(expr) } else { None } - } else if block.stmts.is_empty() { - if let Some(ref p) = block.expr { - Some(p) - } else { - None - } } else { None } diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index aa6dd46cf0b9..930fd7ae9a66 100644 --- a/clippy_lints/src/formatting.rs +++ b/clippy_lints/src/formatting.rs @@ -59,21 +59,13 @@ impl EarlyLintPass for Formatting { fn check_block(&mut self, cx: &EarlyContext, block: &ast::Block) { for w in block.stmts.windows(2) { match (&w[0].node, &w[1].node) { - (&ast::StmtKind::Expr(ref first, _), &ast::StmtKind::Expr(ref second, _)) | - (&ast::StmtKind::Expr(ref first, _), &ast::StmtKind::Semi(ref second, _)) => { + (&ast::StmtKind::Expr(ref first), &ast::StmtKind::Expr(ref second)) | + (&ast::StmtKind::Expr(ref first), &ast::StmtKind::Semi(ref second)) => { check_consecutive_ifs(cx, first, second); } _ => (), } } - - if let Some(ref expr) = block.expr { - if let Some(ref stmt) = block.stmts.iter().last() { - if let ast::StmtKind::Expr(ref first, _) = stmt.node { - check_consecutive_ifs(cx, first, expr); - } - } - } } fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) { diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs index 2e6b33ab3903..a4012a33c704 100644 --- a/clippy_lints/src/items_after_statements.rs +++ b/clippy_lints/src/items_after_statements.rs @@ -46,24 +46,23 @@ impl EarlyLintPass for ItemsAfterStatements { } let mut stmts = item.stmts.iter().map(|stmt| &stmt.node); // skip initial items - while let Some(&StmtKind::Decl(ref decl, _)) = stmts.next() { - if let DeclKind::Local(_) = decl.node { + while let Some(decl) = stmts.next() { + if let StmtKind::Item(_) = *decl { + } else { break; } } // lint on all further items for stmt in stmts { - if let StmtKind::Decl(ref decl, _) = *stmt { - if let DeclKind::Item(ref it) = decl.node { - if in_macro(cx, it.span) { - return; - } - cx.struct_span_lint(ITEMS_AFTER_STATEMENTS, - it.span, - "adding items after statements is confusing, since items exist from the \ - start of the scope") - .emit(); + if let StmtKind::Item(ref it) = *stmt { + if in_macro(cx, it.span) { + return; } + cx.struct_span_lint(ITEMS_AFTER_STATEMENTS, + it.span, + "adding items after statements is confusing, since items exist from the \ + start of the scope") + .emit(); } } } diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index e382b7dc5f69..b0bddc7ba0d8 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -171,12 +171,11 @@ impl EarlyLintPass for MiscEarly { fn check_block(&mut self, cx: &EarlyContext, block: &Block) { for w in block.stmts.windows(2) { if_let_chain! {[ - let StmtKind::Decl(ref first, _) = w[0].node, - let DeclKind::Local(ref local) = first.node, + let StmtKind::Local(ref local) = w[0].node, let Option::Some(ref t) = local.init, let ExprKind::Closure(_,_,_,_) = t.node, let PatKind::Ident(_,sp_ident,_) = local.pat.node, - let StmtKind::Semi(ref second,_) = w[1].node, + let StmtKind::Semi(ref second) = w[1].node, let ExprKind::Assign(_,ref call) = second.node, let ExprKind::Call(ref closure,_) = call.node, let ExprKind::Path(_,ref path) = closure.node diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 6beed822a81a..13ba36029466 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -36,10 +36,10 @@ pub struct ReturnPass; impl ReturnPass { // Check the final stmt or expr in a block for unnecessary return. fn check_block_return(&mut self, cx: &EarlyContext, block: &Block) { - if let Some(ref expr) = block.expr { - self.check_final_expr(cx, expr); - } else if let Some(stmt) = block.stmts.last() { - if let StmtKind::Semi(ref expr, _) = stmt.node { + if let Some(stmt) = block.stmts.last() { + if let StmtKind::Expr(ref expr) = stmt.node { + self.check_final_expr(cx, expr); + } else if let StmtKind::Semi(ref expr) = stmt.node { if let ExprKind::Ret(Some(ref inner)) = expr.node { self.emit_return_lint(cx, (stmt.span, inner.span)); } @@ -90,10 +90,10 @@ impl ReturnPass { fn check_let_return(&mut self, cx: &EarlyContext, block: &Block) { // we need both a let-binding stmt and an expr if_let_chain! {[ - let Some(stmt) = block.stmts.last(), - let Some(ref retexpr) = block.expr, - let StmtKind::Decl(ref decl, _) = stmt.node, - let DeclKind::Local(ref local) = decl.node, + let Some((stmt, rest)) = block.stmts.split_last(), + let Some(ntl_stmt) = rest.last(), + let StmtKind::Expr(ref retexpr) = stmt.node, + let StmtKind::Local(ref local) = ntl_stmt.node, let Some(ref initexpr) = local.init, let PatKind::Ident(_, Spanned { node: id, .. }, _) = local.pat.node, let ExprKind::Path(_, ref path) = retexpr.node, From 56e73bad149826685ac7c1be405091dd850c9a5f Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 1 Jul 2016 22:58:41 -0400 Subject: [PATCH 3/6] Visitor: remove lifetime parameter --- clippy_lints/src/non_expressive_names.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index aa8608fb7bd0..6c333d9881ca 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -68,8 +68,8 @@ const WHITELIST: &'static [&'static [&'static str]] = &[ struct SimilarNamesNameVisitor<'a, 'b: 'a, 'c: 'b>(&'a mut SimilarNamesLocalVisitor<'b, 'c>); -impl<'v, 'a, 'b, 'c> Visitor<'v> for SimilarNamesNameVisitor<'a, 'b, 'c> { - fn visit_pat(&mut self, pat: &'v Pat) { +impl<'v, 'a, 'b, 'c> Visitor for SimilarNamesNameVisitor<'a, 'b, 'c> { + fn visit_pat(&mut self, pat: &Pat) { match pat.node { PatKind::Ident(_, id, _) => self.check_name(id.span, id.node.name), PatKind::Struct(_, ref fields, _) => { @@ -226,25 +226,25 @@ impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> { } } -impl<'v, 'a, 'b> Visitor<'v> for SimilarNamesLocalVisitor<'a, 'b> { - fn visit_local(&mut self, local: &'v Local) { +impl<'v, 'a, 'b> Visitor for SimilarNamesLocalVisitor<'a, 'b> { + fn visit_local(&mut self, local: &Local) { if let Some(ref init) = local.init { self.apply(|this| walk_expr(this, &**init)); } // add the pattern after the expression because the bindings aren't available yet in the init expression SimilarNamesNameVisitor(self).visit_pat(&*local.pat); } - fn visit_block(&mut self, blk: &'v Block) { + fn visit_block(&mut self, blk: &Block) { self.apply(|this| walk_block(this, blk)); } - fn visit_arm(&mut self, arm: &'v Arm) { + fn visit_arm(&mut self, arm: &Arm) { self.apply(|this| { // just go through the first pattern, as either all patterns bind the same bindings or rustc would have errored much earlier SimilarNamesNameVisitor(this).visit_pat(&arm.pats[0]); this.apply(|this| walk_expr(this, &arm.body)); }); } - fn visit_item(&mut self, _: &'v Item) { + fn visit_item(&mut self, _: &Item) { // do not recurse into inner items } } From 8094c4a76a57d7fbc39588d282ba25823814c1a4 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 1 Jul 2016 22:59:18 -0400 Subject: [PATCH 4/6] diagnostics: now its own crate --- src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 17a219cafa08..e39ac1c40183 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ extern crate rustc_driver; extern crate getopts; extern crate rustc; +extern crate rustc_errors as errors; extern crate syntax; extern crate rustc_plugin; extern crate clippy_lints; @@ -12,7 +13,6 @@ extern crate clippy_lints; use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation}; use rustc::session::{config, Session}; use rustc::session::config::{Input, ErrorOutputType}; -use syntax::diagnostics; use std::path::PathBuf; use std::process::Command; @@ -36,7 +36,7 @@ impl<'a> CompilerCalls<'a> for ClippyCompilerCalls { fn early_callback(&mut self, matches: &getopts::Matches, sopts: &config::Options, - descriptions: &diagnostics::registry::Registry, + descriptions: &errors::registry::Registry, output: ErrorOutputType) -> Compilation { self.0.early_callback(matches, sopts, descriptions, output) @@ -46,7 +46,7 @@ impl<'a> CompilerCalls<'a> for ClippyCompilerCalls { sopts: &config::Options, odir: &Option, ofile: &Option, - descriptions: &diagnostics::registry::Registry) + descriptions: &errors::registry::Registry) -> Option<(Input, Option)> { self.0.no_input(matches, sopts, odir, ofile, descriptions) } From 6d07c94f1805ee85194c1ae59cd4040975d8d715 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 1 Jul 2016 22:59:33 -0400 Subject: [PATCH 5/6] TokenTree: now in syntax::tokenstream --- mini-macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mini-macro/src/lib.rs b/mini-macro/src/lib.rs index 699d17d4d70c..4b0c5ea5afde 100644 --- a/mini-macro/src/lib.rs +++ b/mini-macro/src/lib.rs @@ -5,7 +5,7 @@ extern crate rustc; extern crate rustc_plugin; use syntax::codemap::Span; -use syntax::ast::TokenTree; +use syntax::tokenstream::TokenTree; use syntax::ext::base::{ExtCtxt, MacResult, MacEager}; use syntax::ext::build::AstBuilder; // trait for expr_usize use rustc_plugin::Registry; From 8636c5c0b726d8bb56d84ab1783b1fccff444562 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 1 Jul 2016 22:59:42 -0400 Subject: [PATCH 6/6] typo: use commas around "e.g." --- clippy_lints/src/methods.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index a959dbe1d6ad..c59453333a4d 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -73,7 +73,7 @@ declare_lint! { /// |`is_` |`&self` or none | /// |`to_` |`&self` | /// -/// **Why is this bad?** Consistency breeds readability. If you follow the conventions, your users won't be surprised that they e.g. need to supply a mutable reference to a `as_..` function. +/// **Why is this bad?** Consistency breeds readability. If you follow the conventions, your users won't be surprised that they, e.g., need to supply a mutable reference to a `as_..` function. /// /// **Known problems:** None ///