@@ -293,12 +293,26 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
293
293
self . activate_fv ( pkg_id, fv, for_build) ?;
294
294
}
295
295
if !self . processed_deps . insert ( ( pkg_id, for_build) ) {
296
- // Already processed dependencies.
296
+ // Already processed dependencies. There's no need to process them
297
+ // again. This is primarily to avoid cycles, but also helps speed
298
+ // things up.
299
+ //
300
+ // This is safe because if another package comes along and adds a
301
+ // feature on this package, it will immediately add it (in
302
+ // `activate_fv`), and recurse as necessary right then and there.
303
+ // For example, consider we've already processed our dependencies,
304
+ // and another package comes along and enables one of our optional
305
+ // dependencies, it will do so immediately in the
306
+ // `FeatureValue::CrateFeature` branch, and then immediately
307
+ // recurse into that optional dependency. This also holds true for
308
+ // features that enable other features.
297
309
return Ok ( ( ) ) ;
298
310
}
299
311
for ( dep_pkg_id, deps) in self . deps ( pkg_id, for_build) {
300
312
for ( dep, dep_for_build) in deps {
301
313
if dep. is_optional ( ) {
314
+ // Optional dependencies are enabled in `activate_fv` when
315
+ // a feature enables it.
302
316
continue ;
303
317
}
304
318
// Recurse into the dependency.
0 commit comments