X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_errors%2Femitter.rs;h=ad2562e28fa4f5b001d88200144f0de85e01d455;hb=1edbc3df0d051902916ead8e81db16a6f546f973;hp=2d25d12d3a96e437ffec77d1a8b655498207ab18;hpb=9b4c4d001f0b9f3c9f4b1660c603d33b78a4425f;p=rust.git diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 2d25d12d3a9..ad2562e28fa 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -47,7 +47,12 @@ fn emit(&mut self, db: &DiagnosticBuilder) { // don't display multiline suggestions as labels sugg.substitution_parts[0].substitutions[0].find('\n').is_none() { let substitution = &sugg.substitution_parts[0].substitutions[0]; - let msg = format!("help: {} `{}`", sugg.msg, substitution); + let msg = if substitution.len() == 0 { + // This substitution is only removal, don't show it + format!("help: {}", sugg.msg) + } else { + format!("help: {}: `{}`", sugg.msg, substitution) + }; primary_span.push_span_label(sugg.substitution_spans().next().unwrap(), msg); } else { // if there are multiple suggestions, print them all in full @@ -341,9 +346,20 @@ fn render_source_line(&self, // and "annotations lines", where the highlight lines have the `^`. // Sort the annotations by (start, end col) + // The labels are reversed, sort and then reversed again. + // Consider a list of annotations (A1, A2, C1, C2, B1, B2) where + // the letter signifies the span. Here we are only sorting by the + // span and hence, the order of the elements with the same span will + // not change. On reversing the ordering (|a, b| but b.cmp(a)), you get + // (C1, C2, B1, B2, A1, A2). All the elements with the same span are + // still ordered first to last, but all the elements with different + // spans are ordered by their spans in last to first order. Last to + // first order is important, because the jiggly lines and | are on + // the left, so the rightmost span needs to be rendered first, + // otherwise the lines would end up needing to go over a message. + let mut annotations = line.annotations.clone(); - annotations.sort(); - annotations.reverse(); + annotations.sort_by(|a,b| b.start_col.cmp(&a.start_col)); // First, figure out where each label will be positioned. // @@ -1055,44 +1071,72 @@ fn emit_suggestion_default(&mut self, -> io::Result<()> { use std::borrow::Borrow; - let primary_span = suggestion.substitution_spans().next().unwrap(); + let primary_sub = &suggestion.substitution_parts[0]; if let Some(ref cm) = self.cm { let mut buffer = StyledBuffer::new(); - let lines = cm.span_to_lines(primary_span).unwrap(); + let lines = cm.span_to_lines(primary_sub.span).unwrap(); assert!(!lines.lines.is_empty()); buffer.append(0, &level.to_string(), Style::Level(level.clone())); buffer.append(0, ": ", Style::HeaderMsg); self.msg_to_buffer(&mut buffer, - &[(suggestion.msg.to_owned(), Style::NoStyle)], - max_line_num_len, - "suggestion", - Some(Style::HeaderMsg)); + &[(suggestion.msg.to_owned(), Style::NoStyle)], + max_line_num_len, + "suggestion", + Some(Style::HeaderMsg)); let suggestions = suggestion.splice_lines(cm.borrow()); - let mut row_num = 1; - for complete in suggestions.iter().take(MAX_SUGGESTIONS) { - - // print the suggestion without any line numbers, but leave - // space for them. This helps with lining up with previous - // snippets from the actual error being reported. + let span_start_pos = cm.lookup_char_pos(primary_sub.span.lo); + let line_start = span_start_pos.line; + draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1); + let mut row_num = 2; + for (&(ref complete, show_underline), ref sub) in suggestions + .iter().zip(primary_sub.substitutions.iter()).take(MAX_SUGGESTIONS) + { + let mut line_pos = 0; + // Only show underline if there's a single suggestion and it is a single line let mut lines = complete.lines(); for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) { + // Print the span column to avoid confusion + buffer.puts(row_num, + 0, + &((line_start + line_pos).to_string()), + Style::LineNumber); + // print the suggestion draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); buffer.append(row_num, line, Style::NoStyle); + line_pos += 1; row_num += 1; + // Only show an underline in the suggestions if the suggestion is not the + // entirety of the code being shown and the displayed code is not multiline. + if show_underline { + draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); + let sub_len = sub.trim_right().len(); + let underline_start = span_start_pos.col.0; + let underline_end = span_start_pos.col.0 + sub_len; + for p in underline_start..underline_end { + buffer.putc(row_num, + max_line_num_len + 3 + p, + '^', + Style::UnderlinePrimary); + } + row_num += 1; + } } // if we elided some lines, add an ellipsis if let Some(_) = lines.next() { - buffer.append(row_num, "...", Style::NoStyle); + buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber); + } else if !show_underline { + draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1); + row_num += 1; } } if suggestions.len() > MAX_SUGGESTIONS { let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS); - buffer.append(row_num, &msg, Style::NoStyle); + buffer.puts(row_num, 0, &msg, Style::NoStyle); } emit_to_destination(&buffer.render(), level, &mut self.dst)?; } @@ -1340,7 +1384,7 @@ fn from_stderr() -> Destination { fn apply_style(&mut self, lvl: Level, style: Style) -> io::Result<()> { match style { - Style::FileNameStyle | Style::LineAndColumn => {} + Style::LineAndColumn => {} Style::LineNumber => { self.start_attr(term::Attr::Bold)?; if cfg!(windows) { @@ -1349,16 +1393,8 @@ fn apply_style(&mut self, lvl: Level, style: Style) -> io::Result<()> { self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))?; } } - Style::ErrorCode => { - self.start_attr(term::Attr::Bold)?; - self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA))?; - } Style::Quotation => {} - Style::OldSchoolNote => { - self.start_attr(term::Attr::Bold)?; - self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_GREEN))?; - } - Style::OldSchoolNoteText | Style::HeaderMsg => { + Style::HeaderMsg => { self.start_attr(term::Attr::Bold)?; if cfg!(windows) { self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_WHITE))?;