@@ -26,6 +26,22 @@ pub enum Node {
26
26
} ,
27
27
}
28
28
29
+ #[ derive( Debug , Copy , Hash , Eq , Clone , PartialEq ) ]
30
+ pub struct Edge {
31
+ kind : EdgeKind ,
32
+ node : usize ,
33
+ }
34
+
35
+ impl Edge {
36
+ pub fn kind ( & self ) -> EdgeKind {
37
+ self . kind
38
+ }
39
+
40
+ pub fn node ( & self ) -> usize {
41
+ self . node
42
+ }
43
+ }
44
+
29
45
/// The kind of edge, for separating dependencies into different sections.
30
46
#[ derive( Debug , Copy , Hash , Eq , Clone , PartialEq ) ]
31
47
pub enum EdgeKind {
@@ -42,20 +58,32 @@ pub enum EdgeKind {
42
58
/// The value is a `Vec` because each edge kind can have multiple outgoing
43
59
/// edges. For example, package "foo" can have multiple normal dependencies.
44
60
#[ derive( Clone ) ]
45
- struct Edges ( HashMap < EdgeKind , Vec < usize > > ) ;
61
+ struct Edges ( HashMap < EdgeKind , Vec < Edge > > ) ;
46
62
47
63
impl Edges {
48
64
fn new ( ) -> Edges {
49
65
Edges ( HashMap :: new ( ) )
50
66
}
51
67
52
68
/// Adds an edge pointing to the given node.
53
- fn add_edge ( & mut self , kind : EdgeKind , index : usize ) {
54
- let indexes = self . 0 . entry ( kind) . or_default ( ) ;
55
- if !indexes. contains ( & index ) {
56
- indexes. push ( index )
69
+ fn add_edge ( & mut self , edge : Edge ) {
70
+ let indexes = self . 0 . entry ( edge . kind ( ) ) . or_default ( ) ;
71
+ if !indexes. contains ( & edge ) {
72
+ indexes. push ( edge )
57
73
}
58
74
}
75
+
76
+ fn all ( & self ) -> impl Iterator < Item = & Edge > + ' _ {
77
+ self . 0 . values ( ) . flatten ( )
78
+ }
79
+
80
+ fn of_kind ( & self , kind : & EdgeKind ) -> & [ Edge ] {
81
+ self . 0 . get ( kind) . map ( Vec :: as_slice) . unwrap_or_default ( )
82
+ }
83
+
84
+ fn is_empty ( & self ) -> bool {
85
+ self . 0 . is_empty ( )
86
+ }
59
87
}
60
88
61
89
/// A graph of dependencies.
@@ -104,21 +132,17 @@ impl<'a> Graph<'a> {
104
132
}
105
133
106
134
/// Returns a list of nodes the given node index points to for the given kind.
107
- pub fn connected_nodes ( & self , from : usize , kind : & EdgeKind ) -> Vec < usize > {
108
- match self . edges [ from] . 0 . get ( kind) {
109
- Some ( indexes) => {
110
- // Created a sorted list for consistent output.
111
- let mut indexes = indexes. clone ( ) ;
112
- indexes. sort_unstable_by ( |a, b| self . nodes [ * a] . cmp ( & self . nodes [ * b] ) ) ;
113
- indexes
114
- }
115
- None => Vec :: new ( ) ,
116
- }
135
+ pub fn edges ( & self , from : usize , kind : & EdgeKind ) -> Vec < Edge > {
136
+ let edges = self . edges [ from] . of_kind ( kind) ;
137
+ // Created a sorted list for consistent output.
138
+ let mut edges = edges. to_owned ( ) ;
139
+ edges. sort_unstable_by ( |a, b| self . nodes [ a. node ( ) ] . cmp ( & self . nodes [ b. node ( ) ] ) ) ;
140
+ edges
117
141
}
118
142
119
143
/// Returns `true` if the given node has any outgoing edges.
120
144
pub fn has_outgoing_edges ( & self , index : usize ) -> bool {
121
- !self . edges [ index] . 0 . is_empty ( )
145
+ !self . edges [ index] . is_empty ( )
122
146
}
123
147
124
148
/// Gets a node by index.
@@ -184,11 +208,13 @@ impl<'a> Graph<'a> {
184
208
let new_from = new_graph. add_node ( node) ;
185
209
remap[ index] = Some ( new_from) ;
186
210
// Visit dependencies.
187
- for ( edge_kind, edge_indexes) in & graph. edges [ index] . 0 {
188
- for edge_index in edge_indexes {
189
- let new_to_index = visit ( graph, new_graph, remap, * edge_index) ;
190
- new_graph. edges [ new_from] . add_edge ( * edge_kind, new_to_index) ;
191
- }
211
+ for edge in graph. edges [ index] . all ( ) {
212
+ let new_to_index = visit ( graph, new_graph, remap, edge. node ( ) ) ;
213
+ let new_edge = Edge {
214
+ kind : edge. kind ( ) ,
215
+ node : new_to_index,
216
+ } ;
217
+ new_graph. edges [ new_from] . add_edge ( new_edge) ;
192
218
}
193
219
new_from
194
220
}
@@ -205,10 +231,12 @@ impl<'a> Graph<'a> {
205
231
pub fn invert ( & mut self ) {
206
232
let mut new_edges = vec ! [ Edges :: new( ) ; self . edges. len( ) ] ;
207
233
for ( from_idx, node_edges) in self . edges . iter ( ) . enumerate ( ) {
208
- for ( kind, edges) in & node_edges. 0 {
209
- for edge_idx in edges {
210
- new_edges[ * edge_idx] . add_edge ( * kind, from_idx) ;
211
- }
234
+ for edge in node_edges. all ( ) {
235
+ let new_edge = Edge {
236
+ kind : edge. kind ( ) ,
237
+ node : from_idx,
238
+ } ;
239
+ new_edges[ edge. node ( ) ] . add_edge ( new_edge) ;
212
240
}
213
241
}
214
242
self . edges = new_edges;
@@ -280,7 +308,7 @@ pub fn build<'a>(
280
308
) -> CargoResult < Graph < ' a > > {
281
309
let mut graph = Graph :: new ( package_map) ;
282
310
let mut members_with_features = ws. members_with_features ( specs, cli_features) ?;
283
- members_with_features. sort_unstable_by_key ( |e| e . 0 . package_id ( ) ) ;
311
+ members_with_features. sort_unstable_by_key ( |( member , _ ) | member . package_id ( ) ) ;
284
312
for ( member, cli_features) in members_with_features {
285
313
let member_id = member. package_id ( ) ;
286
314
let features_for = FeaturesFor :: from_for_host ( member. proc_macro ( ) ) ;
@@ -428,36 +456,28 @@ fn add_pkg(
428
456
requested_kind,
429
457
opts,
430
458
) ;
459
+ let new_edge = Edge {
460
+ kind : EdgeKind :: Dep ( dep. kind ( ) ) ,
461
+ node : dep_index,
462
+ } ;
431
463
if opts. graph_features {
432
464
// Add the dependency node with feature nodes in-between.
433
465
dep_name_map
434
466
. entry ( dep. name_in_toml ( ) )
435
467
. or_default ( )
436
468
. insert ( ( dep_index, dep. is_optional ( ) ) ) ;
437
469
if dep. uses_default_features ( ) {
438
- add_feature (
439
- graph,
440
- INTERNED_DEFAULT ,
441
- Some ( from_index) ,
442
- dep_index,
443
- EdgeKind :: Dep ( dep. kind ( ) ) ,
444
- ) ;
470
+ add_feature ( graph, INTERNED_DEFAULT , Some ( from_index) , new_edge) ;
445
471
}
446
472
for feature in dep. features ( ) . iter ( ) {
447
- add_feature (
448
- graph,
449
- * feature,
450
- Some ( from_index) ,
451
- dep_index,
452
- EdgeKind :: Dep ( dep. kind ( ) ) ,
453
- ) ;
473
+ add_feature ( graph, * feature, Some ( from_index) , new_edge) ;
454
474
}
455
475
if !dep. uses_default_features ( ) && dep. features ( ) . is_empty ( ) {
456
476
// No features, use a direct connection.
457
- graph. edges [ from_index] . add_edge ( EdgeKind :: Dep ( dep . kind ( ) ) , dep_index ) ;
477
+ graph. edges [ from_index] . add_edge ( new_edge ) ;
458
478
}
459
479
} else {
460
- graph. edges [ from_index] . add_edge ( EdgeKind :: Dep ( dep . kind ( ) ) , dep_index ) ;
480
+ graph. edges [ from_index] . add_edge ( new_edge ) ;
461
481
}
462
482
}
463
483
}
@@ -486,23 +506,30 @@ fn add_feature(
486
506
graph : & mut Graph < ' _ > ,
487
507
name : InternedString ,
488
508
from : Option < usize > ,
489
- to : usize ,
490
- kind : EdgeKind ,
509
+ to : Edge ,
491
510
) -> ( bool , usize ) {
492
511
// `to` *must* point to a package node.
493
- assert ! ( matches! { graph. nodes[ to] , Node :: Package { ..} } ) ;
512
+ assert ! ( matches! { graph. nodes[ to. node ( ) ] , Node :: Package { ..} } ) ;
494
513
let node = Node :: Feature {
495
- node_index : to,
514
+ node_index : to. node ( ) ,
496
515
name,
497
516
} ;
498
517
let ( missing, node_index) = match graph. index . get ( & node) {
499
518
Some ( idx) => ( false , * idx) ,
500
519
None => ( true , graph. add_node ( node) ) ,
501
520
} ;
502
521
if let Some ( from) = from {
503
- graph. edges [ from] . add_edge ( kind, node_index) ;
522
+ let from_edge = Edge {
523
+ kind : to. kind ( ) ,
524
+ node : node_index,
525
+ } ;
526
+ graph. edges [ from] . add_edge ( from_edge) ;
504
527
}
505
- graph. edges [ node_index] . add_edge ( EdgeKind :: Feature , to) ;
528
+ let to_edge = Edge {
529
+ kind : EdgeKind :: Feature ,
530
+ node : to. node ( ) ,
531
+ } ;
532
+ graph. edges [ node_index] . add_edge ( to_edge) ;
506
533
( missing, node_index)
507
534
}
508
535
@@ -535,7 +562,11 @@ fn add_cli_features(
535
562
for fv in to_add {
536
563
match fv {
537
564
FeatureValue :: Feature ( feature) => {
538
- let index = add_feature ( graph, feature, None , package_index, EdgeKind :: Feature ) . 1 ;
565
+ let feature_edge = Edge {
566
+ kind : EdgeKind :: Feature ,
567
+ node : package_index,
568
+ } ;
569
+ let index = add_feature ( graph, feature, None , feature_edge) . 1 ;
539
570
graph. cli_features . insert ( index) ;
540
571
}
541
572
// This is enforced by CliFeatures.
@@ -565,12 +596,18 @@ fn add_cli_features(
565
596
for ( dep_index, is_optional) in dep_connections {
566
597
if is_optional {
567
598
// Activate the optional dep on self.
568
- let index =
569
- add_feature ( graph, dep_name, None , package_index, EdgeKind :: Feature ) . 1 ;
599
+ let feature_edge = Edge {
600
+ kind : EdgeKind :: Feature ,
601
+ node : package_index,
602
+ } ;
603
+ let index = add_feature ( graph, dep_name, None , feature_edge) . 1 ;
570
604
graph. cli_features . insert ( index) ;
571
605
}
572
- let index =
573
- add_feature ( graph, dep_feature, None , dep_index, EdgeKind :: Feature ) . 1 ;
606
+ let dep_edge = Edge {
607
+ kind : EdgeKind :: Feature ,
608
+ node : dep_index,
609
+ } ;
610
+ let index = add_feature ( graph, dep_feature, None , dep_edge) . 1 ;
574
611
graph. cli_features . insert ( index) ;
575
612
}
576
613
}
@@ -626,13 +663,11 @@ fn add_feature_rec(
626
663
for fv in fvs {
627
664
match fv {
628
665
FeatureValue :: Feature ( dep_name) => {
629
- let ( missing, feat_index) = add_feature (
630
- graph,
631
- * dep_name,
632
- Some ( from) ,
633
- package_index,
634
- EdgeKind :: Feature ,
635
- ) ;
666
+ let feature_edge = Edge {
667
+ kind : EdgeKind :: Feature ,
668
+ node : package_index,
669
+ } ;
670
+ let ( missing, feat_index) = add_feature ( graph, * dep_name, Some ( from) , feature_edge) ;
636
671
// Don't recursive if the edge already exists to deal with cycles.
637
672
if missing {
638
673
add_feature_rec (
@@ -678,21 +713,18 @@ fn add_feature_rec(
678
713
let dep_pkg_id = graph. package_id_for_index ( dep_index) ;
679
714
if is_optional && !weak {
680
715
// Activate the optional dep on self.
681
- add_feature (
682
- graph,
683
- * dep_name,
684
- Some ( from) ,
685
- package_index,
686
- EdgeKind :: Feature ,
687
- ) ;
716
+ let feature_edge = Edge {
717
+ kind : EdgeKind :: Feature ,
718
+ node : package_index,
719
+ } ;
720
+ add_feature ( graph, * dep_name, Some ( from) , feature_edge) ;
688
721
}
689
- let ( missing, feat_index) = add_feature (
690
- graph,
691
- * dep_feature,
692
- Some ( from) ,
693
- dep_index,
694
- EdgeKind :: Feature ,
695
- ) ;
722
+ let dep_edge = Edge {
723
+ kind : EdgeKind :: Feature ,
724
+ node : dep_index,
725
+ } ;
726
+ let ( missing, feat_index) =
727
+ add_feature ( graph, * dep_feature, Some ( from) , dep_edge) ;
696
728
if missing {
697
729
add_feature_rec (
698
730
graph,
0 commit comments