Skip to content

Commit e986b64

Browse files
committed
Auto merge of #10917 - Centri3:module_inception, r=xFrednet
allow disabling module inception on private modules Fixes #10842 changelog: Enhancement [`module_inception`]: Added `allow-private-module-inception` configuration. [#10917](#10917) <!-- changelog_checked -->
2 parents 9011c4d + b303e20 commit e986b64

File tree

10 files changed

+121
-17
lines changed

10 files changed

+121
-17
lines changed

book/src/lint_configuration.md

+10
Original file line numberDiff line numberDiff line change
@@ -653,3 +653,13 @@ The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::u
653653
* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
654654

655655

656+
## `allow-private-module-inception`
657+
Whether to allow module inception if it's not public.
658+
659+
**Default Value:** `false` (`bool`)
660+
661+
---
662+
**Affected lints:**
663+
* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception)
664+
665+

clippy_lints/src/enum_variants.rs

+17-14
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

+2
Original file line numberDiff line numberDiff line change
@@ -822,10 +822,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
822822
))
823823
});
824824
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
825+
let allow_private_module_inception = conf.allow_private_module_inception;
825826
store.register_late_pass(move |_| {
826827
Box::new(enum_variants::EnumVariantNames::new(
827828
enum_variant_name_threshold,
828829
avoid_breaking_exported_api,
830+
allow_private_module_inception,
829831
))
830832
});
831833
store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments));

clippy_lints/src/utils/conf.rs

+4
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,10 @@ define_Conf! {
518518
///
519519
/// The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
520520
(unnecessary_box_size: u64 = 128),
521+
/// Lint: MODULE_INCEPTION.
522+
///
523+
/// Whether to allow module inception if it's not public.
524+
(allow_private_module_inception: bool = false),
521525
}
522526

523527
/// Search for the configuration file.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
allow-private-module-inception = true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![warn(clippy::module_inception)]
2+
3+
// Lint
4+
pub mod foo2 {
5+
pub mod bar2 {
6+
pub mod bar2 {
7+
pub mod foo2 {}
8+
}
9+
pub mod foo2 {}
10+
}
11+
pub mod foo2 {
12+
pub mod bar2 {}
13+
}
14+
}
15+
16+
// Don't lint
17+
mod foo {
18+
pub mod bar {
19+
pub mod foo {
20+
pub mod bar {}
21+
}
22+
}
23+
pub mod foo {
24+
pub mod bar {}
25+
}
26+
}
27+
28+
// No warning. See <https://github.com/rust-lang/rust-clippy/issues/1220>.
29+
pub mod bar {
30+
#[allow(clippy::module_inception)]
31+
pub mod bar {}
32+
}
33+
34+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: module has the same name as its containing module
2+
--> $DIR/module_inception.rs:6:9
3+
|
4+
LL | / pub mod bar2 {
5+
LL | | pub mod foo2 {}
6+
LL | | }
7+
| |_________^
8+
|
9+
= note: `-D clippy::module-inception` implied by `-D warnings`
10+
11+
error: module has the same name as its containing module
12+
--> $DIR/module_inception.rs:11:5
13+
|
14+
LL | / pub mod foo2 {
15+
LL | | pub mod bar2 {}
16+
LL | | }
17+
| |_____^
18+
19+
error: aborting due to 2 previous errors
20+

tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr

+2
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
@@ -65,6 +66,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
6566
allow-expect-in-tests
6667
allow-mixed-uninlined-format-args
6768
allow-print-in-tests
69+
allow-private-module-inception
6870
allow-unwrap-in-tests
6971
allowed-scripts
7072
arithmetic-side-effects-allowed

tests/ui/module_inception.rs

+12
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

+19-3
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)