From b206064fc86b356759e4cbfc60407b426c362cac Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 8 Jan 2017 14:00:57 -0800 Subject: Teach diagnostics to correct margin on multiline messages Make any diagnostic line to have the correct margin to align with the first line: ``` error: message --> file.rs:3:20 | 3 | | ^^^^ | = note: this is a multiline note with a correct margin = note: this is a single line note = help: here are some functions which might fulfill your needs: - .len() - .foo() - .bar() = suggestion: this is a multiline suggestion with a correct margin ``` --- src/librustc_errors/diagnostic.rs | 18 -------- src/librustc_errors/diagnostic_builder.rs | 1 - src/librustc_errors/emitter.rs | 71 +++++++++++-------------------- 3 files changed, 24 insertions(+), 66 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 73a8343eafc..730ca8f9e2e 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -32,7 +32,6 @@ pub struct SubDiagnostic { pub message: String, pub span: MultiSpan, pub render_span: Option, - pub list: Vec, } impl Diagnostic { @@ -133,11 +132,6 @@ impl Diagnostic { self } - pub fn help_with_list(&mut self , msg: &str, list: Vec) -> &mut Self { - self.sub_with_list(Level::Help, msg, MultiSpan::new(), None, list); - self - } - pub fn span_help>(&mut self, sp: S, msg: &str) @@ -197,23 +191,11 @@ impl Diagnostic { message: &str, span: MultiSpan, render_span: Option) { - self.sub_with_list(level, message, span, render_span, vec![]); - } - - /// Convenience function for internal use, clients should use one of the - /// public methods above. - fn sub_with_list(&mut self, - level: Level, - message: &str, - span: MultiSpan, - render_span: Option, - list: Vec) { let sub = SubDiagnostic { level: level, message: message.to_owned(), span: span, render_span: render_span, - list: list, }; self.children.push(sub); } diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 24f1b86739d..7dfea6b8951 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -135,7 +135,6 @@ impl<'a> DiagnosticBuilder<'a> { forward!(pub fn warn(&mut self, msg: &str) -> &mut Self); forward!(pub fn span_warn>(&mut self, sp: S, msg: &str) -> &mut Self); forward!(pub fn help(&mut self , msg: &str) -> &mut Self); - forward!(pub fn help_with_list(&mut self , msg: &str, list: Vec) -> &mut Self); forward!(pub fn span_help>(&mut self, sp: S, msg: &str) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 88373bf988d..dbef287f113 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -699,11 +699,25 @@ impl EmitterWriter { .to_string(), span: MultiSpan::new(), render_span: None, - list: vec![], }); } } + fn msg_with_padding(&self, msg: &str, padding: usize) -> String { + let padding = (0..padding) + .map(|_| " ") + .collect::(); + msg.split('\n').enumerate().fold("".to_owned(), |mut acc, x| { + if x.0 != 0 { + acc.push_str("\n"); + // Align every line with first one. + acc.push_str(&padding); + } + acc.push_str(&x.1); + acc + }) + } + fn emit_message_default(&mut self, msp: &MultiSpan, msg: &str, @@ -722,7 +736,10 @@ impl EmitterWriter { draw_note_separator(&mut buffer, 0, max_line_num_len + 1); buffer.append(0, &level.to_string(), Style::HeaderMsg); buffer.append(0, ": ", Style::NoStyle); - buffer.append(0, msg, Style::NoStyle); + + // The extra 9 ` ` is the padding that's always needed to align to the `note: `. + let message = self.msg_with_padding(msg, max_line_num_len + 9); + buffer.append(0, &message, Style::NoStyle); } else { buffer.append(0, &level.to_string(), Style::Level(level.clone())); match code { @@ -855,7 +872,10 @@ impl EmitterWriter { buffer.append(0, &level.to_string(), Style::Level(level.clone())); buffer.append(0, ": ", Style::HeaderMsg); - buffer.append(0, msg, Style::HeaderMsg); + + // The extra 15 ` ` is the padding that's always needed to align to the `suggestion: `. + let message = self.msg_with_padding(msg, max_line_num_len + 15); + buffer.append(0, &message, Style::HeaderMsg); let lines = cm.span_to_lines(primary_span).unwrap(); @@ -924,51 +944,8 @@ impl EmitterWriter { } }, None => { - // Diagnostic with lists need to render the list items at the - // appropriate depth and composed into the body of the message. - let msg = if child.list.len() == 0 { - // Diagnostics without lists just need the original message - child.message.to_owned() - } else { - // Diagnostic with a list of items needs to be rendered with the - // appropriate padding at the left to have a consistent margin with - // the `note: ` text. - - // Add as many ` ` chars at the beggining to align the `- item` - // text to the beggining of the `note: ` text. The extra 9 ` ` is - // the padding that's always needed to align to the `note: `. - let padding = (0..max_line_num_len + 9) - .map(|_| " ") - .collect::(); - - // Concatenate the message and all the list items, properly aligned - child.list.iter().fold(child.message.to_owned(), |mut acc, x| { - acc.push_str("\n"); - acc.push_str(&padding); - acc.push_str("- "); - acc.push_str(x); - acc - }) - // msg will now be: - // - // child.message's content - // - item 1 - // - item 2 - // - // and the diagnostic will look like - // - // error: message - // --> file.rs:3:20 - // | - // 3 | - // | ^^^^ highlight - // | - // = help: child.message's content - // - item 1 - // - item 2 - }; match self.emit_message_default(&child.span, - &msg, + &child.message, &None, &child.level, max_line_num_len, -- cgit 1.4.1-3-g733a5