1 use clippy_utils::diagnostics::span_lint_and_then;
2 use rustc_errors::Applicability;
3 use rustc_hir::def::{DefKind, Res};
4 use rustc_hir::{Item, ItemKind, VisibilityKind};
5 use rustc_lint::{LateContext, LateLintPass};
6 use rustc_session::{declare_tool_lint, impl_lint_pass};
7 use rustc_span::hygiene::MacroKind;
11 /// Checks for items declared `pub(crate)` that are not crate visible because they
12 /// are inside a private module.
14 /// ### Why is this bad?
15 /// Writing `pub(crate)` is misleading when it's redundant due to the parent
16 /// module's visibility.
21 /// pub(crate) fn internal_fn() { }
24 /// This function is not visible outside the module and it can be declared with `pub` or
25 /// private visibility
28 /// pub fn internal_fn() { }
31 #[clippy::version = "1.44.0"]
32 pub REDUNDANT_PUB_CRATE,
34 "Using `pub(crate)` visibility on items that are not crate visible due to the visibility of the module that contains them."
38 pub struct RedundantPubCrate {
39 is_exported: Vec<bool>,
42 impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);
44 impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
45 fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
47 if let VisibilityKind::Crate { .. } = item.vis.node;
48 if !cx.access_levels.is_exported(item.def_id) && self.is_exported.last() == Some(&false);
49 if is_not_macro_export(item);
51 let span = item.span.with_hi(item.ident.span.hi());
52 let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id());
57 &format!("pub(crate) {} inside private module", descr),
63 Applicability::MachineApplicable,
70 if let ItemKind::Mod { .. } = item.kind {
71 self.is_exported.push(cx.access_levels.is_exported(item.def_id));
75 fn check_item_post(&mut self, _cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
76 if let ItemKind::Mod { .. } = item.kind {
77 self.is_exported.pop().expect("unbalanced check_item/check_item_post");
82 fn is_not_macro_export<'tcx>(item: &'tcx Item<'tcx>) -> bool {
83 if let ItemKind::Use(path, _) = item.kind {
84 if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = path.res {