diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 3432ce59c7d1..07d838bef2ed 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -82,14 +82,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> 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.tables.expr_ty(assignee); - if ty.walk_shallow().next().is_some() { - return; // implements_trait does not work with generics - } - let rty = cx.tables.expr_ty(rhs); - if rty.walk_shallow().next().is_some() { - return; // implements_trait does not work with generics - } span_lint_and_then(cx, MISREFACTORED_ASSIGN_OP, expr.span, @@ -120,13 +112,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { #[allow(cyclomatic_complexity)] let lint = |assignee: &hir::Expr, rhs: &hir::Expr| { let ty = cx.tables.expr_ty(assignee); - if ty.walk_shallow().next().is_some() { - return; // implements_trait does not work with generics - } let rty = cx.tables.expr_ty(rhs); - if rty.walk_shallow().next().is_some() { - return; // implements_trait does not work with generics - } macro_rules! ops { ($op:expr, $cx:expr, @@ -152,7 +138,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { let hir::Item_::ItemImpl(_, _, _, _, Some(ref trait_ref), _, _) = item.node, trait_ref.path.def.def_id() == trait_id ], { return; }} - implements_trait($cx, $ty, trait_id, &[$rty], None) + implements_trait($cx, $ty, trait_id, &[$rty]) },)* _ => false, } diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index e9fd654eebf8..d8e2f0872630 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -136,8 +136,7 @@ fn check_hash_peq<'a, 'tcx>( /// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint. fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref: &TraitRef, ty: ty::Ty<'tcx>) { if match_path_old(&trait_ref.path, &paths::CLONE_TRAIT) { - let def_id = cx.tcx.hir.local_def_id(item.id); - if !is_copy(cx, ty, def_id) { + if !is_copy(cx, ty) { return; } diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index e5064febe954..c938f17cd497 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -136,7 +136,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { &msg, arg.span, &format!("argument has type {}", arg_ty.sty)); - } else if is_copy(cx, arg_ty, cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(arg.id))) { + } else if is_copy(cx, arg_ty) { if match_def_path(cx.tcx, def_id, &paths::DROP) { lint = DROP_COPY; msg = DROP_COPY_SUMMARY.to_string(); diff --git a/clippy_lints/src/enum_glob_use.rs b/clippy_lints/src/enum_glob_use.rs index 0bd1740c5459..12b588967f8a 100644 --- a/clippy_lints/src/enum_glob_use.rs +++ b/clippy_lints/src/enum_glob_use.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EnumGlobUse { fn check_mod(&mut self, cx: &LateContext<'a, 'tcx>, m: &'tcx Mod, _: Span, _: NodeId) { // only check top level `use` statements for item in &m.item_ids { - self.lint_item(cx, cx.krate.item(item.id)); + self.lint_item(cx, cx.tcx.hir.expect_item(item.id)); } } } diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs index 894ba09f50fa..9eab6352cc2e 100644 --- a/clippy_lints/src/eq_op.rs +++ b/clippy_lints/src/eq_op.rs @@ -75,8 +75,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { BiNe | BiEq => (cx.tcx.lang_items.eq_trait(), true), BiLt | BiLe | BiGe | BiGt => (cx.tcx.lang_items.ord_trait(), true), }; - let parent = cx.tcx.hir.get_parent(e.id); - let parent = cx.tcx.hir.local_def_id(parent); if let Some(trait_id) = trait_id { #[allow(match_same_arms)] match (&left.node, &right.node) { @@ -87,10 +85,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { (&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => { let lty = cx.tables.expr_ty(l); let rty = cx.tables.expr_ty(r); - let lcpy = is_copy(cx, lty, parent); - let rcpy = is_copy(cx, rty, parent); + let lcpy = is_copy(cx, lty); + let rcpy = is_copy(cx, rty); // either operator autorefs or both args are copyable - if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty], None) { + if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty]) { span_lint_and_then(cx, OP_REF, e.span, @@ -104,13 +102,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { (right.span, rsnip)]); }) } else if lcpy && !rcpy && - implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)], None) { + implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)]) { span_lint_and_then(cx, OP_REF, e.span, "needlessly taken reference of left operand", |db| { let lsnip = snippet(cx, l.span, "...").to_string(); db.span_suggestion(left.span, "use the left value directly", lsnip); }) } else if !lcpy && rcpy && - implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty], None) { + implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty]) { span_lint_and_then(cx, OP_REF, e.span, @@ -124,9 +122,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { // &foo == bar (&ExprAddrOf(_, ref l), _) => { let lty = cx.tables.expr_ty(l); - let lcpy = is_copy(cx, lty, parent); + let lcpy = is_copy(cx, lty); if (requires_ref || lcpy) && - implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)], None) { + implements_trait(cx, lty, trait_id, &[cx.tables.expr_ty(right)]) { span_lint_and_then(cx, OP_REF, e.span, "needlessly taken reference of left operand", |db| { let lsnip = snippet(cx, l.span, "...").to_string(); db.span_suggestion(left.span, "use the left value directly", lsnip); @@ -136,9 +134,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp { // foo == &bar (_, &ExprAddrOf(_, ref r)) => { let rty = cx.tables.expr_ty(r); - let rcpy = is_copy(cx, rty, parent); + let rcpy = is_copy(cx, rty); if (requires_ref || rcpy) && - implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty], None) { + implements_trait(cx, cx.tables.expr_ty(left), trait_id, &[rty]) { span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |db| { let rsnip = snippet(cx, r.span, "...").to_string(); db.span_suggestion(right.span, "use the right value directly", rsnip); diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 6f073478027a..24026f2624ac 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -8,7 +8,7 @@ use rustc::ty; use rustc::util::nodemap::NodeSet; use syntax::ast::NodeId; use syntax::codemap::Span; -use utils::span_lint; +use utils::{span_lint, type_size}; pub struct Pass { pub too_large_for_stack: u64, @@ -42,9 +42,8 @@ fn is_non_trait_box(ty: ty::Ty) -> bool { } struct EscapeDelegate<'a, 'tcx: 'a> { + cx: &'a LateContext<'a, 'tcx>, set: NodeSet, - tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, too_large_for_stack: u64, } @@ -65,19 +64,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { node_id: NodeId ) { 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 { + cx: cx, set: NodeSet(), - tcx: cx.tcx, - param_env: param_env, too_large_for_stack: self.too_large_for_stack, }; - 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); - }); + let region_maps = &cx.tcx.region_maps(fn_def_id); + ExprUseVisitor::new(&mut v, cx.tcx, cx.param_env, region_maps, cx.tables) + .consume_body(body); for node in v.set { span_lint(cx, @@ -88,7 +83,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } -impl<'a, 'gcx: 'tcx, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'gcx> { +impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { fn consume(&mut self, _: NodeId, _: Span, cmt: cmt<'tcx>, mode: ConsumeMode) { if let Categorization::Local(lid) = cmt.cat { if let Move(DirectRefMove) = mode { @@ -99,7 +94,7 @@ impl<'a, 'gcx: 'tcx, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'gcx> { } fn matched_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: MatchMode) {} fn consume_pat(&mut self, consume_pat: &Pat, cmt: cmt<'tcx>, _: ConsumeMode) { - let map = &self.tcx.hir; + let map = &self.cx.tcx.hir; if map.is_argument(consume_pat.id) { // Skip closure arguments if let Some(NodeExpr(..)) = map.find(map.get_parent_node(consume_pat.id)) { @@ -172,18 +167,14 @@ impl<'a, 'gcx: 'tcx, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'gcx> { fn mutate(&mut self, _: NodeId, _: Span, _: cmt<'tcx>, _: MutateMode) {} } -impl<'a, 'tcx: 'a> EscapeDelegate<'a, 'tcx> { - fn is_large_box(&self, ty: ty::Ty) -> bool { +impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> { + fn is_large_box(&self, ty: ty::Ty<'tcx>) -> bool { // Large types need to be boxed to avoid stack // overflows. if ty.is_box() { - 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; - } - } + type_size(self.cx, ty.boxed_ty()).unwrap_or(0) > self.too_large_for_stack + } else { + false } - - false } } diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index f8fae40121e3..586bef3aa3af 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -659,7 +659,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { // check conventions w.r.t. conversion method names and predicates let def_id = cx.tcx.hir.local_def_id(item.id); let ty = cx.tcx.type_of(def_id); - let is_copy = is_copy(cx, ty, def_id); + let is_copy = is_copy(cx, ty); for &(ref conv, self_kinds) in &CONVENTIONS { if_let_chain! {[ conv.check(&name.as_str()), @@ -684,9 +684,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } let ret_ty = return_ty(cx, implitem.id); - let implitem_defid = cx.tcx.hir.local_def_id(implitem.id); if name == "new" && - !ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem_defid)) { + !ret_ty.walk().any(|t| same_tys(cx, t, ty)) { span_lint(cx, NEW_RET_NO_SELF, implitem.span, @@ -725,7 +724,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir: return false; }; - if implements_trait(cx, arg_ty, default_trait_id, &[], None) { + if implements_trait(cx, arg_ty, default_trait_id, &[]) { span_lint_and_then(cx, OR_FUN_CALL, span, @@ -822,7 +821,6 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir: /// Checks for the `CLONE_ON_COPY` lint. fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_ty: ty::Ty) { let ty = cx.tables.expr_ty(expr); - let parent = cx.tcx.hir.get_parent(expr.id); if let ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) = arg_ty.sty { if let ty::TyRef(..) = inner.sty { span_lint_and_then(cx, @@ -839,7 +837,7 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t } } - if is_copy(cx, ty, cx.tcx.hir.local_def_id(parent)) { + if is_copy(cx, ty) { span_lint_and_then(cx, CLONE_ON_COPY, expr.span, @@ -1268,7 +1266,7 @@ fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option> { /// This checks whether a given type is known to implement Debug. fn has_debug_impl<'a, 'b>(ty: ty::Ty<'a>, cx: &LateContext<'b, 'a>) -> bool { match cx.tcx.lang_items.debug_trait() { - Some(debug) => implements_trait(cx, ty, debug, &[], None), + Some(debug) => implements_trait(cx, ty, debug, &[]), None => false, } } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index b5acafac1698..fda048110fe4 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -455,13 +455,13 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) { // *arg impls PartialEq if !arg_ty .builtin_deref(true, ty::LvaluePreference::NoPreference) - .map_or(false, |tam| implements_trait(cx, tam.ty, partial_eq_trait_id, &[other_ty], None)) + .map_or(false, |tam| implements_trait(cx, tam.ty, partial_eq_trait_id, &[other_ty])) // arg impls PartialEq<*other> && !other_ty .builtin_deref(true, ty::LvaluePreference::NoPreference) - .map_or(false, |tam| implements_trait(cx, arg_ty, partial_eq_trait_id, &[tam.ty], None)) + .map_or(false, |tam| implements_trait(cx, arg_ty, partial_eq_trait_id, &[tam.ty])) // arg impls PartialEq - && !implements_trait(cx, arg_ty, partial_eq_trait_id, &[other_ty], None) { + && !implements_trait(cx, arg_ty, partial_eq_trait_id, &[other_ty]) { return; } diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 2ce22b8c9c9a..fda67f3202d5 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -82,8 +82,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { let fn_def_id = cx.tcx.hir.local_def_id(node_id); let preds: Vec = { - let parameter_env = cx.tcx.param_env(fn_def_id); - traits::elaborate_predicates(cx.tcx, parameter_env.caller_bounds.to_vec()) + traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds.to_vec()) .filter(|p| !p.is_global()) .collect() }; @@ -91,12 +90,9 @@ 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); - 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); - }); + let region_maps = &cx.tcx.region_maps(fn_def_id); + euv::ExprUseVisitor::new(&mut ctx, cx.tcx, cx.param_env, region_maps, cx.tables) + .consume_body(body); ctx }; @@ -119,9 +115,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { if_let_chain! {[ !is_self(arg), !ty.is_mutable_pointer(), - !is_copy(cx, ty, fn_def_id), - !implements_trait(cx, ty, fn_trait, &[], Some(node_id)), - !implements_trait(cx, ty, asref_trait, &[], Some(node_id)), + !is_copy(cx, ty), + !implements_trait(cx, ty, fn_trait, &[]), + !implements_trait(cx, ty, asref_trait, &[]), !implements_borrow_trait, let PatKind::Binding(mode, defid, ..) = arg.pat.node, @@ -190,7 +186,7 @@ struct MovedVariablesCtxt<'a, 'tcx: 'a> { spans_need_deref: HashMap>, } -impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { +impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> { fn new(cx: &'a LateContext<'a, 'tcx>) -> Self { MovedVariablesCtxt { cx: cx, @@ -199,7 +195,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { } } - fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt) { + fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt<'tcx>) { let cmt = unwrap_downcast_or_interior(cmt); if_let_chain! {[ @@ -210,7 +206,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { }} } - fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt) { + fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt<'tcx>) { let cmt = unwrap_downcast_or_interior(cmt); if_let_chain! {[ @@ -262,7 +258,7 @@ impl<'a, 'tcx: 'a> MovedVariablesCtxt<'a, 'tcx> { } } -impl<'a, 'gcx: 'tcx, 'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'gcx> { +impl<'a, 'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt<'a, 'tcx> { 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/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 0abb639d59a1..0d102164ebc0 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -108,15 +108,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault { // can't be implemented by default return; } - let def_id = cx.tcx.hir.local_def_id(id); if decl.inputs.is_empty() && name == "new" && cx.access_levels.is_reachable(id) { let self_ty = cx.tcx .type_of(cx.tcx.hir.local_def_id(cx.tcx.hir.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), def_id), + same_tys(cx, self_ty, return_ty(cx, id)), let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT), - !implements_trait(cx, self_ty, default_trait_id, &[], None) + !implements_trait(cx, self_ty, default_trait_id, &[]) ], { if let Some(sp) = can_derive_default(self_ty, cx, default_trait_id) { span_lint_and_then(cx, @@ -157,7 +155,7 @@ fn can_derive_default<'t, 'c>(ty: ty::Ty<'t>, cx: &LateContext<'c, 't>, default_ ty::TyAdt(adt_def, substs) if adt_def.is_struct() => { for field in adt_def.all_fields() { let f_ty = field.ty(cx.tcx, substs); - if !implements_trait(cx, f_ty, default_trait_id, &[], None) { + if !implements_trait(cx, f_ty, default_trait_id, &[]) { return None; } } diff --git a/clippy_lints/src/should_assert_eq.rs b/clippy_lints/src/should_assert_eq.rs index 93baab863472..ea79a77877a0 100644 --- a/clippy_lints/src/should_assert_eq.rs +++ b/clippy_lints/src/should_assert_eq.rs @@ -49,10 +49,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ShouldAssertEq { let ty1 = cx.tables.expr_ty(expr1); let ty2 = cx.tables.expr_ty(expr2); - let parent = cx.tcx.hir.get_parent(e.id); - - if implements_trait(cx, ty1, debug_trait, &[], Some(parent)) && - implements_trait(cx, ty2, debug_trait, &[], Some(parent)) { + if implements_trait(cx, ty1, debug_trait, &[]) && + implements_trait(cx, ty2, debug_trait, &[]) { span_lint(cx, SHOULD_ASSERT_EQ, e.span, &format!("use `{}{}` for better reporting", debug, sugg)); } }} diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index fa14be236499..9833cc537939 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -5,9 +5,7 @@ use rustc::hir::def::Def; use rustc::hir::map::Node; use rustc::lint::{LintContext, LateContext, Level, Lint}; use rustc::session::Session; -use rustc::traits::Reveal; use rustc::traits; -use rustc::ty::subst::{Subst, Substs}; use rustc::ty; use rustc::mir::transform::MirSource; use rustc_errors; @@ -312,20 +310,12 @@ pub fn implements_trait<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, trait_id: DefId, - ty_params: &[ty::Ty<'tcx>], - parent_node_id: Option + ty_params: &[ty::Ty<'tcx>] ) -> bool { let ty = cx.tcx.erase_regions(&ty); - 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 { - ty::ParamEnv::empty(Reveal::All) - }; - 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); - + let obligation = cx.tcx.predicate_for_trait_def( + cx.param_env, traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params); + cx.tcx.infer_ctxt().enter(|infcx| { traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation) }) } @@ -776,12 +766,10 @@ pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> ty::T pub fn same_tys<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, a: ty::Ty<'tcx>, - b: ty::Ty<'tcx>, - parameter_item: DefId + b: ty::Ty<'tcx> ) -> bool { - 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() + cx.tcx.infer_ctxt().enter(|infcx| { + infcx.can_eq(cx.param_env, a, b).is_ok() }) } @@ -794,10 +782,8 @@ pub fn type_is_unsafe_function(ty: ty::Ty) -> bool { } } -pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, env: DefId) -> bool { - let substs = Substs::identity_for_item(cx.tcx, env); - let env = cx.tcx.param_env(env); - !ty.subst(cx.tcx, substs).moves_by_default(cx.tcx.global_tcx(), env, DUMMY_SP) +pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>) -> bool { + !ty.moves_by_default(cx.tcx.global_tcx(), cx.param_env, DUMMY_SP) } /// Return whether a pattern is refutable. @@ -959,6 +945,5 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { } pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>) -> Option { - ty.layout(cx.tcx, ty::ParamEnv::empty(Reveal::All)) - .ok().map(|layout| layout.size(cx.tcx).bytes()) + ty.layout(cx.tcx, cx.param_env).ok().map(|layout| layout.size(cx.tcx).bytes()) } diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index e162406b8dc3..369c27d357fd 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -47,7 +47,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> 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.tables.expr_ty_adjusted(arg)), cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(expr.id))), + is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg))), ], { // report the error around the `vec!` not inside `:` let span = arg.span.ctxt.outer().expn_info().map(|info| info.call_site).expect("unable to get call_site"); diff --git a/clippy_tests/examples/assign_ops.stderr b/clippy_tests/examples/assign_ops.stderr index 0c7d2b3b4931..8e399b90d9d2 100644 --- a/clippy_tests/examples/assign_ops.stderr +++ b/clippy_tests/examples/assign_ops.stderr @@ -166,6 +166,14 @@ error: manual implementation of an assign operation | = note: `-D assign-op-pattern` implied by `-D warnings` +error: manual implementation of an assign operation + --> assign_ops.rs:40:5 + | +40 | s = s + "bla"; + | ^^^^^^^^^^^^^ help: replace it with `s += "bla"` + | + = note: `-D assign-op-pattern` implied by `-D warnings` + error: aborting due to previous error(s) error: Could not compile `clippy_tests`. diff --git a/clippy_tests/examples/strings.stderr b/clippy_tests/examples/strings.stderr index a12346086d3a..2b0e4dcdf1b3 100644 --- a/clippy_tests/examples/strings.stderr +++ b/clippy_tests/examples/strings.stderr @@ -1,3 +1,11 @@ +error: manual implementation of an assign operation + --> strings.rs:10:9 + | +10 | x = x + "."; + | ^^^^^^^^^^^ help: replace it with `x += "."` + | + = note: `-D assign-op-pattern` implied by `-D warnings` + error: you added something to a string. Consider using `String::push_str()` instead --> strings.rs:10:13 | @@ -22,6 +30,14 @@ error: you assigned the result of adding something to this string. Consider usin | = note: `-D string-add-assign` implied by `-D warnings` +error: manual implementation of an assign operation + --> strings.rs:24:9 + | +24 | x = x + "."; + | ^^^^^^^^^^^ help: replace it with `x += "."` + | + = note: `-D assign-op-pattern` implied by `-D warnings` + error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead --> strings.rs:38:9 | @@ -30,6 +46,14 @@ error: you assigned the result of adding something to this string. Consider usin | = note: `-D string-add-assign` implied by `-D warnings` +error: manual implementation of an assign operation + --> strings.rs:38:9 + | +38 | x = x + "."; + | ^^^^^^^^^^^ help: replace it with `x += "."` + | + = note: `-D assign-op-pattern` implied by `-D warnings` + error: you added something to a string. Consider using `String::push_str()` instead --> strings.rs:42:13 |