diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 808fe504b95cd..77c6c36836417 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -703,6 +703,40 @@ impl EmitterWriter { } } + /// Add a left margin to every line but the first, given a padding length and the label being + /// displayed. + fn msg_with_padding(&self, msg: &str, padding: usize, label: &str) -> String { + // The extra 5 ` ` is padding that's always needed to align to the `note: `: + // + // error: message + // --> file.rs:13:20 + // | + // 13 | + // | ^^^^ + // | + // = note: multiline + // message + // ++^^^----xx + // | | | | + // | | | magic `2` + // | | length of label + // | magic `3` + // `max_line_num_len` + let padding = (0..padding + label.len() + 5) + .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, @@ -721,7 +755,9 @@ 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); + + let message = self.msg_with_padding(msg, max_line_num_len, "note"); + buffer.append(0, &message, Style::NoStyle); } else { buffer.append(0, &level.to_string(), Style::Level(level.clone())); match code { @@ -854,7 +890,9 @@ impl EmitterWriter { buffer.append(0, &level.to_string(), Style::Level(level.clone())); buffer.append(0, ": ", Style::HeaderMsg); - buffer.append(0, msg, Style::HeaderMsg); + + let message = self.msg_with_padding(msg, max_line_num_len, "suggestion"); + buffer.append(0, &message, Style::HeaderMsg); let lines = cm.span_to_lines(primary_span).unwrap(); @@ -930,7 +968,7 @@ impl EmitterWriter { max_line_num_len, true) { Err(e) => panic!("failed to emit error: {}", e), - _ => () + _ => (), } } } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 393d9341a0843..3bc3d1a2c970e 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -71,15 +71,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e); if suggestions.len() > 0 { err.help(&format!("here are some functions which \ - might fulfill your needs:\n - {}", - self.get_best_match(&suggestions))); + 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) { "" @@ -88,15 +88,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }) } - fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> String { + fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> Vec { methods.iter() .take(5) .map(|method| self.format_method_suggestion(&*method)) .collect::>() - .join("\n - ") } - fn get_best_match(&self, methods: &[AssociatedItem]) -> String { + fn get_best_match(&self, methods: &[AssociatedItem]) -> Vec { let no_argument_methods: Vec<_> = methods.iter() .filter(|ref x| self.has_no_input_arg(&*x)) diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index 0b15c23909ca6..bb6f310fec813 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -37,9 +37,9 @@ error[E0308]: mismatched types = note: expected type `()` = note: found type `std::result::Result` = help: here are some functions which might fulfill your needs: - - .unwrap() - - .unwrap_err() - - .unwrap_or_default() + - .unwrap() + - .unwrap_err() + - .unwrap_or_default() error: aborting due to previous error diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index e316466150703..ed1bcd318a4f6 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -7,8 +7,8 @@ error[E0308]: mismatched types = note: expected type `usize` = note: found type `std::string::String` = help: here are some functions which might fulfill your needs: - - .capacity() - - .len() + - .capacity() + - .len() error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:23:19 @@ -19,10 +19,10 @@ error[E0308]: mismatched types = note: expected type `&str` = note: found type `std::string::String` = help: here are some functions which might fulfill your needs: - - .as_str() - - .trim() - - .trim_left() - - .trim_right() + - .as_str() + - .trim() + - .trim_left() + - .trim_right() error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:30:10