From 7ee4a9a659336b98a5cc76c172cbd0ffcfb3ed88 Mon Sep 17 00:00:00 2001 From: Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> Date: Tue, 16 Aug 2016 14:29:21 +0200 Subject: [PATCH 1/2] lint modules that have the same name as their parent module --- CHANGELOG.md | 1 + README.md | 3 +- clippy_lints/src/lib.rs | 3 ++ clippy_lints/src/module_inception.rs | 47 ++++++++++++++++++++++++++ tests/compile-fail/module_inception.rs | 16 +++++++++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 clippy_lints/src/module_inception.rs create mode 100644 tests/compile-fail/module_inception.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index ffb5ad82f1b..725cdcc10b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -222,6 +222,7 @@ All notable changes to this project will be documented in this file. [`min_max`]: https://github.com/Manishearth/rust-clippy/wiki#min_max [`misrefactored_assign_op`]: https://github.com/Manishearth/rust-clippy/wiki#misrefactored_assign_op [`mixed_case_hex_literals`]: https://github.com/Manishearth/rust-clippy/wiki#mixed_case_hex_literals +[`module_inception`]: https://github.com/Manishearth/rust-clippy/wiki#module_inception [`modulo_one`]: https://github.com/Manishearth/rust-clippy/wiki#modulo_one [`mut_mut`]: https://github.com/Manishearth/rust-clippy/wiki#mut_mut [`mutex_atomic`]: https://github.com/Manishearth/rust-clippy/wiki#mutex_atomic diff --git a/README.md b/README.md index 4e6f864fec3..1da19a71044 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Table of contents: ## Lints -There are 163 lints included in this crate: +There are 164 lints included in this crate: name | default | triggers on ---------------------------------------------------------------------------------------------------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------- @@ -100,6 +100,7 @@ name [min_max](https://github.com/Manishearth/rust-clippy/wiki#min_max) | warn | `min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant [misrefactored_assign_op](https://github.com/Manishearth/rust-clippy/wiki#misrefactored_assign_op) | warn | having a variable on both sides of an assign op [mixed_case_hex_literals](https://github.com/Manishearth/rust-clippy/wiki#mixed_case_hex_literals) | warn | hex literals whose letter digits are not consistently upper- or lowercased +[module_inception](https://github.com/Manishearth/rust-clippy/wiki#module_inception) | warn | modules that have the same name as their parent module [modulo_one](https://github.com/Manishearth/rust-clippy/wiki#modulo_one) | warn | taking a number modulo 1, which always returns 0 [mut_mut](https://github.com/Manishearth/rust-clippy/wiki#mut_mut) | allow | usage of double-mut refs, e.g. `&mut &mut ...` [mutex_atomic](https://github.com/Manishearth/rust-clippy/wiki#mutex_atomic) | warn | using a mutex where an atomic value could be used instead diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 260b5c1ba57..3a5051b9308 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -96,6 +96,7 @@ pub mod methods; pub mod minmax; pub mod misc; pub mod misc_early; +pub mod module_inception; pub mod mut_mut; pub mod mut_reference; pub mod mutex_atomic; @@ -173,6 +174,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_early_lint_pass(box utils::internal_lints::Clippy); reg.register_late_lint_pass(box types::TypePass); reg.register_late_lint_pass(box booleans::NonminimalBool); + reg.register_early_lint_pass(box module_inception::Pass); reg.register_late_lint_pass(box misc::TopLevelRefPass); reg.register_late_lint_pass(box misc::CmpNan); reg.register_late_lint_pass(box eq_op::EqOp); @@ -384,6 +386,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { misc_early::MIXED_CASE_HEX_LITERALS, misc_early::REDUNDANT_CLOSURE_CALL, misc_early::UNNEEDED_FIELD_PATTERN, + module_inception::MODULE_INCEPTION, mut_reference::UNNECESSARY_MUT_PASSED, mutex_atomic::MUTEX_ATOMIC, needless_bool::BOOL_COMPARISON, diff --git a/clippy_lints/src/module_inception.rs b/clippy_lints/src/module_inception.rs new file mode 100644 index 00000000000..8215929291c --- /dev/null +++ b/clippy_lints/src/module_inception.rs @@ -0,0 +1,47 @@ +use rustc::lint::*; +use syntax::ast::*; +use utils::span_lint; + +/// **What it does:** Checks for modules that have the same name as their parent module +/// +/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and again `mod foo { .. }` in `foo.rs` +/// +/// **Known problems:** None. +/// +/// **Example:** +/// ```rust +/// // lib.rs +/// mod foo; +/// // foo.rs +/// mod foo { +/// ... +/// } +/// ``` +declare_lint! { + pub MODULE_INCEPTION, + Warn, + "modules that have the same name as their parent module" +} + +pub struct Pass; + +impl LintPass for Pass { + fn get_lints(&self) -> LintArray { + lint_array![MODULE_INCEPTION] + } +} + +impl EarlyLintPass for Pass { + fn check_item(&mut self, cx: &EarlyContext, item: &Item) { + if let ItemKind::Mod(ref module) = item.node { + for sub_item in &module.items { + if let ItemKind::Mod(_) = sub_item.node { + if item.ident == sub_item.ident { + span_lint(cx, MODULE_INCEPTION, sub_item.span, + "module has the same name as its containing module"); + } + } + } + } + } +} diff --git a/tests/compile-fail/module_inception.rs b/tests/compile-fail/module_inception.rs new file mode 100644 index 00000000000..499daadee69 --- /dev/null +++ b/tests/compile-fail/module_inception.rs @@ -0,0 +1,16 @@ +#![feature(plugin)] +#![plugin(clippy)] +#![deny(module_inception)] + +mod foo { + mod bar { + mod bar { //~ ERROR module has the same name as its containing module + + } + } + mod foo { //~ ERROR module has the same name as its containing module + + } +} + +fn main() {} From b6f320a495d2d144b22c5a5fcfda1488e3d5133b Mon Sep 17 00:00:00 2001 From: Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> Date: Tue, 16 Aug 2016 14:36:48 +0200 Subject: [PATCH 2/2] address nits and improve docs --- clippy_lints/src/module_inception.rs | 5 ++++- tests/compile-fail/module_inception.rs | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/module_inception.rs b/clippy_lints/src/module_inception.rs index 8215929291c..10c8154d100 100644 --- a/clippy_lints/src/module_inception.rs +++ b/clippy_lints/src/module_inception.rs @@ -4,7 +4,10 @@ use utils::span_lint; /// **What it does:** Checks for modules that have the same name as their parent module /// -/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and again `mod foo { .. }` in `foo.rs` +/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and again `mod foo { .. }` in `foo.rs`. +/// The expectation is that items inside the inner `mod foo { .. }` are then available +/// through `foo::x`, but they are only available through `foo::foo::x`. +/// If this is done on purpose, it would be better to choose a more representative module name. /// /// **Known problems:** None. /// diff --git a/tests/compile-fail/module_inception.rs b/tests/compile-fail/module_inception.rs index 499daadee69..88497c9a6a7 100644 --- a/tests/compile-fail/module_inception.rs +++ b/tests/compile-fail/module_inception.rs @@ -5,11 +5,12 @@ mod foo { mod bar { mod bar { //~ ERROR module has the same name as its containing module - + mod foo {} } + mod foo {} } mod foo { //~ ERROR module has the same name as its containing module - + mod bar {} } }