diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2017-01-08 14:00:57 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2017-01-08 16:07:14 -0800 |
| commit | b206064fc86b356759e4cbfc60407b426c362cac (patch) | |
| tree | c77cbd402fec8ae5e7d45717516a48a12afefa29 | |
| parent | f65a907ef9e21a350118d2efa323ebf49c3ec1cf (diff) | |
| download | rust-b206064fc86b356759e4cbfc60407b426c362cac.tar.gz rust-b206064fc86b356759e4cbfc60407b426c362cac.zip | |
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 | <CODE>
| ^^^^
|
= 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
```
| -rw-r--r-- | src/librustc_errors/diagnostic.rs | 18 | ||||
| -rw-r--r-- | src/librustc_errors/diagnostic_builder.rs | 1 | ||||
| -rw-r--r-- | src/librustc_errors/emitter.rs | 71 | ||||
| -rw-r--r-- | src/librustc_typeck/check/demand.rs | 7 |
4 files changed, 28 insertions, 69 deletions
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<RenderSpan>, - pub list: Vec<String>, } impl Diagnostic { @@ -133,11 +132,6 @@ impl Diagnostic { self } - pub fn help_with_list(&mut self , msg: &str, list: Vec<String>) -> &mut Self { - self.sub_with_list(Level::Help, msg, MultiSpan::new(), None, list); - self - } - pub fn span_help<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) @@ -197,23 +191,11 @@ impl Diagnostic { message: &str, span: MultiSpan, render_span: Option<RenderSpan>) { - 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<RenderSpan>, - list: Vec<String>) { 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<S: Into<MultiSpan>>(&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<String>) -> &mut Self); forward!(pub fn span_help<S: Into<MultiSpan>>(&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::<String>(); + 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::<String>(); - - // 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 | <Code> - // | ^^^^ 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, diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 06d629c1732..3bc3d1a2c97 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -70,15 +70,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ast::DUMMY_NODE_ID); let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e); if suggestions.len() > 0 { - err.help_with_list("here are some functions which might fulfill your needs:", - self.get_best_match(&suggestions)); + err.help(&format!("here are some functions which \ + might fulfill your needs:\n{}", + self.get_best_match(&suggestions).join("\n"))); }; err.emit(); } } fn format_method_suggestion(&self, method: &AssociatedItem) -> String { - format!(".{}({})", + format!("- .{}({})", method.name, if self.has_no_input_arg(method) { "" |
