about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-28 09:08:43 +0000
committerbors <bors@rust-lang.org>2023-06-28 09:08:43 +0000
commit36f4feb273bbe978a1c4622a55264e0123e0a4bf (patch)
treeada2917b5902ee07ede08783896d1741049d625e
parent1df9110b855c6a4b52787eb1f82542aea07b6b4d (diff)
parent46aa8abf08057618038c60c11b98a3c6cff927de (diff)
downloadrust-36f4feb273bbe978a1c4622a55264e0123e0a4bf.tar.gz
rust-36f4feb273bbe978a1c4622a55264e0123e0a4bf.zip
Auto merge of #10967 - Centri3:visibility_lints2, r=Manishearth
New lints ['`needless_pub_self`], [`pub_with_shorthand`] and [`pub_without_shorthand`]

Closes #10963
Closes #10964

changelog: New lints ['`needless_pub_self`], [`pub_with_shorthand`] and [`pub_without_shorthand`]
-rw-r--r--CHANGELOG.md3
-rw-r--r--clippy_lints/src/declared_lints.rs3
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--clippy_lints/src/visibility.rs131
-rw-r--r--tests/ui/manual_async_fn.fixed2
-rw-r--r--tests/ui/manual_async_fn.rs2
-rw-r--r--tests/ui/needless_pub_self.fixed33
-rw-r--r--tests/ui/needless_pub_self.rs33
-rw-r--r--tests/ui/needless_pub_self.stderr22
-rw-r--r--tests/ui/pub_with_shorthand.fixed38
-rw-r--r--tests/ui/pub_with_shorthand.rs38
-rw-r--r--tests/ui/pub_with_shorthand.stderr28
-rw-r--r--tests/ui/pub_without_shorthand.fixed38
-rw-r--r--tests/ui/pub_without_shorthand.rs38
-rw-r--r--tests/ui/pub_without_shorthand.stderr22
15 files changed, 431 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5193db5a35d..4debe304857 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5047,6 +5047,7 @@ Released 2018-09-13
 [`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take
 [`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals
 [`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
+[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pub_self
 [`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
 [`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
 [`needless_raw_string_hashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
@@ -5121,6 +5122,8 @@ Released 2018-09-13
 [`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
+[`pub_with_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_with_shorthand
+[`pub_without_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_without_shorthand
 [`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark
 [`question_mark_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark_used
 [`range_minus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_minus_one
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
index 881ff9baf18..46f4082f0c7 100644
--- a/clippy_lints/src/declared_lints.rs
+++ b/clippy_lints/src/declared_lints.rs
@@ -666,6 +666,9 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::useless_conversion::USELESS_CONVERSION_INFO,
     crate::vec::USELESS_VEC_INFO,
     crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO,
+    crate::visibility::NEEDLESS_PUB_SELF_INFO,
+    crate::visibility::PUB_WITHOUT_SHORTHAND_INFO,
+    crate::visibility::PUB_WITH_SHORTHAND_INFO,
     crate::wildcard_imports::ENUM_GLOB_USE_INFO,
     crate::wildcard_imports::WILDCARD_IMPORTS_INFO,
     crate::write::PRINTLN_EMPTY_STRING_INFO,
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 0c71fdccae0..2f88fe8dcd5 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -338,6 +338,7 @@ mod use_self;
 mod useless_conversion;
 mod vec;
 mod vec_init_then_push;
+mod visibility;
 mod wildcard_imports;
 mod write;
 mod zero_div_zero;
@@ -1070,6 +1071,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         })
     });
     store.register_late_pass(|_| Box::new(manual_range_patterns::ManualRangePatterns));
+    store.register_early_pass(|| Box::new(visibility::Visibility));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/clippy_lints/src/visibility.rs b/clippy_lints/src/visibility.rs
new file mode 100644
index 00000000000..43248bccc13
--- /dev/null
+++ b/clippy_lints/src/visibility.rs
@@ -0,0 +1,131 @@
+use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_opt};
+use rustc_ast::ast::{Item, VisibilityKind};
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::{symbol::kw, Span};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `pub(self)` and `pub(in self)`.
+    ///
+    /// ### Why is this bad?
+    /// It's unnecessary, omitting the `pub` entirely will give the same results.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// pub(self) type OptBox<T> = Option<Box<T>>;
+    /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// type OptBox<T> = Option<Box<T>>;
+    /// ```
+    #[clippy::version = "1.72.0"]
+    pub NEEDLESS_PUB_SELF,
+    style,
+    "checks for usage of `pub(self)` and `pub(in self)`."
+}
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `pub(<loc>)` with `in`.
+    ///
+    /// ### Why is this bad?
+    /// Consistency. Use it or don't, just be consistent about it.
+    ///
+    /// Also see the `pub_without_shorthand` lint for an alternative.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// pub(super) type OptBox<T> = Option<Box<T>>;
+    /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// pub(in super) type OptBox<T> = Option<Box<T>>;
+    /// ```
+    #[clippy::version = "1.72.0"]
+    pub PUB_WITH_SHORTHAND,
+    restriction,
+    "disallows usage of `pub(<loc>)`, without `in`"
+}
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `pub(<loc>)` without `in`.
+    ///
+    /// Note: As you cannot write a module's path in `pub(<loc>)`, this will only trigger on
+    /// `pub(super)` and the like.
+    ///
+    /// ### Why is this bad?
+    /// Consistency. Use it or don't, just be consistent about it.
+    ///
+    /// Also see the `pub_with_shorthand` lint for an alternative.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// pub(in super) type OptBox<T> = Option<Box<T>>;
+    /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// pub(super) type OptBox<T> = Option<Box<T>>;
+    /// ```
+    #[clippy::version = "1.72.0"]
+    pub PUB_WITHOUT_SHORTHAND,
+    restriction,
+    "disallows usage of `pub(in <loc>)` with `in`"
+}
+declare_lint_pass!(Visibility => [NEEDLESS_PUB_SELF, PUB_WITH_SHORTHAND, PUB_WITHOUT_SHORTHAND]);
+
+impl EarlyLintPass for Visibility {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        if !in_external_macro(cx.sess(), item.span)
+            && let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind
+        {
+            if **path == kw::SelfLower && let Some(false) = is_from_proc_macro(cx, item.vis.span) {
+                span_lint_and_sugg(
+                    cx,
+                    NEEDLESS_PUB_SELF,
+                    item.vis.span,
+                    &format!("unnecessary `pub({}self)`", if *shorthand { "" } else { "in " }),
+                    "remove it",
+                    String::new(),
+                    Applicability::MachineApplicable,
+                );
+            }
+
+            if (**path == kw::Super || **path == kw::SelfLower || **path == kw::Crate)
+                && !*shorthand
+                && let [.., last] = &*path.segments
+                && let Some(false) = is_from_proc_macro(cx, item.vis.span)
+            {
+                span_lint_and_sugg(
+                    cx,
+                    PUB_WITHOUT_SHORTHAND,
+                    item.vis.span,
+                    "usage of `pub` with `in`",
+                    "remove it",
+                    format!("pub({})", last.ident),
+                    Applicability::MachineApplicable,
+                );
+            }
+
+            if *shorthand
+                && let [.., last] = &*path.segments
+                && let Some(false) = is_from_proc_macro(cx, item.vis.span)
+            {
+                span_lint_and_sugg(
+                    cx,
+                    PUB_WITH_SHORTHAND,
+                    item.vis.span,
+                    "usage of `pub` without `in`",
+                    "add it",
+                    format!("pub(in {})", last.ident),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+    }
+}
+
+fn is_from_proc_macro(cx: &EarlyContext<'_>, span: Span) -> Option<bool> {
+    snippet_opt(cx, span).map(|s| !s.starts_with("pub"))
+}
diff --git a/tests/ui/manual_async_fn.fixed b/tests/ui/manual_async_fn.fixed
index e458f0d254f..e609b4b1bdb 100644
--- a/tests/ui/manual_async_fn.fixed
+++ b/tests/ui/manual_async_fn.fixed
@@ -1,6 +1,6 @@
 //@run-rustfix
 #![warn(clippy::manual_async_fn)]
-#![allow(unused)]
+#![allow(clippy::needless_pub_self, unused)]
 
 use std::future::Future;
 
diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs
index dd5ca1c9b5b..6c1a9edaa11 100644
--- a/tests/ui/manual_async_fn.rs
+++ b/tests/ui/manual_async_fn.rs
@@ -1,6 +1,6 @@
 //@run-rustfix
 #![warn(clippy::manual_async_fn)]
-#![allow(unused)]
+#![allow(clippy::needless_pub_self, unused)]
 
 use std::future::Future;
 
diff --git a/tests/ui/needless_pub_self.fixed b/tests/ui/needless_pub_self.fixed
new file mode 100644
index 00000000000..672b4c318a8
--- /dev/null
+++ b/tests/ui/needless_pub_self.fixed
@@ -0,0 +1,33 @@
+//@run-rustfix
+//@aux-build:proc_macros.rs:proc-macro
+#![feature(custom_inner_attributes)]
+#![allow(unused)]
+#![warn(clippy::needless_pub_self)]
+#![no_main]
+#![rustfmt::skip] // rustfmt will remove `in`, understandable
+                  // but very annoying for our purposes!
+
+#[macro_use]
+extern crate proc_macros;
+
+ fn a() {}
+ fn b() {}
+
+pub fn c() {}
+mod a {
+    pub(in super) fn d() {}
+    pub(super) fn e() {}
+     fn f() {}
+}
+
+external! {
+    pub(self) fn g() {}
+    pub(in self) fn h() {}
+}
+with_span! {
+    span
+    pub(self) fn i() {}
+    pub(in self) fn j() {}
+}
+
+// not really anything more to test. just a really simple lint overall
diff --git a/tests/ui/needless_pub_self.rs b/tests/ui/needless_pub_self.rs
new file mode 100644
index 00000000000..5ac1edf8e99
--- /dev/null
+++ b/tests/ui/needless_pub_self.rs
@@ -0,0 +1,33 @@
+//@run-rustfix
+//@aux-build:proc_macros.rs:proc-macro
+#![feature(custom_inner_attributes)]
+#![allow(unused)]
+#![warn(clippy::needless_pub_self)]
+#![no_main]
+#![rustfmt::skip] // rustfmt will remove `in`, understandable
+                  // but very annoying for our purposes!
+
+#[macro_use]
+extern crate proc_macros;
+
+pub(self) fn a() {}
+pub(in self) fn b() {}
+
+pub fn c() {}
+mod a {
+    pub(in super) fn d() {}
+    pub(super) fn e() {}
+    pub(self) fn f() {}
+}
+
+external! {
+    pub(self) fn g() {}
+    pub(in self) fn h() {}
+}
+with_span! {
+    span
+    pub(self) fn i() {}
+    pub(in self) fn j() {}
+}
+
+// not really anything more to test. just a really simple lint overall
diff --git a/tests/ui/needless_pub_self.stderr b/tests/ui/needless_pub_self.stderr
new file mode 100644
index 00000000000..3aa2feb5ecd
--- /dev/null
+++ b/tests/ui/needless_pub_self.stderr
@@ -0,0 +1,22 @@
+error: unnecessary `pub(self)`
+  --> $DIR/needless_pub_self.rs:13:1
+   |
+LL | pub(self) fn a() {}
+   | ^^^^^^^^^ help: remove it
+   |
+   = note: `-D clippy::needless-pub-self` implied by `-D warnings`
+
+error: unnecessary `pub(in self)`
+  --> $DIR/needless_pub_self.rs:14:1
+   |
+LL | pub(in self) fn b() {}
+   | ^^^^^^^^^^^^ help: remove it
+
+error: unnecessary `pub(self)`
+  --> $DIR/needless_pub_self.rs:20:5
+   |
+LL |     pub(self) fn f() {}
+   |     ^^^^^^^^^ help: remove it
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/pub_with_shorthand.fixed b/tests/ui/pub_with_shorthand.fixed
new file mode 100644
index 00000000000..a774faa0a67
--- /dev/null
+++ b/tests/ui/pub_with_shorthand.fixed
@@ -0,0 +1,38 @@
+//@run-rustfix
+//@aux-build:proc_macros.rs:proc-macro
+#![feature(custom_inner_attributes)]
+#![allow(clippy::needless_pub_self, unused)]
+#![warn(clippy::pub_with_shorthand)]
+#![no_main]
+#![rustfmt::skip] // rustfmt will remove `in`, understandable
+                  // but very annoying for our purposes!
+
+#[macro_use]
+extern crate proc_macros;
+
+pub(in self) fn a() {}
+pub(in self) fn b() {}
+
+pub fn c() {}
+mod a {
+    pub(in super) fn d() {}
+    pub(in super) fn e() {}
+    pub(in self) fn f() {}
+    pub(in crate) fn k() {}
+    pub(in crate) fn m() {}
+    mod b {
+        pub(in crate::a) fn l() {}
+    }
+}
+
+external! {
+    pub(self) fn g() {}
+    pub(in self) fn h() {}
+}
+with_span! {
+    span
+    pub(self) fn i() {}
+    pub(in self) fn j() {}
+}
+
+// not really anything more to test. just a really simple lint overall
diff --git a/tests/ui/pub_with_shorthand.rs b/tests/ui/pub_with_shorthand.rs
new file mode 100644
index 00000000000..4a4bbc18728
--- /dev/null
+++ b/tests/ui/pub_with_shorthand.rs
@@ -0,0 +1,38 @@
+//@run-rustfix
+//@aux-build:proc_macros.rs:proc-macro
+#![feature(custom_inner_attributes)]
+#![allow(clippy::needless_pub_self, unused)]
+#![warn(clippy::pub_with_shorthand)]
+#![no_main]
+#![rustfmt::skip] // rustfmt will remove `in`, understandable
+                  // but very annoying for our purposes!
+
+#[macro_use]
+extern crate proc_macros;
+
+pub(self) fn a() {}
+pub(in self) fn b() {}
+
+pub fn c() {}
+mod a {
+    pub(in super) fn d() {}
+    pub(super) fn e() {}
+    pub(self) fn f() {}
+    pub(crate) fn k() {}
+    pub(in crate) fn m() {}
+    mod b {
+        pub(in crate::a) fn l() {}
+    }
+}
+
+external! {
+    pub(self) fn g() {}
+    pub(in self) fn h() {}
+}
+with_span! {
+    span
+    pub(self) fn i() {}
+    pub(in self) fn j() {}
+}
+
+// not really anything more to test. just a really simple lint overall
diff --git a/tests/ui/pub_with_shorthand.stderr b/tests/ui/pub_with_shorthand.stderr
new file mode 100644
index 00000000000..323b5a23b24
--- /dev/null
+++ b/tests/ui/pub_with_shorthand.stderr
@@ -0,0 +1,28 @@
+error: usage of `pub` without `in`
+  --> $DIR/pub_with_shorthand.rs:13:1
+   |
+LL | pub(self) fn a() {}
+   | ^^^^^^^^^ help: add it: `pub(in self)`
+   |
+   = note: `-D clippy::pub-with-shorthand` implied by `-D warnings`
+
+error: usage of `pub` without `in`
+  --> $DIR/pub_with_shorthand.rs:19:5
+   |
+LL |     pub(super) fn e() {}
+   |     ^^^^^^^^^^ help: add it: `pub(in super)`
+
+error: usage of `pub` without `in`
+  --> $DIR/pub_with_shorthand.rs:20:5
+   |
+LL |     pub(self) fn f() {}
+   |     ^^^^^^^^^ help: add it: `pub(in self)`
+
+error: usage of `pub` without `in`
+  --> $DIR/pub_with_shorthand.rs:21:5
+   |
+LL |     pub(crate) fn k() {}
+   |     ^^^^^^^^^^ help: add it: `pub(in crate)`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/pub_without_shorthand.fixed b/tests/ui/pub_without_shorthand.fixed
new file mode 100644
index 00000000000..fdb49ac4d90
--- /dev/null
+++ b/tests/ui/pub_without_shorthand.fixed
@@ -0,0 +1,38 @@
+//@run-rustfix
+//@aux-build:proc_macros.rs:proc-macro
+#![feature(custom_inner_attributes)]
+#![allow(clippy::needless_pub_self, unused)]
+#![warn(clippy::pub_without_shorthand)]
+#![no_main]
+#![rustfmt::skip] // rustfmt will remove `in`, understandable
+                  // but very annoying for our purposes!
+
+#[macro_use]
+extern crate proc_macros;
+
+pub(self) fn a() {}
+pub(self) fn b() {}
+
+pub fn c() {}
+mod a {
+    pub(super) fn d() {}
+    pub(super) fn e() {}
+    pub(self) fn f() {}
+    pub(crate) fn k() {}
+    pub(crate) fn m() {}
+    mod b {
+        pub(in crate::a) fn l() {}
+    }
+}
+
+external! {
+    pub(self) fn g() {}
+    pub(in self) fn h() {}
+}
+with_span! {
+    span
+    pub(self) fn i() {}
+    pub(in self) fn j() {}
+}
+
+// not really anything more to test. just a really simple lint overall
diff --git a/tests/ui/pub_without_shorthand.rs b/tests/ui/pub_without_shorthand.rs
new file mode 100644
index 00000000000..1f2ef7ece39
--- /dev/null
+++ b/tests/ui/pub_without_shorthand.rs
@@ -0,0 +1,38 @@
+//@run-rustfix
+//@aux-build:proc_macros.rs:proc-macro
+#![feature(custom_inner_attributes)]
+#![allow(clippy::needless_pub_self, unused)]
+#![warn(clippy::pub_without_shorthand)]
+#![no_main]
+#![rustfmt::skip] // rustfmt will remove `in`, understandable
+                  // but very annoying for our purposes!
+
+#[macro_use]
+extern crate proc_macros;
+
+pub(self) fn a() {}
+pub(in self) fn b() {}
+
+pub fn c() {}
+mod a {
+    pub(in super) fn d() {}
+    pub(super) fn e() {}
+    pub(self) fn f() {}
+    pub(crate) fn k() {}
+    pub(in crate) fn m() {}
+    mod b {
+        pub(in crate::a) fn l() {}
+    }
+}
+
+external! {
+    pub(self) fn g() {}
+    pub(in self) fn h() {}
+}
+with_span! {
+    span
+    pub(self) fn i() {}
+    pub(in self) fn j() {}
+}
+
+// not really anything more to test. just a really simple lint overall
diff --git a/tests/ui/pub_without_shorthand.stderr b/tests/ui/pub_without_shorthand.stderr
new file mode 100644
index 00000000000..a18c9bf8934
--- /dev/null
+++ b/tests/ui/pub_without_shorthand.stderr
@@ -0,0 +1,22 @@
+error: usage of `pub` with `in`
+  --> $DIR/pub_without_shorthand.rs:14:1
+   |
+LL | pub(in self) fn b() {}
+   | ^^^^^^^^^^^^ help: remove it: `pub(self)`
+   |
+   = note: `-D clippy::pub-without-shorthand` implied by `-D warnings`
+
+error: usage of `pub` with `in`
+  --> $DIR/pub_without_shorthand.rs:18:5
+   |
+LL |     pub(in super) fn d() {}
+   |     ^^^^^^^^^^^^^ help: remove it: `pub(super)`
+
+error: usage of `pub` with `in`
+  --> $DIR/pub_without_shorthand.rs:22:5
+   |
+LL |     pub(in crate) fn m() {}
+   |     ^^^^^^^^^^^^^ help: remove it: `pub(crate)`
+
+error: aborting due to 3 previous errors
+