@@ -507,7 +507,7 @@ pub fn create_bcx<'a, 'cfg>(
507
507
// TODO: In theory, Cargo should also dedupe the roots, but I'm uncertain
508
508
// what heuristics to use in that case.
509
509
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) ;
511
511
}
512
512
513
513
if build_config
@@ -1508,14 +1508,11 @@ fn opt_patterns_and_names(
1508
1508
/// - Different sources. See `collision_doc_sources` test.
1509
1509
///
1510
1510
/// 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
+ ) {
1519
1516
// First, create a mapping of crate_name -> Unit so we can see where the
1520
1517
// duplicates are.
1521
1518
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)
1601
1598
for unit_deps in unit_graph. values_mut ( ) {
1602
1599
unit_deps. retain ( |unit_dep| !removed_units. contains ( & unit_dep. unit ) ) ;
1603
1600
}
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) ) ;
1604
1615
}
0 commit comments