@@ -14,7 +14,7 @@ use dashmap::DashMap;
1414use dashmap:: mapref:: entry:: Entry ;
1515use intern:: Symbol ;
1616use la_arena:: { Arena , Idx , RawIdx } ;
17- use rustc_hash:: { FxHashMap , FxHashSet , FxHasher } ;
17+ use rustc_hash:: { FxBuildHasher , FxHashMap , FxHashSet , FxHasher } ;
1818use salsa:: { Durability , Setter } ;
1919use span:: Edition ;
2020use triomphe:: Arc ;
@@ -24,6 +24,8 @@ use crate::{CrateWorkspaceData, EditionedFileId, RootQueryDb};
2424
2525pub type ProcMacroPaths = FxHashMap < CrateBuilderId , Result < ( String , AbsPathBuf ) , String > > ;
2626
27+ type FxIndexSet < T > = indexmap:: IndexSet < T , FxBuildHasher > ;
28+
2729#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
2830pub struct SourceRootId ( pub u32 ) ;
2931
@@ -474,7 +476,9 @@ impl CrateGraphBuilder {
474476 }
475477
476478 pub fn set_in_db ( self , db : & mut dyn RootQueryDb ) -> CratesIdMap {
477- let mut all_crates = Vec :: with_capacity ( self . arena . len ( ) ) ;
479+ // For some reason in some repositories we have duplicate crates, so we use a set and not `Vec`.
480+ // We use an `IndexSet` because the list needs to be topologically sorted.
481+ let mut all_crates = FxIndexSet :: with_capacity_and_hasher ( self . arena . len ( ) , FxBuildHasher ) ;
478482 let mut visited = FxHashMap :: default ( ) ;
479483 let mut visited_root_files = FxHashSet :: default ( ) ;
480484
@@ -494,9 +498,11 @@ impl CrateGraphBuilder {
494498 ) ;
495499 }
496500
497- if * * old_all_crates != * all_crates {
501+ if old_all_crates. len ( ) != all_crates. len ( )
502+ || old_all_crates. iter ( ) . any ( |& krate| !all_crates. contains ( & krate) )
503+ {
498504 db. set_all_crates_with_durability (
499- Arc :: new ( all_crates. into_boxed_slice ( ) ) ,
505+ Arc :: new ( Vec :: from_iter ( all_crates) . into_boxed_slice ( ) ) ,
500506 Durability :: MEDIUM ,
501507 ) ;
502508 }
@@ -509,7 +515,7 @@ impl CrateGraphBuilder {
509515 crates_map : & CratesMap ,
510516 visited : & mut FxHashMap < CrateBuilderId , Crate > ,
511517 visited_root_files : & mut FxHashSet < FileId > ,
512- all_crates : & mut Vec < Crate > ,
518+ all_crates : & mut FxIndexSet < Crate > ,
513519 source : CrateBuilderId ,
514520 ) -> Crate {
515521 if let Some ( & crate_id) = visited. get ( & source) {
@@ -597,7 +603,7 @@ impl CrateGraphBuilder {
597603 input
598604 }
599605 } ;
600- all_crates. push ( crate_input) ;
606+ all_crates. insert ( crate_input) ;
601607 visited. insert ( source, crate_input) ;
602608 crate_input
603609 }
0 commit comments