diff --git a/clippy_lints/src/enum_glob_use.rs b/clippy_lints/src/enum_glob_use.rs index 9a0263f2f68..e90dc6f693a 100644 --- a/clippy_lints/src/enum_glob_use.rs +++ b/clippy_lints/src/enum_glob_use.rs @@ -44,7 +44,7 @@ fn check_mod(&mut self, cx: &LateContext<'a, 'tcx>, m: &'tcx Mod, _: Span, _: No impl EnumGlobUse { fn lint_item(&self, cx: &LateContext, item: &Item) { - if item.vis.node == VisibilityKind::Public { + if item.vis.node.is_pub() { return; // re-exports are fine } if let ItemUse(ref path, UseKind::Glob) = item.node { diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs index a200383b41d..d272cab0a0d 100644 --- a/clippy_lints/src/enum_variants.rs +++ b/clippy_lints/src/enum_variants.rs @@ -262,7 +262,7 @@ fn check_item(&mut self, cx: &EarlyContext, item: &Item) { ); } } - if item.vis.node == VisibilityKind::Public { + if item.vis.node.is_pub() { let matching = partial_match(mod_camel, &item_camel); let rmatching = partial_rmatch(mod_camel, &item_camel); let nchars = mod_camel.chars().count(); diff --git a/clippy_lints/src/if_let_redundant_pattern_matching.rs b/clippy_lints/src/if_let_redundant_pattern_matching.rs index 92b2bab3ba8..78b21478d88 100644 --- a/clippy_lints/src/if_let_redundant_pattern_matching.rs +++ b/clippy_lints/src/if_let_redundant_pattern_matching.rs @@ -48,13 +48,17 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { if let ExprMatch(ref op, ref arms, MatchSource::IfLetDesugar { .. }) = expr.node { if arms[0].pats.len() == 1 { let good_method = match arms[0].pats[0].node { - PatKind::TupleStruct(ref path, ref pats, _) if pats.len() == 1 && pats[0].node == PatKind::Wild => { - if match_qpath(path, &paths::RESULT_OK) { - "is_ok()" - } else if match_qpath(path, &paths::RESULT_ERR) { - "is_err()" - } else if match_qpath(path, &paths::OPTION_SOME) { - "is_some()" + PatKind::TupleStruct(ref path, ref pats, _) if pats.len() == 1 => { + if let PatKind::Wild = pats[0].node { + if match_qpath(path, &paths::RESULT_OK) { + "is_ok()" + } else if match_qpath(path, &paths::RESULT_ERR) { + "is_err()" + } else if match_qpath(path, &paths::OPTION_SOME) { + "is_some()" + } else { + return; + } } else { return; } diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index 33930ab58db..c1ec7a16296 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -258,11 +258,10 @@ fn has_is_empty_impl(cx: &LateContext, id: DefId) -> bool { let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr)); match ty.sty { - ty::TyDynamic(..) => cx.tcx - .associated_items(ty.ty_to_def_id().expect("trait impl not found")) + ty::TyDynamic(ref tt, ..) => cx.tcx + .associated_items(tt.principal().expect("trait impl not found").def_id()) .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::TyProjection(ref proj) => has_is_empty_impl(cx, proj.item_def_id), ty::TyAdt(id, _) => has_is_empty_impl(cx, id.did), ty::TyArray(..) | ty::TySlice(..) | ty::TyStr => true, _ => false, diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 8b7032893d8..963a8da49cb 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -23,7 +23,7 @@ use crate::utils::{get_enclosing_block, get_parent_expr, higher, in_external_macro, is_integer_literal, is_refutable, last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, snippet, snippet_opt, - span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then}; + span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, SpanlessEq}; use crate::utils::paths; /// **What it does:** Checks for for-loops that manually copy items between @@ -1955,7 +1955,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) { if self.state == VarState::DontWarn { return; } - if expr == self.end_expr { + if SpanlessEq::new(self.cx).eq_expr(&expr, self.end_expr) { self.past_loop = true; return; } diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 5ea873e31e1..0d58732f24d 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -3,7 +3,7 @@ use rustc::ty; use syntax::ast; use crate::utils::{get_arg_ident, is_adjusted, iter_input_pats, match_qpath, match_trait_method, match_type, - paths, remove_blocks, snippet, span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; + paths, remove_blocks, snippet, span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq}; /// **What it does:** Checks for mapping `clone()` over an iterator. /// @@ -66,7 +66,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { if clone_call.ident.name == "clone" && clone_args.len() == 1 && match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) && - expr_eq_name(&clone_args[0], arg_ident) + expr_eq_name(cx, &clone_args[0], arg_ident) { span_help_and_lint(cx, MAP_CLONE, expr.span, &format!( "you seem to be using .map() to clone the contents of an {}, consider \ @@ -98,7 +98,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { } } -fn expr_eq_name(expr: &Expr, id: ast::Ident) -> bool { +fn expr_eq_name(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool { match expr.node { ExprPath(QPath::Resolved(None, ref path)) => { let arg_segment = [ @@ -108,7 +108,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Ident) -> bool { infer_types: true, }, ]; - !path.is_global() && path.segments[..] == arg_segment + !path.is_global() && SpanlessEq::new(cx).eq_path_segments(&path.segments[..], &arg_segment) }, _ => false, } @@ -127,7 +127,7 @@ fn get_type_name(cx: &LateContext, expr: &Expr, arg: &Expr) -> Option<&'static s fn only_derefs(cx: &LateContext, expr: &Expr, id: ast::Ident) -> bool { match expr.node { ExprUnary(UnDeref, ref subexpr) if !is_adjusted(cx, subexpr) => only_derefs(cx, subexpr, id), - _ => expr_eq_name(expr, id), + _ => expr_eq_name(cx, expr, id), } } diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 207343c92c6..a14c6a0d8b9 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -221,7 +221,7 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) { } fn check_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, els: Option<&Expr>) { - if arms[1].pats[0].node == PatKind::Wild { + if is_wild(&arms[1].pats[0]) { report_single_match_single_pattern(cx, ex, arms, expr, els); } } @@ -265,7 +265,7 @@ fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: let path = match arms[1].pats[0].node { PatKind::TupleStruct(ref path, ref inner, _) => { // contains any non wildcard patterns? e.g. Err(err) - if inner.iter().any(|pat| pat.node != PatKind::Wild) { + if !inner.iter().all(is_wild) { return; } print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)) @@ -356,6 +356,13 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr, } } +fn is_wild(pat: &impl std::ops::Deref) -> bool { + match pat.node { + PatKind::Wild => true, + _ => false, + } +} + fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) { let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex)); if match_type(cx, ex_ty, &paths::RESULT) { @@ -364,7 +371,7 @@ fn check_wild_err_arm(cx: &LateContext, ex: &Expr, arms: &[Arm]) { let path_str = print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)); if_chain! { if path_str == "Err"; - if inner.iter().any(|pat| pat.node == PatKind::Wild); + if inner.iter().any(is_wild); if let ExprBlock(ref block, _) = arm.body.node; if is_panic_block(block); then { diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 1d1d0ef8faa..ca739558e62 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -10,7 +10,7 @@ use crate::utils::{get_arg_name, get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, is_expn_of, is_self, is_self_ty, iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type, method_chain_args, match_var, return_ty, remove_blocks, same_tys, single_segment_path, snippet, - span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; + span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq}; use crate::utils::paths; use crate::utils::sugg; use crate::consts::{constant, Constant}; @@ -820,8 +820,8 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS { if name == method_name && sig.decl.inputs.len() == n_args && - out_type.matches(&sig.decl.output) && - self_kind.matches(first_arg_ty, first_arg, self_ty, false, &implitem.generics) { + out_type.matches(cx, &sig.decl.output) && + self_kind.matches(cx, first_arg_ty, first_arg, self_ty, false, &implitem.generics) { span_lint(cx, SHOULD_IMPLEMENT_TRAIT, implitem.span, &format!( "defining a method called `{}` on this type; consider implementing \ the `{}` trait or choosing a less ambiguous name", name, trait_name)); @@ -838,9 +838,9 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I if conv.check(&name.as_str()); if !self_kinds .iter() - .any(|k| k.matches(first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics)); + .any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics)); then { - let lint = if item.vis.node == hir::VisibilityKind::Public { + let lint = if item.vis.node.is_pub() { WRONG_PUB_SELF_CONVENTION } else { WRONG_SELF_CONVENTION @@ -2030,6 +2030,7 @@ enum SelfKind { impl SelfKind { fn matches( self, + cx: &LateContext, ty: &hir::Ty, arg: &hir::Arg, self_ty: &hir::Ty, @@ -2047,7 +2048,7 @@ fn matches( // `Self`, `&mut Self`, // and `Box`, including the equivalent types with `Foo`. - let is_actually_self = |ty| is_self_ty(ty) || ty == self_ty; + let is_actually_self = |ty| is_self_ty(ty) || SpanlessEq::new(cx).eq_ty(ty, self_ty); if is_self(arg) { match self { SelfKind::Value => is_actually_self(ty), @@ -2173,12 +2174,13 @@ enum OutType { } impl OutType { - fn matches(self, ty: &hir::FunctionRetTy) -> bool { + fn matches(self, cx: &LateContext, ty: &hir::FunctionRetTy) -> bool { + let is_unit = |ty: &hir::Ty| SpanlessEq::new(cx).eq_ty_kind(&ty.node, &hir::TyTup(vec![].into())); match (self, ty) { (OutType::Unit, &hir::DefaultReturn(_)) => true, - (OutType::Unit, &hir::Return(ref ty)) if ty.node == hir::TyTup(vec![].into()) => true, + (OutType::Unit, &hir::Return(ref ty)) if is_unit(ty) => true, (OutType::Bool, &hir::Return(ref ty)) if is_bool(ty) => true, - (OutType::Any, &hir::Return(ref ty)) if ty.node != hir::TyTup(vec![].into()) => true, + (OutType::Any, &hir::Return(ref ty)) if !is_unit(ty) => true, (OutType::Ref, &hir::Return(ref ty)) => matches!(ty.node, hir::TyRptr(_, _)), _ => false, } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 697f15bdd1d..4fc65b2f89a 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -6,7 +6,7 @@ use syntax::codemap::{ExpnFormat, Span}; use crate::utils::{get_item_name, get_parent_expr, implements_trait, in_constant, in_macro, is_integer_literal, iter_input_pats, last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint, - span_lint_and_then, walk_ptrs_ty}; + span_lint_and_then, walk_ptrs_ty, SpanlessEq}; use crate::utils::sugg::Sugg; use syntax::ast::{LitKind, CRATE_NODE_ID}; use crate::consts::{constant, Constant}; @@ -418,7 +418,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) { if let PatKind::Binding(_, _, ident, Some(ref right)) = pat.node { - if right.node == PatKind::Wild { + if let PatKind::Wild = right.node { span_lint( cx, REDUNDANT_PATTERN, @@ -542,7 +542,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr) { fn is_used(cx: &LateContext, expr: &Expr) -> bool { if let Some(parent) = get_parent_expr(cx, expr) { match parent.node { - ExprAssign(_, ref rhs) | ExprAssignOp(_, _, ref rhs) => **rhs == *expr, + ExprAssign(_, ref rhs) | ExprAssignOp(_, _, ref rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr), _ => is_used(cx, parent), } } else { diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index 87e4d343ab4..e527a05c851 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -213,7 +213,7 @@ fn check_pat(&mut self, cx: &EarlyContext, pat: &Pat) { .name; for field in pfields { - if field.node.pat.node == PatKind::Wild { + if let PatKind::Wild = field.node.pat.node { wilds += 1; } } @@ -231,14 +231,15 @@ fn check_pat(&mut self, cx: &EarlyContext, pat: &Pat) { let mut normal = vec![]; for field in pfields { - if field.node.pat.node != PatKind::Wild { - if let Ok(n) = cx.sess().codemap().span_to_snippet(field.span) { + match field.node.pat.node { + PatKind::Wild => {}, + _ => if let Ok(n) = cx.sess().codemap().span_to_snippet(field.span) { normal.push(n); - } + }, } } for field in pfields { - if field.node.pat.node == PatKind::Wild { + if let PatKind::Wild = field.node.pat.node { wilds -= 1; if wilds > 0 { span_lint( diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs index 3a95471d0a2..c5b0c977956 100644 --- a/clippy_lints/src/overflow_check_conditional.rs +++ b/clippy_lints/src/overflow_check_conditional.rs @@ -1,6 +1,6 @@ use rustc::lint::*; use rustc::hir::*; -use crate::utils::span_lint; +use crate::utils::{span_lint, SpanlessEq}; /// **What it does:** Detects classic underflow/overflow checks. /// @@ -31,13 +31,14 @@ fn get_lints(&self) -> LintArray { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional { // a + b < a, a > a + b, a < a - b, a - b > a fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { + let eq = |l, r| SpanlessEq::new(cx).eq_path_segment(l, r); if_chain! { if let Expr_::ExprBinary(ref op, ref first, ref second) = expr.node; if let Expr_::ExprBinary(ref op2, ref ident1, ref ident2) = first.node; if let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node; if let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node; if let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = second.node; - if path1.segments[0] == path3.segments[0] || path2.segments[0] == path3.segments[0]; + if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); if cx.tables.expr_ty(ident1).is_integral(); if cx.tables.expr_ty(ident2).is_integral(); then { @@ -62,7 +63,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { if let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node; if let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node; if let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = first.node; - if path1.segments[0] == path3.segments[0] || path2.segments[0] == path3.segments[0]; + if eq(&path1.segments[0], &path3.segments[0]) || eq(&path2.segments[0], &path3.segments[0]); if cx.tables.expr_ty(ident1).is_integral(); if cx.tables.expr_ty(ident2).is_integral(); then { diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 6ec624d26e9..c0fac47b34e 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -3,7 +3,7 @@ use syntax::ast::RangeLimits; use syntax::codemap::Spanned; use crate::utils::{is_integer_literal, paths, snippet, span_lint, span_lint_and_then}; -use crate::utils::{get_trait_def_id, higher, implements_trait}; +use crate::utils::{get_trait_def_id, higher, implements_trait, SpanlessEq}; use crate::utils::sugg::Sugg; /// **What it does:** Checks for calling `.step_by(0)` on iterators, @@ -118,7 +118,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { // .iter() and .len() called on same Path if let ExprPath(QPath::Resolved(_, ref iter_path)) = iter_args[0].node; if let ExprPath(QPath::Resolved(_, ref len_path)) = len_args[0].node; - if iter_path.segments == len_path.segments; + if SpanlessEq::new(cx).eq_path_segments(&iter_path.segments, &len_path.segments); then { span_lint(cx, RANGE_ZIP_WITH_LEN, diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index f95fb046b49..1f6092789e5 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -118,7 +118,7 @@ pub fn eq_expr(&mut self, left: &Expr, right: &Expr) -> bool { }) }, (&ExprMethodCall(ref l_path, _, ref l_args), &ExprMethodCall(ref r_path, _, ref r_args)) => { - !self.ignore_fn && l_path == r_path && self.eq_exprs(l_args, r_args) + !self.ignore_fn && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args) }, (&ExprRepeat(ref le, ref ll_id), &ExprRepeat(ref re, ref rl_id)) => { let mut celcx = constant_context(self.cx, self.cx.tcx.body_tables(ll_id.body)); @@ -225,7 +225,11 @@ fn eq_path_parameters(&mut self, left: &GenericArgs, right: &GenericArgs) -> boo } } - fn eq_path_segment(&mut self, left: &PathSegment, right: &PathSegment) -> bool { + pub fn eq_path_segments(&mut self, left: &[PathSegment], right: &[PathSegment]) -> bool { + left.len() == right.len() && left.iter().zip(right).all(|(l, r)| self.eq_path_segment(l, r)) + } + + pub fn eq_path_segment(&mut self, left: &PathSegment, right: &PathSegment) -> bool { // The == of idents doesn't work with different contexts, // we have to be explicit about hygiene if left.ident.as_str() != right.ident.as_str() { @@ -238,8 +242,12 @@ fn eq_path_segment(&mut self, left: &PathSegment, right: &PathSegment) -> bool { } } - fn eq_ty(&mut self, left: &Ty, right: &Ty) -> bool { - match (&left.node, &right.node) { + pub fn eq_ty(&mut self, left: &Ty, right: &Ty) -> bool { + self.eq_ty_kind(&left.node, &right.node) + } + + pub fn eq_ty_kind(&mut self, left: &Ty_, right: &Ty_) -> bool { + match (left, right) { (&TySlice(ref l_vec), &TySlice(ref r_vec)) => self.eq_ty(l_vec, r_vec), (&TyArray(ref lt, ref ll_id), &TyArray(ref rt, ref rl_id)) => { let full_table = self.tables; @@ -336,7 +344,12 @@ pub fn hash_block(&mut self, b: &Block) { self.hash_expr(e); } - b.rules.hash(&mut self.s); + match b.rules { + BlockCheckMode::DefaultBlock => 0, + BlockCheckMode::UnsafeBlock(_) => 1, + BlockCheckMode::PushUnsafeBlock(_) => 2, + BlockCheckMode::PopUnsafeBlock(_) => 3, + }.hash(&mut self.s); } #[allow(many_single_char_names)] @@ -419,7 +432,10 @@ pub fn hash_expr(&mut self, e: &Expr) { ExprClosure(cap, _, eid, _, _) => { let c: fn(_, _, _, _, _) -> _ = ExprClosure; c.hash(&mut self.s); - cap.hash(&mut self.s); + match cap { + CaptureClause::CaptureByValue => 0, + CaptureClause::CaptureByRef => 1, + }.hash(&mut self.s); self.hash_expr(&self.cx.tcx.hir.body(eid).value); }, ExprField(ref e, ref f) => { diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index f0e3961600c..ef26b77ea1a 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -120,12 +120,14 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { if let ItemStatic(ref ty, MutImmutable, body_id) = item.node { if is_lint_ref_type(ty) { self.declared_lints.insert(item.name, item.span); - } else if is_lint_array_type(ty) && item.vis.node == VisibilityKind::Inherited && item.name == "ARRAY" { - let mut collector = LintCollector { - output: &mut self.registered_lints, - cx, - }; - collector.visit_expr(&cx.tcx.hir.body(body_id).value); + } else if is_lint_array_type(ty) && item.name == "ARRAY" { + if let VisibilityKind::Inherited = item.vis.node { + let mut collector = LintCollector { + output: &mut self.registered_lints, + cx, + }; + collector.visit_expr(&cx.tcx.hir.body(body_id).value); + } } } }