Skip to content

Commit d3989ee

Browse files
committed
Auto merge of #5319 - 1tgr:master, r=flip1995
Lint for `pub(crate)` items that are not crate visible due to the visibility of the module that contains them changelog: Add `redundant_pub_crate` lint Closes #5274.
2 parents 1ff81c1 + 870b9e8 commit d3989ee

13 files changed

+458
-21
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,7 @@ Released 2018-09-13
14391439
[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
14401440
[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
14411441
[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching
1442+
[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate
14421443
[`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
14431444
[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
14441445
[`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
77

8-
[There are 361 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
8+
[There are 362 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
99

1010
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1111

clippy_lints/src/lib.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ pub mod ranges;
285285
pub mod redundant_clone;
286286
pub mod redundant_field_names;
287287
pub mod redundant_pattern_matching;
288+
pub mod redundant_pub_crate;
288289
pub mod redundant_static_lifetimes;
289290
pub mod reference;
290291
pub mod regex;
@@ -323,7 +324,7 @@ pub mod zero_div_zero;
323324
pub use crate::utils::conf::Conf;
324325

325326
mod reexport {
326-
crate use rustc_ast::ast::Name;
327+
pub use rustc_ast::ast::Name;
327328
}
328329

329330
/// Register all pre expansion lints
@@ -745,6 +746,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
745746
&redundant_clone::REDUNDANT_CLONE,
746747
&redundant_field_names::REDUNDANT_FIELD_NAMES,
747748
&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING,
749+
&redundant_pub_crate::REDUNDANT_PUB_CRATE,
748750
&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
749751
&reference::DEREF_ADDROF,
750752
&reference::REF_IN_DEREF,
@@ -1021,6 +1023,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10211023
store.register_late_pass(|| box wildcard_imports::WildcardImports);
10221024
store.register_early_pass(|| box macro_use::MacroUseImports);
10231025
store.register_late_pass(|| box verbose_file_reads::VerboseFileReads);
1026+
store.register_late_pass(|| box redundant_pub_crate::RedundantPubCrate::default());
10241027

10251028
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
10261029
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
@@ -1322,6 +1325,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
13221325
LintId::of(&redundant_clone::REDUNDANT_CLONE),
13231326
LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
13241327
LintId::of(&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING),
1328+
LintId::of(&redundant_pub_crate::REDUNDANT_PUB_CRATE),
13251329
LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
13261330
LintId::of(&reference::DEREF_ADDROF),
13271331
LintId::of(&reference::REF_IN_DEREF),
@@ -1463,6 +1467,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
14631467
LintId::of(&question_mark::QUESTION_MARK),
14641468
LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
14651469
LintId::of(&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING),
1470+
LintId::of(&redundant_pub_crate::REDUNDANT_PUB_CRATE),
14661471
LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
14671472
LintId::of(&regex::REGEX_MACRO),
14681473
LintId::of(&regex::TRIVIAL_REGEX),
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use crate::utils::span_lint_and_then;
2+
use rustc_errors::Applicability;
3+
use rustc_hir::{Item, ItemKind, VisibilityKind};
4+
use rustc_lint::{LateContext, LateLintPass};
5+
use rustc_session::{declare_tool_lint, impl_lint_pass};
6+
7+
declare_clippy_lint! {
8+
/// **What it does:** Checks for items declared `pub(crate)` that are not crate visible because they
9+
/// are inside a private module.
10+
///
11+
/// **Why is this bad?** Writing `pub(crate)` is misleading when it's redundant due to the parent
12+
/// module's visibility.
13+
///
14+
/// **Known problems:** None.
15+
///
16+
/// **Example:**
17+
///
18+
/// ```rust
19+
/// mod internal {
20+
/// pub(crate) fn internal_fn() { }
21+
/// }
22+
/// ```
23+
/// This function is not visible outside the module and it can be declared with `pub` or
24+
/// private visibility
25+
/// ```rust
26+
/// mod internal {
27+
/// pub fn internal_fn() { }
28+
/// }
29+
/// ```
30+
pub REDUNDANT_PUB_CRATE,
31+
style,
32+
"Using `pub(crate)` visibility on items that are not crate visible due to the visibility of the module that contains them."
33+
}
34+
35+
#[derive(Default)]
36+
pub struct RedundantPubCrate {
37+
is_exported: Vec<bool>,
38+
}
39+
40+
impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);
41+
42+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPubCrate {
43+
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'tcx>) {
44+
if let VisibilityKind::Crate { .. } = item.vis.node {
45+
if !cx.access_levels.is_exported(item.hir_id) {
46+
if let Some(false) = self.is_exported.last() {
47+
let span = item.span.with_hi(item.ident.span.hi());
48+
span_lint_and_then(
49+
cx,
50+
REDUNDANT_PUB_CRATE,
51+
span,
52+
&format!("pub(crate) {} inside private module", item.kind.descr()),
53+
|db| {
54+
db.span_suggestion(
55+
item.vis.span,
56+
"consider using",
57+
"pub".to_string(),
58+
Applicability::MachineApplicable,
59+
);
60+
},
61+
)
62+
}
63+
}
64+
}
65+
66+
if let ItemKind::Mod { .. } = item.kind {
67+
self.is_exported.push(cx.access_levels.is_exported(item.hir_id));
68+
}
69+
}
70+
71+
fn check_item_post(&mut self, _cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'tcx>) {
72+
if let ItemKind::Mod { .. } = item.kind {
73+
self.is_exported.pop().expect("unbalanced check_item/check_item_post");
74+
}
75+
}
76+
}

clippy_lints/src/utils/conf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ macro_rules! define_Conf {
8080
$(
8181
mod $config {
8282
use serde::Deserialize;
83-
crate fn deserialize<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<$Ty, D::Error> {
83+
pub fn deserialize<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<$Ty, D::Error> {
8484
use super::super::{ERRORS, Error};
8585
Ok(
8686
<$Ty>::deserialize(deserializer).unwrap_or_else(|e| {

clippy_lints/src/utils/numeric_literal.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_ast::ast::{Lit, LitFloatType, LitIntType, LitKind};
22

33
#[derive(Debug, PartialEq)]
4-
pub(crate) enum Radix {
4+
pub enum Radix {
55
Binary,
66
Octal,
77
Decimal,
@@ -26,7 +26,7 @@ pub fn format(lit: &str, type_suffix: Option<&str>, float: bool) -> String {
2626
}
2727

2828
#[derive(Debug)]
29-
pub(crate) struct NumericLiteral<'a> {
29+
pub struct NumericLiteral<'a> {
3030
/// Which radix the literal was represented in.
3131
pub radix: Radix,
3232
/// The radix prefix, if present.

src/lintlist/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub use lint::Lint;
66
pub use lint::LINT_LEVELS;
77

88
// begin lint list, do not remove this comment, it’s used in `update_lints`
9-
pub const ALL_LINTS: [Lint; 361] = [
9+
pub const ALL_LINTS: [Lint; 362] = [
1010
Lint {
1111
name: "absurd_extreme_comparisons",
1212
group: "correctness",
@@ -1764,6 +1764,13 @@ pub const ALL_LINTS: [Lint; 361] = [
17641764
deprecation: None,
17651765
module: "redundant_pattern_matching",
17661766
},
1767+
Lint {
1768+
name: "redundant_pub_crate",
1769+
group: "style",
1770+
desc: "Using `pub(crate)` visibility on items that are not crate visible due to the visibility of the module that contains them.",
1771+
deprecation: None,
1772+
module: "redundant_pub_crate",
1773+
},
17671774
Lint {
17681775
name: "redundant_static_lifetimes",
17691776
group: "style",

tests/ui/redundant_pub_crate.fixed

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
#![warn(clippy::redundant_pub_crate)]
4+
5+
mod m1 {
6+
fn f() {}
7+
pub fn g() {} // private due to m1
8+
pub fn h() {}
9+
10+
mod m1_1 {
11+
fn f() {}
12+
pub fn g() {} // private due to m1_1 and m1
13+
pub fn h() {}
14+
}
15+
16+
pub mod m1_2 {
17+
// ^ private due to m1
18+
fn f() {}
19+
pub fn g() {} // private due to m1_2 and m1
20+
pub fn h() {}
21+
}
22+
23+
pub mod m1_3 {
24+
fn f() {}
25+
pub fn g() {} // private due to m1
26+
pub fn h() {}
27+
}
28+
}
29+
30+
pub(crate) mod m2 {
31+
fn f() {}
32+
pub fn g() {} // already crate visible due to m2
33+
pub fn h() {}
34+
35+
mod m2_1 {
36+
fn f() {}
37+
pub fn g() {} // private due to m2_1
38+
pub fn h() {}
39+
}
40+
41+
pub mod m2_2 {
42+
// ^ already crate visible due to m2
43+
fn f() {}
44+
pub fn g() {} // already crate visible due to m2_2 and m2
45+
pub fn h() {}
46+
}
47+
48+
pub mod m2_3 {
49+
fn f() {}
50+
pub fn g() {} // already crate visible due to m2
51+
pub fn h() {}
52+
}
53+
}
54+
55+
pub mod m3 {
56+
fn f() {}
57+
pub(crate) fn g() {} // ok: m3 is exported
58+
pub fn h() {}
59+
60+
mod m3_1 {
61+
fn f() {}
62+
pub fn g() {} // private due to m3_1
63+
pub fn h() {}
64+
}
65+
66+
pub(crate) mod m3_2 {
67+
// ^ ok
68+
fn f() {}
69+
pub fn g() {} // already crate visible due to m3_2
70+
pub fn h() {}
71+
}
72+
73+
pub mod m3_3 {
74+
fn f() {}
75+
pub(crate) fn g() {} // ok: m3 and m3_3 are exported
76+
pub fn h() {}
77+
}
78+
}
79+
80+
mod m4 {
81+
fn f() {}
82+
pub fn g() {} // private: not re-exported by `pub use m4::*`
83+
pub fn h() {}
84+
85+
mod m4_1 {
86+
fn f() {}
87+
pub fn g() {} // private due to m4_1
88+
pub fn h() {}
89+
}
90+
91+
pub mod m4_2 {
92+
// ^ private: not re-exported by `pub use m4::*`
93+
fn f() {}
94+
pub fn g() {} // private due to m4_2
95+
pub fn h() {}
96+
}
97+
98+
pub mod m4_3 {
99+
fn f() {}
100+
pub(crate) fn g() {} // ok: m4_3 is re-exported by `pub use m4::*`
101+
pub fn h() {}
102+
}
103+
}
104+
105+
pub use m4::*;
106+
107+
fn main() {}

0 commit comments

Comments
 (0)