Skip to content

Commit 04a9f5e

Browse files
committed
allow disabling module inception on private modules
1 parent bf1e96b commit 04a9f5e

File tree

8 files changed

+59
-37
lines changed

8 files changed

+59
-37
lines changed

clippy_lints/src/enum_variants.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};
44
use clippy_utils::source::is_present_in_source;
55
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start};
6-
use rustc_hir::{EnumDef, Item, ItemKind, Variant};
6+
use rustc_hir::{EnumDef, Item, ItemKind, OwnerId, Variant};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_session::{declare_tool_lint, impl_lint_pass};
99
use rustc_span::source_map::Span;
@@ -105,18 +105,20 @@ declare_clippy_lint! {
105105
}
106106

107107
pub struct EnumVariantNames {
108-
modules: Vec<(Symbol, String)>,
108+
modules: Vec<(Symbol, String, OwnerId)>,
109109
threshold: u64,
110110
avoid_breaking_exported_api: bool,
111+
allow_private_module_inception: bool,
111112
}
112113

113114
impl EnumVariantNames {
114115
#[must_use]
115-
pub fn new(threshold: u64, avoid_breaking_exported_api: bool) -> Self {
116+
pub fn new(threshold: u64, avoid_breaking_exported_api: bool, allow_private_module_inception: bool) -> Self {
116117
Self {
117118
modules: Vec::new(),
118119
threshold,
119120
avoid_breaking_exported_api,
121+
allow_private_module_inception,
120122
}
121123
}
122124
}
@@ -252,18 +254,19 @@ impl LateLintPass<'_> for EnumVariantNames {
252254
let item_name = item.ident.name.as_str();
253255
let item_camel = to_camel_case(item_name);
254256
if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
255-
if let Some((mod_name, mod_camel)) = self.modules.last() {
257+
if let [.., (mod_name, mod_camel, owner_id)] = &*self.modules {
256258
// constants don't have surrounding modules
257259
if !mod_camel.is_empty() {
258-
if mod_name == &item.ident.name {
259-
if let ItemKind::Mod(..) = item.kind {
260-
span_lint(
261-
cx,
262-
MODULE_INCEPTION,
263-
item.span,
264-
"module has the same name as its containing module",
265-
);
266-
}
260+
if mod_name == &item.ident.name
261+
&& let ItemKind::Mod(..) = item.kind
262+
&& (!self.allow_private_module_inception || cx.tcx.visibility(owner_id.def_id).is_public())
263+
{
264+
span_lint(
265+
cx,
266+
MODULE_INCEPTION,
267+
item.span,
268+
"module has the same name as its containing module",
269+
);
267270
}
268271
// The `module_name_repetitions` lint should only trigger if the item has the module in its
269272
// name. Having the same name is accepted.
@@ -302,6 +305,6 @@ impl LateLintPass<'_> for EnumVariantNames {
302305
check_variant(cx, self.threshold, def, item_name, item.span);
303306
}
304307
}
305-
self.modules.push((item.ident.name, item_camel));
308+
self.modules.push((item.ident.name, item_camel, item.owner_id));
306309
}
307310
}

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,10 +813,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
813813
))
814814
});
815815
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
816+
let allow_private_module_inception = conf.allow_private_module_inception;
816817
store.register_late_pass(move |_| {
817818
Box::new(enum_variants::EnumVariantNames::new(
818819
enum_variant_name_threshold,
819820
avoid_breaking_exported_api,
821+
allow_private_module_inception,
820822
))
821823
});
822824
store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments));

clippy_lints/src/utils/conf.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,10 @@ define_Conf! {
514514
///
515515
/// The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
516516
(unnecessary_box_size: u64 = 128),
517+
/// Lint: MODULE_INCEPTION.
518+
///
519+
/// Whether to allow module inception if it's not public.
520+
(allow_private_module_inception: bool = false),
517521
}
518522

519523
/// Search for the configuration file.

tests/ui-toml/module_inception/module_inception.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ pub mod foo2 {
1616
// Don't lint
1717
mod foo {
1818
pub mod bar {
19-
pub mod bar {
20-
pub mod foo {}
19+
pub mod foo {
20+
pub mod bar {}
2121
}
22-
pub mod foo {}
2322
}
2423
pub mod foo {
2524
pub mod bar {}

tests/ui-toml/module_inception/module_inception.stderr

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,5 @@ LL | | pub mod bar2 {}
1616
LL | | }
1717
| |_____^
1818

19-
error: module has the same name as its containing module
20-
--> $DIR/module_inception.rs:19:9
21-
|
22-
LL | / pub mod bar {
23-
LL | | pub mod foo {}
24-
LL | | }
25-
| |_________^
26-
27-
error: module has the same name as its containing module
28-
--> $DIR/module_inception.rs:24:5
29-
|
30-
LL | / pub mod foo {
31-
LL | | pub mod bar {}
32-
LL | | }
33-
| |_____^
34-
35-
error: aborting due to 4 previous errors
19+
error: aborting due to 2 previous errors
3620

tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
33
allow-expect-in-tests
44
allow-mixed-uninlined-format-args
55
allow-print-in-tests
6+
allow-private-module-inception
67
allow-unwrap-in-tests
78
allowed-scripts
89
arithmetic-side-effects-allowed
@@ -64,6 +65,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
6465
allow-expect-in-tests
6566
allow-mixed-uninlined-format-args
6667
allow-print-in-tests
68+
allow-private-module-inception
6769
allow-unwrap-in-tests
6870
allowed-scripts
6971
arithmetic-side-effects-allowed

tests/ui/module_inception.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
#![warn(clippy::module_inception)]
22

3+
pub mod foo2 {
4+
pub mod bar2 {
5+
pub mod bar2 {
6+
pub mod foo2 {}
7+
}
8+
pub mod foo2 {}
9+
}
10+
pub mod foo2 {
11+
pub mod bar2 {}
12+
}
13+
}
14+
315
mod foo {
416
mod bar {
517
mod bar {

tests/ui/module_inception.stderr

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: module has the same name as its containing module
22
--> $DIR/module_inception.rs:5:9
33
|
4-
LL | / mod bar {
5-
LL | | mod foo {}
4+
LL | / pub mod bar2 {
5+
LL | | pub mod foo2 {}
66
LL | | }
77
| |_________^
88
|
@@ -11,10 +11,26 @@ LL | | }
1111
error: module has the same name as its containing module
1212
--> $DIR/module_inception.rs:10:5
1313
|
14+
LL | / pub mod foo2 {
15+
LL | | pub mod bar2 {}
16+
LL | | }
17+
| |_____^
18+
19+
error: module has the same name as its containing module
20+
--> $DIR/module_inception.rs:17:9
21+
|
22+
LL | / mod bar {
23+
LL | | mod foo {}
24+
LL | | }
25+
| |_________^
26+
27+
error: module has the same name as its containing module
28+
--> $DIR/module_inception.rs:22:5
29+
|
1430
LL | / mod foo {
1531
LL | | mod bar {}
1632
LL | | }
1733
| |_____^
1834

19-
error: aborting due to 2 previous errors
35+
error: aborting due to 4 previous errors
2036

0 commit comments

Comments
 (0)