@@ -1088,7 +1088,11 @@ fn check_duplicate_pkgs_in_lockfile(resolve: &Resolve) -> CargoResult<()> {
10881088 Ok ( ( ) )
10891089}
10901090
1091- /// re-run all used resolve_features so it can print warnings
1091+ /// Re-run all used `resolve_features` so it can print warnings.
1092+ /// Within the resolution loop we do not pass a `config` to `resolve_features`
1093+ /// this tells it not to print warnings. Hear we do pass `config` triggering it to print them.
1094+ /// This is done as the resolution is NP-Hard so the loop can potentially call `resolve features`
1095+ /// an exponential number of times, but this pass is linear in the number of dependencies.
10921096fn emit_warnings (
10931097 cx : & Context ,
10941098 resolve : & Resolve ,
@@ -1098,22 +1102,26 @@ fn emit_warnings(
10981102 let mut new_cx = cx. clone ( ) ;
10991103 new_cx. resolve_features = im_rc:: HashMap :: new ( ) ;
11001104 let mut features_from_dep = HashMap :: new ( ) ;
1101- for ( summery , method) in summaries {
1105+ for ( summary , method) in summaries {
11021106 for ( dep, features) in new_cx
1103- . resolve_features ( None , summery , & method, config)
1104- . expect ( "can not resolve_features for a required summery " )
1107+ . resolve_features ( None , summary , & method, config)
1108+ . expect ( "can not resolve_features for a required summary " )
11051109 {
1106- features_from_dep. insert ( ( summery . package_id ( ) , dep) , features) ;
1110+ features_from_dep. insert ( ( summary . package_id ( ) , dep) , features) ;
11071111 }
11081112 }
1109- for summery in resolve. sort ( ) . iter ( ) . rev ( ) . map ( |id| {
1113+ // crates enable features for their dependencies.
1114+ // So by iterating reverse topologically we process all of the parents before each child.
1115+ // Then we know all the needed features for each crate.
1116+ let topological_sort = resolve. sort ( ) ;
1117+ for summary in topological_sort. iter ( ) . rev ( ) . map ( |id| {
11101118 cx. activations
11111119 . get ( & id. as_activations_key ( ) )
11121120 . expect ( "id in dependency graph but not in activations" )
11131121 . 0
11141122 . clone ( )
11151123 } ) {
1116- for ( parent, deps) in cx. parents . edges ( & summery . package_id ( ) ) {
1124+ for ( parent, deps) in cx. parents . edges ( & summary . package_id ( ) ) {
11171125 for dep in deps. iter ( ) {
11181126 let features = features_from_dep
11191127 . remove ( & ( * parent, dep. clone ( ) ) )
@@ -1125,10 +1133,10 @@ fn emit_warnings(
11251133 uses_default_features : dep. uses_default_features ( ) ,
11261134 } ;
11271135 for ( dep, features) in new_cx
1128- . resolve_features ( None , & summery , & method, config)
1136+ . resolve_features ( None , & summary , & method, config)
11291137 . expect ( "can not resolve_features for a used dep" )
11301138 {
1131- features_from_dep. insert ( ( summery . package_id ( ) , dep) , features) ;
1139+ features_from_dep. insert ( ( summary . package_id ( ) , dep) , features) ;
11321140 }
11331141 }
11341142 }
0 commit comments