allow disabling module inception on private modules
allow disabling module inception on private modules
This commit is contained in:
parent
4886937212
commit
b303e2053c
@ -643,3 +643,13 @@ The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::u
|
|||||||
* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
|
* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
|
||||||
|
|
||||||
|
|
||||||
|
## `allow-private-module-inception`
|
||||||
|
Whether to allow module inception if it's not public.
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
---
|
||||||
|
**Affected lints:**
|
||||||
|
* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};
|
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};
|
||||||
use clippy_utils::source::is_present_in_source;
|
use clippy_utils::source::is_present_in_source;
|
||||||
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start};
|
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start};
|
||||||
use rustc_hir::{EnumDef, Item, ItemKind, Variant};
|
use rustc_hir::{EnumDef, Item, ItemKind, OwnerId, Variant};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
@ -105,18 +105,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct EnumVariantNames {
|
pub struct EnumVariantNames {
|
||||||
modules: Vec<(Symbol, String)>,
|
modules: Vec<(Symbol, String, OwnerId)>,
|
||||||
threshold: u64,
|
threshold: u64,
|
||||||
avoid_breaking_exported_api: bool,
|
avoid_breaking_exported_api: bool,
|
||||||
|
allow_private_module_inception: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EnumVariantNames {
|
impl EnumVariantNames {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(threshold: u64, avoid_breaking_exported_api: bool) -> Self {
|
pub fn new(threshold: u64, avoid_breaking_exported_api: bool, allow_private_module_inception: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
modules: Vec::new(),
|
modules: Vec::new(),
|
||||||
threshold,
|
threshold,
|
||||||
avoid_breaking_exported_api,
|
avoid_breaking_exported_api,
|
||||||
|
allow_private_module_inception,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,18 +254,19 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
|||||||
let item_name = item.ident.name.as_str();
|
let item_name = item.ident.name.as_str();
|
||||||
let item_camel = to_camel_case(item_name);
|
let item_camel = to_camel_case(item_name);
|
||||||
if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
|
if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
|
||||||
if let Some((mod_name, mod_camel)) = self.modules.last() {
|
if let [.., (mod_name, mod_camel, owner_id)] = &*self.modules {
|
||||||
// constants don't have surrounding modules
|
// constants don't have surrounding modules
|
||||||
if !mod_camel.is_empty() {
|
if !mod_camel.is_empty() {
|
||||||
if mod_name == &item.ident.name {
|
if mod_name == &item.ident.name
|
||||||
if let ItemKind::Mod(..) = item.kind {
|
&& let ItemKind::Mod(..) = item.kind
|
||||||
span_lint(
|
&& (!self.allow_private_module_inception || cx.tcx.visibility(owner_id.def_id).is_public())
|
||||||
cx,
|
{
|
||||||
MODULE_INCEPTION,
|
span_lint(
|
||||||
item.span,
|
cx,
|
||||||
"module has the same name as its containing module",
|
MODULE_INCEPTION,
|
||||||
);
|
item.span,
|
||||||
}
|
"module has the same name as its containing module",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// The `module_name_repetitions` lint should only trigger if the item has the module in its
|
// The `module_name_repetitions` lint should only trigger if the item has the module in its
|
||||||
// name. Having the same name is accepted.
|
// name. Having the same name is accepted.
|
||||||
@ -302,6 +305,6 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
|||||||
check_variant(cx, self.threshold, def, item_name, item.span);
|
check_variant(cx, self.threshold, def, item_name, item.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.modules.push((item.ident.name, item_camel));
|
self.modules.push((item.ident.name, item_camel, item.owner_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -813,10 +813,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
))
|
))
|
||||||
});
|
});
|
||||||
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
|
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
|
||||||
|
let allow_private_module_inception = conf.allow_private_module_inception;
|
||||||
store.register_late_pass(move |_| {
|
store.register_late_pass(move |_| {
|
||||||
Box::new(enum_variants::EnumVariantNames::new(
|
Box::new(enum_variants::EnumVariantNames::new(
|
||||||
enum_variant_name_threshold,
|
enum_variant_name_threshold,
|
||||||
avoid_breaking_exported_api,
|
avoid_breaking_exported_api,
|
||||||
|
allow_private_module_inception,
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments));
|
store.register_early_pass(|| Box::new(tabs_in_doc_comments::TabsInDocComments));
|
||||||
|
@ -514,6 +514,10 @@ pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
|
|||||||
///
|
///
|
||||||
/// The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
|
/// The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
|
||||||
(unnecessary_box_size: u64 = 128),
|
(unnecessary_box_size: u64 = 128),
|
||||||
|
/// Lint: MODULE_INCEPTION.
|
||||||
|
///
|
||||||
|
/// Whether to allow module inception if it's not public.
|
||||||
|
(allow_private_module_inception: bool = false),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search for the configuration file.
|
/// Search for the configuration file.
|
||||||
|
1
tests/ui-toml/module_inception/clippy.toml
Normal file
1
tests/ui-toml/module_inception/clippy.toml
Normal file
@ -0,0 +1 @@
|
|||||||
|
allow-private-module-inception = true
|
34
tests/ui-toml/module_inception/module_inception.rs
Normal file
34
tests/ui-toml/module_inception/module_inception.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#![warn(clippy::module_inception)]
|
||||||
|
|
||||||
|
// Lint
|
||||||
|
pub mod foo2 {
|
||||||
|
pub mod bar2 {
|
||||||
|
pub mod bar2 {
|
||||||
|
pub mod foo2 {}
|
||||||
|
}
|
||||||
|
pub mod foo2 {}
|
||||||
|
}
|
||||||
|
pub mod foo2 {
|
||||||
|
pub mod bar2 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't lint
|
||||||
|
mod foo {
|
||||||
|
pub mod bar {
|
||||||
|
pub mod foo {
|
||||||
|
pub mod bar {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub mod foo {
|
||||||
|
pub mod bar {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No warning. See <https://github.com/rust-lang/rust-clippy/issues/1220>.
|
||||||
|
pub mod bar {
|
||||||
|
#[allow(clippy::module_inception)]
|
||||||
|
pub mod bar {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
20
tests/ui-toml/module_inception/module_inception.stderr
Normal file
20
tests/ui-toml/module_inception/module_inception.stderr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
error: module has the same name as its containing module
|
||||||
|
--> $DIR/module_inception.rs:6:9
|
||||||
|
|
|
||||||
|
LL | / pub mod bar2 {
|
||||||
|
LL | | pub mod foo2 {}
|
||||||
|
LL | | }
|
||||||
|
| |_________^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::module-inception` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: module has the same name as its containing module
|
||||||
|
--> $DIR/module_inception.rs:11:5
|
||||||
|
|
|
||||||
|
LL | / pub mod foo2 {
|
||||||
|
LL | | pub mod bar2 {}
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -3,6 +3,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
|
|||||||
allow-expect-in-tests
|
allow-expect-in-tests
|
||||||
allow-mixed-uninlined-format-args
|
allow-mixed-uninlined-format-args
|
||||||
allow-print-in-tests
|
allow-print-in-tests
|
||||||
|
allow-private-module-inception
|
||||||
allow-unwrap-in-tests
|
allow-unwrap-in-tests
|
||||||
allowed-scripts
|
allowed-scripts
|
||||||
arithmetic-side-effects-allowed
|
arithmetic-side-effects-allowed
|
||||||
@ -64,6 +65,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
|
|||||||
allow-expect-in-tests
|
allow-expect-in-tests
|
||||||
allow-mixed-uninlined-format-args
|
allow-mixed-uninlined-format-args
|
||||||
allow-print-in-tests
|
allow-print-in-tests
|
||||||
|
allow-private-module-inception
|
||||||
allow-unwrap-in-tests
|
allow-unwrap-in-tests
|
||||||
allowed-scripts
|
allowed-scripts
|
||||||
arithmetic-side-effects-allowed
|
arithmetic-side-effects-allowed
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
#![warn(clippy::module_inception)]
|
#![warn(clippy::module_inception)]
|
||||||
|
|
||||||
|
pub mod foo2 {
|
||||||
|
pub mod bar2 {
|
||||||
|
pub mod bar2 {
|
||||||
|
pub mod foo2 {}
|
||||||
|
}
|
||||||
|
pub mod foo2 {}
|
||||||
|
}
|
||||||
|
pub mod foo2 {
|
||||||
|
pub mod bar2 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod foo {
|
mod foo {
|
||||||
mod bar {
|
mod bar {
|
||||||
mod bar {
|
mod bar {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: module has the same name as its containing module
|
error: module has the same name as its containing module
|
||||||
--> $DIR/module_inception.rs:5:9
|
--> $DIR/module_inception.rs:5:9
|
||||||
|
|
|
|
||||||
LL | / mod bar {
|
LL | / pub mod bar2 {
|
||||||
LL | | mod foo {}
|
LL | | pub mod foo2 {}
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_________^
|
| |_________^
|
||||||
|
|
|
|
||||||
@ -11,10 +11,26 @@ LL | | }
|
|||||||
error: module has the same name as its containing module
|
error: module has the same name as its containing module
|
||||||
--> $DIR/module_inception.rs:10:5
|
--> $DIR/module_inception.rs:10:5
|
||||||
|
|
|
|
||||||
|
LL | / pub mod foo2 {
|
||||||
|
LL | | pub mod bar2 {}
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: module has the same name as its containing module
|
||||||
|
--> $DIR/module_inception.rs:17:9
|
||||||
|
|
|
||||||
|
LL | / mod bar {
|
||||||
|
LL | | mod foo {}
|
||||||
|
LL | | }
|
||||||
|
| |_________^
|
||||||
|
|
||||||
|
error: module has the same name as its containing module
|
||||||
|
--> $DIR/module_inception.rs:22:5
|
||||||
|
|
|
||||||
LL | / mod foo {
|
LL | / mod foo {
|
||||||
LL | | mod bar {}
|
LL | | mod bar {}
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user