Skip to content

Commit 90b6fa8

Browse files
committed
Auto merge of #9142 - ehuss:fix-doc-orphan, r=Eh2406
Fix panic with doc collision orphan. As I feared, the collision removal added in #9077 caused problems due to orphans left in the unit graph. Ironically, it was the collision warning detection code which failed, as it iterates over all the keys of the graph. The solution is to remove all orphans from the graph after collisions have been removed. Fixes #9136
2 parents 34170fc + 5ebb605 commit 90b6fa8

File tree

2 files changed

+69
-11
lines changed

2 files changed

+69
-11
lines changed

src/cargo/ops/cargo_compile.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ pub fn create_bcx<'a, 'cfg>(
507507
// TODO: In theory, Cargo should also dedupe the roots, but I'm uncertain
508508
// what heuristics to use in that case.
509509
if build_config.mode == (CompileMode::Doc { deps: true }) {
510-
remove_duplicate_doc(build_config, &mut unit_graph);
510+
remove_duplicate_doc(build_config, &units, &mut unit_graph);
511511
}
512512

513513
if build_config
@@ -1508,14 +1508,11 @@ fn opt_patterns_and_names(
15081508
/// - Different sources. See `collision_doc_sources` test.
15091509
///
15101510
/// Ideally this would not be necessary.
1511-
fn remove_duplicate_doc(build_config: &BuildConfig, unit_graph: &mut UnitGraph) {
1512-
// NOTE: There is some risk that this can introduce problems because it
1513-
// may create orphans in the unit graph (parts of the tree get detached
1514-
// from the roots). I currently can't think of any ways this will cause a
1515-
// problem because all other parts of Cargo traverse the graph starting
1516-
// from the roots. Perhaps this should scan for detached units and remove
1517-
// them too?
1518-
//
1511+
fn remove_duplicate_doc(
1512+
build_config: &BuildConfig,
1513+
root_units: &[Unit],
1514+
unit_graph: &mut UnitGraph,
1515+
) {
15191516
// First, create a mapping of crate_name -> Unit so we can see where the
15201517
// duplicates are.
15211518
let mut all_docs: HashMap<String, Vec<Unit>> = HashMap::new();
@@ -1601,4 +1598,18 @@ fn remove_duplicate_doc(build_config: &BuildConfig, unit_graph: &mut UnitGraph)
16011598
for unit_deps in unit_graph.values_mut() {
16021599
unit_deps.retain(|unit_dep| !removed_units.contains(&unit_dep.unit));
16031600
}
1601+
// Remove any orphan units that were detached from the graph.
1602+
let mut visited = HashSet::new();
1603+
fn visit(unit: &Unit, graph: &UnitGraph, visited: &mut HashSet<Unit>) {
1604+
if !visited.insert(unit.clone()) {
1605+
return;
1606+
}
1607+
for dep in &graph[unit] {
1608+
visit(&dep.unit, graph, visited);
1609+
}
1610+
}
1611+
for unit in root_units {
1612+
visit(unit, unit_graph, &mut visited);
1613+
}
1614+
unit_graph.retain(|unit, _| visited.contains(unit));
16041615
}

tests/testsuite/collisions.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
//! Ideally these should never happen, but I don't think we'll ever be able to
44
//! prevent all collisions.
55
6-
use cargo_test_support::basic_manifest;
7-
use cargo_test_support::project;
86
use cargo_test_support::registry::Package;
7+
use cargo_test_support::{basic_manifest, cross_compile, project};
98
use std::env;
109

1110
#[cargo_test]
@@ -431,3 +430,51 @@ the same path; see <https://github.com/rust-lang/cargo/issues/6313>.
431430
)
432431
.run();
433432
}
433+
434+
#[cargo_test]
435+
fn collision_doc_target() {
436+
// collision in doc with --target, doesn't fail due to orphans
437+
if cross_compile::disabled() {
438+
return;
439+
}
440+
441+
Package::new("orphaned", "1.0.0").publish();
442+
Package::new("bar", "1.0.0")
443+
.dep("orphaned", "1.0")
444+
.publish();
445+
Package::new("bar", "2.0.0").publish();
446+
let p = project()
447+
.file(
448+
"Cargo.toml",
449+
r#"
450+
[package]
451+
name = "foo"
452+
version = "0.1.0"
453+
454+
[dependencies]
455+
bar2 = { version = "2.0", package="bar" }
456+
bar = "1.0"
457+
"#,
458+
)
459+
.file("src/lib.rs", "")
460+
.build();
461+
462+
p.cargo("doc --target")
463+
.arg(cross_compile::alternate())
464+
.with_stderr_unordered(
465+
"\
466+
[UPDATING] [..]
467+
[DOWNLOADING] crates ...
468+
[DOWNLOADED] orphaned v1.0.0 [..]
469+
[DOWNLOADED] bar v2.0.0 [..]
470+
[DOWNLOADED] bar v1.0.0 [..]
471+
[CHECKING] orphaned v1.0.0
472+
[DOCUMENTING] bar v2.0.0
473+
[CHECKING] bar v2.0.0
474+
[CHECKING] bar v1.0.0
475+
[DOCUMENTING] foo v0.1.0 [..]
476+
[FINISHED] [..]
477+
",
478+
)
479+
.run();
480+
}

0 commit comments

Comments
 (0)