about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYoav Lavi <yoavlavi122@gmail.com>2022-04-12 11:09:34 +0200
committerYoav Lavi <yoavlavi122@gmail.com>2022-04-13 13:48:27 +0200
commit66d253f0f219578264ac7cb4e1c10f01dcfe8ad7 (patch)
tree0e77aa251b76441198868ab710ef058c89568974
parent5c19ae96e7e7b8eecf86c87c96ba666cd5b5066d (diff)
downloadrust-66d253f0f219578264ac7cb4e1c10f01dcfe8ad7.tar.gz
rust-66d253f0f219578264ac7cb4e1c10f01dcfe8ad7.zip
pub_use
-rw-r--r--CHANGELOG.md1
-rw-r--r--clippy_lints/src/lib.register_lints.rs1
-rw-r--r--clippy_lints/src/lib.register_restriction.rs1
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--clippy_lints/src/pub_use.rs56
-rw-r--r--tests/ui/pub_use.rs14
-rw-r--r--tests/ui/pub_use.stderr11
7 files changed, 86 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44a36870108..444c649c84f 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 704e79885cf..4132802c9c6 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 4802dd877e9..555a8ad841f 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 74ade422dc8..17552873b0a 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 00000000000..9d2b0cedb60
--- /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 00000000000..65542bedec7
--- /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 00000000000..9ab710df818
--- /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
+