Skip to content

Commit 182ac89

Browse files
committed
Auto merge of rust-lang#5636 - ebroto:issue_5041, r=phansch
multiple_crate_versions: skip dev and build deps changelog: multiple_crate_versions: skip dev and build deps Closes rust-lang#5041
2 parents 2a6cfa7 + ec0a00e commit 182ac89

File tree

10 files changed

+85
-19
lines changed

10 files changed

+85
-19
lines changed

clippy_dev/src/new_lint.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ fn create_test(lint: &LintData) -> io::Result<()> {
7676

7777
path.push("src");
7878
fs::create_dir(&path)?;
79-
write_file(path.join("main.rs"), get_test_file_contents(lint_name))?;
79+
let header = format!("// compile-flags: --crate-name={}", lint_name);
80+
write_file(path.join("main.rs"), get_test_file_contents(lint_name, Some(&header)))?;
8081

8182
Ok(())
8283
}
@@ -90,7 +91,7 @@ fn create_test(lint: &LintData) -> io::Result<()> {
9091
create_project_layout(lint.name, &test_dir, "pass", "This file should not trigger the lint")
9192
} else {
9293
let test_path = format!("tests/ui/{}.rs", lint.name);
93-
let test_contents = get_test_file_contents(lint.name);
94+
let test_contents = get_test_file_contents(lint.name, None);
9495
write_file(lint.project_root.join(test_path), test_contents)
9596
}
9697
}
@@ -119,16 +120,22 @@ fn to_camel_case(name: &str) -> String {
119120
.collect()
120121
}
121122

122-
fn get_test_file_contents(lint_name: &str) -> String {
123-
format!(
123+
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
124+
let mut contents = format!(
124125
"#![warn(clippy::{})]
125126
126127
fn main() {{
127128
// test code goes here
128129
}}
129130
",
130131
lint_name
131-
)
132+
);
133+
134+
if let Some(header) = header_commands {
135+
contents = format!("{}\n{}", header, contents);
136+
}
137+
138+
contents
132139
}
133140

134141
fn get_manifest_contents(lint_name: &str, hint: &str) -> String {

clippy_lints/src/multiple_crate_versions.rs

+46-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
//! lint on multiple versions of a crate being used
22
33
use crate::utils::{run_lints, span_lint};
4+
use rustc_hir::def_id::LOCAL_CRATE;
45
use rustc_hir::{Crate, CRATE_HIR_ID};
56
use rustc_lint::{LateContext, LateLintPass};
67
use rustc_session::{declare_lint_pass, declare_tool_lint};
78
use rustc_span::source_map::DUMMY_SP;
89

10+
use cargo_metadata::{DependencyKind, MetadataCommand, Node, Package, PackageId};
11+
use if_chain::if_chain;
912
use itertools::Itertools;
1013

1114
declare_clippy_lint! {
@@ -39,32 +42,61 @@ impl LateLintPass<'_, '_> for MultipleCrateVersions {
3942
return;
4043
}
4144

42-
let metadata = if let Ok(metadata) = cargo_metadata::MetadataCommand::new().exec() {
45+
let metadata = if let Ok(metadata) = MetadataCommand::new().exec() {
4346
metadata
4447
} else {
4548
span_lint(cx, MULTIPLE_CRATE_VERSIONS, DUMMY_SP, "could not read cargo metadata");
46-
4749
return;
4850
};
4951

52+
let local_name = cx.tcx.crate_name(LOCAL_CRATE).as_str();
5053
let mut packages = metadata.packages;
5154
packages.sort_by(|a, b| a.name.cmp(&b.name));
5255

53-
for (name, group) in &packages.into_iter().group_by(|p| p.name.clone()) {
54-
let group: Vec<cargo_metadata::Package> = group.collect();
56+
if_chain! {
57+
if let Some(resolve) = &metadata.resolve;
58+
if let Some(local_id) = packages
59+
.iter()
60+
.find_map(|p| if p.name == *local_name { Some(&p.id) } else { None });
61+
then {
62+
for (name, group) in &packages.iter().group_by(|p| p.name.clone()) {
63+
let group: Vec<&Package> = group.collect();
64+
65+
if group.len() <= 1 {
66+
continue;
67+
}
5568

56-
if group.len() > 1 {
57-
let mut versions: Vec<_> = group.into_iter().map(|p| p.version).collect();
58-
versions.sort();
59-
let versions = versions.iter().join(", ");
69+
if group.iter().all(|p| is_normal_dep(&resolve.nodes, local_id, &p.id)) {
70+
let mut versions: Vec<_> = group.into_iter().map(|p| &p.version).collect();
71+
versions.sort();
72+
let versions = versions.iter().join(", ");
6073

61-
span_lint(
62-
cx,
63-
MULTIPLE_CRATE_VERSIONS,
64-
DUMMY_SP,
65-
&format!("multiple versions for dependency `{}`: {}", name, versions),
66-
);
74+
span_lint(
75+
cx,
76+
MULTIPLE_CRATE_VERSIONS,
77+
DUMMY_SP,
78+
&format!("multiple versions for dependency `{}`: {}", name, versions),
79+
);
80+
}
81+
}
6782
}
6883
}
6984
}
7085
}
86+
87+
fn is_normal_dep(nodes: &[Node], local_id: &PackageId, dep_id: &PackageId) -> bool {
88+
fn depends_on(node: &Node, dep_id: &PackageId) -> bool {
89+
node.deps.iter().any(|dep| {
90+
dep.pkg == *dep_id
91+
&& dep
92+
.dep_kinds
93+
.iter()
94+
.any(|info| matches!(info.kind, DependencyKind::Normal))
95+
})
96+
}
97+
98+
nodes
99+
.iter()
100+
.filter(|node| depends_on(node, dep_id))
101+
.any(|node| node.id == *local_id || is_normal_dep(nodes, local_id, &node.id))
102+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: --crate-name=cargo_common_metadata
12
#![warn(clippy::cargo_common_metadata)]
23

34
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: --crate-name=cargo_common_metadata
12
#![warn(clippy::cargo_common_metadata)]
23

34
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Should not lint for dev or build dependencies. See issue 5041.
2+
3+
[package]
4+
name = "multiple_crate_versions"
5+
version = "0.1.0"
6+
publish = false
7+
8+
# One of the versions of winapi is only a dev dependency: allowed
9+
[dependencies]
10+
ctrlc = "=3.1.0"
11+
[dev-dependencies]
12+
ansi_term = "=0.11.0"
13+
14+
# Both versions of winapi are a build dependency: allowed
15+
[build-dependencies]
16+
ctrlc = "=3.1.0"
17+
ansi_term = "=0.11.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// compile-flags: --crate-name=multiple_crate_versions
2+
#![warn(clippy::multiple_crate_versions)]
3+
4+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: --crate-name=multiple_crate_versions
12
#![warn(clippy::multiple_crate_versions)]
23

34
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: --crate-name=multiple_crate_versions
12
#![warn(clippy::multiple_crate_versions)]
23

34
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: --crate-name=wildcard_dependencies
12
#![warn(clippy::wildcard_dependencies)]
23

34
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: --crate-name=wildcard_dependencies
12
#![warn(clippy::wildcard_dependencies)]
23

34
fn main() {}

0 commit comments

Comments
 (0)