1- use std:: collections:: { HashMap , HashSet } ;
21use std:: cell:: Cell ;
2+ use std:: collections:: { HashMap , HashSet } ;
33use std:: io;
44use std:: marker;
55use std:: sync:: mpsc:: { channel, Receiver , Sender } ;
@@ -152,7 +152,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
152152 job : Job ,
153153 ) -> CargoResult < ( ) > {
154154 let dependencies = cx. dep_targets ( unit) ;
155- let dependencies = dependencies
155+ let mut queue_deps = dependencies
156156 . iter ( )
157157 . filter ( |unit| {
158158 // Binaries aren't actually needed to *compile* tests, just to run
@@ -171,10 +171,52 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
171171 Artifact :: All
172172 } ;
173173 ( dep, artifact)
174- } ) ;
175- self . queue . queue ( * unit, job, dependencies) ;
174+ } )
175+ . collect :: < Vec < _ > > ( ) ;
176+
177+ // This is somewhat tricky, but we may need to synthesize some
178+ // dependencies for this target if it requires full upstream
179+ // compilations to have completed. If we're in pipelining mode then some
180+ // dependency edges may be `Metadata` due to the above clause (as
181+ // opposed to everything being `All`). For example consider:
182+ //
183+ // a (binary)
184+ // └ b (lib)
185+ // └ c (lib)
186+ //
187+ // Here the dependency edge from B to C will be `Metadata`, and the
188+ // dependency edge from A to B will be `All`. For A to be compiled,
189+ // however, it currently actually needs the full rlib of C. This means
190+ // that we need to synthesize a dependency edge for the dependency graph
191+ // from A to C. That's done here.
192+ //
193+ // This will walk all dependencies of the current target, and if any of
194+ // *their* dependencies are `Metadata` then we depend on the `All` of
195+ // the target as well. This should ensure that edges changed to
196+ // `Metadata` propagate upwards `All` dependencies to anything that
197+ // transitively contains the `Metadata` edge.
198+ if unit. target . requires_upstream_objects ( ) {
199+ for dep in dependencies. iter ( ) {
200+ depend_on_deps_of_deps ( cx, & mut queue_deps, dep) ;
201+ }
202+
203+ fn depend_on_deps_of_deps < ' a > (
204+ cx : & Context < ' a , ' _ > ,
205+ deps : & mut Vec < ( Unit < ' a > , Artifact ) > ,
206+ unit : & Unit < ' a > ,
207+ ) {
208+ for dep in cx. dep_targets ( unit) {
209+ if cx. only_requires_rmeta ( unit, & dep) {
210+ deps. push ( ( dep, Artifact :: All ) ) ;
211+ depend_on_deps_of_deps ( cx, deps, & dep) ;
212+ }
213+ }
214+ }
215+ }
216+
217+ self . queue . queue ( * unit, job, queue_deps) ;
176218 * self . counts . entry ( unit. pkg . package_id ( ) ) . or_insert ( 0 ) += 1 ;
177- Ok ( ( ) )
219+ return Ok ( ( ) ) ;
178220 }
179221
180222 /// Executes all jobs necessary to build the dependency graph.
@@ -430,7 +472,6 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
430472 cx : & Context < ' a , ' _ > ,
431473 scope : & Scope < ' a > ,
432474 ) -> CargoResult < ( ) > {
433-
434475 let id = self . next_id ;
435476 self . next_id = id. checked_add ( 1 ) . unwrap ( ) ;
436477
@@ -464,7 +505,9 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
464505 // we need to make sure that the metadata is flagged as produced so
465506 // send a synthetic message here.
466507 if state. rmeta_required . get ( ) && res. is_ok ( ) {
467- my_tx. send ( Message :: Finish ( id, Artifact :: Metadata , Ok ( ( ) ) ) ) . unwrap ( ) ;
508+ my_tx
509+ . send ( Message :: Finish ( id, Artifact :: Metadata , Ok ( ( ) ) ) )
510+ . unwrap ( ) ;
468511 }
469512
470513 my_tx. send ( Message :: Finish ( id, Artifact :: All , res) ) . unwrap ( ) ;
@@ -513,7 +556,12 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
513556 Ok ( ( ) )
514557 }
515558
516- fn finish ( & mut self , unit : & Unit < ' a > , artifact : Artifact , cx : & mut Context < ' _ , ' _ > ) -> CargoResult < ( ) > {
559+ fn finish (
560+ & mut self ,
561+ unit : & Unit < ' a > ,
562+ artifact : Artifact ,
563+ cx : & mut Context < ' _ , ' _ > ,
564+ ) -> CargoResult < ( ) > {
517565 if unit. mode . is_run_custom_build ( ) && cx. bcx . show_warnings ( unit. pkg . package_id ( ) ) {
518566 self . emit_warnings ( None , unit, cx) ?;
519567 }
0 commit comments