Skip to content

Commit 0e5a537

Browse files
committed
new lints for visibility
1 parent ef90412 commit 0e5a537

15 files changed

+427
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5020,6 +5020,7 @@ Released 2018-09-13
50205020
[`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take
50215021
[`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals
50225022
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
5023+
[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pub_self
50235024
[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
50245025
[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
50255026
[`needless_raw_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string
@@ -5094,6 +5095,8 @@ Released 2018-09-13
50945095
[`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast
50955096
[`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names
50965097
[`pub_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_use
5098+
[`pub_with_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_with_shorthand
5099+
[`pub_without_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_without_shorthand
50975100
[`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark
50985101
[`question_mark_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark_used
50995102
[`range_minus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_minus_one

clippy_lints/src/declared_lints.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,9 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
664664
crate::useless_conversion::USELESS_CONVERSION_INFO,
665665
crate::vec::USELESS_VEC_INFO,
666666
crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO,
667+
crate::visibility::NEEDLESS_PUB_SELF_INFO,
668+
crate::visibility::PUB_WITHOUT_SHORTHAND_INFO,
669+
crate::visibility::PUB_WITH_SHORTHAND_INFO,
667670
crate::wildcard_imports::ENUM_GLOB_USE_INFO,
668671
crate::wildcard_imports::WILDCARD_IMPORTS_INFO,
669672
crate::write::PRINTLN_EMPTY_STRING_INFO,

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ mod use_self;
337337
mod useless_conversion;
338338
mod vec;
339339
mod vec_init_then_push;
340+
mod visibility;
340341
mod wildcard_imports;
341342
mod write;
342343
mod zero_div_zero;
@@ -1057,6 +1058,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10571058
needless_raw_string_hashes_allow_one,
10581059
})
10591060
});
1061+
store.register_early_pass(|| Box::new(visibility::Visibility));
10601062
// add lints here, do not remove this comment, it's used in `new_lint`
10611063
}
10621064

clippy_lints/src/visibility.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_opt};
2+
use rustc_ast::ast::{Item, VisibilityKind};
3+
use rustc_errors::Applicability;
4+
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
5+
use rustc_middle::lint::in_external_macro;
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
use rustc_span::{symbol::kw, Span};
8+
9+
declare_clippy_lint! {
10+
/// ### What it does
11+
/// Checks for usage of `pub(self)` and `pub(in self)`.
12+
///
13+
/// ### Why is this bad?
14+
/// It's unnecessary, omitting the `pub` entirely will give the same results.
15+
///
16+
/// ### Example
17+
/// ```rust
18+
/// pub(self) type OptBox<T> = Option<Box<T>>;
19+
/// ```
20+
/// Use instead:
21+
/// ```rust
22+
/// type OptBox<T> = Option<Box<T>>;
23+
/// ```
24+
#[clippy::version = "1.72.0"]
25+
pub NEEDLESS_PUB_SELF,
26+
complexity,
27+
"checks for usage of `pub(self)` and `pub(in self)`."
28+
}
29+
declare_clippy_lint! {
30+
/// ### What it does
31+
/// Checks for missing usage of the `pub(in <loc>)` shorthand.
32+
///
33+
/// ### Why is this bad?
34+
/// Consistency. Use it or don't, just be consistent about it.
35+
///
36+
/// ### Example
37+
/// ```rust
38+
/// pub(super) type OptBox<T> = Option<Box<T>>;
39+
/// ```
40+
/// Use instead:
41+
/// ```rust
42+
/// pub(in super) type OptBox<T> = Option<Box<T>>;
43+
/// ```
44+
#[clippy::version = "1.72.0"]
45+
pub PUB_WITH_SHORTHAND,
46+
restriction,
47+
"disallows usage of the `pub(<loc>)`, suggesting use of the `in` shorthand"
48+
}
49+
declare_clippy_lint! {
50+
/// ### What it does
51+
/// Checks for usage of the `pub(in <loc>)` shorthand.
52+
///
53+
/// Note: As you cannot write a module's path in `pub(<loc>)`, this will only trigger on
54+
/// `pub(super)` and the like.
55+
///
56+
/// ### Why is this bad?
57+
/// Consistency. Use it or don't, just be consistent about it.
58+
///
59+
/// ### Example
60+
/// ```rust
61+
/// pub(in super) type OptBox<T> = Option<Box<T>>;
62+
/// ```
63+
/// Use instead:
64+
/// ```rust
65+
/// pub(super) type OptBox<T> = Option<Box<T>>;
66+
/// ```
67+
#[clippy::version = "1.72.0"]
68+
pub PUB_WITHOUT_SHORTHAND,
69+
restriction,
70+
"disallows usage of the `pub(in <loc>)` shorthand wherever possible"
71+
}
72+
declare_lint_pass!(Visibility => [NEEDLESS_PUB_SELF, PUB_WITH_SHORTHAND, PUB_WITHOUT_SHORTHAND]);
73+
74+
impl EarlyLintPass for Visibility {
75+
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
76+
if !in_external_macro(cx.sess(), item.span)
77+
&& let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind
78+
{
79+
if **path == kw::SelfLower && let Some(false) = is_from_proc_macro(cx, item.vis.span) {
80+
span_lint_and_sugg(
81+
cx,
82+
NEEDLESS_PUB_SELF,
83+
item.vis.span,
84+
&format!("unnecessary `pub({}self)`", if *shorthand { "" } else { "in " }),
85+
"remove it",
86+
String::new(),
87+
Applicability::MachineApplicable,
88+
);
89+
}
90+
91+
if (**path == kw::Super || **path == kw::SelfLower || **path == kw::Crate)
92+
&& !*shorthand
93+
&& let [.., last] = &*path.segments
94+
&& let Some(false) = is_from_proc_macro(cx, item.vis.span)
95+
{
96+
span_lint_and_sugg(
97+
cx,
98+
PUB_WITHOUT_SHORTHAND,
99+
item.vis.span,
100+
"usage of `pub` with `in`",
101+
"remove it",
102+
format!("pub({})", last.ident),
103+
Applicability::MachineApplicable,
104+
);
105+
}
106+
107+
if *shorthand
108+
&& let [.., last] = &*path.segments
109+
&& let Some(false) = is_from_proc_macro(cx, item.vis.span)
110+
{
111+
span_lint_and_sugg(
112+
cx,
113+
PUB_WITH_SHORTHAND,
114+
item.vis.span,
115+
"usage of `pub` without `in`",
116+
"add it",
117+
format!("pub(in {})", last.ident),
118+
Applicability::MachineApplicable,
119+
);
120+
}
121+
}
122+
}
123+
}
124+
125+
fn is_from_proc_macro(cx: &EarlyContext<'_>, span: Span) -> Option<bool> {
126+
snippet_opt(cx, span).map(|s| !s.starts_with("pub"))
127+
}

tests/ui/manual_async_fn.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@run-rustfix
22
#![warn(clippy::manual_async_fn)]
3-
#![allow(unused)]
3+
#![allow(clippy::needless_pub_self, unused)]
44

55
use std::future::Future;
66

tests/ui/manual_async_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@run-rustfix
22
#![warn(clippy::manual_async_fn)]
3-
#![allow(unused)]
3+
#![allow(clippy::needless_pub_self, unused)]
44

55
use std::future::Future;
66

tests/ui/needless_pub_self.fixed

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//@run-rustfix
2+
//@aux-build:proc_macros.rs
3+
#![feature(custom_inner_attributes)]
4+
#![allow(unused)]
5+
#![warn(clippy::needless_pub_self)]
6+
#![no_main]
7+
#![rustfmt::skip] // rustfmt will remove `in`, understandable
8+
// but very annoying for our purposes!
9+
10+
#[macro_use]
11+
extern crate proc_macros;
12+
13+
fn a() {}
14+
fn b() {}
15+
16+
pub fn c() {}
17+
mod a {
18+
pub(in super) fn d() {}
19+
pub(super) fn e() {}
20+
fn f() {}
21+
}
22+
23+
external! {
24+
pub(self) fn g() {}
25+
pub(in self) fn h() {}
26+
}
27+
with_span! {
28+
span
29+
pub(self) fn i() {}
30+
pub(in self) fn j() {}
31+
}
32+
33+
// not really anything more to test. just a really simple lint overall

tests/ui/needless_pub_self.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//@run-rustfix
2+
//@aux-build:proc_macros.rs
3+
#![feature(custom_inner_attributes)]
4+
#![allow(unused)]
5+
#![warn(clippy::needless_pub_self)]
6+
#![no_main]
7+
#![rustfmt::skip] // rustfmt will remove `in`, understandable
8+
// but very annoying for our purposes!
9+
10+
#[macro_use]
11+
extern crate proc_macros;
12+
13+
pub(self) fn a() {}
14+
pub(in self) fn b() {}
15+
16+
pub fn c() {}
17+
mod a {
18+
pub(in super) fn d() {}
19+
pub(super) fn e() {}
20+
pub(self) fn f() {}
21+
}
22+
23+
external! {
24+
pub(self) fn g() {}
25+
pub(in self) fn h() {}
26+
}
27+
with_span! {
28+
span
29+
pub(self) fn i() {}
30+
pub(in self) fn j() {}
31+
}
32+
33+
// not really anything more to test. just a really simple lint overall

tests/ui/needless_pub_self.stderr

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error: unnecessary `pub(self)`
2+
--> $DIR/needless_pub_self.rs:13:1
3+
|
4+
LL | pub(self) fn a() {}
5+
| ^^^^^^^^^ help: remove it
6+
|
7+
= note: `-D clippy::needless-pub-self` implied by `-D warnings`
8+
9+
error: unnecessary `pub(in self)`
10+
--> $DIR/needless_pub_self.rs:14:1
11+
|
12+
LL | pub(in self) fn b() {}
13+
| ^^^^^^^^^^^^ help: remove it
14+
15+
error: unnecessary `pub(self)`
16+
--> $DIR/needless_pub_self.rs:20:5
17+
|
18+
LL | pub(self) fn f() {}
19+
| ^^^^^^^^^ help: remove it
20+
21+
error: aborting due to 3 previous errors
22+

tests/ui/pub_with_shorthand.fixed

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//@run-rustfix
2+
//@aux-build:proc_macros.rs
3+
#![feature(custom_inner_attributes)]
4+
#![allow(clippy::needless_pub_self, unused)]
5+
#![warn(clippy::pub_with_shorthand)]
6+
#![no_main]
7+
#![rustfmt::skip] // rustfmt will remove `in`, understandable
8+
// but very annoying for our purposes!
9+
10+
#[macro_use]
11+
extern crate proc_macros;
12+
13+
pub(in self) fn a() {}
14+
pub(in self) fn b() {}
15+
16+
pub fn c() {}
17+
mod a {
18+
pub(in super) fn d() {}
19+
pub(in super) fn e() {}
20+
pub(in self) fn f() {}
21+
pub(in crate) fn k() {}
22+
pub(in crate) fn m() {}
23+
mod b {
24+
pub(in crate::a) fn l() {}
25+
}
26+
}
27+
28+
external! {
29+
pub(self) fn g() {}
30+
pub(in self) fn h() {}
31+
}
32+
with_span! {
33+
span
34+
pub(self) fn i() {}
35+
pub(in self) fn j() {}
36+
}
37+
38+
// not really anything more to test. just a really simple lint overall

tests/ui/pub_with_shorthand.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//@run-rustfix
2+
//@aux-build:proc_macros.rs
3+
#![feature(custom_inner_attributes)]
4+
#![allow(clippy::needless_pub_self, unused)]
5+
#![warn(clippy::pub_with_shorthand)]
6+
#![no_main]
7+
#![rustfmt::skip] // rustfmt will remove `in`, understandable
8+
// but very annoying for our purposes!
9+
10+
#[macro_use]
11+
extern crate proc_macros;
12+
13+
pub(self) fn a() {}
14+
pub(in self) fn b() {}
15+
16+
pub fn c() {}
17+
mod a {
18+
pub(in super) fn d() {}
19+
pub(super) fn e() {}
20+
pub(self) fn f() {}
21+
pub(crate) fn k() {}
22+
pub(in crate) fn m() {}
23+
mod b {
24+
pub(in crate::a) fn l() {}
25+
}
26+
}
27+
28+
external! {
29+
pub(self) fn g() {}
30+
pub(in self) fn h() {}
31+
}
32+
with_span! {
33+
span
34+
pub(self) fn i() {}
35+
pub(in self) fn j() {}
36+
}
37+
38+
// not really anything more to test. just a really simple lint overall

tests/ui/pub_with_shorthand.stderr

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error: usage of `pub` without `in`
2+
--> $DIR/pub_with_shorthand.rs:13:1
3+
|
4+
LL | pub(self) fn a() {}
5+
| ^^^^^^^^^ help: add it: `pub(in self)`
6+
|
7+
= note: `-D clippy::pub-with-shorthand` implied by `-D warnings`
8+
9+
error: usage of `pub` without `in`
10+
--> $DIR/pub_with_shorthand.rs:19:5
11+
|
12+
LL | pub(super) fn e() {}
13+
| ^^^^^^^^^^ help: add it: `pub(in super)`
14+
15+
error: usage of `pub` without `in`
16+
--> $DIR/pub_with_shorthand.rs:20:5
17+
|
18+
LL | pub(self) fn f() {}
19+
| ^^^^^^^^^ help: add it: `pub(in self)`
20+
21+
error: usage of `pub` without `in`
22+
--> $DIR/pub_with_shorthand.rs:21:5
23+
|
24+
LL | pub(crate) fn k() {}
25+
| ^^^^^^^^^^ help: add it: `pub(in crate)`
26+
27+
error: aborting due to 4 previous errors
28+

0 commit comments

Comments
 (0)