@@ -7,11 +7,36 @@ pub type FeaturesMap = BTreeMap<String, Vec<String>>;
77///
88/// See <https://rust-lang.github.io/rfcs/3143-cargo-weak-namespaced-features.html>.
99pub fn split_features ( features : FeaturesMap ) -> ( FeaturesMap , FeaturesMap ) {
10- features. into_iter ( ) . partition ( |( _k, vals) | {
11- !vals
12- . iter ( )
13- . any ( |v| v. starts_with ( "dep:" ) || v. contains ( "?/" ) )
14- } )
10+ // First, we partition the features into two groups: those that use the new
11+ // features syntax (`features2`) and those that don't (`features`).
12+ let ( mut features, mut features2) =
13+ features
14+ . into_iter ( )
15+ . partition :: < FeaturesMap , _ > ( |( _k, vals) | {
16+ !vals
17+ . iter ( )
18+ . any ( |v| v. starts_with ( "dep:" ) || v. contains ( "?/" ) )
19+ } ) ;
20+
21+ // Then, we recursively move features from `features` to `features2` if they
22+ // depend on features in `features2`.
23+ loop {
24+ let split = features
25+ . into_iter ( )
26+ . partition :: < FeaturesMap , _ > ( |( _k, vals) | {
27+ !vals. iter ( ) . any ( |v| features2. contains_key ( v) )
28+ } ) ;
29+
30+ features = split. 0 ;
31+
32+ if !split. 1 . is_empty ( ) {
33+ features2. extend ( split. 1 ) ;
34+ } else {
35+ break ;
36+ }
37+ }
38+
39+ ( features, features2)
1540}
1641
1742#[ cfg( test) ]
@@ -93,8 +118,8 @@ mod tests {
93118
94119 let ( features, features2) = split_features ( features) ;
95120
96- assert_compact_debug_snapshot ! ( features, @r#"{"feature1": ["feature2"], "feature2": ["feature3"]}"# ) ;
97- assert_compact_debug_snapshot ! ( features2, @r#"{"feature3": ["dep:foo"]}"# ) ;
121+ assert_compact_debug_snapshot ! ( features, @"{}" ) ;
122+ assert_compact_debug_snapshot ! ( features2, @r#"{"feature1": ["feature2"], "feature2": ["feature3"], " feature3": ["dep:foo"]}"# ) ;
98123 }
99124
100125 #[ test]
0 commit comments