@@ -301,15 +301,24 @@ pub fn resolve_features<'b>(
301
301
302
302
let reqs = build_requirements ( parent, s, opts) ?;
303
303
let mut ret = Vec :: new ( ) ;
304
- let default_dep = BTreeSet :: new ( ) ;
304
+ let default_dep = ( false , BTreeSet :: new ( ) ) ;
305
305
let mut valid_dep_names = HashSet :: new ( ) ;
306
306
307
307
// Next, collect all actually enabled dependencies and their features.
308
308
for dep in deps {
309
309
// Skip optional dependencies, but not those enabled through a
310
310
// feature
311
- if dep. is_optional ( ) && !reqs. deps . contains_key ( & dep. name_in_toml ( ) ) {
312
- continue ;
311
+ if dep. is_optional ( ) {
312
+ let disabled = reqs
313
+ . deps
314
+ . get ( & dep. name_in_toml ( ) )
315
+ . map ( |( weak, _) | {
316
+ * weak && !reqs. features . contains ( & dep. name_in_toml ( ) )
317
+ } )
318
+ . unwrap_or ( true ) ;
319
+ if disabled {
320
+ continue ;
321
+ }
313
322
}
314
323
valid_dep_names. insert ( dep. name_in_toml ( ) ) ;
315
324
// So we want this dependency. Move the features we want from
@@ -319,7 +328,8 @@ pub fn resolve_features<'b>(
319
328
. deps
320
329
. get ( & dep. name_in_toml ( ) )
321
330
. unwrap_or ( & default_dep)
322
- . clone ( ) ;
331
+ . clone ( )
332
+ . 1 ;
323
333
base. extend ( dep. features ( ) . iter ( ) ) ;
324
334
ret. push ( ( dep. clone ( ) , Rc :: new ( base) ) ) ;
325
335
}
@@ -400,11 +410,11 @@ fn build_requirements<'a, 'b: 'a>(
400
410
#[ derive( Debug ) ]
401
411
struct Requirements < ' a > {
402
412
summary : & ' a Summary ,
403
- /// The deps map is a mapping of dependency name to list of features enabled.
413
+ /// The deps map is a mapping of dependency name to (weak, list of features enabled) .
404
414
///
405
- /// The resolver will activate all of these dependencies, with the given
406
- /// features enabled.
407
- deps : HashMap < InternedString , BTreeSet < InternedString > > ,
415
+ /// Non-weak deps will all be activated, while for weak deps the
416
+ /// corresponding feature needs to be enabled first .
417
+ deps : HashMap < InternedString , ( bool , BTreeSet < InternedString > ) > ,
408
418
/// The set of features enabled on this package which is later used when
409
419
/// compiling to instruct the code what features were enabled.
410
420
features : HashSet < InternedString > ,
@@ -457,7 +467,16 @@ impl Requirements<'_> {
457
467
{
458
468
self . require_feature ( package) ?;
459
469
}
460
- self . deps . entry ( package) . or_default ( ) . insert ( feat) ;
470
+
471
+ let dep = self
472
+ . deps
473
+ . entry ( package)
474
+ . or_insert_with ( || ( weak, BTreeSet :: new ( ) ) ) ;
475
+ // If the feature is non-weak, mark the entire dep as non-weak.
476
+ dep. 0 &= weak;
477
+ // Add the feature as to be enabled.
478
+ dep. 1 . insert ( feat) ;
479
+
461
480
Ok ( ( ) )
462
481
}
463
482
@@ -494,9 +513,6 @@ impl Requirements<'_> {
494
513
FeatureValue :: DepFeature {
495
514
dep_name,
496
515
dep_feature,
497
- // Weak features are always activated in the dependency
498
- // resolver. They will be narrowed inside the new feature
499
- // resolver.
500
516
weak,
501
517
} => self . require_dep_feature ( * dep_name, * dep_feature, * weak) ?,
502
518
} ;
0 commit comments