From 58906aac9da5425ff5de207962ff889385bce2a4 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Wed, 9 Mar 2022 00:33:47 +0800 Subject: [PATCH] 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();