diff --git a/CHANGELOG.md b/CHANGELOG.md index 047a5c4b34b3..47b91d267fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Change Log All notable changes to this project will be documented in this file. +## 0.0.99 — 2016-11-18 +* Update to rustc 1.15.0-nightly (0ed951993 2016-11-14) + ## 0.0.98 — 2016-11-08 * Fixes a an issue due to a change in how cargo handles `--sysroot`, which broke `cargo clippy` diff --git a/Cargo.toml b/Cargo.toml index 7cd83c12eae3..a29b962ec7ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.0.98" +version = "0.0.99" authors = [ "Manish Goregaokar ", "Andre Bogus ", @@ -25,7 +25,7 @@ test = false [dependencies] # begin automatic update -clippy_lints = { version = "0.0.98", path = "clippy_lints" } +clippy_lints = { version = "0.0.99", path = "clippy_lints" } # end automatic update [dev-dependencies] diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index b7f541e09b09..f8f40d1ba1cb 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.98" +version = "0.0.99" # end automatic update authors = [ "Manish Goregaokar ", diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs index 104c693350a2..7c1042e52374 100644 --- a/clippy_lints/src/arithmetic.rs +++ b/clippy_lints/src/arithmetic.rs @@ -59,7 +59,7 @@ impl LateLintPass for Arithmetic { hir::BiShr | hir::BiEq | hir::BiLt | hir::BiLe | hir::BiNe | hir::BiGe | hir::BiGt => return, _ => (), } - let (l_ty, r_ty) = (cx.tcx.expr_ty(l), cx.tcx.expr_ty(r)); + let (l_ty, r_ty) = (cx.tcx.tables().expr_ty(l), cx.tcx.tables().expr_ty(r)); if l_ty.is_integral() && r_ty.is_integral() { span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); self.span = Some(expr.span); @@ -69,7 +69,7 @@ impl LateLintPass for Arithmetic { } } hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => { - let ty = cx.tcx.expr_ty(arg); + let ty = cx.tcx.tables().expr_ty(arg); if ty.is_integral() { span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); self.span = Some(expr.span); diff --git a/clippy_lints/src/array_indexing.rs b/clippy_lints/src/array_indexing.rs index 4d8f3de5e046..eb84f459e985 100644 --- a/clippy_lints/src/array_indexing.rs +++ b/clippy_lints/src/array_indexing.rs @@ -59,7 +59,7 @@ impl LateLintPass for ArrayIndexing { fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { if let hir::ExprIndex(ref array, ref index) = e.node { // Array with known size can be checked statically - let ty = cx.tcx.expr_ty(array); + let ty = cx.tcx.tables().expr_ty(array); if let ty::TyArray(_, size) = ty.sty { let size = ConstInt::Infer(size as u64); diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 36814808a2bc..9e702fe3b4e3 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -81,11 +81,11 @@ impl LateLintPass for AssignOps { if let hir::ExprBinary(binop, ref l, ref r) = rhs.node { if op.node == binop.node { let lint = |assignee: &hir::Expr, rhs: &hir::Expr| { - let ty = cx.tcx.expr_ty(assignee); + let ty = cx.tcx.tables().expr_ty(assignee); if ty.walk_shallow().next().is_some() { return; // implements_trait does not work with generics } - let rty = cx.tcx.expr_ty(rhs); + let rty = cx.tcx.tables().expr_ty(rhs); if rty.walk_shallow().next().is_some() { return; // implements_trait does not work with generics } @@ -116,11 +116,11 @@ impl LateLintPass for AssignOps { hir::ExprAssign(ref assignee, ref e) => { if let hir::ExprBinary(op, ref l, ref r) = e.node { let lint = |assignee: &hir::Expr, rhs: &hir::Expr| { - let ty = cx.tcx.expr_ty(assignee); + let ty = cx.tcx.tables().expr_ty(assignee); if ty.walk_shallow().next().is_some() { return; // implements_trait does not work with generics } - let rty = cx.tcx.expr_ty(rhs); + let rty = cx.tcx.tables().expr_ty(rhs); if rty.walk_shallow().next().is_some() { return; // implements_trait does not work with generics } diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index fbbbf497d596..1af2273dc782 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -152,8 +152,8 @@ impl LateLintPass for AttrPass { } fn is_relevant_item(cx: &LateContext, item: &Item) -> bool { - if let ItemFn(_, _, _, _, _, ref block) = item.node { - is_relevant_block(cx, block) + if let ItemFn(_, _, _, _, _, ref expr) = item.node { + is_relevant_expr(cx, expr) } else { false } @@ -161,7 +161,7 @@ fn is_relevant_item(cx: &LateContext, item: &Item) -> bool { fn is_relevant_impl(cx: &LateContext, item: &ImplItem) -> bool { match item.node { - ImplItemKind::Method(_, ref block) => is_relevant_block(cx, block), + ImplItemKind::Method(_, ref expr) => is_relevant_expr(cx, expr), _ => false, } } @@ -169,7 +169,7 @@ fn is_relevant_impl(cx: &LateContext, item: &ImplItem) -> bool { fn is_relevant_trait(cx: &LateContext, item: &TraitItem) -> bool { match item.node { MethodTraitItem(_, None) => true, - MethodTraitItem(_, Some(ref block)) => is_relevant_block(cx, block), + MethodTraitItem(_, Some(ref expr)) => is_relevant_expr(cx, expr), _ => false, } } diff --git a/clippy_lints/src/block_in_if_condition.rs b/clippy_lints/src/block_in_if_condition.rs index 3f506e4f26d3..704729c4e36e 100644 --- a/clippy_lints/src/block_in_if_condition.rs +++ b/clippy_lints/src/block_in_if_condition.rs @@ -55,19 +55,8 @@ struct ExVisitor<'v> { impl<'v> Visitor<'v> for ExVisitor<'v> { fn visit_expr(&mut self, expr: &'v Expr) { - if let ExprClosure(_, _, ref block, _) = expr.node { - let complex = { - if block.stmts.is_empty() { - if let Some(ref ex) = block.expr { - matches!(ex.node, ExprBlock(_)) - } else { - false - } - } else { - true - } - }; - if complex { + if let ExprClosure(_, _, ref expr, _) = expr.node { + if matches!(expr.node, ExprBlock(_)) { self.found_block = Some(expr); return; } @@ -119,7 +108,7 @@ impl LateLintPass for BlockInIfCondition { let mut visitor = ExVisitor { found_block: None }; walk_expr(&mut visitor, check); if let Some(block) = visitor.found_block { - span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_STMT, block.span, COMPLEX_BLOCK_MESSAGE, ""); + span_lint(cx, BLOCK_IN_IF_CONDITION_STMT, block.span, COMPLEX_BLOCK_MESSAGE); } } } diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index b27984d9d2be..21ac913253b2 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -392,7 +392,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for NonminimalBoolVisitor<'a, 'tcx> { match e.node { ExprBinary(binop, _, _) if binop.node == BiOr || binop.node == BiAnd => self.bool_expr(e), ExprUnary(UnNot, ref inner) => { - if self.0.tcx.node_types()[&inner.id].is_bool() { + if self.0.tcx.tables.borrow().node_types[&inner.id].is_bool() { self.bool_expr(e); } else { walk_expr(self, e); diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 1245ec97051c..4d403329979a 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -120,8 +120,8 @@ impl LateLintPass for CopyAndPaste { } let (conds, blocks) = if_sequence(expr); - lint_same_then_else(cx, blocks.as_slice()); - lint_same_cond(cx, conds.as_slice()); + lint_same_then_else(cx, &blocks); + lint_same_cond(cx, &conds); lint_match_arms(cx, expr); } } @@ -219,8 +219,8 @@ fn lint_match_arms(cx: &LateContext, expr: &Expr) { /// Eg. would return `([a, b], [c, d, e])` for the expression /// `if a { c } else if b { d } else { e }`. fn if_sequence(mut expr: &Expr) -> (SmallVector<&Expr>, SmallVector<&Block>) { - let mut conds = SmallVector::zero(); - let mut blocks = SmallVector::zero(); + let mut conds = SmallVector::new(); + let mut blocks = SmallVector::new(); while let ExprIf(ref cond, ref then_block, ref else_expr) = expr.node { conds.push(&**cond); @@ -256,7 +256,7 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap { if let Entry::Vacant(v) = map.entry(ident.node.as_str()) { - v.insert(cx.tcx.pat_ty(pat)); + v.insert(cx.tcx.tables().pat_ty(pat)); } if let Some(ref as_pat) = *as_pat { bindings_impl(cx, as_pat, map); diff --git a/clippy_lints/src/cyclomatic_complexity.rs b/clippy_lints/src/cyclomatic_complexity.rs index faa56bccb228..f7758e3af231 100644 --- a/clippy_lints/src/cyclomatic_complexity.rs +++ b/clippy_lints/src/cyclomatic_complexity.rs @@ -42,12 +42,12 @@ impl LintPass for CyclomaticComplexity { } impl CyclomaticComplexity { - fn check<'a, 'tcx>(&mut self, cx: &'a LateContext<'a, 'tcx>, block: &Block, span: Span) { + fn check<'a, 'tcx>(&mut self, cx: &'a LateContext<'a, 'tcx>, expr: &Expr, span: Span) { if in_macro(cx, span) { return; } - let cfg = CFG::new(cx.tcx, block); + let cfg = CFG::new(cx.tcx, expr); let n = cfg.graph.len_nodes() as u64; let e = cfg.graph.len_edges() as u64; if e + 2 < n { @@ -62,9 +62,9 @@ impl CyclomaticComplexity { returns: 0, tcx: &cx.tcx, }; - helper.visit_block(block); + helper.visit_expr(expr); let CCHelper { match_arms, divergence, short_circuits, returns, .. } = helper; - let ret_ty = cx.tcx.node_id_to_type(block.id); + let ret_ty = cx.tcx.tables().node_id_to_type(expr.id); let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) { returns } else { @@ -92,22 +92,22 @@ impl CyclomaticComplexity { impl LateLintPass for CyclomaticComplexity { fn check_item(&mut self, cx: &LateContext, item: &Item) { - if let ItemFn(_, _, _, _, _, ref block) = item.node { + if let ItemFn(_, _, _, _, _, ref expr) = item.node { if !attr::contains_name(&item.attrs, "test") { - self.check(cx, block, item.span); + self.check(cx, expr, item.span); } } } fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) { - if let ImplItemKind::Method(_, ref block) = item.node { - self.check(cx, block, item.span); + if let ImplItemKind::Method(_, ref expr) = item.node { + self.check(cx, expr, item.span); } } fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) { - if let MethodTraitItem(_, Some(ref block)) = item.node { - self.check(cx, block, item.span); + if let MethodTraitItem(_, Some(ref expr)) = item.node { + self.check(cx, expr, item.span); } } @@ -139,7 +139,7 @@ impl<'a, 'b, 'tcx, 'gcx> Visitor<'a> for CCHelper<'b, 'gcx, 'tcx> { } ExprCall(ref callee, _) => { walk_expr(self, e); - let ty = self.tcx.node_id_to_type(callee.id); + let ty = self.tcx.tables().node_id_to_type(callee.id); match ty.sty { ty::TyFnDef(_, _, ty) | ty::TyFnPtr(ty) if ty.sig.skip_binder().output.sty == ty::TyNever => { diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index d95c72c58f4a..59687aa191be 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -73,7 +73,7 @@ impl LintPass for Derive { impl LateLintPass for Derive { fn check_item(&mut self, cx: &LateContext, item: &Item) { if let ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node { - let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty; + let ty = cx.tcx.item_type(cx.tcx.map.local_def_id(item.id)); let is_automatically_derived = is_automatically_derived(&*item.attrs); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); diff --git a/clippy_lints/src/drop_ref.rs b/clippy_lints/src/drop_ref.rs index 88739bb6d78e..4fb4009dd2f0 100644 --- a/clippy_lints/src/drop_ref.rs +++ b/clippy_lints/src/drop_ref.rs @@ -52,7 +52,7 @@ impl LateLintPass for Pass { } fn check_drop_arg(cx: &LateContext, call_span: Span, arg: &Expr) { - let arg_ty = cx.tcx.expr_ty(arg); + let arg_ty = cx.tcx.tables().expr_ty(arg); if let ty::TyRef(..) = arg_ty.sty { span_note_and_lint(cx, DROP_REF, diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs index 2a56ba1f22db..50bf299a3c3f 100644 --- a/clippy_lints/src/entry.rs +++ b/clippy_lints/src/entry.rs @@ -86,7 +86,7 @@ fn check_cond<'a, 'tcx, 'b>(cx: &'a LateContext<'a, 'tcx>, check: &'b Expr) -> O let ExprAddrOf(_, ref key) = params[1].node ], { let map = ¶ms[0]; - let obj_ty = walk_ptrs_ty(cx.tcx.expr_ty(map)); + let obj_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(map)); return if match_type(cx, obj_ty, &paths::BTREEMAP) { Some(("BTreeMap", map, key)) diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 30c7e067d289..703e37e77b01 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -5,7 +5,6 @@ use rustc::infer::InferCtxt; use rustc::lint::*; use rustc::middle::expr_use_visitor::*; use rustc::middle::mem_categorization::{cmt, Categorization}; -use rustc::ty::adjustment::AutoAdjustment; use rustc::ty; use rustc::ty::layout::TargetDataLayout; use rustc::util::nodemap::NodeSet; @@ -62,7 +61,7 @@ impl LintPass for Pass { } impl LateLintPass for Pass { - fn check_fn(&mut self, cx: &LateContext, _: visit::FnKind, decl: &FnDecl, body: &Block, _: Span, id: NodeId) { + fn check_fn(&mut self, cx: &LateContext, _: visit::FnKind, decl: &FnDecl, body: &Expr, _: Span, id: NodeId) { let param_env = ty::ParameterEnvironment::for_item(cx.tcx, id); let infcx = cx.tcx.borrowck_fake_infer_ctxt(param_env); @@ -146,17 +145,19 @@ impl<'a, 'tcx: 'a+'gcx, 'gcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx, 'g } fn borrow(&mut self, borrow_id: NodeId, _: Span, cmt: cmt<'tcx>, _: &ty::Region, _: ty::BorrowKind, loan_cause: LoanCause) { + use rustc::ty::adjustment::Adjust; if let Categorization::Local(lid) = cmt.cat { if self.set.contains(&lid) { - if let Some(&AutoAdjustment::AdjustDerefRef(adj)) = self.tcx + if let Some(&Adjust::DerefRef { autoderefs, .. }) = self.tcx .tables .borrow() .adjustments - .get(&borrow_id) { + .get(&borrow_id) + .map(|a| &a.kind) { if LoanCause::AutoRef == loan_cause { // x.foo() - if adj.autoderefs == 0 { + if autoderefs == 0 { self.set.remove(&lid); // Used without autodereffing (i.e. x.clone()) } } else { @@ -164,14 +165,15 @@ impl<'a, 'tcx: 'a+'gcx, 'gcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx, 'g } } else if LoanCause::AddrOf == loan_cause { // &x - if let Some(&AutoAdjustment::AdjustDerefRef(adj)) = self.tcx + if let Some(&Adjust::DerefRef { autoderefs, .. }) = self.tcx .tables .borrow() .adjustments .get(&self.tcx - .map - .get_parent_node(borrow_id)) { - if adj.autoderefs <= 1 { + .map + .get_parent_node(borrow_id)) + .map(|a| &a.kind) { + if autoderefs <= 1 { // foo(&x) where no extra autoreffing is happening self.set.remove(&lid); } diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index ad7da71eab05..ee0767f57dfd 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -48,60 +48,53 @@ impl LateLintPass for EtaPass { } fn check_closure(cx: &LateContext, expr: &Expr) { - if let ExprClosure(_, ref decl, ref blk, _) = expr.node { - if !blk.stmts.is_empty() { - // || {foo(); bar()}; can't be reduced here - return; - } - - if let Some(ref ex) = blk.expr { - if let ExprCall(ref caller, ref args) = ex.node { - if args.len() != decl.inputs.len() { - // Not the same number of arguments, there - // is no way the closure is the same as the function - return; - } - if is_adjusted(cx, ex) || args.iter().any(|arg| is_adjusted(cx, arg)) { - // Are the expression or the arguments type-adjusted? Then we need the closure - return; + if let ExprClosure(_, ref decl, ref ex, _) = expr.node { + if let ExprCall(ref caller, ref args) = ex.node { + if args.len() != decl.inputs.len() { + // Not the same number of arguments, there + // is no way the closure is the same as the function + return; + } + if is_adjusted(cx, ex) || args.iter().any(|arg| is_adjusted(cx, arg)) { + // Are the expression or the arguments type-adjusted? Then we need the closure + return; + } + let fn_ty = cx.tcx.tables().expr_ty(caller); + match fn_ty.sty { + // Is it an unsafe function? They don't implement the closure traits + ty::TyFnDef(_, _, fn_ty) | + ty::TyFnPtr(fn_ty) => { + if fn_ty.unsafety == Unsafety::Unsafe || + fn_ty.sig.skip_binder().output.sty == ty::TyNever { + return; + } } - let fn_ty = cx.tcx.expr_ty(caller); - match fn_ty.sty { - // Is it an unsafe function? They don't implement the closure traits - ty::TyFnDef(_, _, fn_ty) | - ty::TyFnPtr(fn_ty) => { - if fn_ty.unsafety == Unsafety::Unsafe || - fn_ty.sig.skip_binder().output.sty == ty::TyNever { + _ => (), + } + for (a1, a2) in decl.inputs.iter().zip(args) { + if let PatKind::Binding(_, ident, _) = a1.pat.node { + // XXXManishearth Should I be checking the binding mode here? + if let ExprPath(None, ref p) = a2.node { + if p.segments.len() != 1 { + // If it's a proper path, it can't be a local variable return; } - } - _ => (), - } - for (a1, a2) in decl.inputs.iter().zip(args) { - if let PatKind::Binding(_, ident, _) = a1.pat.node { - // XXXManishearth Should I be checking the binding mode here? - if let ExprPath(None, ref p) = a2.node { - if p.segments.len() != 1 { - // If it's a proper path, it can't be a local variable - return; - } - if p.segments[0].name != ident.node { - // The two idents should be the same - return; - } - } else { + if p.segments[0].name != ident.node { + // The two idents should be the same return; } } else { return; } + } else { + return; } - span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| { - if let Some(snippet) = snippet_opt(cx, caller.span) { - db.span_suggestion(expr.span, "remove closure as shown:", snippet); - } - }); } + span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| { + if let Some(snippet) = snippet_opt(cx, caller.span) { + db.span_suggestion(expr.span, "remove closure as shown:", snippet); + } + }); } } } diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 451ad50f3100..be5e67391abb 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DivergenceVisitor<'a, 'tcx> { ExprAgain(_) | ExprBreak(_) | ExprRet(_) => self.report_diverging_sub_expr(e), - ExprCall(ref func, _) => match self.0.tcx.expr_ty(func).sty { + ExprCall(ref func, _) => match self.0.tcx.tables().expr_ty(func).sty { ty::TyFnDef(_, _, fn_ty) | ty::TyFnPtr(fn_ty) => if let ty::TyNever = self.0.tcx.erase_late_bound_regions(&fn_ty.sig).output.sty { self.report_diverging_sub_expr(e); diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 7b178281415a..2013b406f2b7 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -132,7 +132,7 @@ fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool { let Some(fun) = resolve_node(cx, args[1].id), match_def_path(cx, fun.def_id(), &paths::DISPLAY_FMT_METHOD), ], { - let ty = walk_ptrs_ty(cx.tcx.pat_ty(&pat[0])); + let ty = walk_ptrs_ty(cx.tcx.tables().pat_ty(&pat[0])); return ty.sty == TypeVariants::TyStr || match_type(cx, ty, &paths::STRING); }} diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index eadbd01e4ea9..c6f17b615b62 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -69,7 +69,7 @@ impl LintPass for Functions { } impl LateLintPass for Functions { - fn check_fn(&mut self, cx: &LateContext, kind: intravisit::FnKind, decl: &hir::FnDecl, block: &hir::Block, span: Span, nodeid: ast::NodeId) { + fn check_fn(&mut self, cx: &LateContext, kind: intravisit::FnKind, decl: &hir::FnDecl, expr: &hir::Expr, span: Span, nodeid: ast::NodeId) { use rustc::hir::map::Node::*; let is_impl = if let Some(NodeItem(item)) = cx.tcx.map.find(cx.tcx.map.get_parent_node(nodeid)) { @@ -94,18 +94,18 @@ impl LateLintPass for Functions { } } - self.check_raw_ptr(cx, unsafety, decl, block, nodeid); + self.check_raw_ptr(cx, unsafety, decl, expr, nodeid); } fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) { - if let hir::MethodTraitItem(ref sig, ref block) = item.node { + if let hir::MethodTraitItem(ref sig, ref expr) = item.node { // don't lint extern functions decls, it's not their fault if sig.abi == Abi::Rust { self.check_arg_number(cx, &sig.decl, item.span); } - if let Some(ref block) = *block { - self.check_raw_ptr(cx, sig.unsafety, &sig.decl, block, item.id); + if let Some(ref expr) = *expr { + self.check_raw_ptr(cx, sig.unsafety, &sig.decl, expr, item.id); } } } @@ -122,7 +122,7 @@ impl Functions { } } - fn check_raw_ptr(&self, cx: &LateContext, unsafety: hir::Unsafety, decl: &hir::FnDecl, block: &hir::Block, nodeid: ast::NodeId) { + fn check_raw_ptr(&self, cx: &LateContext, unsafety: hir::Unsafety, decl: &hir::FnDecl, expr: &hir::Expr, nodeid: ast::NodeId) { if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(nodeid) { let raw_ptrs = decl.inputs.iter().filter_map(|arg| raw_ptr_arg(cx, arg)).collect::>(); @@ -132,7 +132,7 @@ impl Functions { ptrs: raw_ptrs, }; - hir::intravisit::walk_block(&mut v, block); + hir::intravisit::walk_expr(&mut v, expr); } } } @@ -155,7 +155,7 @@ impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for DerefVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'v hir::Expr) { match expr.node { hir::ExprCall(ref f, ref args) => { - let ty = self.cx.tcx.expr_ty(f); + let ty = self.cx.tcx.tables().expr_ty(f); if type_is_unsafe_function(ty) { for arg in args { diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 7ca24208fdff..269936776f7a 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,6 +1,6 @@ use rustc::lint::*; use rustc::hir::def_id::DefId; -use rustc::ty::{self, ImplOrTraitItem}; +use rustc::ty; use rustc::hir::*; use syntax::ast::{Lit, LitKind, Name}; use syntax::codemap::{Span, Spanned}; @@ -133,7 +133,8 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItem]) { if let Some(i) = impl_items.iter().find(|i| is_named_self(i, "len")) { if cx.access_levels.is_exported(i.id) { - let ty = cx.tcx.node_id_to_type(item.id); + let def_id = cx.tcx.map.local_def_id(item.id); + let ty = cx.tcx.item_type(def_id); span_lint(cx, LEN_WITHOUT_IS_EMPTY, @@ -183,10 +184,15 @@ fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[P], l /// Check if this type has an `is_empty` method. fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool { - /// Get an `ImplOrTraitItem` and return true if it matches `is_empty(self)`. - fn is_is_empty(item: &ImplOrTraitItem) -> bool { - if let ty::MethodTraitItem(ref method) = *item { - method.name.as_str() == "is_empty" && method.fty.sig.skip_binder().inputs.len() == 1 + /// Get an `AssociatedItem` and return true if it matches `is_empty(self)`. + fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool { + if let ty::AssociatedKind::Method = item.kind { + if item.name.as_str() == "is_empty" { + let ty = cx.tcx.item_type(item.def_id).fn_sig().skip_binder(); + ty.inputs.len() == 1 + } else { + false + } } else { false } @@ -195,19 +201,18 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool { /// Check the inherent impl's items for an `is_empty(self)` method. fn has_is_empty_impl(cx: &LateContext, id: DefId) -> bool { cx.tcx.inherent_impls.borrow().get(&id).map_or(false, |impls| impls.iter().any(|imp| { - cx.tcx.impl_or_trait_items(*imp).iter().any(|item| { - is_is_empty(&cx.tcx.impl_or_trait_item(*item)) + cx.tcx.associated_items(*imp).any(|item| { + is_is_empty(cx, &item) }) })) } - let ty = &walk_ptrs_ty(cx.tcx.expr_ty(expr)); + let ty = &walk_ptrs_ty(cx.tcx.tables().expr_ty(expr)); match ty.sty { ty::TyTrait(_) => { cx.tcx - .impl_or_trait_items(ty.ty_to_def_id().expect("trait impl not found")) - .iter() - .any(|item| is_is_empty(&cx.tcx.impl_or_trait_item(*item))) + .associated_items(ty.ty_to_def_id().expect("trait impl not found")) + .any(|item| is_is_empty(cx, &item)) } ty::TyProjection(_) => ty.ty_to_def_id().map_or(false, |id| has_is_empty_impl(cx, id)), ty::TyAdt(id, _) => has_is_empty_impl(cx, id.did), diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 8d5edb036823..07ec1f3f244b 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -3,7 +3,6 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(custom_attribute)] -#![feature(dotdot_in_tuple_patterns)] #![feature(rustc_private)] #![feature(slice_patterns)] #![feature(stmt_expr_attributes)] diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index c0455fa3c671..8f1ef44bf1c7 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -247,8 +247,8 @@ impl<'v, 't> RefVisitor<'v, 't> { match def { Def::TyAlias(def_id) | Def::Struct(def_id) => { - let type_scheme = self.cx.tcx.lookup_item_type(def_id); - for _ in type_scheme.generics.regions.as_slice() { + let generics = self.cx.tcx.item_generics(def_id); + for _ in generics.regions.as_slice() { self.record(&None); } } diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index fad72db74ed4..de4eee225738 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -623,7 +623,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { /// Check for `for` loops over `Option`s and `Results` fn check_arg_type(cx: &LateContext, pat: &Pat, arg: &Expr) { - let ty = cx.tcx.expr_ty(arg); + let ty = cx.tcx.tables().expr_ty(arg); if match_type(cx, ty, &paths::OPTION) { span_help_and_lint(cx, FOR_LOOP_OVER_OPTION, @@ -709,7 +709,7 @@ fn check_for_loop_over_map_kv(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Ex _ => (arg.span, arg), }; - let ty = walk_ptrs_ty(cx.tcx.expr_ty(arg)); + let ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(arg)); if match_type(cx, ty, &paths::HASHMAP) || match_type(cx, ty, &paths::BTREEMAP) { span_lint_and_then(cx, FOR_KV_MAP, @@ -854,7 +854,7 @@ impl<'v, 't> Visitor<'v> for VarUsedAfterLoopVisitor<'v, 't> { fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool { // no walk_ptrs_ty: calling iter() on a reference can make sense because it // will allow further borrows afterwards - let ty = cx.tcx.expr_ty(e); + let ty = cx.tcx.tables().expr_ty(e); is_iterable_array(ty) || match_type(cx, ty, &paths::VEC) || match_type(cx, ty, &paths::LINKED_LIST) || diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 39b0c7d80a59..674f2bbc11a8 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -1,7 +1,7 @@ use rustc::lint::*; use rustc::hir::*; use syntax::ast; -use utils::{is_adjusted, match_path, match_trait_method, match_type, paths, snippet, +use utils::{is_adjusted, match_path, match_trait_method, match_type, remove_blocks, paths, snippet, span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; /// **What it does:** Checks for mapping `clone()` over an iterator. @@ -30,11 +30,9 @@ impl LateLintPass for Pass { if let ExprMethodCall(name, _, ref args) = expr.node { if name.node.as_str() == "map" && args.len() == 2 { match args[1].node { - ExprClosure(_, ref decl, ref blk, _) => { + ExprClosure(_, ref decl, ref closure_expr, _) => { + let closure_expr = remove_blocks(closure_expr); if_let_chain! {[ - // just one expression in the closure - blk.stmts.is_empty(), - let Some(ref closure_expr) = blk.expr, // nothing special in the argument, besides reference bindings // (e.g. .map(|&x| x) ) let Some(arg_ident) = get_arg_name(&*decl.inputs[0].pat), @@ -44,7 +42,7 @@ impl LateLintPass for Pass { // look for derefs, for .map(|x| *x) if only_derefs(cx, &*closure_expr, arg_ident) && // .cloned() only removes one level of indirection, don't lint on more - walk_ptrs_ty_depth(cx.tcx.pat_ty(&*decl.inputs[0].pat)).1 == 1 + walk_ptrs_ty_depth(cx.tcx.tables().pat_ty(&*decl.inputs[0].pat)).1 == 1 { span_help_and_lint(cx, MAP_CLONE, expr.span, &format!( "you seem to be using .map() to clone the contents of an {}, consider \ @@ -101,7 +99,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Name) -> bool { fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static str> { if match_trait_method(cx, expr, &paths::ITERATOR) { Some("iterator") - } else if match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(arg)), &paths::OPTION) { + } else if match_type(cx, walk_ptrs_ty(cx.tcx.tables().expr_ty(arg)), &paths::OPTION) { Some("Option") } else { None diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index a3a4b7155f5b..844715835b99 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -159,7 +159,7 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { // allow match arms with just expressions return; }; - let ty = cx.tcx.expr_ty(ex); + let ty = cx.tcx.tables().expr_ty(ex); if ty.sty != ty::TyBool || cx.current_level(MATCH_BOOL) == Allow { check_single_match_single_pattern(cx, ex, arms, expr, els); check_single_match_opt_like(cx, ex, arms, expr, ty, els); @@ -243,7 +243,7 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { // type of expression == bool - if cx.tcx.expr_ty(ex).sty == ty::TyBool { + if cx.tcx.tables().expr_ty(ex).sty == ty::TyBool { span_lint_and_then(cx, MATCH_BOOL, expr.span, @@ -296,7 +296,7 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { } fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) { - if arms.len() >= 2 && cx.tcx.expr_ty(ex).is_integral() { + if arms.len() >= 2 && cx.tcx.tables().expr_ty(ex).is_integral() { let ranges = all_ranges(cx, arms); let type_ranges = type_ranges(&ranges); if !type_ranges.is_empty() { diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs index 41151835ce18..492962def6ab 100644 --- a/clippy_lints/src/mem_forget.rs +++ b/clippy_lints/src/mem_forget.rs @@ -33,7 +33,7 @@ impl LateLintPass for MemForget { if let ExprPath(None, _) = path_expr.node { let def_id = cx.tcx.expect_def(path_expr.id).def_id(); if match_def_path(cx, def_id, &paths::MEM_FORGET) { - let forgot_ty = cx.tcx.expr_ty(&args[0]); + let forgot_ty = cx.tcx.tables().expr_ty(&args[0]); if match forgot_ty.ty_adt_def() { Some(def) => def.has_dtor(), diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 70ae2e6a189f..a0c64c23bb9d 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -573,7 +573,7 @@ impl LateLintPass for Pass { lint_or_fun_call(cx, expr, &name.node.as_str(), args); - let self_ty = cx.tcx.expr_ty_adjusted(&args[0]); + let self_ty = cx.tcx.tables().expr_ty_adjusted(&args[0]); if args.len() == 1 && name.node.as_str() == "clone" { lint_clone_on_copy(cx, expr, &args[0], self_ty); } @@ -623,7 +623,7 @@ impl LateLintPass for Pass { } // check conventions w.r.t. conversion method names and predicates - let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty; + let ty = cx.tcx.item_type(cx.tcx.map.local_def_id(item.id)); let is_copy = is_copy(cx, ty, item.id); for &(ref conv, self_kinds) in &CONVENTIONS { if_let_chain! {[ @@ -680,7 +680,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[P Option Option bool { } fn is_float(cx: &LateContext, expr: &Expr) -> bool { - matches!(walk_ptrs_ty(cx.tcx.expr_ty(expr)).sty, ty::TyFloat(_)) + matches!(walk_ptrs_ty(cx.tcx.tables().expr_ty(expr)).sty, ty::TyFloat(_)) } fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) { let (arg_ty, snip) = match expr.node { ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => { if name.as_str() == "to_string" || name.as_str() == "to_owned" && is_str_arg(cx, args) { - (cx.tcx.expr_ty(&args[0]), snippet(cx, args[0].span, "..")) + (cx.tcx.tables().expr_ty(&args[0]), snippet(cx, args[0].span, "..")) } else { return; } @@ -368,7 +368,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S ExprCall(ref path, ref v) if v.len() == 1 => { if let ExprPath(None, ref path) = path.node { if match_path(path, &["String", "from_str"]) || match_path(path, &["String", "from"]) { - (cx.tcx.expr_ty(&v[0]), snippet(cx, v[0].span, "..")) + (cx.tcx.tables().expr_ty(&v[0]), snippet(cx, v[0].span, "..")) } else { return; } @@ -379,7 +379,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S _ => return, }; - let other_ty = cx.tcx.expr_ty(other); + let other_ty = cx.tcx.tables().expr_ty(other); let partial_eq_trait_id = match cx.tcx.lang_items.eq_trait() { Some(id) => id, None => return, @@ -413,7 +413,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S fn is_str_arg(cx: &LateContext, args: &[P]) -> bool { args.len() == 1 && - matches!(walk_ptrs_ty(cx.tcx.expr_ty(&args[0])).sty, ty::TyStr) + matches!(walk_ptrs_ty(cx.tcx.tables().expr_ty(&args[0])).sty, ty::TyStr) } /// Heuristic to see if an expression is used. Should be compatible with `unused_variables`'s idea diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index 61e4530a1df4..abb9d0fcb49a 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -239,7 +239,7 @@ impl EarlyLintPass for MiscEarly { } } - fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) { + fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: Span, _: NodeId) { let mut registered_names: HashMap = HashMap::new(); for arg in &decl.inputs { diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 454f591756bb..7ca00500475f 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -147,10 +147,7 @@ impl LateLintPass for MissingDoc { fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) { // If the method is an impl for a trait, don't doc. let def_id = cx.tcx.map.local_def_id(impl_item.id); - match cx.tcx.impl_or_trait_items.borrow() - .get(&def_id) - .expect("missing method descriptor?!") - .container() { + match cx.tcx.associated_item(def_id).container { ty::TraitContainer(_) => return, ty::ImplContainer(cid) => { if cx.tcx.impl_trait_ref(cid).is_some() { diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index 24eb8dfc3635..fe430a539a0f 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -65,7 +65,7 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for MutVisitor<'a, 'tcx> { } else if let hir::ExprAddrOf(hir::MutMutable, ref e) = expr.node { if let hir::ExprAddrOf(hir::MutMutable, _) = e.node { span_lint(self.cx, MUT_MUT, expr.span, "generally you want to avoid `&mut &mut _` if possible"); - } else if let TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) = self.cx.tcx.expr_ty(e).sty { + } else if let TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) = self.cx.tcx.tables().expr_ty(e).sty { span_lint(self.cx, MUT_MUT, expr.span, diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs index a2117656f9d7..bdf0ad2af98b 100644 --- a/clippy_lints/src/mutex_atomic.rs +++ b/clippy_lints/src/mutex_atomic.rs @@ -56,7 +56,7 @@ pub struct MutexAtomic; impl LateLintPass for MutexAtomic { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { - let ty = cx.tcx.expr_ty(expr); + let ty = cx.tcx.tables().expr_ty(expr); if let ty::TyAdt(_, subst) = ty.sty { if match_type(cx, ty, &paths::MUTEX) { let mutex_param = &subst.type_at(0).sty; diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 29691504b828..b2199c226e96 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -4,9 +4,8 @@ use rustc::lint::*; use rustc::hir::{ExprAddrOf, Expr, MutImmutable, Pat, PatKind, BindingMode}; -use rustc::ty::TyRef; +use rustc::ty; use utils::{span_lint, in_macro}; -use rustc::ty::adjustment::AutoAdjustment::AdjustDerefRef; /// **What it does:** Checks for address of operations (`&`) that are going to /// be dereferenced immediately by the compiler. @@ -41,9 +40,9 @@ impl LateLintPass for NeedlessBorrow { return; } if let ExprAddrOf(MutImmutable, ref inner) = e.node { - if let TyRef(..) = cx.tcx.expr_ty(inner).sty { - if let Some(&AdjustDerefRef(ref deref)) = cx.tcx.tables.borrow().adjustments.get(&e.id) { - if deref.autoderefs > 1 && deref.autoref.is_some() { + if let ty::TyRef(..) = cx.tcx.tables().expr_ty(inner).sty { + if let Some(&ty::adjustment::Adjust::DerefRef { autoderefs, autoref, .. }) = cx.tcx.tables.borrow().adjustments.get(&e.id).map(|a| &a.kind) { + if autoderefs > 1 && autoref.is_some() { span_lint(cx, NEEDLESS_BORROW, e.span, @@ -59,9 +58,9 @@ impl LateLintPass for NeedlessBorrow { return; } if let PatKind::Binding(BindingMode::BindByRef(MutImmutable), _, _) = pat.node { - if let TyRef(_, ref tam) = cx.tcx.pat_ty(pat).sty { + if let ty::TyRef(_, ref tam) = cx.tcx.tables().pat_ty(pat).sty { if tam.mutbl == MutImmutable { - if let TyRef(..) = tam.ty.sty { + if let ty::TyRef(..) = tam.ty.sty { span_lint(cx, NEEDLESS_BORROW, pat.span, diff --git a/clippy_lints/src/needless_update.rs b/clippy_lints/src/needless_update.rs index 9f607f4350d2..cdd266ec2e87 100644 --- a/clippy_lints/src/needless_update.rs +++ b/clippy_lints/src/needless_update.rs @@ -33,7 +33,7 @@ impl LintPass for Pass { impl LateLintPass for Pass { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { if let ExprStruct(_, ref fields, Some(ref base)) = expr.node { - let ty = cx.tcx.expr_ty(expr); + let ty = cx.tcx.tables().expr_ty(expr); if let TyAdt(def, _) = ty.sty { if fields.len() == def.struct_variant().fields.len() { span_lint(cx, diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index 3749b36540c4..5ca6172b6bcc 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -50,7 +50,7 @@ fn check_mul(cx: &LateContext, span: Span, lit: &Expr, exp: &Expr) { let Constant::Int(ref ci) = consts::lit_to_constant(&l.node), let Some(val) = ci.to_u64(), val == 1, - cx.tcx.expr_ty(exp).is_integral() + cx.tcx.tables().expr_ty(exp).is_integral() ], { span_lint(cx, NEG_MULTIPLY, diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 538d3abd5ea4..66420f00c674 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -90,7 +90,7 @@ impl LintPass for NewWithoutDefault { } impl LateLintPass for NewWithoutDefault { - fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, _: &hir::Block, span: Span, id: ast::NodeId) { + fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, _: &hir::Expr, span: Span, id: ast::NodeId) { if in_external_macro(cx, span) { return; } @@ -102,8 +102,7 @@ impl LateLintPass for NewWithoutDefault { } if decl.inputs.is_empty() && name.as_str() == "new" && cx.access_levels.is_reachable(id) { let self_ty = cx.tcx - .lookup_item_type(cx.tcx.map.local_def_id(cx.tcx.map.get_parent(id))) - .ty; + .item_type(cx.tcx.map.local_def_id(cx.tcx.map.get_parent(id))); if_let_chain!{[ self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics same_tys(cx, self_ty, return_ty(cx, id), id), diff --git a/clippy_lints/src/ok_if_let.rs b/clippy_lints/src/ok_if_let.rs index 09e3fa641f9a..1fdfe43b6845 100644 --- a/clippy_lints/src/ok_if_let.rs +++ b/clippy_lints/src/ok_if_let.rs @@ -50,7 +50,7 @@ impl LateLintPass for Pass { method_chain_args(op, &["ok"]).is_some() //test to see if using ok() methoduse std::marker::Sized; ], { - let is_result_type = match_type(cx, cx.tcx.expr_ty(&result_types[0]), &paths::RESULT); + let is_result_type = match_type(cx, cx.tcx.tables().expr_ty(&result_types[0]), &paths::RESULT); let some_expr_string = snippet(cx, y[0].span, ""); if print::path_to_string(x) == "Some" && is_result_type { span_help_and_lint(cx, IF_LET_SOME_RESULT, expr.span, diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs index 42851c1fe24c..51d961e9fe63 100644 --- a/clippy_lints/src/open_options.rs +++ b/clippy_lints/src/open_options.rs @@ -35,7 +35,7 @@ impl LintPass for NonSensical { impl LateLintPass for NonSensical { fn check_expr(&mut self, cx: &LateContext, e: &Expr) { if let ExprMethodCall(ref name, _, ref arguments) = e.node { - let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&arguments[0])); + let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0])); if name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) { let mut options = Vec::new(); get_open_options(cx, &arguments[0], &mut options); @@ -63,7 +63,7 @@ enum OpenOption { fn get_open_options(cx: &LateContext, argument: &Expr, options: &mut Vec<(OpenOption, Argument)>) { if let ExprMethodCall(ref name, _, ref arguments) = argument.node { - let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&arguments[0])); + let (obj_ty, _) = walk_ptrs_ty_depth(cx.tcx.tables().expr_ty(&arguments[0])); // Only proceed if this is a call on some object of type std::fs::OpenOptions if match_type(cx, obj_ty, &paths::OPEN_OPTIONS) && arguments.len() >= 2 { diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs index 24bccf687f18..98c2b986d202 100644 --- a/clippy_lints/src/overflow_check_conditional.rs +++ b/clippy_lints/src/overflow_check_conditional.rs @@ -39,8 +39,8 @@ impl LateLintPass for OverflowCheckConditional { let Expr_::ExprPath(_, ref path2) = ident2.node, let Expr_::ExprPath(_, ref path3) = second.node, &path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0], - cx.tcx.expr_ty(ident1).is_integral(), - cx.tcx.expr_ty(ident2).is_integral() + cx.tcx.tables().expr_ty(ident1).is_integral(), + cx.tcx.tables().expr_ty(ident2).is_integral() ], { if let BinOp_::BiLt = op.node { if let BinOp_::BiAdd = op2.node { @@ -61,8 +61,8 @@ impl LateLintPass for OverflowCheckConditional { let Expr_::ExprPath(_, ref path2) = ident2.node, let Expr_::ExprPath(_, ref path3) = first.node, &path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0], - cx.tcx.expr_ty(ident1).is_integral(), - cx.tcx.expr_ty(ident2).is_integral() + cx.tcx.tables().expr_ty(ident1).is_integral(), + cx.tcx.tables().expr_ty(ident2).is_integral() ], { if let BinOp_::BiGt = op.node { if let BinOp_::BiAdd = op2.node { diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index dea950ac063e..2863b14b1121 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -91,7 +91,8 @@ impl LateLintPass for PointerPass { } fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) { - let fn_ty = cx.tcx.node_id_to_type(fn_id).fn_sig().skip_binder(); + let fn_def_id = cx.tcx.map.local_def_id(fn_id); + let fn_ty = cx.tcx.item_type(fn_def_id).fn_sig().skip_binder(); for (arg, ty) in decl.inputs.iter().zip(&fn_ty.inputs) { if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = ty.sty { diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 2e9a72e54a9d..45886a903942 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -89,7 +89,7 @@ impl LateLintPass for StepByZero { fn has_step_by(cx: &LateContext, expr: &Expr) -> bool { // No need for walk_ptrs_ty here because step_by moves self, so it // can't be called on a borrowed range. - let ty = cx.tcx.expr_ty(expr); + let ty = cx.tcx.tables().expr_ty(expr); // Note: `RangeTo`, `RangeToInclusive` and `RangeFull` don't have step_by match_type(cx, ty, &paths::RANGE) diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index ab0c4f237c2f..fef03d19cc78 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -91,7 +91,7 @@ impl LateLintPass for Pass { if_let_chain!{[ self.last.is_none(), let Some(ref expr) = block.expr, - match_type(cx, cx.tcx.expr_ty(expr), &paths::REGEX), + match_type(cx, cx.tcx.tables().expr_ty(expr), &paths::REGEX), let Some(span) = is_expn_of(cx, expr.span, "regex"), ], { if !self.spans.contains(&span) { diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 456f17e74a7f..0e6de0d39b22 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,5 +1,5 @@ use rustc::lint::*; -use syntax::ast::*; +use syntax::ast; use syntax::codemap::{Span, Spanned}; use syntax::visit::FnKind; @@ -45,10 +45,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) { + fn check_block_return(&mut self, cx: &EarlyContext, block: &ast::Block) { if let Some(stmt) = block.stmts.last() { match stmt.node { - StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => { + ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => { self.check_final_expr(cx, expr, Some(stmt.span)); } _ => (), @@ -57,25 +57,25 @@ impl ReturnPass { } // Check a the final expression in a block if it's a return. - fn check_final_expr(&mut self, cx: &EarlyContext, expr: &Expr, span: Option) { + fn check_final_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr, span: Option) { match expr.node { // simple return is always "bad" - ExprKind::Ret(Some(ref inner)) => { + ast::ExprKind::Ret(Some(ref inner)) => { self.emit_return_lint(cx, span.expect("`else return` is not possible"), inner.span); } // a whole block? check it! - ExprKind::Block(ref block) => { + ast::ExprKind::Block(ref block) => { self.check_block_return(cx, block); } // an if/if let expr, check both exprs // note, if without else is going to be a type checking error anyways // (except for unit type functions) so we don't match it - ExprKind::If(_, ref ifblock, Some(ref elsexpr)) => { + ast::ExprKind::If(_, ref ifblock, Some(ref elsexpr)) => { self.check_block_return(cx, ifblock); self.check_final_expr(cx, elsexpr, None); } // a match expr, check all arms - ExprKind::Match(_, ref arms) => { + ast::ExprKind::Match(_, ref arms) => { for arm in arms { self.check_final_expr(cx, &arm.body, Some(arm.body.span)); } @@ -96,18 +96,18 @@ impl ReturnPass { } // Check for "let x = EXPR; x" - fn check_let_return(&mut self, cx: &EarlyContext, block: &Block) { + fn check_let_return(&mut self, cx: &EarlyContext, block: &ast::Block) { let mut it = block.stmts.iter(); // we need both a let-binding stmt and an expr if_let_chain! {[ let Some(ref retexpr) = it.next_back(), - let StmtKind::Expr(ref retexpr) = retexpr.node, + let ast::StmtKind::Expr(ref retexpr) = retexpr.node, let Some(stmt) = it.next_back(), - let StmtKind::Local(ref local) = stmt.node, + let ast::StmtKind::Local(ref local) = stmt.node, let Some(ref initexpr) = local.init, - let PatKind::Ident(_, Spanned { node: id, .. }, _) = local.pat.node, - let ExprKind::Path(_, ref path) = retexpr.node, + let ast::PatKind::Ident(_, Spanned { node: id, .. }, _) = local.pat.node, + let ast::ExprKind::Path(_, ref path) = retexpr.node, match_path_ast(path, &[&id.name.as_str()]), !in_external_macro(cx, initexpr.span), ], { @@ -129,11 +129,14 @@ impl LintPass for ReturnPass { } impl EarlyLintPass for ReturnPass { - fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, _: &FnDecl, block: &Block, _: Span, _: NodeId) { - self.check_block_return(cx, block); + fn check_fn(&mut self, cx: &EarlyContext, kind: FnKind, _: &ast::FnDecl, _: Span, _: ast::NodeId) { + match kind { + FnKind::ItemFn(.., block) | FnKind::Method(.., block) => self.check_block_return(cx, block), + FnKind::Closure(body) => self.check_final_expr(cx, body, None), + } } - fn check_block(&mut self, cx: &EarlyContext, block: &Block) { + fn check_block(&mut self, cx: &EarlyContext, block: &ast::Block) { self.check_let_return(cx, block); } } diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 53ee82957680..b57ec1d052aa 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -81,22 +81,22 @@ impl LintPass for Pass { } impl LateLintPass for Pass { - fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, block: &Block, _: Span, _: NodeId) { - if in_external_macro(cx, block.span) { + fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, expr: &Expr, _: Span, _: NodeId) { + if in_external_macro(cx, expr.span) { return; } - check_fn(cx, decl, block); + check_fn(cx, decl, expr); } } -fn check_fn(cx: &LateContext, decl: &FnDecl, block: &Block) { +fn check_fn(cx: &LateContext, decl: &FnDecl, expr: &Expr) { let mut bindings = Vec::new(); for arg in &decl.inputs { if let PatKind::Binding(_, ident, _) = arg.pat.node { bindings.push((ident.node, ident.span)) } } - check_block(cx, block, &mut bindings); + check_expr(cx, expr, &mut bindings); } fn check_block(cx: &LateContext, block: &Block, bindings: &mut Vec<(Name, Span)>) { diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 28e61cf2e206..9fd09eab2ddc 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -114,7 +114,7 @@ impl LateLintPass for StringAdd { } fn is_string(cx: &LateContext, e: &Expr) -> bool { - match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(e)), &paths::STRING) + match_type(cx, walk_ptrs_ty(cx.tcx.tables().expr_ty(e)), &paths::STRING) } fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool { diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 584bcb0d866a..278df3bad352 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -85,7 +85,7 @@ fn check_manual_swap(cx: &LateContext, block: &Block) { if let ExprIndex(ref lhs1, ref idx1) = lhs1.node { if let ExprIndex(ref lhs2, ref idx2) = lhs2.node { if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs1, lhs2) { - let ty = walk_ptrs_ty(cx.tcx.expr_ty(lhs1)); + let ty = walk_ptrs_ty(cx.tcx.tables().expr_ty(lhs1)); if matches!(ty.sty, ty::TySlice(_)) || matches!(ty.sty, ty::TyArray(_, _)) || diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index 5e9931c3bd2d..b4505c89f3b7 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -91,8 +91,8 @@ impl LateLintPass for Transmute { let def_id = cx.tcx.expect_def(path_expr.id).def_id(); if match_def_path(cx, def_id, &paths::TRANSMUTE) { - let from_ty = cx.tcx.expr_ty(&args[0]); - let to_ty = cx.tcx.expr_ty(e); + let from_ty = cx.tcx.tables().expr_ty(&args[0]); + let to_ty = cx.tcx.tables().expr_ty(e); match (&from_ty.sty, &to_ty.sty) { _ if from_ty == to_ty => span_lint( diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 40bd87f08cd5..de8fbdcc5d7a 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -126,7 +126,7 @@ declare_lint! { fn check_let_unit(cx: &LateContext, decl: &Decl) { if let DeclLocal(ref local) = decl.node { - let bindtype = &cx.tcx.pat_ty(&local.pat).sty; + let bindtype = &cx.tcx.tables().pat_ty(&local.pat).sty; match *bindtype { ty::TyTuple(slice) if slice.is_empty() => { if in_external_macro(cx, decl.span) || in_macro(cx, local.pat.span) { @@ -197,7 +197,7 @@ impl LateLintPass for UnitCmp { if let ExprBinary(ref cmp, ref left, _) = expr.node { let op = cmp.node; if op.is_comparison() { - let sty = &cx.tcx.expr_ty(left).sty; + let sty = &cx.tcx.tables().expr_ty(left).sty; match *sty { ty::TyTuple(slice) if slice.is_empty() => { let result = match op { @@ -449,7 +449,7 @@ impl LintPass for CastPass { impl LateLintPass for CastPass { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { if let ExprCast(ref ex, _) = expr.node { - let (cast_from, cast_to) = (cx.tcx.expr_ty(ex), cx.tcx.expr_ty(expr)); + let (cast_from, cast_to) = (cx.tcx.tables().expr_ty(ex), cx.tcx.tables().expr_ty(expr)); if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx, expr.span) { match (cast_from.is_integral(), cast_to.is_integral()) { (true, false) => { @@ -535,7 +535,7 @@ impl LintPass for TypeComplexityPass { } impl LateLintPass for TypeComplexityPass { - fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) { + fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Expr, _: Span, _: NodeId) { self.check_fndecl(cx, decl); } @@ -683,7 +683,7 @@ impl LateLintPass for CharLitAsU8 { if let ExprCast(ref e, _) = expr.node { if let ExprLit(ref l) = e.node { if let LitKind::Char(_) = l.node { - if ty::TyUint(UintTy::U8) == cx.tcx.expr_ty(expr).sty && !in_macro(cx, expr.span) { + if ty::TyUint(UintTy::U8) == cx.tcx.tables().expr_ty(expr).sty && !in_macro(cx, expr.span) { let msg = "casting character literal to u8. `char`s \ are 4 bytes wide in rust, so casting to u8 \ truncates them"; @@ -791,7 +791,7 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option (), @@ -953,7 +953,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<( use std::*; if let ExprCast(ref cast_exp, _) = expr.node { - match cx.tcx.expr_ty(cast_exp).sty { + match cx.tcx.tables().expr_ty(cast_exp).sty { TyInt(int_ty) => { Some(match int_ty { IntTy::I8 => (FullInt::S(i8::min_value() as i64), FullInt::S(i8::max_value() as i64)), diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs index 899fc940cf13..63a6321f0eae 100644 --- a/clippy_lints/src/unused_label.rs +++ b/clippy_lints/src/unused_label.rs @@ -47,7 +47,7 @@ impl LintPass for UnusedLabel { } impl LateLintPass for UnusedLabel { - fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, body: &hir::Block, span: Span, fn_id: ast::NodeId) { + fn check_fn(&mut self, cx: &LateContext, kind: FnKind, decl: &hir::FnDecl, body: &hir::Expr, span: Span, fn_id: ast::NodeId) { if in_macro(cx, span) { return; } diff --git a/clippy_lints/src/utils/hir.rs b/clippy_lints/src/utils/hir.rs index b1be2ebb883c..bd9969714a4c 100644 --- a/clippy_lints/src/utils/hir.rs +++ b/clippy_lints/src/utils/hir.rs @@ -368,11 +368,11 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> { self.hash_expr(e); // TODO: _ty } - ExprClosure(cap, _, ref b, _) => { + ExprClosure(cap, _, ref e, _) => { let c: fn(_, _, _, _) -> _ = ExprClosure; c.hash(&mut self.s); cap.hash(&mut self.s); - self.hash_block(b); + self.hash_expr(e); } ExprField(ref e, ref f) => { let c: fn(_, _) -> _ = ExprField; diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index a4d9e8452e6e..0ccdd0ef356a 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -135,7 +135,7 @@ fn has_attr(attrs: &[Attribute]) -> bool { fn print_decl(cx: &LateContext, decl: &hir::Decl) { match decl.node { hir::DeclLocal(ref local) => { - println!("local variable of type {}", cx.tcx.node_id_to_type(local.id)); + println!("local variable of type {}", cx.tcx.tables().node_id_to_type(local.id)); println!("pattern:"); print_pat(cx, &local.pat, 0); if let Some(ref e) = local.init { @@ -149,7 +149,7 @@ fn print_decl(cx: &LateContext, decl: &hir::Decl) { fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { let ind = " ".repeat(indent); - let ty = cx.tcx.node_id_to_type(expr.id); + let ty = cx.tcx.tables().node_id_to_type(expr.id); println!("{}+", ind); match expr.node { hir::ExprBox(ref e) => { @@ -350,25 +350,25 @@ fn print_item(cx: &LateContext, item: &hir::Item) { } } hir::ItemUse(ref path) => println!("{:?}", path.node), - hir::ItemStatic(..) => println!("static item: {:#?}", cx.tcx.opt_lookup_item_type(did)), - hir::ItemConst(..) => println!("const item: {:#?}", cx.tcx.opt_lookup_item_type(did)), + hir::ItemStatic(..) => println!("static item of type {:#?}", cx.tcx.item_type(did)), + hir::ItemConst(..) => println!("const item of type {:#?}", cx.tcx.item_type(did)), hir::ItemFn(..) => { - let item_ty = cx.tcx.opt_lookup_item_type(did); - println!("function: {:#?}", item_ty); + let item_ty = cx.tcx.item_type(did); + println!("function of type {:#?}", item_ty); }, hir::ItemMod(..) => println!("module"), hir::ItemForeignMod(ref fm) => println!("foreign module with abi: {}", fm.abi), hir::ItemTy(..) => { - println!("type alias: {:?}", cx.tcx.opt_lookup_item_type(did)); + println!("type alias for {:?}", cx.tcx.item_type(did)); }, hir::ItemEnum(..) => { - println!("enum definition: {:?}", cx.tcx.opt_lookup_item_type(did)); + println!("enum definition of type {:?}", cx.tcx.item_type(did)); }, hir::ItemStruct(..) => { - println!("struct definition: {:?}", cx.tcx.opt_lookup_item_type(did)); + println!("struct definition of type {:?}", cx.tcx.item_type(did)); }, hir::ItemUnion(..) => { - println!("union definition: {:?}", cx.tcx.opt_lookup_item_type(did)); + println!("union definition of type {:?}", cx.tcx.item_type(did)); }, hir::ItemTrait(..) => { println!("trait decl"); diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 276ff8f065e4..122ba9cdc1ae 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -429,7 +429,12 @@ pub fn get_enclosing_block<'c>(cx: &'c LateContext, node: NodeId) -> Option<&'c if let Some(node) = enclosing_node { match node { Node::NodeBlock(block) => Some(block), - Node::NodeItem(&Item { node: ItemFn(_, _, _, _, _, ref block), .. }) => Some(block), + Node::NodeItem(&Item { node: ItemFn(_, _, _, _, _, ref expr), .. }) => { + match expr.node { + ExprBlock(ref block) => Some(block), + _ => None, + } + } _ => None, } } else { @@ -696,8 +701,9 @@ pub fn camel_case_from(s: &str) -> usize { /// Convenience function to get the return type of a function pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> ty::Ty<'tcx> { let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, fn_item); - let fn_sig = cx.tcx.node_id_to_type(fn_item).fn_sig().subst(cx.tcx, parameter_env.free_substs); - let fn_sig = cx.tcx.liberate_late_bound_regions(parameter_env.free_id_outlive, &fn_sig); + let fn_def_id = cx.tcx.map.local_def_id(fn_item); + let fn_sig = cx.tcx.item_type(fn_def_id).fn_sig(); + let fn_sig = cx.tcx.liberate_late_bound_regions(parameter_env.free_id_outlive, fn_sig); fn_sig.output } @@ -767,3 +773,22 @@ pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool { pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool { attr::contains_name(attrs, "automatically_derived") } + +/// Remove blocks around an expression. +/// +/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return themselves. +pub fn remove_blocks(expr: &Expr) -> &Expr { + if let ExprBlock(ref block) = expr.node { + if block.stmts.is_empty() { + if let Some(ref expr) = block.expr { + remove_blocks(expr) + } else { + expr + } + } else { + expr + } + } else { + expr + } +} diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 06d3d040ccdc..f847c397da86 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -36,7 +36,7 @@ impl LateLintPass for Pass { fn check_expr(&mut self, cx: &LateContext, expr: &Expr) { // search for `&vec![_]` expressions where the adjusted type is `&[_]` if_let_chain!{[ - let ty::TypeVariants::TyRef(_, ref ty) = cx.tcx.expr_ty_adjusted(expr).sty, + let ty::TypeVariants::TyRef(_, ref ty) = cx.tcx.tables().expr_ty_adjusted(expr).sty, let ty::TypeVariants::TySlice(..) = ty.ty.sty, let ExprAddrOf(_, ref addressee) = expr.node, let Some(vec_args) = higher::vec_macro(cx, addressee), @@ -48,7 +48,7 @@ impl LateLintPass for Pass { if_let_chain!{[ let Some((_, arg, _)) = higher::for_loop(expr), let Some(vec_args) = higher::vec_macro(cx, arg), - is_copy(cx, vec_type(cx.tcx.expr_ty_adjusted(arg)), cx.tcx.map.get_parent(expr.id)), + is_copy(cx, vec_type(cx.tcx.tables().expr_ty_adjusted(arg)), cx.tcx.map.get_parent(expr.id)), ], { // report the error around the `vec!` not inside `:` let span = cx.sess().codemap().source_callsite(arg.span); diff --git a/tests/compile-fail/block_in_if_condition.rs b/tests/compile-fail/block_in_if_condition.rs index 3d47fc74a113..43216754f753 100644 --- a/tests/compile-fail/block_in_if_condition.rs +++ b/tests/compile-fail/block_in_if_condition.rs @@ -27,7 +27,6 @@ fn macro_if() { } fn condition_has_block() -> i32 { - if { //~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' let x = 3; x == 3 diff --git a/tests/compile-fail/copies.rs b/tests/compile-fail/copies.rs index d9eb842d680d..3e65d1aeec47 100644 --- a/tests/compile-fail/copies.rs +++ b/tests/compile-fail/copies.rs @@ -1,5 +1,4 @@ #![feature(plugin, inclusive_range_syntax)] -#![feature(dotdot_in_tuple_patterns)] #![plugin(clippy)] #![allow(dead_code, no_effect, unnecessary_operation)] diff --git a/tests/compile-fail/diverging_sub_expression.rs b/tests/compile-fail/diverging_sub_expression.rs index f9a6e66da42f..e7daebfdf2f9 100644 --- a/tests/compile-fail/diverging_sub_expression.rs +++ b/tests/compile-fail/diverging_sub_expression.rs @@ -1,6 +1,7 @@ #![feature(plugin, never_type)] #![plugin(clippy)] #![deny(diverging_sub_expression)] +#![allow(match_same_arms, logic_bug)] #[allow(empty_loop)] fn diverge() -> ! { loop {} } @@ -16,8 +17,6 @@ fn main() { let b = true; b || diverge(); //~ ERROR sub-expression diverges b || A.foo(); //~ ERROR sub-expression diverges - let y = (5, diverge(), 6); //~ ERROR sub-expression diverges - println!("{}", y.1); } #[allow(dead_code, unused_variables)] @@ -26,16 +25,16 @@ fn foobar() { let x = match 5 { 4 => return, 5 => continue, - 6 => (println!("foo"), return), //~ ERROR sub-expression diverges - 7 => (println!("bar"), continue), //~ ERROR sub-expression diverges + 6 => true || return, //~ ERROR sub-expression diverges + 7 => true || continue, //~ ERROR sub-expression diverges 8 => break, 9 => diverge(), - 3 => (println!("moo"), diverge()), //~ ERROR sub-expression diverges + 3 => true || diverge(), //~ ERROR sub-expression diverges 10 => match 42 { 99 => return, - _ => ((), panic!("boo")), + _ => true || panic!("boo"), }, - _ => (println!("boo"), break), //~ ERROR sub-expression diverges + _ => true || break, //~ ERROR sub-expression diverges }; } } diff --git a/tests/compile-fail/eq_op.rs b/tests/compile-fail/eq_op.rs index 768eadd00eba..f0502a717968 100644 --- a/tests/compile-fail/eq_op.rs +++ b/tests/compile-fail/eq_op.rs @@ -43,8 +43,8 @@ fn main() { true || true; //~ERROR equal expressions //~|ERROR this boolean expression can be simplified - let a: u32 = unimplemented!(); - let b: u32 = unimplemented!(); + let a: u32 = 0; + let b: u32 = 0; a == b && b == a; //~ERROR equal expressions //~|ERROR this boolean expression can be simplified diff --git a/tests/compile-fail/map_clone.rs b/tests/compile-fail/map_clone.rs index bd630211f19f..b4f97ae8e6e4 100644 --- a/tests/compile-fail/map_clone.rs +++ b/tests/compile-fail/map_clone.rs @@ -15,6 +15,12 @@ fn map_clone_iter() { //~^ 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 }