From 83bca40350f1b78fbe00e7082c40b3ef79eae4ce Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 16 Sep 2017 19:24:08 +0200 Subject: [PATCH 1/2] Add short message-format --- src/librustc/session/config.rs | 12 +- src/librustc/session/mod.rs | 24 ++- src/librustc_driver/lib.rs | 8 +- src/librustc_errors/emitter.rs | 294 ++++++++++++++------------ src/librustc_errors/lib.rs | 2 +- src/librustdoc/test.rs | 3 +- src/libsyntax/parse/lexer/mod.rs | 4 +- src/libsyntax/test_snippet.rs | 3 +- src/test/ui/short-error-format.rs | 19 ++ src/test/ui/short-error-format.stderr | 3 + 10 files changed, 223 insertions(+), 149 deletions(-) create mode 100644 src/test/ui/short-error-format.rs create mode 100644 src/test/ui/short-error-format.stderr diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index f9a4b5bb9a537..2710094d4c1fe 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -156,6 +156,7 @@ impl OutputType { pub enum ErrorOutputType { HumanReadable(ColorConfig), Json, + Short(ColorConfig), } impl Default for ErrorOutputType { @@ -1362,7 +1363,7 @@ pub fn rustc_optgroups() -> Vec { opt::multi("Z", "", "Set internal debugging options", "FLAG"), opt::opt_s("", "error-format", "How errors and other messages are produced", - "human|json"), + "human|json|short"), opt::opt_s("", "color", "Configure coloring of output: auto = colorize, if output goes to a tty (default); always = always colorize output; @@ -1429,15 +1430,16 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) // opt_present because the latter will panic. let error_format = if matches.opts_present(&["error-format".to_owned()]) { match matches.opt_str("error-format").as_ref().map(|s| &s[..]) { - Some("human") => ErrorOutputType::HumanReadable(color), - Some("json") => ErrorOutputType::Json, + Some("human") => ErrorOutputType::HumanReadable(color), + Some("json") => ErrorOutputType::Json, + Some("short") => ErrorOutputType::Short(color), None => ErrorOutputType::HumanReadable(color), Some(arg) => { early_error(ErrorOutputType::HumanReadable(color), - &format!("argument for --error-format must be human or json (instead \ - was `{}`)", + &format!("argument for --error-format must be `human`, `json` or \ + `short` (instead was `{}`)", arg)) } } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 2634ab1000703..050487bcc0022 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -711,12 +711,10 @@ pub fn build_session_with_codemap(sopts: config::Options, let emitter: Box = match (sopts.error_format, emitter_dest) { (config::ErrorOutputType::HumanReadable(color_config), None) => { - Box::new(EmitterWriter::stderr(color_config, - Some(codemap.clone()))) + Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), false)) } (config::ErrorOutputType::HumanReadable(_), Some(dst)) => { - Box::new(EmitterWriter::new(dst, - Some(codemap.clone()))) + Box::new(EmitterWriter::new(dst, Some(codemap.clone()), false)) } (config::ErrorOutputType::Json, None) => { Box::new(JsonEmitter::stderr(Some(registry), codemap.clone())) @@ -724,6 +722,12 @@ pub fn build_session_with_codemap(sopts: config::Options, (config::ErrorOutputType::Json, Some(dst)) => { Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone())) } + (config::ErrorOutputType::Short(color_config), None) => { + Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), true)) + } + (config::ErrorOutputType::Short(_), Some(dst)) => { + Box::new(EmitterWriter::new(dst, Some(codemap.clone()), true)) + } }; let diagnostic_handler = @@ -867,10 +871,12 @@ pub enum IncrCompSession { pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { - Box::new(EmitterWriter::stderr(color_config, - None)) + Box::new(EmitterWriter::stderr(color_config, None, false)) } config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()), + config::ErrorOutputType::Short(color_config) => { + Box::new(EmitterWriter::stderr(color_config, None, true)) + } }; let handler = errors::Handler::with_emitter(true, false, emitter); handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal); @@ -880,10 +886,12 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { pub fn early_warn(output: config::ErrorOutputType, msg: &str) { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { - Box::new(EmitterWriter::stderr(color_config, - None)) + Box::new(EmitterWriter::stderr(color_config, None, false)) } config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()), + config::ErrorOutputType::Short(color_config) => { + Box::new(EmitterWriter::stderr(color_config, None, true)) + } }; let handler = errors::Handler::with_emitter(true, false, emitter); handler.emit(&MultiSpan::new(), msg, errors::Level::Warning); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3514302c6c8f3..fc503f4eb4be1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -138,7 +138,9 @@ pub fn run(run_compiler: F) -> isize } None => { let emitter = - errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None); + errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, + None, + true); let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); handler.emit(&MultiSpan::new(), "aborting due to previous error(s)", @@ -1208,7 +1210,9 @@ pub fn monitor(f: F) { // Thread panicked without emitting a fatal diagnostic if !value.is::() { let emitter = - Box::new(errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None)); + Box::new(errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, + None, + false)); let handler = errors::Handler::with_emitter(true, false, emitter); // a .span_bug or .bug call has already printed what diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 2f994de396c6f..5db5a9a1133d8 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -107,6 +107,7 @@ impl ColorConfig { pub struct EmitterWriter { dst: Destination, cm: Option>, + short_message: bool, } struct FileWithAnnotatedLines { @@ -116,25 +117,34 @@ struct FileWithAnnotatedLines { } impl EmitterWriter { - pub fn stderr(color_config: ColorConfig, code_map: Option>) -> EmitterWriter { + pub fn stderr(color_config: ColorConfig, + code_map: Option>, + short_message: bool) + -> EmitterWriter { if color_config.use_color() { let dst = Destination::from_stderr(); EmitterWriter { dst, cm: code_map, + short_message: short_message, } } else { EmitterWriter { dst: Raw(Box::new(io::stderr())), cm: code_map, + short_message: short_message, } } } - pub fn new(dst: Box, code_map: Option>) -> EmitterWriter { + pub fn new(dst: Box, + code_map: Option>, + short_message: bool) + -> EmitterWriter { EmitterWriter { dst: Raw(dst), cm: code_map, + short_message: short_message, } } @@ -671,7 +681,7 @@ impl EmitterWriter { Style::LabelSecondary }; Some((p, style)) - }, + } _ => None } @@ -689,11 +699,13 @@ impl EmitterWriter { } } } - for span_label in msp.span_labels() { - if span_label.span != DUMMY_SP { - let hi = cm.lookup_char_pos(span_label.span.hi()); - if hi.line > max { - max = hi.line; + if !self.short_message { + for span_label in msp.span_labels() { + if span_label.span != DUMMY_SP { + let hi = cm.lookup_char_pos(span_label.span.hi()); + if hi.line > max { + max = hi.line; + } } } } @@ -881,7 +893,8 @@ impl EmitterWriter { -> io::Result<()> { let mut buffer = StyledBuffer::new(); - if msp.primary_spans().is_empty() && msp.span_labels().is_empty() && is_secondary { + if msp.primary_spans().is_empty() && msp.span_labels().is_empty() && is_secondary + && !self.short_message { // This is a secondary message with no span info for _ in 0..max_line_num_len { buffer.prepend(0, " ", Style::NoStyle); @@ -916,12 +929,12 @@ impl EmitterWriter { if primary_span != &&DUMMY_SP { (cm.lookup_char_pos(primary_span.lo()), cm) } else { - emit_to_destination(&buffer.render(), level, &mut self.dst)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; return Ok(()); } } else { // If we don't have span information, emit and exit - emit_to_destination(&buffer.render(), level, &mut self.dst)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; return Ok(()); }; if let Ok(pos) = @@ -940,18 +953,24 @@ impl EmitterWriter { // to do this, we need to know if this span will be primary let is_primary = primary_lo.file.name == annotated_file.file.name; if is_primary { - // remember where we are in the output buffer for easy reference - let buffer_msg_line_offset = buffer.num_lines(); - - buffer.prepend(buffer_msg_line_offset, "--> ", Style::LineNumber); let loc = primary_lo.clone(); - buffer.append(buffer_msg_line_offset, - &format!("{}:{}:{}", loc.file.name, loc.line, loc.col.0 + 1), - Style::LineAndColumn); - for _ in 0..max_line_num_len { - buffer.prepend(buffer_msg_line_offset, " ", Style::NoStyle); + if !self.short_message { + // remember where we are in the output buffer for easy reference + let buffer_msg_line_offset = buffer.num_lines(); + + buffer.prepend(buffer_msg_line_offset, "--> ", Style::LineNumber); + buffer.append(buffer_msg_line_offset, + &format!("{}:{}:{}", loc.file.name, loc.line, loc.col.0 + 1), + Style::LineAndColumn); + for _ in 0..max_line_num_len { + buffer.prepend(buffer_msg_line_offset, " ", Style::NoStyle); + } + } else { + buffer.prepend(0, + &format!("{}:{}:{} - ", loc.file.name, loc.line, loc.col.0 + 1), + Style::LineAndColumn); } - } else { + } else if !self.short_message { // remember where we are in the output buffer for easy reference let buffer_msg_line_offset = buffer.num_lines(); @@ -968,104 +987,111 @@ impl EmitterWriter { } } - // Put in the spacer between the location and annotated source - let buffer_msg_line_offset = buffer.num_lines(); - draw_col_separator_no_space(&mut buffer, buffer_msg_line_offset, max_line_num_len + 1); + if !self.short_message { + // Put in the spacer between the location and annotated source + let buffer_msg_line_offset = buffer.num_lines(); + draw_col_separator_no_space(&mut buffer, + buffer_msg_line_offset, + max_line_num_len + 1); - // Contains the vertical lines' positions for active multiline annotations - let mut multilines = HashMap::new(); + // Contains the vertical lines' positions for active multiline annotations + let mut multilines = HashMap::new(); - // Next, output the annotate source for this file - for line_idx in 0..annotated_file.lines.len() { - let previous_buffer_line = buffer.num_lines(); + // Next, output the annotate source for this file + for line_idx in 0..annotated_file.lines.len() { + let previous_buffer_line = buffer.num_lines(); - let width_offset = 3 + max_line_num_len; - let code_offset = if annotated_file.multiline_depth == 0 { - width_offset - } else { - width_offset + annotated_file.multiline_depth + 1 - }; + let width_offset = 3 + max_line_num_len; + let code_offset = if annotated_file.multiline_depth == 0 { + width_offset + } else { + width_offset + annotated_file.multiline_depth + 1 + }; - let depths = self.render_source_line(&mut buffer, - annotated_file.file.clone(), - &annotated_file.lines[line_idx], - width_offset, - code_offset); + let depths = self.render_source_line(&mut buffer, + annotated_file.file.clone(), + &annotated_file.lines[line_idx], + width_offset, + code_offset); - let mut to_add = HashMap::new(); + let mut to_add = HashMap::new(); - for (depth, style) in depths { - if multilines.get(&depth).is_some() { - multilines.remove(&depth); - } else { - to_add.insert(depth, style); + for (depth, style) in depths { + if multilines.get(&depth).is_some() { + multilines.remove(&depth); + } else { + to_add.insert(depth, style); + } } - } - // Set the multiline annotation vertical lines to the left of - // the code in this line. - for (depth, style) in &multilines { - for line in previous_buffer_line..buffer.num_lines() { - draw_multiline_line(&mut buffer, - line, - width_offset, - *depth, - *style); - } - } - // check to see if we need to print out or elide lines that come between - // this annotated line and the next one. - if line_idx < (annotated_file.lines.len() - 1) { - let line_idx_delta = annotated_file.lines[line_idx + 1].line_index - - annotated_file.lines[line_idx].line_index; - if line_idx_delta > 2 { - let last_buffer_line_num = buffer.num_lines(); - buffer.puts(last_buffer_line_num, 0, "...", Style::LineNumber); - - // Set the multiline annotation vertical lines on `...` bridging line. - for (depth, style) in &multilines { + // Set the multiline annotation vertical lines to the left of + // the code in this line. + for (depth, style) in &multilines { + for line in previous_buffer_line..buffer.num_lines() { draw_multiline_line(&mut buffer, - last_buffer_line_num, + line, width_offset, *depth, *style); } - } else if line_idx_delta == 2 { - let unannotated_line = annotated_file.file - .get_line(annotated_file.lines[line_idx].line_index) - .unwrap_or_else(|| Cow::from("")); - - let last_buffer_line_num = buffer.num_lines(); - - buffer.puts(last_buffer_line_num, - 0, - &(annotated_file.lines[line_idx + 1].line_index - 1) - .to_string(), - Style::LineNumber); - draw_col_separator(&mut buffer, last_buffer_line_num, 1 + max_line_num_len); - buffer.puts(last_buffer_line_num, - code_offset, - &unannotated_line, - Style::Quotation); - - for (depth, style) in &multilines { - draw_multiline_line(&mut buffer, - last_buffer_line_num, - width_offset, - *depth, - *style); + } + // check to see if we need to print out or elide lines that come between + // this annotated line and the next one. + if line_idx < (annotated_file.lines.len() - 1) { + let line_idx_delta = annotated_file.lines[line_idx + 1].line_index - + annotated_file.lines[line_idx].line_index; + if line_idx_delta > 2 { + let last_buffer_line_num = buffer.num_lines(); + buffer.puts(last_buffer_line_num, 0, "...", Style::LineNumber); + + // Set the multiline annotation vertical lines on `...` bridging line. + for (depth, style) in &multilines { + draw_multiline_line(&mut buffer, + last_buffer_line_num, + width_offset, + *depth, + *style); + } + } else if line_idx_delta == 2 { + let unannotated_line = annotated_file.file + .get_line(annotated_file.lines[line_idx].line_index) + .unwrap_or_else(|| Cow::from("")); + + let last_buffer_line_num = buffer.num_lines(); + + buffer.puts(last_buffer_line_num, + 0, + &(annotated_file.lines[line_idx + 1].line_index - 1) + .to_string(), + Style::LineNumber); + draw_col_separator(&mut buffer, + last_buffer_line_num, + 1 + max_line_num_len); + buffer.puts(last_buffer_line_num, + code_offset, + &unannotated_line, + Style::Quotation); + + for (depth, style) in &multilines { + draw_multiline_line(&mut buffer, + last_buffer_line_num, + width_offset, + *depth, + *style); + } } } - } - multilines.extend(&to_add); + multilines.extend(&to_add); + } } } // final step: take our styled buffer, render it, then output it - emit_to_destination(&buffer.render(), level, &mut self.dst)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; Ok(()) + } fn emit_suggestion_default(&mut self, suggestion: &CodeSuggestion, @@ -1141,7 +1167,7 @@ impl EmitterWriter { let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS); buffer.puts(row_num, 0, &msg, Style::NoStyle); } - emit_to_destination(&buffer.render(), level, &mut self.dst)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; } Ok(()) } @@ -1158,42 +1184,47 @@ impl EmitterWriter { Ok(()) => { if !children.is_empty() { let mut buffer = StyledBuffer::new(); - draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1); - match emit_to_destination(&buffer.render(), level, &mut self.dst) { + if !self.short_message { + draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1); + } + match emit_to_destination(&buffer.render(), level, &mut self.dst, + self.short_message) { Ok(()) => (), Err(e) => panic!("failed to emit error: {}", e) } } - for child in children { - match child.render_span { - Some(FullSpan(ref msp)) => { - match self.emit_message_default(msp, - &child.styled_message(), - &None, - &child.level, - max_line_num_len, - true) { - Err(e) => panic!("failed to emit error: {}", e), - _ => () + if !self.short_message { + for child in children { + match child.render_span { + Some(FullSpan(ref msp)) => { + match self.emit_message_default(msp, + &child.styled_message(), + &None, + &child.level, + max_line_num_len, + true) { + Err(e) => panic!("failed to emit error: {}", e), + _ => () + } } - }, - Some(Suggestion(ref cs)) => { - match self.emit_suggestion_default(cs, - &child.level, - max_line_num_len) { - Err(e) => panic!("failed to emit error: {}", e), - _ => () + Some(Suggestion(ref cs)) => { + match self.emit_suggestion_default(cs, + &child.level, + max_line_num_len) { + Err(e) => panic!("failed to emit error: {}", e), + _ => () + } } - }, - None => { - match self.emit_message_default(&child.span, - &child.styled_message(), - &None, - &child.level, - max_line_num_len, - true) { - Err(e) => panic!("failed to emit error: {}", e), - _ => (), + None => { + match self.emit_message_default(&child.span, + &child.styled_message(), + &None, + &child.level, + max_line_num_len, + true) { + Err(e) => panic!("failed to emit error: {}", e), + _ => (), + } } } } @@ -1263,7 +1294,8 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool { fn emit_to_destination(rendered_buffer: &Vec>, lvl: &Level, - dst: &mut Destination) + dst: &mut Destination, + short_message: bool) -> io::Result<()> { use lock; @@ -1286,7 +1318,9 @@ fn emit_to_destination(rendered_buffer: &Vec>, write!(dst, "{}", part.text)?; dst.reset_attrs()?; } - write!(dst, "\n")?; + if !short_message { + write!(dst, "\n")?; + } } dst.flush()?; Ok(()) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index d9b0f4ac8a6c0..adb3e4d3ed654 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -279,7 +279,7 @@ impl Handler { treat_err_as_bug: bool, cm: Option>) -> Handler { - let emitter = Box::new(EmitterWriter::stderr(color_config, cm)); + let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false)); Handler::with_emitter(can_emit_warnings, treat_err_as_bug, emitter) } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 8b2c8d2da395a..9316805b9322a 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -238,7 +238,8 @@ fn run_test(test: &str, cratename: &str, filename: &str, cfgs: Vec, libs let data = Arc::new(Mutex::new(Vec::new())); let codemap = Rc::new(CodeMap::new(sessopts.file_path_mapping())); let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()), - Some(codemap.clone())); + Some(codemap.clone()), + false); let old = io::set_panic(Some(box Sink(data.clone()))); let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout())); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 1cb7b0eca58d0..d9c3dbb630d0c 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1721,7 +1721,9 @@ mod tests { use std::rc::Rc; fn mk_sess(cm: Rc) -> ParseSess { - let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), Some(cm.clone())); + let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), + Some(cm.clone()), + false); ParseSess { span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)), unstable_features: UnstableFeatures::from_environment(), diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index e9b1976ea472b..a29250ea5f19f 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -60,7 +60,8 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & } let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }), - Some(code_map.clone())); + Some(code_map.clone()), + false); let handler = Handler::with_emitter(true, false, Box::new(emitter)); handler.span_err(msp, "foo"); diff --git a/src/test/ui/short-error-format.rs b/src/test/ui/short-error-format.rs new file mode 100644 index 0000000000000..3e6802c51c3a6 --- /dev/null +++ b/src/test/ui/short-error-format.rs @@ -0,0 +1,19 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --error-format=short + +fn foo(_: u32) {} + +fn main() { + foo("Bonjour".to_owned()); + let x = 0u32; + x.salut(); +} diff --git a/src/test/ui/short-error-format.stderr b/src/test/ui/short-error-format.stderr new file mode 100644 index 0000000000000..debe60b463226 --- /dev/null +++ b/src/test/ui/short-error-format.stderr @@ -0,0 +1,3 @@ +$DIR/short-error-format.rs:16:9 - error[E0308]: mismatched types +$DIR/short-error-format.rs:18:7 - error[E0599]: no method named `salut` found for type `u32` in the current scope +error: aborting due to 2 previous errors From b46c014cd33c7ccb900220952128ec29ad576276 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 24 Oct 2017 20:44:02 +0200 Subject: [PATCH 2/2] Set rustfmt broken while waiting for the update of their side --- src/tools/toolstate.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/toolstate.toml b/src/tools/toolstate.toml index f1684f4c5acbe..8346a79f7dd18 100644 --- a/src/tools/toolstate.toml +++ b/src/tools/toolstate.toml @@ -32,4 +32,4 @@ clippy = "Broken" rls = "Testing" # ping @nrc -rustfmt = "Testing" +rustfmt = "Broken"