@@ -262,22 +262,15 @@ fn compute_deps(
262
262
return compute_deps_doc ( unit, state, unit_for) ;
263
263
}
264
264
265
- let id = unit. pkg . package_id ( ) ;
266
-
267
- let filtered_deps = state. deps ( unit, unit_for) ;
268
-
269
265
let mut ret = Vec :: new ( ) ;
270
266
let mut dev_deps = Vec :: new ( ) ;
271
- for ( dep_pkg_id, deps) in filtered_deps {
272
- let dep_pkg = state. get ( dep_pkg_id) ;
273
- let ( could_have_non_artifact_lib, has_artifact_lib) =
274
- calc_artifact_deps ( unit, unit_for, dep_pkg_id, deps, state, & mut ret) ?;
275
-
276
- let lib = package_lib ( dep_pkg, could_have_non_artifact_lib, has_artifact_lib) ;
277
- let dep_lib = match lib {
278
- Some ( t) => t,
267
+ for ( dep_pkg_id, deps) in state. deps ( unit, unit_for) {
268
+ let dep_lib = match calc_artifact_deps ( unit, unit_for, dep_pkg_id, & deps, state, & mut ret) ?
269
+ {
270
+ Some ( lib) => lib,
279
271
None => continue ,
280
272
} ;
273
+ let dep_pkg = state. get ( dep_pkg_id) ;
281
274
let mode = check_or_build_mode ( unit. mode , dep_lib) ;
282
275
let dep_unit_for = unit_for. with_dependency ( unit, dep_lib, unit_for. root_compile_kind ( ) ) ;
283
276
@@ -357,6 +350,7 @@ fn compute_deps(
357
350
&& unit. mode . is_any_test ( )
358
351
&& ( unit. target . is_test ( ) || unit. target . is_bench ( ) )
359
352
{
353
+ let id = unit. pkg . package_id ( ) ;
360
354
ret. extend (
361
355
unit. pkg
362
356
. targets ( )
@@ -396,49 +390,28 @@ fn compute_deps(
396
390
Ok ( ret)
397
391
}
398
392
399
- /// Try to find a target in `dep_pkg` which is a library.
400
- ///
401
- /// `has_artifact` is true if `dep_pkg` has any artifact, and `artifact_lib` is true
402
- /// if any of them wants a library to be available too.
403
- fn package_lib (
404
- dep_pkg : & Package ,
405
- could_have_non_artifact_lib : bool ,
406
- artifact_lib : bool ,
407
- ) -> Option < & Target > {
408
- dep_pkg
409
- . targets ( )
410
- . iter ( )
411
- . find ( |t| t. is_lib ( ) && ( could_have_non_artifact_lib || artifact_lib) )
412
- }
413
-
414
393
/// Find artifacts for all `deps` of `unit` and add units that build these artifacts
415
394
/// to `ret`.
416
- fn calc_artifact_deps (
395
+ fn calc_artifact_deps < ' a > (
417
396
unit : & Unit ,
418
397
unit_for : UnitFor ,
419
398
dep_id : PackageId ,
420
- deps : & HashSet < Dependency > ,
421
- state : & State < ' _ , ' _ > ,
399
+ deps : & [ & Dependency ] ,
400
+ state : & State < ' a , ' _ > ,
422
401
ret : & mut Vec < UnitDep > ,
423
- ) -> CargoResult < ( bool , bool ) > {
402
+ ) -> CargoResult < Option < & ' a Target > > {
424
403
let mut has_artifact_lib = false ;
425
- let mut num_artifacts = 0 ;
404
+ let mut maybe_non_artifact_lib = false ;
426
405
let artifact_pkg = state. get ( dep_id) ;
427
- let mut deps_past_filter = 0 ;
428
- for ( dep, artifact) in deps
429
- . iter ( )
430
- . filter ( |dep| {
431
- if non_custom_and_non_transitive_deps ( unit, dep) {
432
- deps_past_filter += 1 ;
433
- true
434
- } else {
435
- false
406
+ for dep in deps {
407
+ let artifact = match dep. artifact ( ) {
408
+ Some ( a) => a,
409
+ None => {
410
+ maybe_non_artifact_lib = true ;
411
+ continue ;
436
412
}
437
- } )
438
- . filter_map ( |dep| dep. artifact ( ) . map ( |a| ( dep, a) ) )
439
- {
413
+ } ;
440
414
has_artifact_lib |= artifact. is_lib ( ) ;
441
- num_artifacts += 1 ;
442
415
// Custom build scripts (build/compile) never get artifact dependencies,
443
416
// but the run-build-script step does (where it is handled).
444
417
if !unit. target . is_custom_build ( ) {
@@ -462,8 +435,11 @@ fn calc_artifact_deps(
462
435
) ?) ;
463
436
}
464
437
}
465
- let could_be_non_artifact_lib = deps_past_filter != num_artifacts;
466
- Ok ( ( could_be_non_artifact_lib, has_artifact_lib) )
438
+ if has_artifact_lib || maybe_non_artifact_lib {
439
+ Ok ( artifact_pkg. targets ( ) . iter ( ) . find ( |t| t. is_lib ( ) ) )
440
+ } else {
441
+ Ok ( None )
442
+ }
467
443
}
468
444
469
445
/// Returns the dependencies needed to run a build script.
@@ -519,10 +495,7 @@ fn compute_deps_custom_build(
519
495
//
520
496
// This is essentially the same as `calc_artifact_deps`, but there are some
521
497
// subtle differences that require this to be implemented differently.
522
- let artifact_build_deps = state. deps_filtered ( unit, script_unit_for, & |_unit, dep| {
523
- dep. kind ( ) == DepKind :: Build && dep. artifact ( ) . is_some ( )
524
- } ) ;
525
-
498
+ //
526
499
// Produce units that build all required artifact kinds (like binaries,
527
500
// static libraries, etc) with the correct compile target.
528
501
//
@@ -532,10 +505,13 @@ fn compute_deps_custom_build(
532
505
// `root_unit_compile_target` necessary.
533
506
let root_unit_compile_target = unit_for. root_compile_kind ( ) ;
534
507
let unit_for = UnitFor :: new_host ( /*host_features*/ true , root_unit_compile_target) ;
535
- for ( dep_pkg_id, deps) in artifact_build_deps {
536
- let artifact_pkg = state. get ( dep_pkg_id) ;
537
- for build_dep in deps. iter ( ) . filter ( |d| d. is_build ( ) ) {
538
- let artifact = build_dep. artifact ( ) . expect ( "artifact dep" ) ;
508
+ for ( dep_pkg_id, deps) in state. deps ( unit, script_unit_for) {
509
+ for dep in deps {
510
+ if dep. kind ( ) != DepKind :: Build || dep. artifact ( ) . is_none ( ) {
511
+ continue ;
512
+ }
513
+ let artifact_pkg = state. get ( dep_pkg_id) ;
514
+ let artifact = dep. artifact ( ) . expect ( "artifact dep" ) ;
539
515
let resolved_artifact_compile_kind = artifact
540
516
. target ( )
541
517
. map ( |target| target. to_resolved_compile_kind ( root_unit_compile_target) ) ;
@@ -548,7 +524,7 @@ fn compute_deps_custom_build(
548
524
state,
549
525
resolved_artifact_compile_kind. unwrap_or ( CompileKind :: Host ) ,
550
526
artifact_pkg,
551
- build_dep ,
527
+ dep ,
552
528
) ?) ;
553
529
}
554
530
}
@@ -663,22 +639,16 @@ fn compute_deps_doc(
663
639
state : & mut State < ' _ , ' _ > ,
664
640
unit_for : UnitFor ,
665
641
) -> CargoResult < Vec < UnitDep > > {
666
- let deps = state. deps ( unit, unit_for) ;
667
-
668
642
// To document a library, we depend on dependencies actually being
669
643
// built. If we're documenting *all* libraries, then we also depend on
670
644
// the documentation of the library being built.
671
645
let mut ret = Vec :: new ( ) ;
672
- for ( id, deps) in deps {
673
- let ( could_have_non_artifact_lib, has_artifact_lib) =
674
- calc_artifact_deps ( unit, unit_for, id, deps, state, & mut ret) ?;
675
-
676
- let dep_pkg = state. get ( id) ;
677
- let lib = package_lib ( dep_pkg, could_have_non_artifact_lib, has_artifact_lib) ;
678
- let dep_lib = match lib {
646
+ for ( id, deps) in state. deps ( unit, unit_for) {
647
+ let dep_lib = match calc_artifact_deps ( unit, unit_for, id, & deps, state, & mut ret) ? {
679
648
Some ( lib) => lib,
680
649
None => continue ,
681
650
} ;
651
+ let dep_pkg = state. get ( id) ;
682
652
// Rustdoc only needs rmeta files for regular dependencies.
683
653
// However, for plugins/proc macros, deps should be built like normal.
684
654
let mode = check_or_build_mode ( unit. mode , dep_lib) ;
@@ -1098,73 +1068,61 @@ impl<'a, 'cfg> State<'a, 'cfg> {
1098
1068
. unwrap_or_else ( |_| panic ! ( "expected {} to be downloaded" , id) )
1099
1069
}
1100
1070
1101
- /// Returns a set of dependencies for the given unit, with a default filter.
1102
- fn deps ( & self , unit : & Unit , unit_for : UnitFor ) -> Vec < ( PackageId , & HashSet < Dependency > ) > {
1103
- self . deps_filtered ( unit, unit_for, & non_custom_and_non_transitive_deps)
1104
- }
1105
-
1106
1071
/// Returns a filtered set of dependencies for the given unit.
1107
- fn deps_filtered (
1108
- & self ,
1109
- unit : & Unit ,
1110
- unit_for : UnitFor ,
1111
- filter : & dyn Fn ( & Unit , & Dependency ) -> bool ,
1112
- ) -> Vec < ( PackageId , & HashSet < Dependency > ) > {
1072
+ fn deps ( & self , unit : & Unit , unit_for : UnitFor ) -> Vec < ( PackageId , Vec < & Dependency > ) > {
1113
1073
let pkg_id = unit. pkg . package_id ( ) ;
1114
1074
let kind = unit. kind ;
1115
1075
self . resolve ( )
1116
1076
. deps ( pkg_id)
1117
- . filter ( | & ( _id , deps) | {
1077
+ . filter_map ( | ( id , deps) | {
1118
1078
assert ! ( !deps. is_empty( ) ) ;
1119
- deps. iter ( ) . any ( |dep| {
1120
- if !filter ( unit, dep) {
1121
- return false ;
1122
- }
1079
+ let deps: Vec < _ > = deps
1080
+ . iter ( )
1081
+ . filter ( |dep| {
1082
+ // If this target is a build command, then we only want build
1083
+ // dependencies, otherwise we want everything *other than* build
1084
+ // dependencies.
1085
+ if unit. target . is_custom_build ( ) != dep. is_build ( ) {
1086
+ return false ;
1087
+ }
1123
1088
1124
- // If this dependency is only available for certain platforms,
1125
- // make sure we're only enabling it for that platform.
1126
- if !self . target_data . dep_platform_activated ( dep, kind) {
1127
- return false ;
1128
- }
1089
+ // If this dependency is **not** a transitive dependency, then it
1090
+ // only applies to test/example targets.
1091
+ if !dep. is_transitive ( )
1092
+ && !unit. target . is_test ( )
1093
+ && !unit. target . is_example ( )
1094
+ && !unit. mode . is_doc_scrape ( )
1095
+ && !unit. mode . is_any_test ( )
1096
+ {
1097
+ return false ;
1098
+ }
1129
1099
1130
- // If this is an optional dependency, and the new feature resolver
1131
- // did not enable it, don't include it.
1132
- if dep. is_optional ( ) {
1133
- let features_for = unit_for. map_to_features_for ( dep. artifact ( ) ) ;
1134
- if !self . is_dep_activated ( pkg_id, features_for, dep. name_in_toml ( ) ) {
1100
+ // If this dependency is only available for certain platforms,
1101
+ // make sure we're only enabling it for that platform.
1102
+ if !self . target_data . dep_platform_activated ( dep, kind) {
1135
1103
return false ;
1136
1104
}
1137
- }
1138
1105
1139
- // If we've gotten past all that, then this dependency is
1140
- // actually used!
1141
- true
1142
- } )
1106
+ // If this is an optional dependency, and the new feature resolver
1107
+ // did not enable it, don't include it.
1108
+ if dep. is_optional ( ) {
1109
+ let features_for = unit_for. map_to_features_for ( dep. artifact ( ) ) ;
1110
+ if !self . is_dep_activated ( pkg_id, features_for, dep. name_in_toml ( ) ) {
1111
+ return false ;
1112
+ }
1113
+ }
1114
+
1115
+ // If we've gotten past all that, then this dependency is
1116
+ // actually used!
1117
+ true
1118
+ } )
1119
+ . collect ( ) ;
1120
+ if deps. is_empty ( ) {
1121
+ None
1122
+ } else {
1123
+ Some ( ( id, deps) )
1124
+ }
1143
1125
} )
1144
1126
. collect ( )
1145
1127
}
1146
1128
}
1147
-
1148
- fn non_custom_and_non_transitive_deps ( unit : & Unit , dep : & Dependency ) -> bool {
1149
- // If this target is a build command, then we only want build
1150
- // dependencies, otherwise we want everything *other than* build
1151
- // dependencies.
1152
- if unit. target . is_custom_build ( ) != dep. is_build ( ) {
1153
- return false ;
1154
- }
1155
-
1156
- // If this dependency is **not** a transitive dependency, then it
1157
- // only applies to test/example targets.
1158
- if !dep. is_transitive ( )
1159
- && !unit. target . is_test ( )
1160
- && !unit. target . is_example ( )
1161
- && !unit. mode . is_doc_scrape ( )
1162
- && !unit. mode . is_any_test ( )
1163
- {
1164
- return false ;
1165
- }
1166
-
1167
- // If we've gotten past all that, then this dependency is
1168
- // actually used!
1169
- true
1170
- }
0 commit comments