diff --git a/src/cargo/core/compiler/rustdoc.rs b/src/cargo/core/compiler/rustdoc.rs index 95483cb5688..7a856fe1bc5 100644 --- a/src/cargo/core/compiler/rustdoc.rs +++ b/src/cargo/core/compiler/rustdoc.rs @@ -7,6 +7,7 @@ use crate::sources::CRATES_IO_REGISTRY; use crate::util::errors::{internal, CargoResult}; use cargo_util::ProcessBuilder; use std::collections::HashMap; +use std::collections::HashSet; use std::fmt; use std::hash; use url::Url; @@ -113,8 +114,12 @@ fn build_all_urls( name2url: &HashMap<&String, Url>, map: &RustdocExternMap, unstable_opts: &mut bool, + seen: &mut HashSet, ) { for dep in build_runner.unit_deps(unit) { + if !seen.insert(dep.unit.clone()) { + continue; + } if !dep.unit.target.is_linkable() || dep.unit.mode.is_doc() { continue; } @@ -155,6 +160,7 @@ fn build_all_urls( name2url, map, unstable_opts, + seen, ); } } @@ -199,6 +205,7 @@ pub fn add_root_urls( &name2url, map, &mut unstable_opts, + &mut HashSet::new(), ); let std_url = match &map.std { None | Some(RustdocExternMode::Remote) => None, diff --git a/tests/testsuite/rustdoc_extern_html.rs b/tests/testsuite/rustdoc_extern_html.rs index 01ed1240abc..0d6d93b4962 100644 --- a/tests/testsuite/rustdoc_extern_html.rs +++ b/tests/testsuite/rustdoc_extern_html.rs @@ -416,3 +416,50 @@ fn alt_sparse_registry() { let gold = p.read_file("target/doc/foo/fn.gold.html"); assert!(gold.contains(r#"href="https://docs.rs/grimm/1.0.0/grimm/struct.Gold.html""#)); } + +#[cargo_test(nightly, reason = "--extern-html-root-url is unstable")] +fn same_deps_multi_occurrence_in_dep_tree() { + // rust-lang/cargo#13543 + Package::new("baz", "1.0.0") + .file("src/lib.rs", "") + .publish(); + Package::new("bar", "1.0.0") + .file("src/lib.rs", "") + .dep("baz", "1.0") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + edition = "2018" + + [dependencies] + bar = "1.0" + baz = "1.0" + "#, + ) + .file("src/lib.rs", "") + .file( + ".cargo/config.toml", + r#" + [doc.extern-map.registries] + crates-io = "https://docs.rs/" + "#, + ) + .build(); + p.cargo("doc -v --no-deps -Zrustdoc-map") + .masquerade_as_nightly_cargo(&["rustdoc-map"]) + .with_stderr_does_not_contain( + "[..]--extern-html-root-url[..]bar=https://docs.rs\ + [..]--extern-html-root-url[..]baz=https://docs.rs\ + [..]--extern-html-root-url[..]baz=https://docs.rs[..]", + ) + .with_stderr_contains( + "[..]--extern-html-root-url[..]bar=https://docs.rs\ + [..]--extern-html-root-url[..]baz=https://docs.rs[..]", + ) + .run(); +}