From 66d253f0f219578264ac7cb4e1c10f01dcfe8ad7 Mon Sep 17 00:00:00 2001 From: Yoav Lavi Date: Tue, 12 Apr 2022 11:09:34 +0200 Subject: [PATCH] pub_use --- CHANGELOG.md | 1 + clippy_lints/src/lib.register_lints.rs | 1 + clippy_lints/src/lib.register_restriction.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/pub_use.rs | 56 ++++++++++++++++++++ tests/ui/pub_use.rs | 14 +++++ tests/ui/pub_use.stderr | 11 ++++ 7 files changed, 86 insertions(+) create mode 100644 clippy_lints/src/pub_use.rs create mode 100644 tests/ui/pub_use.rs create mode 100644 tests/ui/pub_use.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a368701..444c649c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3527,6 +3527,7 @@ Released 2018-09-13 [`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq [`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast [`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names +[`pub_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_use [`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark [`range_minus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_minus_one [`range_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs index 704e79885..4132802c9 100644 --- a/clippy_lints/src/lib.register_lints.rs +++ b/clippy_lints/src/lib.register_lints.rs @@ -432,6 +432,7 @@ store.register_lints(&[ ptr::PTR_ARG, ptr_eq::PTR_EQ, ptr_offset_with_cast::PTR_OFFSET_WITH_CAST, + pub_use::PUB_USE, question_mark::QUESTION_MARK, ranges::MANUAL_RANGE_CONTAINS, ranges::RANGE_MINUS_ONE, diff --git a/clippy_lints/src/lib.register_restriction.rs b/clippy_lints/src/lib.register_restriction.rs index 4802dd877..555a8ad84 100644 --- a/clippy_lints/src/lib.register_restriction.rs +++ b/clippy_lints/src/lib.register_restriction.rs @@ -53,6 +53,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve LintId::of(panic_unimplemented::UNIMPLEMENTED), LintId::of(panic_unimplemented::UNREACHABLE), LintId::of(pattern_type_mismatch::PATTERN_TYPE_MISMATCH), + LintId::of(pub_use::PUB_USE), LintId::of(redundant_slicing::DEREF_BY_SLICING), LintId::of(same_name_method::SAME_NAME_METHOD), LintId::of(shadow::SHADOW_REUSE), diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 74ade422d..17552873b 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -336,6 +336,7 @@ mod precedence; mod ptr; mod ptr_eq; mod ptr_offset_with_cast; +mod pub_use; mod question_mark; mod ranges; mod redundant_clone; @@ -870,6 +871,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef)); store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets)); store.register_late_pass(|| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings)); + store.register_early_pass(|| Box::new(pub_use::PubUse)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/pub_use.rs b/clippy_lints/src/pub_use.rs new file mode 100644 index 000000000..9d2b0cedb --- /dev/null +++ b/clippy_lints/src/pub_use.rs @@ -0,0 +1,56 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use rustc_ast::ast::{Item, ItemKind, VisibilityKind}; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// + /// Restricts the usage of `pub use ...` + /// + /// ### Why is this bad? + /// + /// `pub use` is usually fine, but a project may wish to limit `pub use` instances to prevent + /// unintentional exports or to encourage placing exported items directly in public modules + /// + /// ### Example + /// ```rust + /// pub mod outer { + /// mod inner { + /// pub struct Test {} + /// } + /// pub use inner::Test; + /// } + /// + /// use outer::Test; + /// ``` + /// Use instead: + /// ```rust + /// pub mod outer { + /// pub struct Test {} + /// } + /// + /// use outer::Test; + /// ``` + #[clippy::version = "1.62.0"] + pub PUB_USE, + restriction, + "restricts the usage of `pub use`" +} +declare_lint_pass!(PubUse => [PUB_USE]); + +impl EarlyLintPass for PubUse { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + if let ItemKind::Use(_) = item.kind && + let VisibilityKind::Public = item.vis.kind { + span_lint_and_help( + cx, + PUB_USE, + item.span, + "using `pub use`", + None, + "move the exported item to a public module instead", + ); + } + } +} diff --git a/tests/ui/pub_use.rs b/tests/ui/pub_use.rs new file mode 100644 index 000000000..65542bede --- /dev/null +++ b/tests/ui/pub_use.rs @@ -0,0 +1,14 @@ +#![warn(clippy::pub_use)] +#![allow(unused_imports)] +#![no_main] + +pub mod outer { + mod inner { + pub struct Test {} + } + // should be linted + pub use inner::Test; +} + +// should not be linted +use std::fmt; diff --git a/tests/ui/pub_use.stderr b/tests/ui/pub_use.stderr new file mode 100644 index 000000000..9ab710df8 --- /dev/null +++ b/tests/ui/pub_use.stderr @@ -0,0 +1,11 @@ +error: using `pub use` + --> $DIR/pub_use.rs:10:5 + | +LL | pub use inner::Test; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::pub-use` implied by `-D warnings` + = help: move the exported item to a public module instead + +error: aborting due to previous error +