9
9
use std:: { fmt, mem, ops, panic:: RefUnwindSafe , str:: FromStr , sync:: Arc } ;
10
10
11
11
use 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 } ;
14
14
use syntax:: SmolStr ;
15
15
use tt:: token_id:: Subtree ;
16
16
use vfs:: { file_set:: FileSet , AbsPathBuf , AnchoredPath , FileId , VfsPath } ;
@@ -84,17 +84,22 @@ impl SourceRoot {
84
84
///
85
85
/// `CrateGraph` is `!Serialize` by design, see
86
86
/// <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 ) ]
88
88
pub struct CrateGraph {
89
- arena : NoHashHashMap < CrateId , CrateData > ,
89
+ arena : Arena < CrateData > ,
90
90
}
91
91
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
+ }
94
99
95
- impl stdx :: hash :: NoHashHashable for CrateId { }
100
+ pub type CrateId = Idx < CrateData > ;
96
101
97
- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
102
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
98
103
pub struct CrateName ( SmolStr ) ;
99
104
100
105
impl CrateName {
@@ -182,7 +187,7 @@ impl fmt::Display for LangCrateOrigin {
182
187
}
183
188
}
184
189
185
- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
190
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
186
191
pub struct CrateDisplayName {
187
192
// The name we use to display various paths (with `_`).
188
193
crate_name : CrateName ,
@@ -261,7 +266,7 @@ pub struct ProcMacro {
261
266
pub expander : Arc < dyn ProcMacroExpander > ,
262
267
}
263
268
264
- #[ derive( Debug , Copy , Clone ) ]
269
+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
265
270
pub enum ReleaseChannel {
266
271
Stable ,
267
272
Beta ,
@@ -287,7 +292,7 @@ impl ReleaseChannel {
287
292
}
288
293
}
289
294
290
- #[ derive( Debug , Clone ) ]
295
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
291
296
pub struct CrateData {
292
297
pub root_file_id : FileId ,
293
298
pub edition : Edition ,
@@ -327,7 +332,7 @@ pub struct Env {
327
332
entries : FxHashMap < String , String > ,
328
333
}
329
334
330
- #[ derive( Debug , Clone , PartialEq , Eq ) ]
335
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
331
336
pub struct Dependency {
332
337
pub crate_id : CrateId ,
333
338
pub name : CrateName ,
@@ -378,10 +383,7 @@ impl CrateGraph {
378
383
is_proc_macro,
379
384
channel,
380
385
} ;
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)
385
387
}
386
388
387
389
pub fn add_dep (
@@ -394,14 +396,14 @@ impl CrateGraph {
394
396
// Check if adding a dep from `from` to `to` creates a cycle. To figure
395
397
// that out, look for a path in the *opposite* direction, from `to` to
396
398
// `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) {
398
400
let path = path. into_iter ( ) . map ( |it| ( it, self [ it] . display_name . clone ( ) ) ) . collect ( ) ;
399
401
let err = CyclicDependenciesError { path } ;
400
402
assert ! ( err. from( ) . 0 == from && err. to( ) . 0 == dep. crate_id) ;
401
403
return Err ( err) ;
402
404
}
403
405
404
- self . arena . get_mut ( & from) . unwrap ( ) . add_dep ( dep) ;
406
+ self . arena [ from] . add_dep ( dep) ;
405
407
Ok ( ( ) )
406
408
}
407
409
@@ -410,14 +412,14 @@ impl CrateGraph {
410
412
}
411
413
412
414
pub fn iter ( & self ) -> impl Iterator < Item = CrateId > + ' _ {
413
- self . arena . keys ( ) . copied ( )
415
+ self . arena . iter ( ) . map ( | ( idx , _ ) | idx )
414
416
}
415
417
416
418
/// Returns an iterator over all transitive dependencies of the given crate,
417
419
/// including the crate itself.
418
420
pub fn transitive_deps ( & self , of : CrateId ) -> impl Iterator < Item = CrateId > {
419
421
let mut worklist = vec ! [ of] ;
420
- let mut deps = NoHashHashSet :: default ( ) ;
422
+ let mut deps = FxHashSet :: default ( ) ;
421
423
422
424
while let Some ( krate) = worklist. pop ( ) {
423
425
if !deps. insert ( krate) {
@@ -434,11 +436,11 @@ impl CrateGraph {
434
436
/// including the crate itself.
435
437
pub fn transitive_rev_deps ( & self , of : CrateId ) -> impl Iterator < Item = CrateId > {
436
438
let mut worklist = vec ! [ of] ;
437
- let mut rev_deps = NoHashHashSet :: default ( ) ;
439
+ let mut rev_deps = FxHashSet :: default ( ) ;
438
440
rev_deps. insert ( of) ;
439
441
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) | {
442
444
data. dependencies
443
445
. iter ( )
444
446
. for_each ( |dep| inverted_graph. entry ( dep. crate_id ) . or_default ( ) . push ( krate) )
@@ -461,17 +463,17 @@ impl CrateGraph {
461
463
/// come before the crate itself).
462
464
pub fn crates_in_topological_order ( & self ) -> Vec < CrateId > {
463
465
let mut res = Vec :: new ( ) ;
464
- let mut visited = NoHashHashSet :: default ( ) ;
466
+ let mut visited = FxHashSet :: default ( ) ;
465
467
466
- for krate in self . arena . keys ( ) . copied ( ) {
468
+ for krate in self . iter ( ) {
467
469
go ( self , & mut visited, & mut res, krate) ;
468
470
}
469
471
470
472
return res;
471
473
472
474
fn go (
473
475
graph : & CrateGraph ,
474
- visited : & mut NoHashHashSet < CrateId > ,
476
+ visited : & mut FxHashSet < CrateId > ,
475
477
res : & mut Vec < CrateId > ,
476
478
source : CrateId ,
477
479
) {
@@ -487,7 +489,7 @@ impl CrateGraph {
487
489
488
490
// FIXME: this only finds one crate with the given root; we could have multiple
489
491
pub fn crate_id_for_crate_root ( & self , file_id : FileId ) -> Option < CrateId > {
490
- let ( & crate_id, _) =
492
+ let ( crate_id, _) =
491
493
self . arena . iter ( ) . find ( |( _crate_id, data) | data. root_file_id == file_id) ?;
492
494
Some ( crate_id)
493
495
}
@@ -499,24 +501,26 @@ impl CrateGraph {
499
501
/// amount.
500
502
pub fn extend ( & mut self , other : CrateGraph , proc_macros : & mut ProcMacroPaths ) -> u32 {
501
503
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) | {
504
505
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) ) ;
506
508
}
507
- ( new_id , data)
509
+ data
508
510
} ) ) ;
509
511
510
512
* proc_macros = mem:: take ( proc_macros)
511
513
. 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
+ } )
513
517
. collect ( ) ;
514
518
start
515
519
}
516
520
517
521
fn find_path (
518
522
& self ,
519
- visited : & mut NoHashHashSet < CrateId > ,
523
+ visited : & mut FxHashSet < CrateId > ,
520
524
from : CrateId ,
521
525
to : CrateId ,
522
526
) -> Option < Vec < CrateId > > {
@@ -546,10 +550,8 @@ impl CrateGraph {
546
550
let std = self . hacky_find_crate ( "std" ) ;
547
551
match ( cfg_if, std) {
548
552
( 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]
553
555
. dependencies
554
556
. push ( Dependency :: new ( CrateName :: new ( "cfg_if" ) . unwrap ( ) , cfg_if) ) ;
555
557
true
@@ -566,13 +568,7 @@ impl CrateGraph {
566
568
impl ops:: Index < CrateId > for CrateGraph {
567
569
type Output = CrateData ;
568
570
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]
576
572
}
577
573
}
578
574
0 commit comments