diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 084a5429f26..12427daa383 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1462,8 +1462,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, the same values as the target option of the same name"), allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], "only allow the listed language features to be enabled in code (space separated)"), - emit_directives: bool = (false, parse_bool, [UNTRACKED], - "emit build directives if producing JSON output"), + emit_artifact_notifications: bool = (false, parse_bool, [UNTRACKED], + "emit notifications after each artifact has been output (only in the JSON format)"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index bfc9113c2d4..59cbd65f05c 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -16,6 +16,7 @@ use std::borrow::Cow; use std::io::prelude::*; use std::io; use std::cmp::{min, Reverse}; +use std::path::Path; use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter, Ansi}; use termcolor::{WriteColor, Color, Buffer}; @@ -52,9 +53,10 @@ pub trait Emitter { /// Emit a structured diagnostic. fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>); - /// Emit a JSON directive. The default is to do nothing; this should only - /// be emitted with --error-format=json. - fn maybe_emit_json_directive(&mut self, _directive: String) {} + /// Emit a notification that an artifact has been output. + /// This is currently only supported for the JSON format, + /// other formats can, and will, simply ignore it. + fn emit_artifact_notification(&mut self, _path: &Path) {} /// Checks if should show explanations about "rustc --explain" fn should_show_explain(&self) -> bool { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index e173e1060cc..3aa87fad071 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -26,6 +26,7 @@ use std::borrow::Cow; use std::cell::Cell; use std::{error, fmt}; use std::panic; +use std::path::Path; use termcolor::{ColorSpec, Color}; @@ -294,16 +295,9 @@ impl error::Error for ExplicitBug { pub use diagnostic::{Diagnostic, SubDiagnostic, DiagnosticStyledString, DiagnosticId}; pub use diagnostic_builder::DiagnosticBuilder; -/// A handler deals with two kinds of compiler output. -/// - Errors: certain errors (fatal, bug, unimpl) may cause immediate exit, -/// others log errors for later reporting. -/// - Directives: with --error-format=json, the compiler produces directives -/// that indicate when certain actions have completed, which are useful for -/// Cargo. They may change at any time and should not be considered a public -/// API. -/// -/// This crate's name (rustc_errors) doesn't encompass the directives, because -/// directives were added much later. +/// A handler deals with errors and other compiler output. +/// Certain errors (fatal, bug, unimpl) may cause immediate exit, +/// others log errors for later reporting. pub struct Handler { pub flags: HandlerFlags, @@ -775,8 +769,8 @@ impl Handler { } } - pub fn maybe_emit_json_directive(&self, directive: String) { - self.emitter.borrow_mut().maybe_emit_json_directive(directive); + pub fn emit_artifact_notification(&self, path: &Path) { + self.emitter.borrow_mut().emit_artifact_notification(path); } } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 8543cca1dd5..54b3e734205 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -1048,14 +1048,11 @@ fn encode_and_write_metadata<'tcx>( tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)) }); let metadata_filename = emit_metadata(tcx.sess, &metadata, &metadata_tmpdir); - match std::fs::rename(&metadata_filename, &out_filename) { - Ok(_) => { - if tcx.sess.opts.debugging_opts.emit_directives { - tcx.sess.parse_sess.span_diagnostic.maybe_emit_json_directive( - format!("metadata file written: {}", out_filename.display())); - } - } - Err(e) => tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)), + if let Err(e) = fs::rename(&metadata_filename, &out_filename) { + tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)); + } + if tcx.sess.opts.debugging_opts.emit_artifact_notifications { + tcx.sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename); } } diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 65f8d0e77d7..2dd2ecb7493 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -19,6 +19,7 @@ use errors::emitter::{Emitter, HumanReadableErrorType}; use syntax_pos::{MacroBacktrace, Span, SpanLabel, MultiSpan}; use rustc_data_structures::sync::{self, Lrc}; use std::io::{self, Write}; +use std::path::Path; use std::vec; use std::sync::{Arc, Mutex}; @@ -91,15 +92,15 @@ impl Emitter for JsonEmitter { } } - fn maybe_emit_json_directive(&mut self, directive: String) { - let data = Directive { directive }; + fn emit_artifact_notification(&mut self, path: &Path) { + let data = ArtifactNotification { artifact: path }; let result = if self.pretty { writeln!(&mut self.dst, "{}", as_pretty_json(&data)) } else { writeln!(&mut self.dst, "{}", as_json(&data)) }; if let Err(e) = result { - panic!("failed to print message: {:?}", e); + panic!("failed to print notification: {:?}", e); } } } @@ -181,9 +182,9 @@ struct DiagnosticCode { } #[derive(RustcEncodable)] -struct Directive { - /// The directive itself. - directive: String, +struct ArtifactNotification<'a> { + /// The path of the artifact. + artifact: &'a Path, } impl Diagnostic { diff --git a/src/test/ui/emit-artifact-notifications.nll.stderr b/src/test/ui/emit-artifact-notifications.nll.stderr new file mode 100644 index 00000000000..347d9aeac23 --- /dev/null +++ b/src/test/ui/emit-artifact-notifications.nll.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/emit-artifact-notifications.nll/libemit_artifact_notifications.rmeta"} diff --git a/src/test/ui/emit-artifact-notifications.rs b/src/test/ui/emit-artifact-notifications.rs new file mode 100644 index 00000000000..c2c930c8b1b --- /dev/null +++ b/src/test/ui/emit-artifact-notifications.rs @@ -0,0 +1,6 @@ +// compile-flags:--emit=metadata --error-format=json -Z emit-artifact-notifications +// compile-pass + +// A very basic test for the emission of artifact notifications in JSON output. + +fn main() {} diff --git a/src/test/ui/emit-artifact-notifications.stderr b/src/test/ui/emit-artifact-notifications.stderr new file mode 100644 index 00000000000..56c977181ff --- /dev/null +++ b/src/test/ui/emit-artifact-notifications.stderr @@ -0,0 +1 @@ +{"artifact":"$TEST_BUILD_DIR/emit-artifact-notifications/libemit_artifact_notifications.rmeta"} diff --git a/src/test/ui/emit-directives.rs b/src/test/ui/emit-directives.rs deleted file mode 100644 index 924569d3e23..00000000000 --- a/src/test/ui/emit-directives.rs +++ /dev/null @@ -1,6 +0,0 @@ -// compile-flags:--emit=metadata --error-format=json -Z emit-directives -// compile-pass - -// A very basic test for the emission of build directives in JSON output. - -fn main() {} diff --git a/src/test/ui/emit-directives.stderr b/src/test/ui/emit-directives.stderr deleted file mode 100644 index 068745edb8d..00000000000 --- a/src/test/ui/emit-directives.stderr +++ /dev/null @@ -1 +0,0 @@ -{"directive":"metadata file written: $TEST_BUILD_DIR/emit-directives/libemit_directives.rmeta"} diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 26a3c4dee40..d651b9a92b6 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -4,7 +4,7 @@ use crate::errors::{Error, ErrorKind}; use crate::runtest::ProcRes; use serde_json; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::str::FromStr; #[derive(Deserialize)] @@ -18,9 +18,9 @@ struct Diagnostic { } #[derive(Deserialize)] -struct Directive { +struct ArtifactNotification { #[allow(dead_code)] - directive: String, + artifact: PathBuf, } #[derive(Deserialize, Clone)] @@ -75,8 +75,8 @@ pub fn extract_rendered(output: &str) -> String { if line.starts_with('{') { if let Ok(diagnostic) = serde_json::from_str::(line) { diagnostic.rendered - } else if let Ok(_directive) = serde_json::from_str::(line) { - // Swallow the directive. + } else if let Ok(_) = serde_json::from_str::(line) { + // Ignore the notification. None } else { print!(