Skip to content

Commit b206064

Browse files
committed
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 ```
1 parent f65a907 commit b206064

File tree

4 files changed

+28
-69
lines changed

4 files changed

+28
-69
lines changed

src/librustc_errors/diagnostic.rs

-18
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ pub struct SubDiagnostic {
3232
pub message: String,
3333
pub span: MultiSpan,
3434
pub render_span: Option<RenderSpan>,
35-
pub list: Vec<String>,
3635
}
3736

3837
impl Diagnostic {
@@ -133,11 +132,6 @@ impl Diagnostic {
133132
self
134133
}
135134

136-
pub fn help_with_list(&mut self , msg: &str, list: Vec<String>) -> &mut Self {
137-
self.sub_with_list(Level::Help, msg, MultiSpan::new(), None, list);
138-
self
139-
}
140-
141135
pub fn span_help<S: Into<MultiSpan>>(&mut self,
142136
sp: S,
143137
msg: &str)
@@ -197,23 +191,11 @@ impl Diagnostic {
197191
message: &str,
198192
span: MultiSpan,
199193
render_span: Option<RenderSpan>) {
200-
self.sub_with_list(level, message, span, render_span, vec![]);
201-
}
202-
203-
/// Convenience function for internal use, clients should use one of the
204-
/// public methods above.
205-
fn sub_with_list(&mut self,
206-
level: Level,
207-
message: &str,
208-
span: MultiSpan,
209-
render_span: Option<RenderSpan>,
210-
list: Vec<String>) {
211194
let sub = SubDiagnostic {
212195
level: level,
213196
message: message.to_owned(),
214197
span: span,
215198
render_span: render_span,
216-
list: list,
217199
};
218200
self.children.push(sub);
219201
}

src/librustc_errors/diagnostic_builder.rs

-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ impl<'a> DiagnosticBuilder<'a> {
135135
forward!(pub fn warn(&mut self, msg: &str) -> &mut Self);
136136
forward!(pub fn span_warn<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self);
137137
forward!(pub fn help(&mut self , msg: &str) -> &mut Self);
138-
forward!(pub fn help_with_list(&mut self , msg: &str, list: Vec<String>) -> &mut Self);
139138
forward!(pub fn span_help<S: Into<MultiSpan>>(&mut self,
140139
sp: S,
141140
msg: &str)

src/librustc_errors/emitter.rs

+24-47
Original file line numberDiff line numberDiff line change
@@ -699,11 +699,25 @@ impl EmitterWriter {
699699
.to_string(),
700700
span: MultiSpan::new(),
701701
render_span: None,
702-
list: vec![],
703702
});
704703
}
705704
}
706705

706+
fn msg_with_padding(&self, msg: &str, padding: usize) -> String {
707+
let padding = (0..padding)
708+
.map(|_| " ")
709+
.collect::<String>();
710+
msg.split('\n').enumerate().fold("".to_owned(), |mut acc, x| {
711+
if x.0 != 0 {
712+
acc.push_str("\n");
713+
// Align every line with first one.
714+
acc.push_str(&padding);
715+
}
716+
acc.push_str(&x.1);
717+
acc
718+
})
719+
}
720+
707721
fn emit_message_default(&mut self,
708722
msp: &MultiSpan,
709723
msg: &str,
@@ -722,7 +736,10 @@ impl EmitterWriter {
722736
draw_note_separator(&mut buffer, 0, max_line_num_len + 1);
723737
buffer.append(0, &level.to_string(), Style::HeaderMsg);
724738
buffer.append(0, ": ", Style::NoStyle);
725-
buffer.append(0, msg, Style::NoStyle);
739+
740+
// The extra 9 ` ` is the padding that's always needed to align to the `note: `.
741+
let message = self.msg_with_padding(msg, max_line_num_len + 9);
742+
buffer.append(0, &message, Style::NoStyle);
726743
} else {
727744
buffer.append(0, &level.to_string(), Style::Level(level.clone()));
728745
match code {
@@ -855,7 +872,10 @@ impl EmitterWriter {
855872

856873
buffer.append(0, &level.to_string(), Style::Level(level.clone()));
857874
buffer.append(0, ": ", Style::HeaderMsg);
858-
buffer.append(0, msg, Style::HeaderMsg);
875+
876+
// The extra 15 ` ` is the padding that's always needed to align to the `suggestion: `.
877+
let message = self.msg_with_padding(msg, max_line_num_len + 15);
878+
buffer.append(0, &message, Style::HeaderMsg);
859879

860880
let lines = cm.span_to_lines(primary_span).unwrap();
861881

@@ -924,51 +944,8 @@ impl EmitterWriter {
924944
}
925945
},
926946
None => {
927-
// Diagnostic with lists need to render the list items at the
928-
// appropriate depth and composed into the body of the message.
929-
let msg = if child.list.len() == 0 {
930-
// Diagnostics without lists just need the original message
931-
child.message.to_owned()
932-
} else {
933-
// Diagnostic with a list of items needs to be rendered with the
934-
// appropriate padding at the left to have a consistent margin with
935-
// the `note: ` text.
936-
937-
// Add as many ` ` chars at the beggining to align the `- item`
938-
// text to the beggining of the `note: ` text. The extra 9 ` ` is
939-
// the padding that's always needed to align to the `note: `.
940-
let padding = (0..max_line_num_len + 9)
941-
.map(|_| " ")
942-
.collect::<String>();
943-
944-
// Concatenate the message and all the list items, properly aligned
945-
child.list.iter().fold(child.message.to_owned(), |mut acc, x| {
946-
acc.push_str("\n");
947-
acc.push_str(&padding);
948-
acc.push_str("- ");
949-
acc.push_str(x);
950-
acc
951-
})
952-
// msg will now be:
953-
//
954-
// child.message's content
955-
// - item 1
956-
// - item 2
957-
//
958-
// and the diagnostic will look like
959-
//
960-
// error: message
961-
// --> file.rs:3:20
962-
// |
963-
// 3 | <Code>
964-
// | ^^^^ highlight
965-
// |
966-
// = help: child.message's content
967-
// - item 1
968-
// - item 2
969-
};
970947
match self.emit_message_default(&child.span,
971-
&msg,
948+
&child.message,
972949
&None,
973950
&child.level,
974951
max_line_num_len,

src/librustc_typeck/check/demand.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
7070
ast::DUMMY_NODE_ID);
7171
let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
7272
if suggestions.len() > 0 {
73-
err.help_with_list("here are some functions which might fulfill your needs:",
74-
self.get_best_match(&suggestions));
73+
err.help(&format!("here are some functions which \
74+
might fulfill your needs:\n{}",
75+
self.get_best_match(&suggestions).join("\n")));
7576
};
7677
err.emit();
7778
}
7879
}
7980

8081
fn format_method_suggestion(&self, method: &AssociatedItem) -> String {
81-
format!(".{}({})",
82+
format!("- .{}({})",
8283
method.name,
8384
if self.has_no_input_arg(method) {
8485
""

0 commit comments

Comments
 (0)