From 58906aac9da5425ff5de207962ff889385bce2a4 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Wed, 9 Mar 2022 00:33:47 +0800 Subject: [PATCH 1/2] Don't treat host/target duplicates as duplicates Signed-off-by: hi-rustin --- src/cargo/ops/tree/graph.rs | 27 +++++++++++++++++++++- tests/testsuite/tree.rs | 45 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/cargo/ops/tree/graph.rs b/src/cargo/ops/tree/graph.rs index bf254e49888..61e9370c99e 100644 --- a/src/cargo/ops/tree/graph.rs +++ b/src/cargo/ops/tree/graph.rs @@ -233,9 +233,34 @@ impl<'a> Graph<'a> { let mut dupes: Vec<(&Node, usize)> = packages .into_iter() - .filter(|(_name, indexes)| indexes.len() > 1) + .filter(|(_name, indexes)| { + let mut pkg_map = HashMap::new(); + indexes + .into_iter() + .filter(|(node, _)| { + // Do not treat duplicates on the host or target as duplicates. + let ignore_kind_package = match node { + Node::Package { + package_id, + features, + .. + } => Node::Package { + package_id: package_id.clone(), + features: features.clone(), + kind: CompileKind::Host, + }, + _ => unreachable!(), + }; + !pkg_map.contains_key(&ignore_kind_package) + && pkg_map.insert(ignore_kind_package, ()).is_none() + }) + .collect::>() + .len() + > 1 + }) .flat_map(|(_name, indexes)| indexes) .collect(); + // For consistent output. dupes.sort_unstable(); dupes.into_iter().map(|(_node, i)| i).collect() diff --git a/tests/testsuite/tree.rs b/tests/testsuite/tree.rs index 63115a85930..53c992d2d56 100644 --- a/tests/testsuite/tree.rs +++ b/tests/testsuite/tree.rs @@ -984,6 +984,51 @@ cat v2.0.0 .run(); } +#[cargo_test] +fn duplicates_with_target() { + // --target flag + if cross_compile::disabled() { + return; + } + Package::new("a", "1.0.0").publish(); + Package::new("dog", "1.0.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + a = "1.0" + dog = "1.0" + + [build-dependencies] + a = "1.0" + dog = "1.0" + + "#, + ) + .file("src/lib.rs", "") + .file("build.rs", "fn main() {}") + .build(); + p.cargo("tree -d").with_stdout("").run(); + + p.cargo("tree -d --target") + .arg(alternate()) + .with_stdout("") + .run(); + + p.cargo("tree -d --target") + .arg(rustc_host()) + .with_stdout("") + .run(); + + p.cargo("tree -d --target=all").with_stdout("").run(); +} + #[cargo_test] fn charset() { let p = make_simple_proj(); From c45c2a5b2806a8f0d85c1f4eac183804ee58fcde Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Wed, 30 Mar 2022 20:00:05 +0800 Subject: [PATCH 2/2] Replace hashmap with hashset Signed-off-by: hi-rustin Better code Signed-off-by: hi-rustin --- src/cargo/ops/tree/graph.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/cargo/ops/tree/graph.rs b/src/cargo/ops/tree/graph.rs index 61e9370c99e..ebe63f2a496 100644 --- a/src/cargo/ops/tree/graph.rs +++ b/src/cargo/ops/tree/graph.rs @@ -234,27 +234,26 @@ impl<'a> Graph<'a> { let mut dupes: Vec<(&Node, usize)> = packages .into_iter() .filter(|(_name, indexes)| { - let mut pkg_map = HashMap::new(); indexes .into_iter() - .filter(|(node, _)| { - // Do not treat duplicates on the host or target as duplicates. - let ignore_kind_package = match node { + .map(|(node, _)| { + match node { Node::Package { package_id, features, .. - } => Node::Package { - package_id: package_id.clone(), - features: features.clone(), - kind: CompileKind::Host, - }, + } => { + // Do not treat duplicates on the host or target as duplicates. + Node::Package { + package_id: package_id.clone(), + features: features.clone(), + kind: CompileKind::Host, + } + } _ => unreachable!(), - }; - !pkg_map.contains_key(&ignore_kind_package) - && pkg_map.insert(ignore_kind_package, ()).is_none() + } }) - .collect::>() + .collect::>() .len() > 1 })