99use std:: { fmt, mem, ops, panic:: RefUnwindSafe , str:: FromStr , sync:: Arc } ;
1010
1111use cfg:: CfgOptions ;
12- use rustc_hash :: FxHashMap ;
13- use stdx :: hash :: { NoHashHashMap , NoHashHashSet } ;
12+ use la_arena :: { Arena , Idx , RawIdx } ;
13+ use rustc_hash :: { FxHashMap , FxHashSet } ;
1414use syntax:: SmolStr ;
1515use tt:: token_id:: Subtree ;
1616use vfs:: { file_set:: FileSet , AbsPathBuf , AnchoredPath , FileId , VfsPath } ;
@@ -84,17 +84,22 @@ impl SourceRoot {
8484///
8585/// `CrateGraph` is `!Serialize` by design, see
8686/// <https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/architecture.md#serialization>
87- #[ derive( Debug , Clone , Default /* Serialize, Deserialize */ ) ]
87+ #[ derive( Clone , Default ) ]
8888pub struct CrateGraph {
89- arena : NoHashHashMap < CrateId , CrateData > ,
89+ arena : Arena < CrateData > ,
9090}
9191
92- #[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
93- pub struct CrateId ( pub u32 ) ;
92+ impl fmt:: Debug for CrateGraph {
93+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
94+ f. debug_map ( )
95+ . entries ( self . arena . iter ( ) . map ( |( id, data) | ( u32:: from ( id. into_raw ( ) ) , data) ) )
96+ . finish ( )
97+ }
98+ }
9499
95- impl stdx :: hash :: NoHashHashable for CrateId { }
100+ pub type CrateId = Idx < CrateData > ;
96101
97- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
102+ #[ derive( Debug , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
98103pub struct CrateName ( SmolStr ) ;
99104
100105impl CrateName {
@@ -182,7 +187,7 @@ impl fmt::Display for LangCrateOrigin {
182187 }
183188}
184189
185- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
190+ #[ derive( Debug , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
186191pub struct CrateDisplayName {
187192 // The name we use to display various paths (with `_`).
188193 crate_name : CrateName ,
@@ -261,7 +266,7 @@ pub struct ProcMacro {
261266 pub expander : Arc < dyn ProcMacroExpander > ,
262267}
263268
264- #[ derive( Debug , Copy , Clone ) ]
269+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
265270pub enum ReleaseChannel {
266271 Stable ,
267272 Beta ,
@@ -287,7 +292,7 @@ impl ReleaseChannel {
287292 }
288293}
289294
290- #[ derive( Debug , Clone ) ]
295+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
291296pub struct CrateData {
292297 pub root_file_id : FileId ,
293298 pub edition : Edition ,
@@ -327,7 +332,7 @@ pub struct Env {
327332 entries : FxHashMap < String , String > ,
328333}
329334
330- #[ derive( Debug , Clone , PartialEq , Eq ) ]
335+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
331336pub struct Dependency {
332337 pub crate_id : CrateId ,
333338 pub name : CrateName ,
@@ -378,10 +383,7 @@ impl CrateGraph {
378383 is_proc_macro,
379384 channel,
380385 } ;
381- let crate_id = CrateId ( self . arena . len ( ) as u32 ) ;
382- let prev = self . arena . insert ( crate_id, data) ;
383- assert ! ( prev. is_none( ) ) ;
384- crate_id
386+ self . arena . alloc ( data)
385387 }
386388
387389 pub fn add_dep (
@@ -394,14 +396,14 @@ impl CrateGraph {
394396 // Check if adding a dep from `from` to `to` creates a cycle. To figure
395397 // that out, look for a path in the *opposite* direction, from `to` to
396398 // `from`.
397- if let Some ( path) = self . find_path ( & mut NoHashHashSet :: default ( ) , dep. crate_id , from) {
399+ if let Some ( path) = self . find_path ( & mut FxHashSet :: default ( ) , dep. crate_id , from) {
398400 let path = path. into_iter ( ) . map ( |it| ( it, self [ it] . display_name . clone ( ) ) ) . collect ( ) ;
399401 let err = CyclicDependenciesError { path } ;
400402 assert ! ( err. from( ) . 0 == from && err. to( ) . 0 == dep. crate_id) ;
401403 return Err ( err) ;
402404 }
403405
404- self . arena . get_mut ( & from) . unwrap ( ) . add_dep ( dep) ;
406+ self . arena [ from] . add_dep ( dep) ;
405407 Ok ( ( ) )
406408 }
407409
@@ -410,14 +412,14 @@ impl CrateGraph {
410412 }
411413
412414 pub fn iter ( & self ) -> impl Iterator < Item = CrateId > + ' _ {
413- self . arena . keys ( ) . copied ( )
415+ self . arena . iter ( ) . map ( | ( idx , _ ) | idx )
414416 }
415417
416418 /// Returns an iterator over all transitive dependencies of the given crate,
417419 /// including the crate itself.
418420 pub fn transitive_deps ( & self , of : CrateId ) -> impl Iterator < Item = CrateId > {
419421 let mut worklist = vec ! [ of] ;
420- let mut deps = NoHashHashSet :: default ( ) ;
422+ let mut deps = FxHashSet :: default ( ) ;
421423
422424 while let Some ( krate) = worklist. pop ( ) {
423425 if !deps. insert ( krate) {
@@ -434,11 +436,11 @@ impl CrateGraph {
434436 /// including the crate itself.
435437 pub fn transitive_rev_deps ( & self , of : CrateId ) -> impl Iterator < Item = CrateId > {
436438 let mut worklist = vec ! [ of] ;
437- let mut rev_deps = NoHashHashSet :: default ( ) ;
439+ let mut rev_deps = FxHashSet :: default ( ) ;
438440 rev_deps. insert ( of) ;
439441
440- let mut inverted_graph = NoHashHashMap :: < _ , Vec < _ > > :: default ( ) ;
441- self . arena . iter ( ) . for_each ( |( & krate, data) | {
442+ let mut inverted_graph = FxHashMap :: < _ , Vec < _ > > :: default ( ) ;
443+ self . arena . iter ( ) . for_each ( |( krate, data) | {
442444 data. dependencies
443445 . iter ( )
444446 . for_each ( |dep| inverted_graph. entry ( dep. crate_id ) . or_default ( ) . push ( krate) )
@@ -461,17 +463,17 @@ impl CrateGraph {
461463 /// come before the crate itself).
462464 pub fn crates_in_topological_order ( & self ) -> Vec < CrateId > {
463465 let mut res = Vec :: new ( ) ;
464- let mut visited = NoHashHashSet :: default ( ) ;
466+ let mut visited = FxHashSet :: default ( ) ;
465467
466- for krate in self . arena . keys ( ) . copied ( ) {
468+ for krate in self . iter ( ) {
467469 go ( self , & mut visited, & mut res, krate) ;
468470 }
469471
470472 return res;
471473
472474 fn go (
473475 graph : & CrateGraph ,
474- visited : & mut NoHashHashSet < CrateId > ,
476+ visited : & mut FxHashSet < CrateId > ,
475477 res : & mut Vec < CrateId > ,
476478 source : CrateId ,
477479 ) {
@@ -487,7 +489,7 @@ impl CrateGraph {
487489
488490 // FIXME: this only finds one crate with the given root; we could have multiple
489491 pub fn crate_id_for_crate_root ( & self , file_id : FileId ) -> Option < CrateId > {
490- let ( & crate_id, _) =
492+ let ( crate_id, _) =
491493 self . arena . iter ( ) . find ( |( _crate_id, data) | data. root_file_id == file_id) ?;
492494 Some ( crate_id)
493495 }
@@ -499,24 +501,26 @@ impl CrateGraph {
499501 /// amount.
500502 pub fn extend ( & mut self , other : CrateGraph , proc_macros : & mut ProcMacroPaths ) -> u32 {
501503 let start = self . arena . len ( ) as u32 ;
502- self . arena . extend ( other. arena . into_iter ( ) . map ( |( id, mut data) | {
503- let new_id = id. shift ( start) ;
504+ self . arena . extend ( other. arena . into_iter ( ) . map ( |( _, mut data) | {
504505 for dep in & mut data. dependencies {
505- dep. crate_id = dep. crate_id . shift ( start) ;
506+ dep. crate_id =
507+ CrateId :: from_raw ( RawIdx :: from ( u32:: from ( dep. crate_id . into_raw ( ) ) + start) ) ;
506508 }
507- ( new_id , data)
509+ data
508510 } ) ) ;
509511
510512 * proc_macros = mem:: take ( proc_macros)
511513 . into_iter ( )
512- . map ( |( id, macros) | ( id. shift ( start) , macros) )
514+ . map ( |( id, macros) | {
515+ ( CrateId :: from_raw ( RawIdx :: from ( u32:: from ( id. into_raw ( ) ) + start) ) , macros)
516+ } )
513517 . collect ( ) ;
514518 start
515519 }
516520
517521 fn find_path (
518522 & self ,
519- visited : & mut NoHashHashSet < CrateId > ,
523+ visited : & mut FxHashSet < CrateId > ,
520524 from : CrateId ,
521525 to : CrateId ,
522526 ) -> Option < Vec < CrateId > > {
@@ -546,10 +550,8 @@ impl CrateGraph {
546550 let std = self . hacky_find_crate ( "std" ) ;
547551 match ( cfg_if, std) {
548552 ( Some ( cfg_if) , Some ( std) ) => {
549- self . arena . get_mut ( & cfg_if) . unwrap ( ) . dependencies . clear ( ) ;
550- self . arena
551- . get_mut ( & std)
552- . unwrap ( )
553+ self . arena [ cfg_if] . dependencies . clear ( ) ;
554+ self . arena [ std]
553555 . dependencies
554556 . push ( Dependency :: new ( CrateName :: new ( "cfg_if" ) . unwrap ( ) , cfg_if) ) ;
555557 true
@@ -566,13 +568,7 @@ impl CrateGraph {
566568impl ops:: Index < CrateId > for CrateGraph {
567569 type Output = CrateData ;
568570 fn index ( & self , crate_id : CrateId ) -> & CrateData {
569- & self . arena [ & crate_id]
570- }
571- }
572-
573- impl CrateId {
574- fn shift ( self , amount : u32 ) -> CrateId {
575- CrateId ( self . 0 + amount)
571+ & self . arena [ crate_id]
576572 }
577573}
578574
0 commit comments