diff --git a/clippy_lints/src/module_style.rs b/clippy_lints/src/module_style.rs index 349fcd2274d..b393db53b36 100644 --- a/clippy_lints/src/module_style.rs +++ b/clippy_lints/src/module_style.rs @@ -2,6 +2,7 @@ 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::def_id::LOCAL_CRATE; use rustc_span::{FileName, SourceFile, Span, SyntaxContext}; use std::ffi::OsStr; use std::path::{Component, Path}; @@ -91,6 +92,13 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { let mut file_map = FxHashMap::default(); for file in files.iter() { if let FileName::Real(name) = &file.name && let Some(lp) = name.local_path() { + if file.cnum != LOCAL_CRATE { + // [#8887](https://github.com/rust-lang/rust-clippy/issues/8887) + // Only check files in the current crate. + // Fix false positive that crate dependency in workspace sub directory + // is checked unintentionally. + continue; + } let path = if lp.is_relative() { lp } else if let Ok(relative) = lp.strip_prefix(trim_to_src) { diff --git a/tests/workspace.rs b/tests/workspace.rs index c9cbc50546c..699ab2be199 100644 --- a/tests/workspace.rs +++ b/tests/workspace.rs @@ -6,6 +6,46 @@ mod test_utils; +#[test] +fn test_module_style_with_dep_in_subdir() { + if IS_RUSTC_TEST_SUITE { + return; + } + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let target_dir = root.join("target").join("workspace_test"); + let cwd = root.join("tests/workspace_test"); + + // Make sure we start with a clean state + Command::new("cargo") + .current_dir(&cwd) + .env("CARGO_TARGET_DIR", &target_dir) + .arg("clean") + .args(["-p", "pass-no-mod-with-dep-in-subdir"]) + .args(["-p", "pass-mod-with-dep-in-subdir"]) + .output() + .unwrap(); + + // [#8887](https://github.com/rust-lang/rust-clippy/issues/8887) + // `mod.rs` checks should not be applied to crate dependencies + // located in the subdirectory of workspace + let output = Command::new(&*CARGO_CLIPPY_PATH) + .current_dir(&cwd) + .env("CARGO_INCREMENTAL", "0") + .env("CARGO_TARGET_DIR", &target_dir) + .arg("clippy") + .args(["-p", "pass-no-mod-with-dep-in-subdir"]) + .args(["-p", "pass-mod-with-dep-in-subdir"]) + .arg("--") + .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir + .output() + .unwrap(); + + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + assert!(output.status.success()); +} + #[test] fn test_no_deps_ignores_path_deps_in_workspaces() { if IS_RUSTC_TEST_SUITE { diff --git a/tests/workspace_test/Cargo.toml b/tests/workspace_test/Cargo.toml index bf5b4ca5288..d24b278ccc2 100644 --- a/tests/workspace_test/Cargo.toml +++ b/tests/workspace_test/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2018" [workspace] -members = ["subcrate"] +members = ["subcrate", "module_style/pass_no_mod_with_dep_in_subdir", "module_style/pass_mod_with_dep_in_subdir"] diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/Cargo.toml b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/Cargo.toml new file mode 100644 index 00000000000..15dcde4e30a --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "pass-mod-with-dep-in-subdir" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dep-no-mod = { path = "dep_no_mod"} diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/Cargo.toml b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/Cargo.toml new file mode 100644 index 00000000000..55569bc25ed --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dep-no-mod" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo.rs new file mode 100644 index 00000000000..7b0966a4586 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo.rs @@ -0,0 +1,2 @@ +pub mod hello; +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo/hello.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo/hello.rs new file mode 100644 index 00000000000..99940dce528 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo/hello.rs @@ -0,0 +1 @@ +pub struct Hello; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/lib.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/lib.rs new file mode 100644 index 00000000000..c62f9acbf2c --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/lib.rs @@ -0,0 +1,5 @@ +pub mod foo; + +pub fn foo() { + let _ = foo::Thing; +} diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/bad/mod.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/bad/mod.rs new file mode 100644 index 00000000000..f19ab10d5fb --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/bad/mod.rs @@ -0,0 +1 @@ +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/main.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/main.rs new file mode 100644 index 00000000000..5cb4795e945 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/main.rs @@ -0,0 +1,13 @@ +#![deny(clippy::self_named_module_files)] + +mod bad; +mod more; +extern crate dep_no_mod; + +fn main() { + let _ = bad::Thing; + let _ = more::foo::Foo; + let _ = more::inner::Inner; + let _ = dep_no_mod::foo::Thing; + let _ = dep_no_mod::foo::hello::Hello; +} diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/foo.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/foo.rs new file mode 100644 index 00000000000..4a835673a59 --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/foo.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/inner/mod.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/inner/mod.rs new file mode 100644 index 00000000000..aa84f78cc2c --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/inner/mod.rs @@ -0,0 +1 @@ +pub struct Inner; diff --git a/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/mod.rs b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/mod.rs new file mode 100644 index 00000000000..d79569f78ff --- /dev/null +++ b/tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/mod.rs @@ -0,0 +1,2 @@ +pub mod foo; +pub mod inner; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/Cargo.toml b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/Cargo.toml new file mode 100644 index 00000000000..060cb18dc9f --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "pass-no-mod-with-dep-in-subdir" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dep-with-mod = { path = "dep_with_mod"} diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/Cargo.toml b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/Cargo.toml new file mode 100644 index 00000000000..b25725cd561 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dep-with-mod" +version = "0.1.0" +edition = "2018" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/lib.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/lib.rs new file mode 100644 index 00000000000..4647424f2c2 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/lib.rs @@ -0,0 +1,7 @@ +pub mod with_mod; + +pub fn foo() { + let _ = with_mod::Thing; + let _ = with_mod::inner::stuff::Inner; + let _ = with_mod::inner::stuff::most::Snarks; +} diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner.rs new file mode 100644 index 00000000000..91cd540a28f --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner.rs @@ -0,0 +1 @@ +pub mod stuff; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff.rs new file mode 100644 index 00000000000..7713fa9d35c --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff.rs @@ -0,0 +1,3 @@ +pub mod most; + +pub struct Inner; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff/most.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff/most.rs new file mode 100644 index 00000000000..5a5eaf9670f --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff/most.rs @@ -0,0 +1 @@ +pub struct Snarks; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/mod.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/mod.rs new file mode 100644 index 00000000000..a12734db7cb --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/mod.rs @@ -0,0 +1,3 @@ +pub mod inner; + +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/good.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/good.rs new file mode 100644 index 00000000000..f19ab10d5fb --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/good.rs @@ -0,0 +1 @@ +pub struct Thing; diff --git a/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/main.rs b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/main.rs new file mode 100644 index 00000000000..42eb99cd7a3 --- /dev/null +++ b/tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/main.rs @@ -0,0 +1,9 @@ +#![deny(clippy::mod_module_files)] + +mod good; +pub use dep_with_mod::with_mod::Thing; + +fn main() { + let _ = good::Thing; + let _ = dep_with_mod::with_mod::Thing; +}