From 67cccc5c1659c62baca6880656279e98c9637899 Mon Sep 17 00:00:00 2001 From: messense Date: Fri, 2 Jun 2017 12:13:04 +0800 Subject: [PATCH 1/4] Try to fix compilation error on rustc 1.19.0-nightly (4ed2edaaf 2017-06-01) --- clippy_lints/src/consts.rs | 4 +--- clippy_lints/src/escape.rs | 8 ++++---- clippy_lints/src/eval_order_dependence.rs | 5 +---- clippy_lints/src/functions.rs | 4 ++-- clippy_lints/src/len_zero.rs | 4 ++-- clippy_lints/src/loops.rs | 9 ++------- clippy_lints/src/mut_reference.rs | 7 +++---- clippy_lints/src/needless_borrow.rs | 2 +- clippy_lints/src/utils/mod.rs | 16 ++++------------ 9 files changed, 20 insertions(+), 39 deletions(-) diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index e094e8da3fca..8d18e613e134 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -286,9 +286,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { match def { Def::Const(def_id) | Def::AssociatedConst(def_id) => { - let substs = self.tables - .node_id_item_substs(id) - .unwrap_or_else(|| self.tcx.intern_substs(&[])); + let substs = self.tables.node_substs(id); let substs = if self.substs.is_empty() { substs } else { diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index a36951b5f365..c68209b43838 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -160,14 +160,14 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { if let Categorization::Local(lid) = cmt.cat { if self.set.contains(&lid) { - if let Some(&Adjust::DerefRef { autoderefs, .. }) = + if let Some(&Adjust::Deref(ref overloaded)) = self.tables .adjustments .get(&borrow_id) .map(|a| &a.kind) { if LoanCause::AutoRef == loan_cause { // x.foo() - if autoderefs == 0 { + if overloaded == 0 { self.set.remove(&lid); // Used without autodereffing (i.e. x.clone()) } } else { @@ -175,14 +175,14 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } } else if LoanCause::AddrOf == loan_cause { // &x - if let Some(&Adjust::DerefRef { autoderefs, .. }) = + if let Some(&Adjust::Deref(ref overloaded)) = self.tables .adjustments .get(&self.tcx .hir .get_parent_node(borrow_id)) .map(|a| &a.kind) { - if autoderefs <= 1 { + if overloaded <= 1 { // foo(&x) where no extra autoreffing is happening self.set.remove(&lid); } diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 9f694dd1cff7..36cae6968d44 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -137,11 +137,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { } }, ExprMethodCall(..) => { - let method_call = ty::MethodCall::expr(e.id); let borrowed_table = self.cx.tables; - let method_type = borrowed_table.method_map.get(&method_call).expect("This should never happen."); - let result_ty = method_type.ty.fn_ret(); - if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&result_ty).sty { + if borrowed_table.expr_ty(e).is_never() { self.report_diverging_sub_expr(e); } }, diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 0c4712a59117..62a843885c76 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -184,8 +184,8 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> { } }, hir::ExprMethodCall(_, _, ref args) => { - let method_call = ty::MethodCall::expr(expr.id); - let base_type = self.cx.tables.method_map[&method_call].ty; + let def_id = self.cx.tables.type_dependent_defs[&expr.id].def_id(); + let base_type = self.cx.tcx.type_of(def_id); if type_is_unsafe_function(base_type) { for arg in args { diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 148eb616be0c..611987ae1630 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -95,7 +95,7 @@ fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef] { let did = cx.tcx.hir.local_def_id(item.id.node_id); let impl_ty = cx.tcx.type_of(did); - impl_ty.fn_args().skip_binder().len() == 1 + impl_ty.fn_sig().inputs().skip_binder().len() == 1 } } else { false @@ -122,7 +122,7 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) { { let did = cx.tcx.hir.local_def_id(item.id.node_id); let impl_ty = cx.tcx.type_of(did); - impl_ty.fn_args().skip_binder().len() == 1 + impl_ty.fn_sig().inputs().skip_binder().len() == 1 } } else { false diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 70e7e99a66df..2e373988887a 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -676,13 +676,8 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { lint_iter_method(cx, args, arg, &method_name); } } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { - let method_call = ty::MethodCall::expr(arg.id); - let fn_ty = cx.tables - .method_map - .get(&method_call) - .map(|method_callee| method_callee.ty) - .expect("method calls need an entry in the method map"); - let fn_arg_tys = fn_ty.fn_args(); + let fn_ty = cx.tables.expr_ty(arg); + let fn_arg_tys = fn_ty.fn_sig().inputs(); assert_eq!(fn_arg_tys.skip_binder().len(), 1); if fn_arg_tys.skip_binder()[0].is_region_ptr() { lint_iter_method(cx, args, arg, &method_name); diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 07c941ecee6b..4712cdde4b9e 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -1,5 +1,5 @@ use rustc::lint::*; -use rustc::ty::{TypeAndMut, TypeVariants, MethodCall, TyS}; +use rustc::ty::{TypeAndMut, TypeVariants, TyS}; use rustc::hir::*; use utils::span_lint; @@ -49,9 +49,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { } }, ExprMethodCall(ref name, _, ref arguments) => { - let method_call = MethodCall::expr(e.id); - let method_type = borrowed_table.method_map.get(&method_call).expect("This should never happen."); - check_arguments(cx, arguments, method_type.ty, &name.node.as_str()) + let method_type = borrowed_table.expr_ty(e); + check_arguments(cx, arguments, method_type, &name.node.as_str()) }, _ => (), } diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 740dd2bcb3fc..1d1d1b1f45da 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -41,7 +41,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty { - if let Some(&ty::adjustment::Adjust::DerefRef { autoderefs, autoref, .. }) = + if let Some(&ty::adjustment::Adjust::Deref(ref overloaded)) = cx.tables.adjustments.get(&e.id).map(|a| &a.kind) { if autoderefs > 1 && autoref.is_some() { span_lint(cx, diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index f5f1fe030f40..e7065c16039c 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -184,12 +184,8 @@ pub fn match_type(cx: &LateContext, ty: ty::Ty, path: &[&str]) -> bool { /// Check if the method call given in `expr` belongs to given type. pub fn match_impl_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { - let method_call = ty::MethodCall::expr(expr.id); - - let trt_id = cx.tables - .method_map - .get(&method_call) - .and_then(|callee| cx.tcx.impl_of_method(callee.def_id)); + let method_call = cx.tables.type_dependent_defs[&expr.id]; + let trt_id = cx.tcx.impl_of_method(method_call.def_id()); if let Some(trt_id) = trt_id { match_def_path(cx.tcx, trt_id, path) } else { @@ -199,12 +195,8 @@ pub fn match_impl_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { /// Check if the method call given in `expr` belongs to given trait. pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool { - let method_call = ty::MethodCall::expr(expr.id); - - let trt_id = cx.tables - .method_map - .get(&method_call) - .and_then(|callee| cx.tcx.trait_of_item(callee.def_id)); + let method_call = cx.tables.type_dependent_defs[&expr.id]; + let trt_id = cx.tcx.trait_of_item(method_call.def_id()); if let Some(trt_id) = trt_id { match_def_path(cx.tcx, trt_id, path) } else { From edef6c53c02dbe8e65fd851f4746dcda6b84d5a2 Mon Sep 17 00:00:00 2001 From: mcarton Date: Sat, 3 Jun 2017 18:41:46 +0200 Subject: [PATCH 2/4] Continue work on rustup --- clippy_lints/src/escape.rs | 6 ++++-- clippy_lints/src/mut_reference.rs | 5 +++-- clippy_lints/src/needless_borrow.rs | 14 ++++++-------- clippy_lints/src/utils/mod.rs | 9 ++++----- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index c68209b43838..6c801b262091 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -81,7 +81,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let fn_def_id = cx.tcx.hir.local_def_id(node_id); let region_maps = &cx.tcx.region_maps(fn_def_id); { - let mut vis = ExprUseVisitor::new(&mut v, region_maps, &infcx); + let def_id = cx.tcx.hir.body_owner_def_id(body.id()); + let param_env = cx.tcx.param_env(def_id); + let mut vis = ExprUseVisitor::new(&mut v, region_maps, &infcx, param_env); vis.consume_body(body); } @@ -205,7 +207,7 @@ impl<'a, 'tcx: 'a> EscapeDelegate<'a, 'tcx> { // overflows. if ty.is_box() { let inner = ty.boxed_ty(); - self.tcx.infer_ctxt((), Reveal::All).enter(|infcx| if let Ok(layout) = inner.layout(&infcx) { + self.tcx.infer_ctxt(()).enter(|infcx| if let Ok(layout) = inner.layout(&infcx) { let size = layout.size(&self.target); size.bytes() > self.too_large_for_stack } else { diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 4712cdde4b9e..aa6acd6795f4 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -49,7 +49,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { } }, ExprMethodCall(ref name, _, ref arguments) => { - let method_type = borrowed_table.expr_ty(e); + let def_id = borrowed_table.type_dependent_defs[&e.id].def_id(); + let method_type = cx.tcx.type_of(def_id); check_arguments(cx, arguments, method_type, &name.node.as_str()) }, _ => (), @@ -70,7 +71,7 @@ fn check_arguments(cx: &LateContext, arguments: &[Expr], type_definition: &TyS, span_lint(cx, UNNECESSARY_MUT_PASSED, argument.span, - &format!("The function/method \"{}\" doesn't need a mutable reference", name)); + &format!("The function/method `{}` doesn't need a mutable reference", name)); } }, _ => (), diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 1d1d1b1f45da..4f5ff86c5e8f 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -41,15 +41,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty { - if let Some(&ty::adjustment::Adjust::Deref(ref overloaded)) = + if let Some(&ty::adjustment::Adjust::Deref(Some(_))) = cx.tables.adjustments.get(&e.id).map(|a| &a.kind) { - if autoderefs > 1 && autoref.is_some() { - span_lint(cx, - NEEDLESS_BORROW, - e.span, - "this expression borrows a reference that is immediately dereferenced by the \ - compiler"); - } + span_lint(cx, + NEEDLESS_BORROW, + e.span, + "this expression borrows a reference that is immediately dereferenced by the \ + compiler"); } } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index e7065c16039c..c75e53d6ef04 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -259,7 +259,6 @@ pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool { } /// Get the definition associated to a path. -/// TODO: investigate if there is something more efficient for that. pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option { let cstore = &cx.tcx.sess.cstore; @@ -319,9 +318,9 @@ pub fn implements_trait<'a, 'tcx>( ) -> bool { let ty = cx.tcx.erase_regions(&ty); let mut b = if let Some(id) = parent_node_id { - cx.tcx.infer_ctxt(BodyId { node_id: id }, Reveal::All) + cx.tcx.infer_ctxt(BodyId { node_id: id }) } else { - cx.tcx.infer_ctxt((), Reveal::All) + cx.tcx.infer_ctxt(()) }; b.enter(|infcx| { let obligation = cx.tcx.predicate_for_trait_def(traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); @@ -780,7 +779,7 @@ pub fn same_tys<'a, 'tcx>( parameter_item: DefId ) -> bool { let parameter_env = cx.tcx.param_env(parameter_item); - cx.tcx.infer_ctxt(parameter_env, Reveal::All).enter(|infcx| { + cx.tcx.infer_ctxt(parameter_env).enter(|infcx| { let substs = Substs::identity_for_item(cx.tcx, parameter_item); let new_a = a.subst(infcx.tcx, substs); let new_b = b.subst(infcx.tcx, substs); @@ -963,6 +962,6 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>) -> Option { cx.tcx - .infer_ctxt((), Reveal::All) + .infer_ctxt(()) .enter(|infcx| ty.layout(&infcx).ok().map(|lay| lay.size(&TargetDataLayout::parse(cx.sess())).bytes())) } From 010974fafe571d2cfb8bc49d079b55bbe04c418d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 5 Jun 2017 00:28:01 +0300 Subject: [PATCH 3/4] Finish rustup. --- clippy_lints/src/escape.rs | 97 ++++++++-------------- clippy_lints/src/functions.rs | 1 - clippy_lints/src/loops.rs | 8 +- clippy_lints/src/mut_reference.rs | 13 ++- clippy_lints/src/needless_borrow.rs | 20 +++-- clippy_lints/src/needless_pass_by_value.rs | 18 ++-- clippy_lints/src/unused_io_amount.rs | 2 +- clippy_lints/src/utils/mod.rs | 27 +++--- clippy_lints/src/utils/paths.rs | 2 +- clippy_tests/examples/for_loop.stderr | 8 ++ clippy_tests/examples/mut_reference.stderr | 6 +- clippy_tests/examples/range.stderr | 40 +++++++++ 12 files changed, 131 insertions(+), 111 deletions(-) diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 6c801b262091..6f073478027a 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -5,8 +5,6 @@ use rustc::lint::*; use rustc::middle::expr_use_visitor::*; use rustc::middle::mem_categorization::{cmt, Categorization}; use rustc::ty; -use rustc::ty::layout::TargetDataLayout; -use rustc::traits::Reveal; use rustc::util::nodemap::NodeSet; use syntax::ast::NodeId; use syntax::codemap::Span; @@ -46,8 +44,7 @@ fn is_non_trait_box(ty: ty::Ty) -> bool { struct EscapeDelegate<'a, 'tcx: 'a> { set: NodeSet, tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - tables: &'a ty::TypeckTables<'tcx>, - target: TargetDataLayout, + param_env: ty::ParamEnv<'tcx>, too_large_for_stack: u64, } @@ -67,25 +64,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { _: Span, node_id: NodeId ) { - // we store the infcx because it is expensive to recreate - // the context each time. + let fn_def_id = cx.tcx.hir.local_def_id(node_id); + let param_env = cx.tcx.param_env(fn_def_id).reveal_all(); let mut v = EscapeDelegate { set: NodeSet(), tcx: cx.tcx, - tables: cx.tables, - target: TargetDataLayout::parse(cx.sess()), + param_env: param_env, too_large_for_stack: self.too_large_for_stack, }; - let infcx = cx.tcx.borrowck_fake_infer_ctxt(body.id()); - let fn_def_id = cx.tcx.hir.local_def_id(node_id); - let region_maps = &cx.tcx.region_maps(fn_def_id); - { - let def_id = cx.tcx.hir.body_owner_def_id(body.id()); - let param_env = cx.tcx.param_env(def_id); + cx.tcx.infer_ctxt(body.id()).enter(|infcx| { + let region_maps = &cx.tcx.region_maps(fn_def_id); let mut vis = ExprUseVisitor::new(&mut v, region_maps, &infcx, param_env); vis.consume_body(body); - } + }); for node in v.set { span_lint(cx, @@ -96,14 +88,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } -impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { +impl<'a, 'gcx: 'tcx, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'gcx> { fn consume(&mut self, _: NodeId, _: Span, cmt: cmt<'tcx>, mode: ConsumeMode) { if let Categorization::Local(lid) = cmt.cat { - if self.set.contains(&lid) { - if let Move(DirectRefMove) = mode { - // moved out or in. clearly can't be localized - self.set.remove(&lid); - } + if let Move(DirectRefMove) = mode { + // moved out or in. clearly can't be localized + self.set.remove(&lid); } } } @@ -151,49 +141,30 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } fn borrow( &mut self, - borrow_id: NodeId, + _: 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(&Adjust::Deref(ref overloaded)) = - self.tables - .adjustments - .get(&borrow_id) - .map(|a| &a.kind) { - if LoanCause::AutoRef == loan_cause { - // x.foo() - if overloaded == 0 { - self.set.remove(&lid); // Used without autodereffing (i.e. x.clone()) - } - } else { - span_bug!(cmt.span, "Unknown adjusted AutoRef"); - } - } else if LoanCause::AddrOf == loan_cause { - // &x - if let Some(&Adjust::Deref(ref overloaded)) = - self.tables - .adjustments - .get(&self.tcx - .hir - .get_parent_node(borrow_id)) - .map(|a| &a.kind) { - if overloaded <= 1 { - // foo(&x) where no extra autoreffing is happening - self.set.remove(&lid); - } - } + match loan_cause { + // x.foo() + // Used without autodereffing (i.e. x.clone()) + LoanCause::AutoRef | - } else if LoanCause::MatchDiscriminant == loan_cause { - self.set.remove(&lid); // `match x` can move + // &x + // foo(&x) where no extra autoreffing is happening + LoanCause::AddrOf | + + // `match x` can move + LoanCause::MatchDiscriminant => { + self.set.remove(&lid); } + // do nothing for matches, etc. These can't escape + _ => {} } } } @@ -202,19 +173,17 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } impl<'a, 'tcx: 'a> EscapeDelegate<'a, 'tcx> { - fn is_large_box(&self, ty: ty::Ty<'tcx>) -> bool { + fn is_large_box(&self, ty: ty::Ty) -> bool { // Large types need to be boxed to avoid stack // overflows. if ty.is_box() { - let inner = ty.boxed_ty(); - self.tcx.infer_ctxt(()).enter(|infcx| if let Ok(layout) = inner.layout(&infcx) { - let size = layout.size(&self.target); - size.bytes() > self.too_large_for_stack - } else { - false - }) - } else { - false + if let Some(inner) = self.tcx.lift(&ty.boxed_ty()) { + if let Ok(layout) = inner.layout(self.tcx, self.param_env) { + return layout.size(self.tcx).bytes() > self.too_large_for_stack; + } + } } + + false } } diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 62a843885c76..463358c99b46 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -1,6 +1,5 @@ use rustc::hir::intravisit; use rustc::hir; -use rustc::ty; use rustc::lint::*; use std::collections::HashSet; use syntax::ast; diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 2e373988887a..606399af547f 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -8,6 +8,7 @@ use rustc::lint::*; use rustc::middle::const_val::ConstVal; use rustc::middle::region::CodeExtent; use rustc::ty; +use rustc::ty::subst::Subst; use rustc_const_eval::ConstContext; use std::collections::HashMap; use syntax::ast; @@ -676,8 +677,11 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) { lint_iter_method(cx, args, arg, &method_name); } } else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) { - let fn_ty = cx.tables.expr_ty(arg); - let fn_arg_tys = fn_ty.fn_sig().inputs(); + let def_id = cx.tables.type_dependent_defs[&arg.id].def_id(); + let substs = cx.tables.node_substs(arg.id); + let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); + + let fn_arg_tys = method_type.fn_sig().inputs(); assert_eq!(fn_arg_tys.skip_binder().len(), 1); if fn_arg_tys.skip_binder()[0].is_region_ptr() { lint_iter_method(cx, args, arg, &method_name); diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index aa6acd6795f4..781398470b86 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -1,5 +1,6 @@ use rustc::lint::*; use rustc::ty::{TypeAndMut, TypeVariants, TyS}; +use rustc::ty::subst::Subst; use rustc::hir::*; use utils::span_lint; @@ -34,23 +35,19 @@ impl LintPass for UnnecessaryMutPassed { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) { - let borrowed_table = cx.tables; match e.node { ExprCall(ref fn_expr, ref arguments) => { - let function_type = borrowed_table.node_types - .get(&fn_expr.id) - .expect("A function with an unknown type is called. If this happened, the compiler would have \ - aborted the compilation long ago"); if let ExprPath(ref path) = fn_expr.node { check_arguments(cx, arguments, - function_type, + cx.tables.expr_ty(fn_expr), &print::to_string(print::NO_ANN, |s| s.print_qpath(path, false))); } }, ExprMethodCall(ref name, _, ref arguments) => { - let def_id = borrowed_table.type_dependent_defs[&e.id].def_id(); - let method_type = cx.tcx.type_of(def_id); + let def_id = cx.tables.type_dependent_defs[&e.id].def_id(); + let substs = cx.tables.node_substs(e.id); + let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); check_arguments(cx, arguments, method_type, &name.node.as_str()) }, _ => (), diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs index 4f5ff86c5e8f..c1965be2c048 100644 --- a/clippy_lints/src/needless_borrow.rs +++ b/clippy_lints/src/needless_borrow.rs @@ -5,6 +5,7 @@ use rustc::lint::*; use rustc::hir::{ExprAddrOf, Expr, MutImmutable, Pat, PatKind, BindingMode}; use rustc::ty; +use rustc::ty::adjustment::{Adjustment, Adjust}; use utils::{span_lint, in_macro}; /// **What it does:** Checks for address of operations (`&`) that are going to @@ -41,13 +42,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow { } if let ExprAddrOf(MutImmutable, ref inner) = e.node { if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty { - if let Some(&ty::adjustment::Adjust::Deref(Some(_))) = - cx.tables.adjustments.get(&e.id).map(|a| &a.kind) { - span_lint(cx, - NEEDLESS_BORROW, - e.span, - "this expression borrows a reference that is immediately dereferenced by the \ - compiler"); + for adj3 in cx.tables.expr_adjustments(e).windows(3) { + if let [ + Adjustment { kind: Adjust::Deref(_), .. }, + Adjustment { kind: Adjust::Deref(_), .. }, + Adjustment { kind: Adjust::Borrow(_), .. } + ] = *adj3 { + span_lint(cx, + NEEDLESS_BORROW, + e.span, + "this expression borrows a reference that is immediately dereferenced by the \ + compiler"); + } } } } diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 33e9d4a7e574..2ce22b8c9c9a 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -91,12 +91,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { // Collect moved variables and spans which will need dereferencings from the function body. let MovedVariablesCtxt { moved_vars, spans_need_deref, .. } = { let mut ctx = MovedVariablesCtxt::new(cx); - let infcx = cx.tcx.borrowck_fake_infer_ctxt(body.id()); - let region_maps = &cx.tcx.region_maps(fn_def_id); - { - let mut v = euv::ExprUseVisitor::new(&mut ctx, region_maps, &infcx); - v.consume_body(body); - } + cx.tcx.infer_ctxt(body.id()).enter(|infcx| { + let param_env = cx.tcx.param_env(fn_def_id); + let region_maps = &cx.tcx.region_maps(fn_def_id); + euv::ExprUseVisitor::new(&mut ctx, region_maps, &infcx, param_env) + .consume_body(body); + }); ctx }; @@ -199,7 +199,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { } } - fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt<'tcx>) { + fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt) { let cmt = unwrap_downcast_or_interior(cmt); if_let_chain! {[ @@ -210,7 +210,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { }} } - fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt<'tcx>) { + fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt) { let cmt = unwrap_downcast_or_interior(cmt); if_let_chain! {[ @@ -262,7 +262,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { } } -impl<'a, 'tcx: 'a> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'tcx> { +impl<'a, 'gcx: 'tcx, 'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'gcx> { fn consume(&mut self, consume_id: NodeId, consume_span: Span, cmt: mc::cmt<'tcx>, mode: euv::ConsumeMode) { if let euv::ConsumeMode::Move(_) = mode { self.move_common(consume_id, consume_span, cmt); diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index c8ceb6be0cc0..1f19e4548572 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -46,7 +46,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount { hir::ExprMatch(ref res, _, _) if is_try(expr).is_some() => { if let hir::ExprCall(ref func, ref args) = res.node { if let hir::ExprPath(ref path) = func.node { - if match_path(path, &paths::CARRIER_TRANSLATE) && args.len() == 1 { + if match_path(path, &paths::TRY_INTO_RESULT) && args.len() == 1 { check_method_call(cx, &args[0], expr); } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index c75e53d6ef04..d068fa51ca40 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -9,7 +9,6 @@ use rustc::traits::Reveal; use rustc::traits; use rustc::ty::subst::{Subst, Substs}; use rustc::ty; -use rustc::ty::layout::TargetDataLayout; use rustc::mir::transform::MirSource; use rustc_errors; use std::borrow::Cow; @@ -317,13 +316,15 @@ pub fn implements_trait<'a, 'tcx>( parent_node_id: Option ) -> bool { let ty = cx.tcx.erase_regions(&ty); - let mut b = if let Some(id) = parent_node_id { - cx.tcx.infer_ctxt(BodyId { node_id: id }) + let param_env = if let Some(id) = parent_node_id { + let def_id = cx.tcx.hir.body_owner_def_id(BodyId { node_id: id }); + cx.tcx.param_env(def_id).reveal_all() } else { - cx.tcx.infer_ctxt(()) + ty::ParamEnv::empty(Reveal::All) }; - b.enter(|infcx| { - let obligation = cx.tcx.predicate_for_trait_def(traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); + cx.tcx.infer_ctxt(()).enter(|infcx| { + let obligation = cx.tcx.predicate_for_trait_def( + param_env, traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation) }) @@ -778,12 +779,9 @@ pub fn same_tys<'a, 'tcx>( b: ty::Ty<'tcx>, parameter_item: DefId ) -> bool { - let parameter_env = cx.tcx.param_env(parameter_item); - cx.tcx.infer_ctxt(parameter_env).enter(|infcx| { - let substs = Substs::identity_for_item(cx.tcx, parameter_item); - let new_a = a.subst(infcx.tcx, substs); - let new_b = b.subst(infcx.tcx, substs); - infcx.can_equate(&new_a, &new_b).is_ok() + let param_env = cx.tcx.param_env(parameter_item).reveal_all(); + cx.tcx.infer_ctxt(()).enter(|infcx| { + infcx.can_eq(param_env, a, b).is_ok() }) } @@ -961,7 +959,6 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { } pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>) -> Option { - cx.tcx - .infer_ctxt(()) - .enter(|infcx| ty.layout(&infcx).ok().map(|lay| lay.size(&TargetDataLayout::parse(cx.sess())).bytes())) + ty.layout(cx.tcx, ty::ParamEnv::empty(Reveal::All)) + .ok().map(|layout| layout.size(cx.tcx).bytes()) } diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 133a2d65f0e3..738a497c6ab6 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -9,7 +9,6 @@ pub const BOX_NEW: [&'static str; 4] = ["std", "boxed", "Box", "new"]; pub const BTREEMAP: [&'static str; 4] = ["collections", "btree", "map", "BTreeMap"]; pub const BTREEMAP_ENTRY: [&'static str; 4] = ["collections", "btree", "map", "Entry"]; pub const BTREESET: [&'static str; 4] = ["collections", "btree", "set", "BTreeSet"]; -pub const CARRIER_TRANSLATE: [&'static str; 4] = ["std", "ops", "Carrier", "translate"]; pub const CLONE: [&'static str; 4] = ["core", "clone", "Clone", "clone"]; pub const CLONE_TRAIT: [&'static str; 3] = ["core", "clone", "Clone"]; pub const CMP_MAX: [&'static str; 3] = ["core", "cmp", "max"]; @@ -72,6 +71,7 @@ pub const STRING: [&'static str; 3] = ["collections", "string", "String"]; pub const TO_OWNED: [&'static str; 3] = ["collections", "borrow", "ToOwned"]; pub const TO_STRING: [&'static str; 3] = ["collections", "string", "ToString"]; pub const TRANSMUTE: [&'static str; 4] = ["core", "intrinsics", "", "transmute"]; +pub const TRY_INTO_RESULT: [&'static str; 4] = ["std", "ops", "Try", "into_result"]; pub const VEC: [&'static str; 3] = ["collections", "vec", "Vec"]; pub const VEC_DEQUE: [&'static str; 3] = ["collections", "vec_deque", "VecDeque"]; pub const VEC_FROM_ELEM: [&'static str; 3] = ["collections", "vec", "from_elem"]; diff --git a/clippy_tests/examples/for_loop.stderr b/clippy_tests/examples/for_loop.stderr index 8ecdc6f5a263..66c42d50e19a 100644 --- a/clippy_tests/examples/for_loop.stderr +++ b/clippy_tests/examples/for_loop.stderr @@ -295,6 +295,14 @@ error: this range is empty so this for loop will never run | = note: `-D reverse-range-loop` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> for_loop.rs:192:22 + | +192 | for i in (10..8).step_by(-1) { + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: it is more idiomatic to loop over references to containers instead of using explicit iteration methods --> for_loop.rs:207:15 | diff --git a/clippy_tests/examples/mut_reference.stderr b/clippy_tests/examples/mut_reference.stderr index 34d33f622190..c8f606db0e17 100644 --- a/clippy_tests/examples/mut_reference.stderr +++ b/clippy_tests/examples/mut_reference.stderr @@ -1,4 +1,4 @@ -error: The function/method "takes_an_immutable_reference" doesn't need a mutable reference +error: The function/method `takes_an_immutable_reference` doesn't need a mutable reference --> mut_reference.rs:22:34 | 22 | takes_an_immutable_reference(&mut 42); @@ -6,7 +6,7 @@ error: The function/method "takes_an_immutable_reference" doesn't need a mutable | = note: `-D unnecessary-mut-passed` implied by `-D warnings` -error: The function/method "as_ptr" doesn't need a mutable reference +error: The function/method `as_ptr` doesn't need a mutable reference --> mut_reference.rs:24:12 | 24 | as_ptr(&mut 42); @@ -14,7 +14,7 @@ error: The function/method "as_ptr" doesn't need a mutable reference | = note: `-D unnecessary-mut-passed` implied by `-D warnings` -error: The function/method "takes_an_immutable_reference" doesn't need a mutable reference +error: The function/method `takes_an_immutable_reference` doesn't need a mutable reference --> mut_reference.rs:28:44 | 28 | my_struct.takes_an_immutable_reference(&mut 42); diff --git a/clippy_tests/examples/range.stderr b/clippy_tests/examples/range.stderr index 1d23f1425870..2f3aa7971d01 100644 --- a/clippy_tests/examples/range.stderr +++ b/clippy_tests/examples/range.stderr @@ -6,6 +6,22 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:13:12 + | +13 | (0..1).step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:15:12 + | +15 | (0..1).step_by(1); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead --> range.rs:17:5 | @@ -14,6 +30,14 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:17:11 + | +17 | (1..).step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead --> range.rs:18:5 | @@ -22,6 +46,14 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:18:13 + | +18 | (1...2).step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: Range::step_by(0) produces an infinite iterator. Consider using `std::iter::repeat()` instead --> range.rs:21:5 | @@ -30,6 +62,14 @@ error: Range::step_by(0) produces an infinite iterator. Consider using `std::ite | = note: `-D range-step-by-zero` implied by `-D warnings` +error: use of deprecated item: replaced by `Iterator::step_by` + --> range.rs:21:7 + | +21 | x.step_by(0); + | ^^^^^^^ + | + = note: `-D deprecated` implied by `-D warnings` + error: It is more idiomatic to use v1.iter().enumerate() --> range.rs:29:14 | From 5b4e7b56df62b60025d6c04fa52bc85ccfe5135e Mon Sep 17 00:00:00 2001 From: mcarton Date: Mon, 5 Jun 2017 00:02:39 +0200 Subject: [PATCH 4/4] Bump to 0.0.137 --- CHANGELOG.md | 17 ++++++++++------- Cargo.toml | 4 ++-- clippy_lints/Cargo.toml | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e062ae640c0f..e66e00197825 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,25 +1,28 @@ # Change Log All notable changes to this project will be documented in this file. -## 0.0.136 - 2017-05-26 +## 0.0.137 — 2017-06-05 +* Update to *rustc 1.19.0-nightly (6684d176c 2017-06-03)* + +## 0.0.136 — 2017—05—26 * Update to *rustc 1.19.0-nightly (557967766 2017-05-26)* -## 0.0.135 - 2017-05-24 +## 0.0.135 — 2017—05—24 * Update to *rustc 1.19.0-nightly (5b13bff52 2017-05-23)* -## 0.0.134 - 2017-05-19 +## 0.0.134 — 2017—05—19 * Update to *rustc 1.19.0-nightly (0ed1ec9f9 2017-05-18)* -## 0.0.133 - 2017-05-14 +## 0.0.133 — 2017—05—14 * Update to *rustc 1.19.0-nightly (826d8f385 2017-05-13)* -## 0.0.132 - 2017-05-05 +## 0.0.132 — 2017—05—05 * Fix various bugs and some ices -## 0.0.131 - 2017-05-04 +## 0.0.131 — 2017—05—04 * Update to *rustc 1.19.0-nightly (2d4ed8e0c 2017-05-03)* -## 0.0.130 - 2017-05-03 +## 0.0.130 — 2017—05—03 * Update to *rustc 1.19.0-nightly (6a5fc9eec 2017-05-02)* ## 0.0.129 — 2017-05-01 diff --git a/Cargo.toml b/Cargo.toml index e2bf05640089..1f50085c6249 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.0.136" +version = "0.0.137" authors = [ "Manish Goregaokar ", "Andre Bogus ", @@ -31,7 +31,7 @@ test = false [dependencies] # begin automatic update -clippy_lints = { version = "0.0.136", path = "clippy_lints" } +clippy_lints = { version = "0.0.137", path = "clippy_lints" } # end automatic update cargo_metadata = "0.2" diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index aa7d2b96e17a..4901b662045b 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.136" +version = "0.0.137" # end automatic update authors = [ "Manish Goregaokar ",