@@ -231,12 +231,16 @@ fn rustc<'a, 'cfg>(
231
231
// present it if we can.
232
232
let extract_rendered_errors = if rmeta_produced {
233
233
match cx. bcx . build_config . message_format {
234
- MessageFormat :: Json => false ,
234
+ MessageFormat :: Json => {
235
+ rustc. arg ( "-Zemit-directives" ) ;
236
+ false
237
+ }
235
238
MessageFormat :: Human => {
236
239
rustc
237
240
. arg ( "--error-format=json" )
238
241
. arg ( "--json-rendered=termcolor" )
239
- . arg ( "-Zunstable-options" ) ;
242
+ . arg ( "-Zunstable-options" )
243
+ . arg ( "-Zemit-directives" ) ;
240
244
true
241
245
}
242
246
@@ -315,32 +319,20 @@ fn rustc<'a, 'cfg>(
315
319
mode,
316
320
& mut |line| on_stdout_line ( state, line, package_id, & target) ,
317
321
& 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
+ )
319
330
} ,
320
331
)
321
332
. map_err ( internal_if_simple_exit_code)
322
333
. chain_err ( || format ! ( "Could not compile `{}`." , name) ) ?;
323
334
}
324
335
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
-
344
336
if do_rename && real_name != crate_name {
345
337
let dst = & outputs[ 0 ] . path ;
346
338
let src = dst. with_file_name (
@@ -698,7 +690,7 @@ fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult
698
690
rustdoc
699
691
. exec_with_streaming (
700
692
& 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 ) ,
702
694
false ,
703
695
)
704
696
. chain_err ( || format ! ( "Could not document `{}`." , name) ) ?;
@@ -1094,6 +1086,7 @@ fn on_stderr_line(
1094
1086
package_id : PackageId ,
1095
1087
target : & Target ,
1096
1088
extract_rendered_errors : bool ,
1089
+ look_for_metadata_directive : bool ,
1097
1090
) -> CargoResult < ( ) > {
1098
1091
// We primarily want to use this function to process JSON messages from
1099
1092
// rustc. The compiler should always print one JSON message per line, and
@@ -1124,6 +1117,27 @@ fn on_stderr_line(
1124
1117
}
1125
1118
}
1126
1119
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
+
1127
1141
// And failing all that above we should have a legitimate JSON diagnostic
1128
1142
// from the compiler, so wrap it in an external Cargo JSON message
1129
1143
// indicating which package it came from and then emit it.
0 commit comments