@@ -231,12 +231,16 @@ fn rustc<'a, 'cfg>(
231231 // present it if we can.
232232 let extract_rendered_errors = if rmeta_produced {
233233 match cx. bcx . build_config . message_format {
234- MessageFormat :: Json => false ,
234+ MessageFormat :: Json => {
235+ rustc. arg ( "-Zemit-directives" ) ;
236+ false
237+ }
235238 MessageFormat :: Human => {
236239 rustc
237240 . arg ( "--error-format=json" )
238241 . arg ( "--json-rendered=termcolor" )
239- . arg ( "-Zunstable-options" ) ;
242+ . arg ( "-Zunstable-options" )
243+ . arg ( "-Zemit-directives" ) ;
240244 true
241245 }
242246
@@ -315,32 +319,20 @@ fn rustc<'a, 'cfg>(
315319 mode,
316320 & mut |line| on_stdout_line ( state, line, package_id, & target) ,
317321 & mut |line| {
318- on_stderr_line ( state, line, package_id, & target, extract_rendered_errors)
322+ on_stderr_line (
323+ state,
324+ line,
325+ package_id,
326+ & target,
327+ extract_rendered_errors,
328+ rmeta_produced,
329+ )
319330 } ,
320331 )
321332 . map_err ( internal_if_simple_exit_code)
322333 . chain_err ( || format ! ( "Could not compile `{}`." , name) ) ?;
323334 }
324335
325- // FIXME(rust-lang/rust#58465): this is the whole point of "pipelined
326- // compilation" in Cargo. We want to, here in this unit, call
327- // `finish_rmeta` as soon as we can which indicates that the metadata
328- // file is emitted by rustc and ready to go. This will start dependency
329- // compilations as soon as possible.
330- //
331- // The compiler doesn't currently actually implement the ability to let
332- // us know, however, when the metadata file is ready to go. It actually
333- // today produces the file very late in compilation, far later than it
334- // would otherwise be able to do!
335- //
336- // In any case this is all covered by the issue above. This is just a
337- // marker for "yes we unconditionally do this today but tomorrow we
338- // should actually read what rustc is doing and execute this at an
339- // appropriate time, ideally long before rustc finishes completely".
340- if rmeta_produced {
341- state. rmeta_produced ( ) ;
342- }
343-
344336 if do_rename && real_name != crate_name {
345337 let dst = & outputs[ 0 ] . path ;
346338 let src = dst. with_file_name (
@@ -698,7 +690,7 @@ fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult
698690 rustdoc
699691 . exec_with_streaming (
700692 & mut |line| on_stdout_line ( state, line, package_id, & target) ,
701- & mut |line| on_stderr_line ( state, line, package_id, & target, false ) ,
693+ & mut |line| on_stderr_line ( state, line, package_id, & target, false , false ) ,
702694 false ,
703695 )
704696 . chain_err ( || format ! ( "Could not document `{}`." , name) ) ?;
@@ -1094,6 +1086,7 @@ fn on_stderr_line(
10941086 package_id : PackageId ,
10951087 target : & Target ,
10961088 extract_rendered_errors : bool ,
1089+ look_for_metadata_directive : bool ,
10971090) -> CargoResult < ( ) > {
10981091 // We primarily want to use this function to process JSON messages from
10991092 // rustc. The compiler should always print one JSON message per line, and
@@ -1124,6 +1117,27 @@ fn on_stderr_line(
11241117 }
11251118 }
11261119
1120+ // In some modes of execution we will execute rustc with `-Z
1121+ // emit-directives` to look for metadata files being produced. When this
1122+ // happens we may be able to start subsequent compilations more quickly than
1123+ // waiting for an entire compile to finish, possibly using more parallelism
1124+ // available to complete a compilation session more quickly.
1125+ //
1126+ // In these cases look for a matching directive and inform Cargo internally
1127+ // that a metadata file has been produced.
1128+ if look_for_metadata_directive {
1129+ #[ derive( serde:: Deserialize ) ]
1130+ struct CompilerDirective {
1131+ directive : String ,
1132+ }
1133+ if let Ok ( directive) = serde_json:: from_str :: < CompilerDirective > ( compiler_message. get ( ) ) {
1134+ if directive. directive . starts_with ( "metadata file written" ) {
1135+ state. rmeta_produced ( ) ;
1136+ return Ok ( ( ) )
1137+ }
1138+ }
1139+ }
1140+
11271141 // And failing all that above we should have a legitimate JSON diagnostic
11281142 // from the compiler, so wrap it in an external Cargo JSON message
11291143 // indicating which package it came from and then emit it.
0 commit comments