diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 693d6d487e2b..9e4dd52c4143 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -376,8 +376,9 @@ fn is_relevant_trait(tcx: TyCtxt<'_, '_, '_>, item: &TraitItem) -> bool { fn is_relevant_block(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>, block: &Block) -> bool { if let Some(stmt) = block.stmts.first() { match &stmt.node { - StmtKind::Decl(_, _) => true, - StmtKind::Expr(expr, _) | StmtKind::Semi(expr, _) => is_relevant_expr(tcx, tables, expr), + StmtKind::Local(_) => true, + StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(tcx, tables, expr), + _ => false, } } else { block.expr.as_ref().map_or(false, |e| is_relevant_expr(tcx, tables, e)) diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 5780b9bcfd41..49722e5ad71f 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -14,6 +14,7 @@ use std::convert::TryInto; use std::hash::{Hash, Hasher}; use syntax::ast::{FloatTy, LitKind}; use syntax::ptr::P; +use syntax_pos::symbol::Symbol; /// A `LitKind`-like enum to fold constant `Expr`s into. #[derive(Debug, Clone)] @@ -38,6 +39,8 @@ pub enum Constant { Repeat(Box, u64), /// a tuple of constants Tuple(Vec), + /// a literal with syntax error + Err(Symbol), } impl PartialEq for Constant { @@ -103,6 +106,9 @@ impl Hash for Constant { c.hash(state); l.hash(state); }, + Constant::Err(ref s) => { + s.hash(state); + }, } } } @@ -155,6 +161,7 @@ pub fn lit_to_constant<'tcx>(lit: &LitKind, ty: Ty<'tcx>) -> Constant { _ => bug!(), }, LitKind::Bool(b) => Constant::Bool(b), + LitKind::Err(s) => Constant::Err(s), } } diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 75020b144924..a7b47fd1e546 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -120,18 +120,16 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { if let Categorization::Rvalue(..) = cmt.cat { let id = map.hir_to_node_id(cmt.hir_id); if let Some(Node::Stmt(st)) = map.find(map.get_parent_node(id)) { - if let StmtKind::Decl(ref decl, _) = st.node { - if let DeclKind::Local(ref loc) = decl.node { - if let Some(ref ex) = loc.init { - if let ExprKind::Box(..) = ex.node { - if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) { - // let x = box (...) - self.set.insert(consume_pat.id); - } - // TODO Box::new - // TODO vec![] - // TODO "foo".to_owned() and friends + if let StmtKind::Local(ref loc) = st.node { + if let Some(ref ex) = loc.init { + if let ExprKind::Box(..) = ex.node { + if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) { + // let x = box (...) + self.set.insert(consume_pat.id); } + // TODO Box::new + // TODO vec![] + // TODO "foo".to_owned() and friends } } } diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 8bd8461b119d..2b4b0d402392 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -89,14 +89,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence { } fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { match stmt.node { - StmtKind::Expr(ref e, _) | StmtKind::Semi(ref e, _) => DivergenceVisitor { cx }.maybe_walk_expr(e), - StmtKind::Decl(ref d, _) => { - if let DeclKind::Local(ref local) = d.node { - if let Local { init: Some(ref e), .. } = **local { - DivergenceVisitor { cx }.visit_expr(e); - } + StmtKind::Local(ref local) => { + if let Local { init: Some(ref e), .. } = **local { + DivergenceVisitor { cx }.visit_expr(e); } }, + StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => DivergenceVisitor { cx }.maybe_walk_expr(e), + StmtKind::Item(..) => {}, } } } @@ -269,18 +268,14 @@ fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr) -> St fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt) -> StopEarly { match stmt.node { - StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => check_expr(vis, expr), - StmtKind::Decl(ref decl, _) => { - // If the declaration is of a local variable, check its initializer - // expression if it has one. Otherwise, keep going. - let local = match decl.node { - DeclKind::Local(ref local) => Some(local), - _ => None, - }; - local - .and_then(|local| local.init.as_ref()) - .map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)) - }, + StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => check_expr(vis, expr), + // If the declaration is of a local variable, check its initializer + // expression if it has one. Otherwise, keep going. + StmtKind::Local(ref local) => local + .init + .as_ref() + .map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)), + _ => StopEarly::KeepGoing, } } diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index c3b3272dffd5..5154c6d4d08e 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -68,10 +68,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { while let Some(stmt) = it.next() { if_chain! { if let Some(expr) = it.peek(); - if let hir::StmtKind::Decl(ref decl, _) = stmt.node; - if let hir::DeclKind::Local(ref decl) = decl.node; - if let hir::PatKind::Binding(mode, canonical_id, ident, None) = decl.pat.node; - if let hir::StmtKind::Expr(ref if_, _) = expr.node; + if let hir::StmtKind::Local(ref local) = stmt.node; + if let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.node; + if let hir::StmtKind::Expr(ref if_) = expr.node; if let hir::ExprKind::If(ref cond, ref then, ref else_) = if_.node; if !used_in_expr(cx, canonical_id, cond); if let hir::ExprKind::Block(ref then, _) = then.node; @@ -84,7 +83,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { if let hir::ExprKind::Block(ref else_, _) = else_.node { if let Some(default) = check_assign(cx, canonical_id, else_) { (else_.stmts.len() > 1, default) - } else if let Some(ref default) = decl.init { + } else if let Some(ref default) = local.init { (true, &**default) } else { continue; @@ -92,7 +91,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { } else { continue; } - } else if let Some(ref default) = decl.init { + } else if let Some(ref default) = local.init { (false, &**default) } else { continue; @@ -169,7 +168,7 @@ fn check_assign<'a, 'tcx>( if_chain! { if block.expr.is_none(); if let Some(expr) = block.stmts.iter().last(); - if let hir::StmtKind::Semi(ref expr, _) = expr.node; + if let hir::StmtKind::Semi(ref expr) = expr.node; if let hir::ExprKind::Assign(ref var, ref value) = expr.node; if let hir::ExprKind::Path(ref qpath) = var.node; if let Def::Local(local_id) = cx.tables.qpath_def(qpath, var.hir_id); diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index acc7b11e3463..70ff86087ea6 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -3,7 +3,7 @@ use if_chain::if_chain; use itertools::Itertools; use rustc::hir::def::Def; use rustc::hir::def_id; -use rustc::hir::intravisit::{walk_block, walk_decl, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; +use rustc::hir::intravisit::{walk_block, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor}; use rustc::hir::*; use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass}; use rustc::middle::region; @@ -597,7 +597,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { - if let StmtKind::Semi(ref expr, _) = stmt.node { + if let StmtKind::Semi(ref expr) = stmt.node { if let ExprKind::MethodCall(ref method, _, ref args) = expr.node { if args.len() == 1 && method.ident.name == "collect" && match_trait_method(cx, expr, &paths::ITERATOR) { span_lint( @@ -668,13 +668,7 @@ fn never_loop_block(block: &Block, main_loop_id: NodeId) -> NeverLoopResult { fn stmt_to_expr(stmt: &Stmt) -> Option<&Expr> { match stmt.node { StmtKind::Semi(ref e, ..) | StmtKind::Expr(ref e, ..) => Some(e), - StmtKind::Decl(ref d, ..) => decl_to_expr(d), - } -} - -fn decl_to_expr(decl: &Decl) -> Option<&Expr> { - match decl.node { - DeclKind::Local(ref local) => local.init.as_ref().map(|p| &**p), + StmtKind::Local(ref local) => local.init.as_ref().map(|p| &**p), _ => None, } } @@ -942,8 +936,8 @@ fn get_indexed_assignments<'a, 'tcx>( stmts .iter() .map(|stmt| match stmt.node { - StmtKind::Decl(..) => None, - StmtKind::Expr(ref e, _node_id) | StmtKind::Semi(ref e, _node_id) => Some(get_assignment(cx, e, var)), + StmtKind::Local(..) | StmtKind::Item(..) => None, + StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => Some(get_assignment(cx, e, var)), }) .chain(expr.as_ref().into_iter().map(|e| Some(get_assignment(cx, &*e, var)))) .filter_map(|op| op) @@ -1976,13 +1970,9 @@ fn extract_expr_from_first_stmt(block: &Block) -> Option<&Expr> { if block.stmts.is_empty() { return None; } - if let StmtKind::Decl(ref decl, _) = block.stmts[0].node { - if let DeclKind::Local(ref local) = decl.node { - if let Some(ref expr) = local.init { - Some(expr) - } else { - None - } + if let StmtKind::Local(ref local) = block.stmts[0].node { + if let Some(ref expr) = local.init { + Some(expr) } else { None } @@ -1996,8 +1986,8 @@ fn extract_first_expr(block: &Block) -> Option<&Expr> { match block.expr { Some(ref expr) if block.stmts.is_empty() => Some(expr), None if !block.stmts.is_empty() => match block.stmts[0].node { - StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => Some(expr), - StmtKind::Decl(..) => None, + StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => Some(expr), + StmtKind::Local(..) | StmtKind::Item(..) => None, }, _ => None, } @@ -2095,9 +2085,9 @@ struct InitializeVisitor<'a, 'tcx: 'a> { } impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { - fn visit_decl(&mut self, decl: &'tcx Decl) { + fn visit_stmt(&mut self, stmt: &'tcx Stmt) { // Look for declarations of the variable - if let DeclKind::Local(ref local) = decl.node { + if let StmtKind::Local(ref local) = stmt.node { if local.pat.id == self.var_id { if let PatKind::Binding(_, _, ident, _) = local.pat.node { self.name = Some(ident.name); @@ -2114,7 +2104,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { } } } - walk_decl(self, decl); + walk_stmt(self, stmt); } fn visit_expr(&mut self, expr: &'tcx Expr) { @@ -2261,7 +2251,7 @@ struct LoopNestVisitor { impl<'tcx> Visitor<'tcx> for LoopNestVisitor { fn visit_stmt(&mut self, stmt: &'tcx Stmt) { - if stmt.node.id() == self.id { + if stmt.id == self.id { self.nesting = LookFurther; } else if self.nesting == Unknown { walk_stmt(self, stmt); diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index 4b4f1ad59190..ad5761f5f04a 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -131,9 +131,10 @@ fn reduce_unit_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a hir::Expr) -> // If block only contains statements, // reduce `{ X; }` to `X` or `X;` match inner_stmt.node { - hir::StmtKind::Decl(ref d, _) => Some(d.span), - hir::StmtKind::Expr(ref e, _) => Some(e.span), - hir::StmtKind::Semi(_, _) => Some(inner_stmt.span), + hir::StmtKind::Local(ref local) => Some(local.span), + hir::StmtKind::Expr(ref e) => Some(e.span), + hir::StmtKind::Semi(..) => Some(inner_stmt.span), + hir::StmtKind::Item(..) => None, } }, _ => { @@ -250,7 +251,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { return; } - if let hir::StmtKind::Semi(ref expr, _) = stmt.node { + if let hir::StmtKind::Semi(ref expr) = stmt.node { if let Some(arglists) = method_chain_args(expr, &["map"]) { lint_map_unit_fn(cx, stmt, expr, arglists[0]); } diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 14fdd6e6225d..6c1befe6e53a 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -1336,12 +1336,10 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp _ => {}, }, hir::Node::Stmt(stmt) => { - if let hir::StmtKind::Decl(ref decl, _) = stmt.node { - if let hir::DeclKind::Local(ref loc) = decl.node { - if let hir::PatKind::Ref(..) = loc.pat.node { - // let ref y = *x borrows x, let ref y = x.clone() does not - return; - } + if let hir::StmtKind::Local(ref loc) = stmt.node { + if let hir::PatKind::Ref(..) = loc.pat.node { + // let ref y = *x borrows x, let ref y = x.clone() does not + return; } } }, diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 4e5910f76bb1..88a6d62ee6df 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -277,8 +277,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, s: &'tcx Stmt) { if_chain! { - if let StmtKind::Decl(ref d, _) = s.node; - if let DeclKind::Local(ref l) = d.node; + if let StmtKind::Local(ref l) = s.node; if let PatKind::Binding(an, _, i, None) = l.pat.node; if let Some(ref init) = l.init; then { @@ -316,7 +315,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } }; if_chain! { - if let StmtKind::Semi(ref expr, _) = s.node; + if let StmtKind::Semi(ref expr) = s.node; if let ExprKind::Binary(ref binop, ref a, ref b) = expr.node; if binop.node == BinOpKind::And || binop.node == BinOpKind::Or; if let Some(sugg) = Sugg::hir_opt(cx, a); diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index 1dfc3f6501e4..6fbb05733651 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -267,7 +267,7 @@ fn fetch_bool_block(block: &Block) -> Expression { match (&*block.stmts, block.expr.as_ref()) { (&[], Some(e)) => fetch_bool_expr(&**e), (&[ref e], None) => { - if let StmtKind::Semi(ref e, _) = e.node { + if let StmtKind::Semi(ref e) = e.node { if let ExprKind::Ret(_) = e.node { fetch_bool_expr(&**e) } else { diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index b02faa08006e..cb1fe475a1ee 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -368,8 +368,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> { Node::Stmt(s) => { // `let = x;` if_chain! { - if let StmtKind::Decl(ref decl, _) = s.node; - if let DeclKind::Local(ref local) = decl.node; + if let StmtKind::Local(ref local) = s.node; then { self.spans_need_deref .entry(vid) diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 53d7575e3e09..648c198df080 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -104,7 +104,7 @@ impl LintPass for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { - if let StmtKind::Semi(ref expr, _) = stmt.node { + if let StmtKind::Semi(ref expr) = stmt.node { if has_no_effect(cx, expr) { span_lint(cx, NO_EFFECT, stmt.span, "statement with no effect"); } else if let Some(reduced) = reduce_expression(cx, expr) { diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index a4c4e66cf719..03f6ea12e001 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -139,7 +139,7 @@ impl Pass { if_chain! { if block.stmts.len() == 1; if let Some(expr) = block.stmts.iter().last(); - if let StmtKind::Semi(ref expr, _) = expr.node; + if let StmtKind::Semi(ref expr) = expr.node; if let ExprKind::Ret(ref ret_expr) = expr.node; if let &Some(ref ret_expr) = ret_expr; diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 84dd339a985b..c99b00bb98f9 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -115,8 +115,9 @@ fn check_block<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, block: &'tcx Block, binding let len = bindings.len(); for stmt in &block.stmts { match stmt.node { - StmtKind::Decl(ref decl, _) => check_decl(cx, decl, bindings), - StmtKind::Expr(ref e, _) | StmtKind::Semi(ref e, _) => check_expr(cx, e, bindings), + StmtKind::Local(ref local) => check_local(cx, local, bindings), + StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => check_expr(cx, e, bindings), + StmtKind::Item(..) => {}, } } if let Some(ref o) = block.expr { @@ -125,30 +126,28 @@ fn check_block<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, block: &'tcx Block, binding bindings.truncate(len); } -fn check_decl<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, decl: &'tcx Decl, bindings: &mut Vec<(Name, Span)>) { - if in_external_macro(cx.sess(), decl.span) { +fn check_local<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, local: &'tcx Local, bindings: &mut Vec<(Name, Span)>) { + if in_external_macro(cx.sess(), local.span) { return; } - if higher::is_from_for_desugar(decl) { + if higher::is_from_for_desugar(local) { return; } - if let DeclKind::Local(ref local) = decl.node { - let Local { - ref pat, - ref ty, - ref init, - span, - .. - } = **local; - if let Some(ref t) = *ty { - check_ty(cx, t, bindings) - } - if let Some(ref o) = *init { - check_expr(cx, o, bindings); - check_pat(cx, pat, Some(o), span, bindings); - } else { - check_pat(cx, pat, None, span, bindings); - } + let Local { + ref pat, + ref ty, + ref init, + span, + .. + } = *local; + if let Some(ref t) = *ty { + check_ty(cx, t, bindings) + } + if let Some(ref o) = *init { + check_expr(cx, o, bindings); + check_pat(cx, pat, Some(o), span, bindings); + } else { + check_pat(cx, pat, None, span, bindings); } } diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 77f70fad5884..aea414065d85 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -91,8 +91,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { // Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)` if_chain! { - if let StmtKind::Decl(ref decl, _) = stmt.node; - if let DeclKind::Local(ref local) = decl.node; + if let StmtKind::Local(ref local) = stmt.node; if let PatKind::Binding(BindingAnnotation::Mutable, _, variable_name, None) = local.pat.node; if let Some(ref init) = local.init; if let Some(ref len_arg) = Self::is_vec_with_capacity(init); @@ -104,7 +103,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { len_expr: len_arg, }; - Self::search_initialization(cx, vi, stmt.node.id()); + Self::search_initialization(cx, vi, stmt.id); } } } @@ -287,7 +286,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VectorInitializationVisitor<'a, 'tcx> { fn visit_stmt(&mut self, stmt: &'tcx Stmt) { if self.initialization_found { match stmt.node { - StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => { + StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => { self.search_slow_extend_filling(expr); self.search_slow_resize_filling(expr); }, diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 56f503afeae8..ddf33fcc411f 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -71,17 +71,16 @@ fn check_manual_swap(cx: &LateContext<'_, '_>, block: &Block) { for w in block.stmts.windows(3) { if_chain! { // let t = foo(); - if let StmtKind::Decl(ref tmp, _) = w[0].node; - if let DeclKind::Local(ref tmp) = tmp.node; + if let StmtKind::Local(ref tmp) = w[0].node; if let Some(ref tmp_init) = tmp.init; if let PatKind::Binding(_, _, ident, None) = tmp.pat.node; // foo() = bar(); - if let StmtKind::Semi(ref first, _) = w[1].node; + if let StmtKind::Semi(ref first) = w[1].node; if let ExprKind::Assign(ref lhs1, ref rhs1) = first.node; // bar() = t; - if let StmtKind::Semi(ref second, _) = w[2].node; + if let StmtKind::Semi(ref second) = w[2].node; if let ExprKind::Assign(ref lhs2, ref rhs2) = second.node; if let ExprKind::Path(QPath::Resolved(None, ref rhs2)) = rhs2.node; if rhs2.segments.len() == 1; @@ -160,8 +159,8 @@ fn check_manual_swap(cx: &LateContext<'_, '_>, block: &Block) { fn check_suspicious_swap(cx: &LateContext<'_, '_>, block: &Block) { for w in block.stmts.windows(2) { if_chain! { - if let StmtKind::Semi(ref first, _) = w[0].node; - if let StmtKind::Semi(ref second, _) = w[1].node; + if let StmtKind::Semi(ref first) = w[0].node; + if let StmtKind::Semi(ref second) = w[1].node; if !differing_macro_contexts(first.span, second.span); if let ExprKind::Assign(ref lhs0, ref rhs0) = first.node; if let ExprKind::Assign(ref lhs1, ref rhs1) = second.node; diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index f4b75437ff6f..898fd5a98089 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -463,28 +463,6 @@ declare_clippy_lint! { "creating a let binding to a value of unit type, which usually can't be used afterwards" } -fn check_let_unit(cx: &LateContext<'_, '_>, decl: &Decl) { - if let DeclKind::Local(ref local) = decl.node { - if is_unit(cx.tables.pat_ty(&local.pat)) { - if in_external_macro(cx.sess(), decl.span) || in_macro(local.pat.span) { - return; - } - if higher::is_from_for_desugar(decl) { - return; - } - span_lint( - cx, - LET_UNIT_VALUE, - decl.span, - &format!( - "this let-binding has unit value. Consider omitting `let {} =`", - snippet(cx, local.pat.span, "..") - ), - ); - } - } -} - impl LintPass for LetPass { fn get_lints(&self) -> LintArray { lint_array!(LET_UNIT_VALUE) @@ -492,8 +470,26 @@ impl LintPass for LetPass { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetPass { - fn check_decl(&mut self, cx: &LateContext<'a, 'tcx>, decl: &'tcx Decl) { - check_let_unit(cx, decl) + fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) { + if let StmtKind::Local(ref local) = stmt.node { + if is_unit(cx.tables.pat_ty(&local.pat)) { + if in_external_macro(cx.sess(), stmt.span) || in_macro(local.pat.span) { + return; + } + if higher::is_from_for_desugar(local) { + return; + } + span_lint( + cx, + LET_UNIT_VALUE, + stmt.span, + &format!( + "this let-binding has unit value. Consider omitting `let {} =`", + snippet(cx, local.pat.span, "..") + ), + ); + } + } } } diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index c33b6b742fa5..27deb0d99459 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -41,7 +41,7 @@ impl LintPass for UnusedIoAmount { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) { let expr = match s.node { - hir::StmtKind::Semi(ref expr, _) | hir::StmtKind::Expr(ref expr, _) => &**expr, + hir::StmtKind::Semi(ref expr) | hir::StmtKind::Expr(ref expr) => &**expr, _ => return, }; diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 51e7d3330843..9623c6cbdadd 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -4,7 +4,7 @@ use crate::utils::get_attr; use rustc::hir; use rustc::hir::intravisit::{NestedVisitorMap, Visitor}; -use rustc::hir::{BindingAnnotation, DeclKind, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind}; +use rustc::hir::{BindingAnnotation, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind}; use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use rustc_data_structures::fx::FxHashMap; @@ -260,6 +260,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { match lit.node { LitKind::Bool(val) => println!(" if let LitKind::Bool({:?}) = {}.node;", val, lit_pat), LitKind::Char(c) => println!(" if let LitKind::Char({:?}) = {}.node;", c, lit_pat), + LitKind::Err(val) => println!(" if let LitKind::Err({}) = {}.node;", val, lit_pat), LitKind::Byte(b) => println!(" if let LitKind::Byte({}) = {}.node;", b, lit_pat), // FIXME: also check int type LitKind::Int(i, _) => println!(" if let LitKind::Int({}, _) = {}.node;", i, lit_pat), @@ -625,35 +626,26 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { print!(" if let StmtKind::"); let current = format!("{}.node", self.current); match s.node { - // Could be an item or a local (let) binding: - StmtKind::Decl(ref decl, _) => { - let decl_pat = self.next("decl"); - println!("Decl(ref {}, _) = {}", decl_pat, current); - print!(" if let DeclKind::"); - let current = format!("{}.node", decl_pat); - match decl.node { - // A local (let) binding: - DeclKind::Local(ref local) => { - let local_pat = self.next("local"); - println!("Local(ref {}) = {};", local_pat, current); - if let Some(ref init) = local.init { - let init_pat = self.next("init"); - println!(" if let Some(ref {}) = {}.init", init_pat, local_pat); - self.current = init_pat; - self.visit_expr(init); - } - self.current = format!("{}.pat", local_pat); - self.visit_pat(&local.pat); - }, - // An item binding: - DeclKind::Item(_) => { - println!("Item(item_id) = {};", current); - }, + // A local (let) binding: + StmtKind::Local(ref local) => { + let local_pat = self.next("local"); + println!("Local(ref {}) = {};", local_pat, current); + if let Some(ref init) = local.init { + let init_pat = self.next("init"); + println!(" if let Some(ref {}) = {}.init", init_pat, local_pat); + self.current = init_pat; + self.visit_expr(init); } + self.current = format!("{}.pat", local_pat); + self.visit_pat(&local.pat); + }, + // An item binding: + StmtKind::Item(_) => { + println!("Item(item_id) = {};", current); }, // Expr without trailing semi-colon (must have unit type): - StmtKind::Expr(ref e, _) => { + StmtKind::Expr(ref e) => { let e_pat = self.next("e"); println!("Expr(ref {}, _) = {}", e_pat, current); self.current = e_pat; @@ -661,7 +653,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { }, // Expr with trailing semi-colon (may have any type): - StmtKind::Semi(ref e, _) => { + StmtKind::Semi(ref e) => { let e_pat = self.next("e"); println!("Semi(ref {}, _) = {}", e_pat, current); self.current = e_pat; diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index 682093b08e4c..537cdf55eb14 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -148,8 +148,8 @@ pub fn range<'a, 'b, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'b hir::Expr) -> O } } -/// Checks if a `let` decl is from a `for` loop desugaring. -pub fn is_from_for_desugar(decl: &hir::Decl) -> bool { +/// Checks if a `let` statement is from a `for` loop desugaring. +pub fn is_from_for_desugar(local: &hir::Local) -> bool { // This will detect plain for-loops without an actual variable binding: // // ``` @@ -158,8 +158,7 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool { // } // ``` if_chain! { - if let hir::DeclKind::Local(ref loc) = decl.node; - if let Some(ref expr) = loc.init; + if let Some(ref expr) = local.init; if let hir::ExprKind::Match(_, _, hir::MatchSource::ForLoopDesugar) = expr.node; then { return true; @@ -174,12 +173,8 @@ pub fn is_from_for_desugar(decl: &hir::Decl) -> bool { // // anything // } // ``` - if_chain! { - if let hir::DeclKind::Local(ref loc) = decl.node; - if let hir::LocalSource::ForLoopDesugar = loc.source; - then { - return true; - } + if let hir::LocalSource::ForLoopDesugar = local.source { + return true; } false @@ -195,11 +190,10 @@ pub fn for_loop(expr: &hir::Expr) -> Option<(&hir::Pat, &hir::Expr, &hir::Expr)> if let hir::ExprKind::Loop(ref block, _, _) = arms[0].body.node; if block.expr.is_none(); if let [ _, _, ref let_stmt, ref body ] = *block.stmts; - if let hir::StmtKind::Decl(ref decl, _) = let_stmt.node; - if let hir::DeclKind::Local(ref decl) = decl.node; - if let hir::StmtKind::Expr(ref expr, _) = body.node; + if let hir::StmtKind::Local(ref local) = let_stmt.node; + if let hir::StmtKind::Expr(ref expr) = body.node; then { - return Some((&*decl.pat, &iterargs[0], expr)); + return Some((&*local.pat, &iterargs[0], expr)); } } None diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index aed9bb9afc9d..a176830be26b 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -43,17 +43,14 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { /// Check whether two statements are the same. pub fn eq_stmt(&mut self, left: &Stmt, right: &Stmt) -> bool { match (&left.node, &right.node) { - (&StmtKind::Decl(ref l, _), &StmtKind::Decl(ref r, _)) => { - if let (&DeclKind::Local(ref l), &DeclKind::Local(ref r)) = (&l.node, &r.node) { - self.eq_pat(&l.pat, &r.pat) - && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) - && both(&l.init, &r.init, |l, r| self.eq_expr(l, r)) - } else { - false - } + (&StmtKind::Local(ref l), &StmtKind::Local(ref r)) => { + self.eq_pat(&l.pat, &r.pat) + && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) + && both(&l.init, &r.init, |l, r| self.eq_expr(l, r)) + }, + (&StmtKind::Expr(ref l), &StmtKind::Expr(ref r)) | (&StmtKind::Semi(ref l), &StmtKind::Semi(ref r)) => { + self.eq_expr(l, r) }, - (&StmtKind::Expr(ref l, _), &StmtKind::Expr(ref r, _)) - | (&StmtKind::Semi(ref l, _), &StmtKind::Semi(ref r, _)) => self.eq_expr(l, r), _ => false, } } @@ -643,23 +640,24 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> { pub fn hash_stmt(&mut self, b: &Stmt) { match b.node { - StmtKind::Decl(ref decl, _) => { - let c: fn(_, _) -> _ = StmtKind::Decl; + StmtKind::Local(ref local) => { + let c: fn(_) -> _ = StmtKind::Local; c.hash(&mut self.s); - - if let DeclKind::Local(ref local) = decl.node { - if let Some(ref init) = local.init { - self.hash_expr(init); - } + if let Some(ref init) = local.init { + self.hash_expr(init); } }, - StmtKind::Expr(ref expr, _) => { - let c: fn(_, _) -> _ = StmtKind::Expr; + StmtKind::Item(..) => { + let c: fn(_) -> _ = StmtKind::Item; + c.hash(&mut self.s); + }, + StmtKind::Expr(ref expr) => { + let c: fn(_) -> _ = StmtKind::Expr; c.hash(&mut self.s); self.hash_expr(expr); }, - StmtKind::Semi(ref expr, _) => { - let c: fn(_, _) -> _ = StmtKind::Semi; + StmtKind::Semi(ref expr) => { + let c: fn(_) -> _ = StmtKind::Semi; c.hash(&mut self.s); self.hash_expr(expr); }, diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 6ce27c18cecf..4116f8ffbafa 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -122,8 +122,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { return; } match stmt.node { - hir::StmtKind::Decl(ref decl, _) => print_decl(cx, decl), - hir::StmtKind::Expr(ref e, _) | hir::StmtKind::Semi(ref e, _) => print_expr(cx, e, 0), + hir::StmtKind::Local(ref local) => { + println!("local variable of type {}", cx.tables.node_id_to_type(local.hir_id)); + println!("pattern:"); + print_pat(cx, &local.pat, 0); + if let Some(ref e) = local.init { + println!("init expression:"); + print_expr(cx, e, 0); + } + }, + hir::StmtKind::Item(_) => println!("item decl"), + hir::StmtKind::Expr(ref e) | hir::StmtKind::Semi(ref e) => print_expr(cx, e, 0), } } // fn check_foreign_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx @@ -139,21 +148,6 @@ fn has_attr(attrs: &[Attribute]) -> bool { get_attr(attrs, "dump").count() > 0 } -fn print_decl(cx: &LateContext<'_, '_>, decl: &hir::Decl) { - match decl.node { - hir::DeclKind::Local(ref local) => { - println!("local variable of type {}", cx.tables.node_id_to_type(local.hir_id)); - println!("pattern:"); - print_pat(cx, &local.pat, 0); - if let Some(ref e) = local.init { - println!("init expression:"); - print_expr(cx, e, 0); - } - }, - hir::DeclKind::Item(_) => println!("item decl"), - } -} - #[allow(clippy::similar_names)] fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr, indent: usize) { let ind = " ".repeat(indent); diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index bb62cdeb9edb..c8c291c8cc87 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -5,7 +5,7 @@ use rustc_errors::Applicability; use std::borrow::Cow; use syntax::ast::*; use syntax::parse::{parser, token}; -use syntax::tokenstream::{ThinTokenStream, TokenStream}; +use syntax::tokenstream::TokenStream; /// **What it does:** This lint warns when you use `println!("")` to /// print a newline. @@ -261,9 +261,9 @@ impl EarlyLintPass for Pass { /// ```rust,ignore /// (Some("string to write: {}"), Some(buf)) /// ``` -fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -> (Option, Option) { +fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &TokenStream, is_write: bool) -> (Option, Option) { use fmt_macros::*; - let tts = TokenStream::from(tts.clone()); + let tts = tts.clone(); let mut parser = parser::Parser::new(&cx.sess.parse_sess, tts, None, false, false); let mut expr: Option = None; if is_write { diff --git a/tests/ui/author.stdout b/tests/ui/author.stdout index b06fb1d21e35..87593fafb464 100644 --- a/tests/ui/author.stdout +++ b/tests/ui/author.stdout @@ -1,6 +1,5 @@ if_chain! { - if let StmtKind::Decl(ref decl, _) = stmt.node - if let DeclKind::Local(ref local) = decl.node; + if let StmtKind::Local(ref local) = stmt.node; if let Some(ref init) = local.init if let ExprKind::Cast(ref expr, ref cast_ty) = init.node; if let TyKind::Path(ref qp) = cast_ty.node; diff --git a/tests/ui/author/call.stdout b/tests/ui/author/call.stdout index 1c25708fb484..d9322d618bfd 100644 --- a/tests/ui/author/call.stdout +++ b/tests/ui/author/call.stdout @@ -1,6 +1,5 @@ if_chain! { - if let StmtKind::Decl(ref decl, _) = stmt.node - if let DeclKind::Local(ref local) = decl.node; + if let StmtKind::Local(ref local) = stmt.node; if let Some(ref init) = local.init if let ExprKind::Call(ref func, ref args) = init.node; if let ExprKind::Path(ref path) = func.node; diff --git a/tests/ui/author/for_loop.stdout b/tests/ui/author/for_loop.stdout index b99e8e0ade5e..1611f419e5d3 100644 --- a/tests/ui/author/for_loop.stdout +++ b/tests/ui/author/for_loop.stdout @@ -1,7 +1,6 @@ if_chain! { if let ExprKind::Block(ref block) = expr.node; - if let StmtKind::Decl(ref decl, _) = block.node - if let DeclKind::Local(ref local) = decl.node; + if let StmtKind::Local(ref local) = block.node; if let Some(ref init) = local.init if let ExprKind::Match(ref expr, ref arms, MatchSource::ForLoopDesugar) = init.node; if let ExprKind::Call(ref func, ref args) = expr.node; @@ -14,8 +13,7 @@ if_chain! { // unimplemented: field checks if arms.len() == 1; if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.node; - if let StmtKind::Decl(ref decl1, _) = body.node - if let DeclKind::Local(ref local1) = decl1.node; + if let StmtKind::Local(ref local1) = body.node; if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local1.pat.node; if name.node.as_str() == "__next"; if let StmtKind::Expr(ref e, _) = local1.pat.node @@ -42,8 +40,7 @@ if_chain! { if arms1[1].pats.len() == 1; if let PatKind::Path(ref path7) = arms1[1].pats[0].node; if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]); - if let StmtKind::Decl(ref decl2, _) = path7.node - if let DeclKind::Local(ref local2) = decl2.node; + if let StmtKind::Local(ref local2) = path7.node; if let Some(ref init1) = local2.init if let ExprKind::Path(ref path8) = init1.node; if match_qpath(path8, &["__next"]); @@ -51,8 +48,7 @@ if_chain! { if name1.node.as_str() == "y"; if let StmtKind::Expr(ref e1, _) = local2.pat.node if let ExprKind::Block(ref block1) = e1.node; - if let StmtKind::Decl(ref decl3, _) = block1.node - if let DeclKind::Local(ref local3) = decl3.node; + if let StmtKind::Local(ref local3) = block1.node; if let Some(ref init2) = local3.init if let ExprKind::Path(ref path9) = init2.node; if match_qpath(path9, &["y"]);