diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index c2d98b8e4ad37..5c33259a37c21 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -233,6 +233,37 @@ fn gen_args(segment: &PathSegment<'_>) -> String { String::new() } +declare_tool_lint! { + pub rustc::PUB_CROSS_CRATE_REEXPORT, + Allow, + "re-exporting items across crates", + report_in_external_macro: true +} + +declare_lint_pass!(PubReexportChecker => [PUB_CROSS_CRATE_REEXPORT]); + +impl<'tcx> LateLintPass<'tcx> for PubReexportChecker { + fn check_item(&mut self, cx: &LateContext<'_>, item: &'tcx rustc_hir::Item<'tcx>) { + use rustc_hir::def_id::LOCAL_CRATE; + + if item.vis.node.is_pub() { + if let rustc_hir::ItemKind::Use(path, _kind) = item.kind { + if path.res.def_id().krate != LOCAL_CRATE { + cx.struct_span_lint( + PUB_CROSS_CRATE_REEXPORT, + item.span, + |lint| { + lint.build("publicly re-exporting an item from a different crate") + .note("facade crates are discouraged; import from the original crate instead") + .emit(); + }, + ); + } + } + } + } +} + declare_tool_lint! { pub rustc::LINT_PASS_IMPL_WITHOUT_MACRO, Allow, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 33caedfc19826..46b11fc59341c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -451,6 +451,8 @@ fn register_internals(store: &mut LintStore) { store.register_early_pass(|| box LintPassImpl); store.register_lints(&TyTyKind::get_lints()); store.register_late_pass(|| box TyTyKind); + store.register_lints(&PubReexportChecker::get_lints()); + store.register_late_pass(|| box PubReexportChecker); store.register_group( false, "rustc::internal", @@ -461,6 +463,7 @@ fn register_internals(store: &mut LintStore) { LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO), LintId::of(TY_PASS_BY_REFERENCE), LintId::of(USAGE_OF_QUALIFIED_TY), + LintId::of(PUB_CROSS_CRATE_REEXPORT), ], ); }