-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add module_style lint to restriction
Add tests for disallowed_mod in ui-cargo test section Use correct algorithm to determine if mod.rs is missing Move to two lints and remove config option Switch lint names so they read "warn on ..." Emit the same help info for self_named_mod_file warnings Bail when both lints are Allow Reword help message for both module_style lints
- Loading branch information
Showing
23 changed files
with
288 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
use std::{ | ||
ffi::OsString, | ||
path::{Component, Path}, | ||
}; | ||
|
||
use rustc_ast::ast; | ||
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; | ||
use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext}; | ||
use rustc_session::{declare_tool_lint, impl_lint_pass}; | ||
use rustc_span::{FileName, RealFileName, SourceFile, Span, SyntaxContext}; | ||
|
||
declare_clippy_lint! { | ||
/// ### What it does | ||
/// Checks that module layout uses only self named module files, bans mod.rs files. | ||
/// | ||
/// ### Why is this bad? | ||
/// Having multiple module layout styles in a project can be confusing. | ||
/// | ||
/// ### Example | ||
/// ```text | ||
/// src/ | ||
/// stuff/ | ||
/// stuff_files.rs | ||
/// mod.rs | ||
/// lib.rs | ||
/// ``` | ||
/// Use instead: | ||
/// ```text | ||
/// src/ | ||
/// stuff/ | ||
/// stuff_files.rs | ||
/// stuff.rs | ||
/// lib.rs | ||
/// ``` | ||
pub MOD_MODULE_FILES, | ||
restriction, | ||
"checks that module layout is consistent" | ||
} | ||
|
||
declare_clippy_lint! { | ||
/// ### What it does | ||
/// Checks that module layout uses only mod.rs files. | ||
/// | ||
/// ### Why is this bad? | ||
/// Having multiple module layout styles in a project can be confusing. | ||
/// | ||
/// ### Example | ||
/// ```text | ||
/// src/ | ||
/// stuff/ | ||
/// stuff_files.rs | ||
/// stuff.rs | ||
/// lib.rs | ||
/// ``` | ||
/// Use instead: | ||
/// ```text | ||
/// src/ | ||
/// stuff/ | ||
/// stuff_files.rs | ||
/// mod.rs | ||
/// lib.rs | ||
/// ``` | ||
pub SELF_NAMED_MODULE_FILES, | ||
restriction, | ||
"checks that module layout is consistent" | ||
} | ||
|
||
pub struct ModStyle; | ||
|
||
impl_lint_pass!(ModStyle => [MOD_MODULE_FILES, SELF_NAMED_MODULE_FILES]); | ||
|
||
impl EarlyLintPass for ModStyle { | ||
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { | ||
if cx.builder.lint_level(MOD_MODULE_FILES).0 == Level::Allow | ||
&& cx.builder.lint_level(SELF_NAMED_MODULE_FILES).0 == Level::Allow | ||
{ | ||
return; | ||
} | ||
|
||
let files = cx.sess.source_map().files(); | ||
|
||
let trim_to_src = if let RealFileName::LocalPath(p) = &cx.sess.working_dir { | ||
p.to_string_lossy() | ||
} else { | ||
return; | ||
}; | ||
|
||
let mut segments = FxHashSet::default(); | ||
let mut mod_folders = FxHashSet::default(); | ||
let mut file_map = FxHashMap::default(); | ||
for file in files.iter() { | ||
match &file.name { | ||
FileName::Real(RealFileName::LocalPath(lp)) | ||
if lp.to_string_lossy().starts_with(trim_to_src.as_ref()) => | ||
{ | ||
let p = lp.to_string_lossy(); | ||
let path = Path::new(p.trim_start_matches(trim_to_src.as_ref())); | ||
if let Some(stem) = path.file_stem() { | ||
file_map.insert(stem.to_os_string(), (file, path.to_owned())); | ||
} | ||
check_mod_file_exists(path, &mut segments, &mut mod_folders); | ||
check_self_named_mod_exists(cx, path, file); | ||
} | ||
_ => {}, | ||
} | ||
} | ||
|
||
for folder in &segments { | ||
if !mod_folders.contains(folder) { | ||
if let Some((file, path)) = file_map.get(folder) { | ||
let mut correct = path.clone(); | ||
correct.pop(); | ||
correct.push(folder); | ||
correct.push("mod.rs"); | ||
cx.struct_span_lint( | ||
SELF_NAMED_MODULE_FILES, | ||
Span::new(file.start_pos, file.start_pos, SyntaxContext::root()), | ||
|build| { | ||
let mut lint = | ||
build.build(&format!("`mod.rs` files are required, found `{}`", path.display())); | ||
lint.help(&format!("move `{}` to `{}`", path.display(), correct.display(),)); | ||
lint.emit(); | ||
}, | ||
); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn check_mod_file_exists( | ||
path: &Path, | ||
folder_segments: &mut FxHashSet<OsString>, | ||
mod_folders: &mut FxHashSet<OsString>, | ||
) { | ||
let mut comp = path.components().rev().peekable(); | ||
let _ = comp.next(); | ||
if path.ends_with("mod.rs") { | ||
mod_folders.insert(comp.peek().map(|c| c.as_os_str().to_owned()).unwrap_or_default()); | ||
} | ||
let folders = comp | ||
.filter_map(|c| { | ||
if let Component::Normal(s) = c { | ||
Some(s.to_os_string()) | ||
} else { | ||
None | ||
} | ||
}) | ||
.collect::<Vec<_>>(); | ||
folder_segments.extend(folders); | ||
} | ||
|
||
fn check_self_named_mod_exists(cx: &EarlyContext<'_>, path: &Path, file: &SourceFile) { | ||
if path.ends_with("mod.rs") { | ||
let mut mod_file = path.to_path_buf(); | ||
mod_file.pop(); | ||
mod_file.set_extension("rs"); | ||
|
||
cx.struct_span_lint( | ||
MOD_MODULE_FILES, | ||
Span::new(file.start_pos, file.start_pos, SyntaxContext::root()), | ||
|build| { | ||
let mut lint = build.build(&format!("`mod.rs` files are not allowed, found `{}`", path.display())); | ||
lint.help(&format!("move `{}` to `{}`", path.display(), mod_file.display(),)); | ||
lint.emit(); | ||
}, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[package] | ||
name = "fail" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod stuff; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod most; | ||
|
||
pub struct Inner; |
1 change: 1 addition & 0 deletions
1
tests/ui-cargo/module_style/fail_mod/src/bad/inner/stuff/most.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub struct Snarks; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod inner; | ||
|
||
pub struct Thing; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#![warn(clippy::self_named_module_files)] | ||
|
||
mod bad; | ||
|
||
fn main() { | ||
let _ = bad::Thing; | ||
let _ = bad::inner::stuff::Inner; | ||
let _ = bad::inner::stuff::most::Snarks; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
error: `mod.rs` files are required, found `/bad/inner.rs` | ||
--> $DIR/bad/inner.rs:1:1 | ||
| | ||
LL | pub mod stuff; | ||
| ^ | ||
| | ||
= note: `-D clippy::self-named-module-files` implied by `-D warnings` | ||
= help: move `/bad/inner.rs` to `/bad/inner/mod.rs` | ||
|
||
error: `mod.rs` files are required, found `/bad/inner/stuff.rs` | ||
--> $DIR/bad/inner/stuff.rs:1:1 | ||
| | ||
LL | pub mod most; | ||
| ^ | ||
| | ||
= help: move `/bad/inner/stuff.rs` to `/bad/inner/stuff/mod.rs` | ||
|
||
error: aborting due to 2 previous errors | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[package] | ||
name = "fail" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub struct Thing; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#![warn(clippy::mod_module_files)] | ||
|
||
mod bad; | ||
|
||
fn main() { | ||
let _ = bad::Thing; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error: `mod.rs` files are not allowed, found `/bad/mod.rs` | ||
--> $DIR/bad/mod.rs:1:1 | ||
| | ||
LL | pub struct Thing; | ||
| ^ | ||
| | ||
= note: `-D clippy::mod-module-files` implied by `-D warnings` | ||
= help: move `/bad/mod.rs` to `/bad.rs` | ||
|
||
error: aborting due to previous error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[package] | ||
name = "fail" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub struct Thing; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![warn(clippy::self_named_module_files)] | ||
|
||
mod bad; | ||
mod more; | ||
|
||
fn main() { | ||
let _ = bad::Thing; | ||
let _ = more::foo::Foo; | ||
let _ = more::inner::Inner; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub struct Foo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub struct Inner; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod foo; | ||
pub mod inner; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[package] | ||
name = "pass" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub struct Thing; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#![warn(clippy::mod_module_files)] | ||
|
||
mod good; | ||
|
||
fn main() { | ||
let _ = good::Thing; | ||
} |