diff --git a/src/cargo/ops/tree/graph.rs b/src/cargo/ops/tree/graph.rs index bf254e49888..ebe63f2a496 100644 --- a/src/cargo/ops/tree/graph.rs +++ b/src/cargo/ops/tree/graph.rs @@ -233,9 +233,33 @@ impl<'a> Graph<'a> { let mut dupes: Vec<(&Node, usize)> = packages .into_iter() - .filter(|(_name, indexes)| indexes.len() > 1) + .filter(|(_name, indexes)| { + indexes + .into_iter() + .map(|(node, _)| { + match node { + Node::Package { + package_id, + features, + .. + } => { + // 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!(), + } + }) + .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();