diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index cfbf233297c..919badfa4aa 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1322,6 +1322,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, epoch). Crates compiled with different epochs can be linked together."), run_dsymutil: Option = (None, parse_opt_bool, [TRACKED], "run `dsymutil` and delete intermediate object files"), + ui_testing: bool = (false, parse_bool, [UNTRACKED], + "format compiler diagnostics in a way that's better suitable for UI testing"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 9d7a9acc3d5..ed89bf0d806 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -919,11 +919,13 @@ pub fn build_session_with_codemap(sopts: config::Options, } (config::ErrorOutputType::Json(pretty), None) => { Box::new(JsonEmitter::stderr(Some(registry), codemap.clone(), - pretty, sopts.debugging_opts.approximate_suggestions)) + pretty, sopts.debugging_opts.approximate_suggestions) + .ui_testing(sopts.debugging_opts.ui_testing)) } (config::ErrorOutputType::Json(pretty), Some(dst)) => { Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone(), - pretty, sopts.debugging_opts.approximate_suggestions)) + pretty, sopts.debugging_opts.approximate_suggestions) + .ui_testing(sopts.debugging_opts.ui_testing)) } (config::ErrorOutputType::Short(color_config), None) => { Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), true, false)) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 86e77d404ff..31c1ddca794 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -25,6 +25,8 @@ use std::collections::{HashMap, HashSet}; use std::cmp::min; use unicode_width; +const ANONYMIZED_LINE_NUM: &str = "LL"; + /// Emitter trait for emitting errors. pub trait Emitter { /// Emit a structured diagnostic. @@ -108,6 +110,7 @@ pub struct EmitterWriter { short_message: bool, teach: bool, error_codes: HashSet, + ui_testing: bool, } struct FileWithAnnotatedLines { @@ -157,6 +160,7 @@ impl EmitterWriter { short_message, teach, error_codes: HashSet::new(), + ui_testing: false, } } else { EmitterWriter { @@ -165,6 +169,7 @@ impl EmitterWriter { short_message, teach, error_codes: HashSet::new(), + ui_testing: false, } } } @@ -180,9 +185,14 @@ impl EmitterWriter { short_message, teach, error_codes: HashSet::new(), + ui_testing: false, } } + pub fn ui_testing(self, ui_testing: bool) -> Self { + Self { ui_testing, ..self } + } + fn preprocess_annotations(&mut self, msp: &MultiSpan) -> Vec { fn add_annotation_to_file(file_vec: &mut Vec, file: Rc, @@ -334,9 +344,14 @@ impl EmitterWriter { // First create the source line we will highlight. buffer.puts(line_offset, code_offset, &source_string, Style::Quotation); + let line_index = if self.ui_testing { + ANONYMIZED_LINE_NUM.to_string() + } else { + line.line_index.to_string() + }; buffer.puts(line_offset, 0, - &(line.line_index.to_string()), + &line_index, Style::LineNumber); draw_col_separator(buffer, line_offset, width_offset - 2); @@ -1288,8 +1303,11 @@ impl EmitterWriter { span: &MultiSpan, children: &Vec, suggestions: &[CodeSuggestion]) { - let max_line_num = self.get_max_line_num(span, children); - let max_line_num_len = max_line_num.to_string().len(); + let max_line_num_len = if self.ui_testing { + ANONYMIZED_LINE_NUM.len() + } else { + self.get_max_line_num(span, children).to_string().len() + }; match self.emit_message_default(span, message, diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 98d5fa8f797..57f07ff33f5 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -40,6 +40,7 @@ pub struct JsonEmitter { pretty: bool, /// Whether "approximate suggestions" are enabled in the config approximate_suggestions: bool, + ui_testing: bool, } impl JsonEmitter { @@ -53,6 +54,7 @@ impl JsonEmitter { cm: code_map, pretty, approximate_suggestions, + ui_testing: false, } } @@ -73,8 +75,13 @@ impl JsonEmitter { cm: code_map, pretty, approximate_suggestions, + ui_testing: false, } } + + pub fn ui_testing(self, ui_testing: bool) -> Self { + Self { ui_testing, ..self } + } } impl Emitter for JsonEmitter { @@ -199,7 +206,8 @@ impl Diagnostic { } let buf = BufWriter::default(); let output = buf.clone(); - EmitterWriter::new(Box::new(buf), Some(je.cm.clone()), false, false).emit(db); + EmitterWriter::new(Box::new(buf), Some(je.cm.clone()), false, false) + .ui_testing(je.ui_testing).emit(db); let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); let output = String::from_utf8(output).unwrap(); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index e5bee56de80..3d751de3dbe 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1627,15 +1627,12 @@ impl<'test> TestCx<'test> { rustc.args(&["--error-format", "json"]); } } - Ui => if !self.props - .compile_flags - .iter() - .any(|s| s.starts_with("--error-format")) - { + Ui => { // In case no "--error-format" has been given in the test, we'll compile // a first time to get the compiler's output then compile with // "--error-format json" to check if all expected errors are actually there // and that no new one appeared. + rustc.arg("-Zui-testing"); } MirOpt => { rustc.args(&[