From 260c5fd58778f14c4f4d19e1b91784a4e0a675e3 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 6 Jun 2022 17:42:53 +0400 Subject: [PATCH 1/6] Fix a typo !(a & b) = !a | !b --- compiler/rustc_errors/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8b6eba122f8f0..25fa2c30e7ebb 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1145,7 +1145,7 @@ impl HandlerInner { !this.emitted_diagnostics.insert(diagnostic_hash) }; - // Only emit the diagnostic if we've been asked to deduplicate and + // Only emit the diagnostic if we've been asked to deduplicate or // haven't already emitted an equivalent diagnostic. if !(self.flags.deduplicate_diagnostics && already_emitted(self)) { debug!(?diagnostic); From 87fded1eddf834f2decbfd05e6fda35cb1ee4747 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 6 Jun 2022 18:04:42 +0400 Subject: [PATCH 2/6] Improve suggestions when its parts are far from each other Previously we only show at most 6 lines of suggestions and, if the suggestions are more than 6 lines apart, we've just showed ... at the end. This is probably fine, but quite confusing in my opinion. This commit is an attempt to show ... in places where there is nothing to suggest instead, for example: Before: ```text help: consider enclosing expression in a block | 3 ~ 'l: { match () { () => break 'l, 4 | 5 | 6 | 7 | 8 | ... ``` After: ```text help: consider enclosing expression in a block | 3 ~ 'l: { match () { () => break 'l, 4 | ... 31| 32~ } }; | ``` --- compiler/rustc_errors/src/emitter.rs | 167 ++++++++++++++++----------- 1 file changed, 99 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index e9e7065ec03cc..269d34ea4325d 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -656,11 +656,6 @@ impl Emitter for SilentEmitter { } } -/// Maximum number of lines we will print for a multiline suggestion; arbitrary. -/// -/// This should be replaced with a more involved mechanism to output multiline suggestions that -/// more closely mimics the regular diagnostic output, where irrelevant code lines are elided. -pub const MAX_SUGGESTION_HIGHLIGHT_LINES: usize = 6; /// Maximum number of suggestions to be shown /// /// Arbitrary, but taken from trait import suggestion limit @@ -1839,79 +1834,115 @@ impl EmitterWriter { } row_num += line_end - line_start; } - for (line_pos, (line, highlight_parts)) in - lines.by_ref().zip(highlights).take(MAX_SUGGESTION_HIGHLIGHT_LINES).enumerate() - { - // Print the span column to avoid confusion - buffer.puts( - row_num, - 0, - &self.maybe_anonymized(line_start + line_pos), - Style::LineNumber, - ); - if let DisplaySuggestion::Diff = show_code_change { - // Add the line number for both addition and removal to drive the point home. - // - // N - fn foo(bar: A) { - // N + fn foo(bar: impl T) { + let mut unhighlighted_lines = Vec::new(); + for (line_pos, (line, highlight_parts)) in lines.by_ref().zip(highlights).enumerate() { + debug!(%line_pos, %line, ?highlight_parts); + + let print_line = |line_pos: usize, + line: &str, + highlight_parts: &Vec, + buffer: &mut StyledBuffer, + row_num: &mut usize| { + // Print the span column to avoid confusion buffer.puts( - row_num - 1, + *row_num, 0, &self.maybe_anonymized(line_start + line_pos), Style::LineNumber, ); - buffer.puts(row_num - 1, max_line_num_len + 1, "- ", Style::Removal); - buffer.puts( - row_num - 1, - max_line_num_len + 3, - &normalize_whitespace( - &*file_lines - .file - .get_line(file_lines.lines[line_pos].line_index) - .unwrap(), - ), - Style::NoStyle, - ); - buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition); - } else if is_multiline { - match &highlight_parts[..] { - [SubstitutionHighlight { start: 0, end }] if *end == line.len() => { - buffer.puts(row_num, max_line_num_len + 1, "+ ", Style::Addition); - } - [] => { - draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); - } - _ => { - buffer.puts(row_num, max_line_num_len + 1, "~ ", Style::Addition); + if let DisplaySuggestion::Diff = show_code_change { + // Add the line number for both addition and removal to drive the point home. + // + // N - fn foo(bar: A) { + // N + fn foo(bar: impl T) { + buffer.puts( + *row_num - 1, + 0, + &self.maybe_anonymized(line_start + line_pos), + Style::LineNumber, + ); + buffer.puts(*row_num - 1, max_line_num_len + 1, "- ", Style::Removal); + buffer.puts( + *row_num - 1, + max_line_num_len + 3, + &normalize_whitespace( + &*file_lines + .file + .get_line(file_lines.lines[line_pos].line_index) + .unwrap(), + ), + Style::NoStyle, + ); + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + } else if is_multiline { + match &highlight_parts[..] { + [SubstitutionHighlight { start: 0, end }] if *end == line.len() => { + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + } + [] => { + draw_col_separator(buffer, *row_num, max_line_num_len + 1); + } + _ => { + buffer.puts(*row_num, max_line_num_len + 1, "~ ", Style::Addition); + } } + } else { + draw_col_separator(buffer, *row_num, max_line_num_len + 1); } - } else { - draw_col_separator(&mut buffer, row_num, max_line_num_len + 1); - } - // print the suggestion - buffer.append(row_num, &normalize_whitespace(line), Style::NoStyle); + // print the suggestion + buffer.append(*row_num, &normalize_whitespace(line), Style::NoStyle); - // Colorize addition/replacements with green. - for &SubstitutionHighlight { start, end } in highlight_parts { - // Account for tabs when highlighting (#87972). - let tabs: usize = line - .chars() - .take(start) - .map(|ch| match ch { - '\t' => 3, - _ => 0, - }) - .sum(); - buffer.set_style_range( - row_num, - max_line_num_len + 3 + start + tabs, - max_line_num_len + 3 + end + tabs, - Style::Addition, - true, - ); + // Colorize addition/replacements with green. + for &SubstitutionHighlight { start, end } in highlight_parts { + // Account for tabs when highlighting (#87972). + let tabs: usize = line + .chars() + .take(start) + .map(|ch| match ch { + '\t' => 3, + _ => 0, + }) + .sum(); + buffer.set_style_range( + *row_num, + max_line_num_len + 3 + start + tabs, + max_line_num_len + 3 + end + tabs, + Style::Addition, + true, + ); + } + *row_num += 1; + }; + + if highlight_parts.is_empty() { + unhighlighted_lines.push((line_pos, line)); + continue; } - row_num += 1; + + match unhighlighted_lines.len() { + 0 => (), + // Since we show first line, "..." line and last line, + // There is no reason to hide if there are 3 or less lines + // (because then we just replace a line with ... which is + // not helpful) + n if n <= 3 => unhighlighted_lines.drain(..).for_each(|(p, l)| { + print_line(p, l, &Vec::new(), &mut buffer, &mut row_num) + }), + _ => { + unhighlighted_lines + .drain(..1) + .next() + .map(|(p, l)| print_line(p, l, &Vec::new(), &mut buffer, &mut row_num)); + buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber); + row_num += 1; + unhighlighted_lines + .pop() + .map(|(p, l)| print_line(p, l, &Vec::new(), &mut buffer, &mut row_num)); + } + } + + print_line(line_pos, line, highlight_parts, &mut buffer, &mut row_num) } // This offset and the ones below need to be signed to account for replacement code From a607cffc8c731f47a828c16d461bb97fda5ed41c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 6 Jun 2022 19:26:50 +0400 Subject: [PATCH 3/6] --bless ui --- src/test/ui/associated-consts/issue-93835.stderr | 7 +++---- .../migrations/auto_traits.stderr | 14 ++++++-------- .../migrations/multi_diagnostics.stderr | 7 +++---- src/test/ui/imports/issue-59764.stderr | 3 +-- src/test/ui/issues/issue-22644.stderr | 7 +++---- src/test/ui/let-else/let-else-if.stderr | 3 +-- .../parser/recover-labeled-non-block-expr.stderr | 7 +++---- src/test/ui/type/ascription/issue-34255-1.stderr | 3 +-- .../unboxed-closure-sugar-lifetime-elision.stderr | 7 +++---- 9 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/test/ui/associated-consts/issue-93835.stderr b/src/test/ui/associated-consts/issue-93835.stderr index 12df0e4381d15..0406a16a39732 100644 --- a/src/test/ui/associated-consts/issue-93835.stderr +++ b/src/test/ui/associated-consts/issue-93835.stderr @@ -19,11 +19,10 @@ help: you might have meant to write a `struct` literal | LL ~ fn e() { SomeStruct { LL | p:a> -LL | -LL | -LL | -LL | ... +LL | +LL ~ }} + | help: maybe you meant to write a path separator here | LL | p::a> diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr index a8367766ae1cf..a3c43690f1f32 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr @@ -17,11 +17,10 @@ help: add a dummy let to cause `fptr` to be fully captured | LL ~ thread::spawn(move || { let _ = &fptr; unsafe { LL | -LL | -LL | -LL | -LL | *fptr.0 = 20; ... +LL | +LL ~ } }); + | error: changes to closure capture in Rust 2021 will affect which traits the closure implements --> $DIR/auto_traits.rs:42:19 @@ -39,12 +38,11 @@ LL | *fptr.0.0 = 20; help: add a dummy let to cause `fptr` to be fully captured | LL ~ thread::spawn(move || { let _ = &fptr; unsafe { -LL | -LL | -LL | -LL | LL | ... +LL | +LL ~ } }); + | error: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements --> $DIR/auto_traits.rs:67:13 diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr index 483eae6bb4b1f..fa6082cbb59b4 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr @@ -108,12 +108,11 @@ LL | *fptr2.0 = 20; help: add a dummy let to cause `fptr1`, `fptr2` to be fully captured | LL ~ thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe { -LL | -LL | -LL | -LL | LL | ... +LL | +LL ~ } }); + | error: aborting due to 5 previous errors diff --git a/src/test/ui/imports/issue-59764.stderr b/src/test/ui/imports/issue-59764.stderr index c2cfc0939d6b3..8d99d757c17d6 100644 --- a/src/test/ui/imports/issue-59764.stderr +++ b/src/test/ui/imports/issue-59764.stderr @@ -209,8 +209,7 @@ help: a macro with this name exists at the root of the crate | LL ~ issue_59764::{makro as foobar, LL | -LL | foobaz, -LL | + ... LL | LL ~ foo::{baz} | diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 6bec98121b759..039ffbfd3d89f 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -89,12 +89,11 @@ LL | 5); help: try comparing the cast value | LL ~ println!("{}", (a -LL | -LL | -LL | as -LL | LL | ... +LL | +LL ~ usize) + | error: `<` is interpreted as a start of generic arguments for `usize`, not a shift --> $DIR/issue-22644.rs:32:31 diff --git a/src/test/ui/let-else/let-else-if.stderr b/src/test/ui/let-else/let-else-if.stderr index a0324565673da..746738bbd939b 100644 --- a/src/test/ui/let-else/let-else-if.stderr +++ b/src/test/ui/let-else/let-else-if.stderr @@ -8,8 +8,7 @@ help: try placing this code inside a block | LL ~ let Some(_) = Some(()) else { if true { LL | -LL | return; -LL | } else { + ... LL | return; LL ~ } }; | diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.stderr b/src/test/ui/parser/recover-labeled-non-block-expr.stderr index 767389c48088a..d95c25fdea8b5 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.stderr +++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr @@ -54,11 +54,10 @@ help: consider enclosing expression in a block | LL ~ let _i = 'label: { match x { LL | 0 => 42, -LL | 1 if false => break 'label 17, -LL | 1 => { -LL | if true { -LL | break 'label 13 ... +LL | _ => 1, +LL ~ } }; + | error: expected `while`, `for`, `loop` or `{` after a label --> $DIR/recover-labeled-non-block-expr.rs:26:24 diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr index 43f0fbbc4e387..6819d14bb0106 100644 --- a/src/test/ui/type/ascription/issue-34255-1.stderr +++ b/src/test/ui/type/ascription/issue-34255-1.stderr @@ -8,8 +8,7 @@ help: you might have meant to write a `struct` literal | LL ~ pub fn new() -> Self { SomeStruct { LL | input_cells: Vec::new() -LL | -LL | + ... LL | LL ~ }} | diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 64d14d0fc5fa4..d25452456bb21 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -9,11 +9,10 @@ help: consider introducing a named lifetime parameter | LL ~ fn main<'a>() { LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, -LL | dyn Foo(&isize) -> &isize >(); -LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, -LL | dyn Foo(&isize) -> (&isize, &isize) >(); -LL | ... +LL | +LL ~ let _: dyn Foo(&'a isize, &'a usize) -> &'a usize; + | error: aborting due to previous error From cf6f821c3372b5ddc3cb0a92afcc48a1e0313efa Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 13 Jun 2022 15:22:26 +0400 Subject: [PATCH 4/6] Try to clean up code... I'm not sure if I succeeded --- compiler/rustc_errors/src/emitter.rs | 243 +++++++++++++++++---------- 1 file changed, 150 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 269d34ea4325d..690ba14e69975 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -10,7 +10,7 @@ use Destination::*; use rustc_span::source_map::SourceMap; -use rustc_span::{SourceFile, Span}; +use rustc_span::{FileLines, SourceFile, Span}; use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString}; use crate::styled_buffer::StyledBuffer; @@ -1756,12 +1756,6 @@ impl EmitterWriter { let has_deletion = parts.iter().any(|p| p.is_deletion()); let is_multiline = complete.lines().count() > 1; - enum DisplaySuggestion { - Underline, - Diff, - None, - } - if let Some(span) = span.primary_span() { // Compare the primary span of the diagnostic with the span of the suggestion // being emitted. If they belong to the same file, we don't *need* to show the @@ -1838,83 +1832,7 @@ impl EmitterWriter { for (line_pos, (line, highlight_parts)) in lines.by_ref().zip(highlights).enumerate() { debug!(%line_pos, %line, ?highlight_parts); - let print_line = |line_pos: usize, - line: &str, - highlight_parts: &Vec, - buffer: &mut StyledBuffer, - row_num: &mut usize| { - // Print the span column to avoid confusion - buffer.puts( - *row_num, - 0, - &self.maybe_anonymized(line_start + line_pos), - Style::LineNumber, - ); - if let DisplaySuggestion::Diff = show_code_change { - // Add the line number for both addition and removal to drive the point home. - // - // N - fn foo(bar: A) { - // N + fn foo(bar: impl T) { - buffer.puts( - *row_num - 1, - 0, - &self.maybe_anonymized(line_start + line_pos), - Style::LineNumber, - ); - buffer.puts(*row_num - 1, max_line_num_len + 1, "- ", Style::Removal); - buffer.puts( - *row_num - 1, - max_line_num_len + 3, - &normalize_whitespace( - &*file_lines - .file - .get_line(file_lines.lines[line_pos].line_index) - .unwrap(), - ), - Style::NoStyle, - ); - buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); - } else if is_multiline { - match &highlight_parts[..] { - [SubstitutionHighlight { start: 0, end }] if *end == line.len() => { - buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); - } - [] => { - draw_col_separator(buffer, *row_num, max_line_num_len + 1); - } - _ => { - buffer.puts(*row_num, max_line_num_len + 1, "~ ", Style::Addition); - } - } - } else { - draw_col_separator(buffer, *row_num, max_line_num_len + 1); - } - - // print the suggestion - buffer.append(*row_num, &normalize_whitespace(line), Style::NoStyle); - - // Colorize addition/replacements with green. - for &SubstitutionHighlight { start, end } in highlight_parts { - // Account for tabs when highlighting (#87972). - let tabs: usize = line - .chars() - .take(start) - .map(|ch| match ch { - '\t' => 3, - _ => 0, - }) - .sum(); - buffer.set_style_range( - *row_num, - max_line_num_len + 3 + start + tabs, - max_line_num_len + 3 + end + tabs, - Style::Addition, - true, - ); - } - *row_num += 1; - }; - + // Remember lines that are not highlighted to hide them if needed if highlight_parts.is_empty() { unhighlighted_lines.push((line_pos, line)); continue; @@ -1927,22 +1845,77 @@ impl EmitterWriter { // (because then we just replace a line with ... which is // not helpful) n if n <= 3 => unhighlighted_lines.drain(..).for_each(|(p, l)| { - print_line(p, l, &Vec::new(), &mut buffer, &mut row_num) + self.draw_code_line( + &mut buffer, + &mut row_num, + &Vec::new(), + p, + l, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) }), + // Print first unhighlighted line, "..." and last unhighlighted line, like so: + // + // LL | this line was highlighted + // LL | this line is just for context + // ... + // LL | this line is just for context + // LL | this line was highlighted _ => { - unhighlighted_lines - .drain(..1) - .next() - .map(|(p, l)| print_line(p, l, &Vec::new(), &mut buffer, &mut row_num)); + let last_line = unhighlighted_lines.pop(); + let first_line = unhighlighted_lines.drain(..).next(); + + first_line.map(|(p, l)| { + self.draw_code_line( + &mut buffer, + &mut row_num, + &Vec::new(), + p, + l, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) + }); + buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber); row_num += 1; - unhighlighted_lines - .pop() - .map(|(p, l)| print_line(p, l, &Vec::new(), &mut buffer, &mut row_num)); + + last_line.map(|(p, l)| { + self.draw_code_line( + &mut buffer, + &mut row_num, + &Vec::new(), + p, + l, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) + }); } } - print_line(line_pos, line, highlight_parts, &mut buffer, &mut row_num) + self.draw_code_line( + &mut buffer, + &mut row_num, + highlight_parts, + line_pos, + line, + line_start, + show_code_change, + max_line_num_len, + &file_lines, + is_multiline, + ) } // This offset and the ones below need to be signed to account for replacement code @@ -2127,6 +2100,90 @@ impl EmitterWriter { } } } + + fn draw_code_line( + &self, + buffer: &mut StyledBuffer, + row_num: &mut usize, + highlight_parts: &Vec, + line_pos: usize, + line: &str, + line_start: usize, + show_code_change: DisplaySuggestion, + max_line_num_len: usize, + file_lines: &FileLines, + is_multiline: bool, + ) { + // Print the span column to avoid confusion + buffer.puts(*row_num, 0, &self.maybe_anonymized(line_start + line_pos), Style::LineNumber); + if let DisplaySuggestion::Diff = show_code_change { + // Add the line number for both addition and removal to drive the point home. + // + // N - fn foo(bar: A) { + // N + fn foo(bar: impl T) { + buffer.puts( + *row_num - 1, + 0, + &self.maybe_anonymized(line_start + line_pos), + Style::LineNumber, + ); + buffer.puts(*row_num - 1, max_line_num_len + 1, "- ", Style::Removal); + buffer.puts( + *row_num - 1, + max_line_num_len + 3, + &normalize_whitespace( + &*file_lines.file.get_line(file_lines.lines[line_pos].line_index).unwrap(), + ), + Style::NoStyle, + ); + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + } else if is_multiline { + match &highlight_parts[..] { + [SubstitutionHighlight { start: 0, end }] if *end == line.len() => { + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + } + [] => { + draw_col_separator(buffer, *row_num, max_line_num_len + 1); + } + _ => { + buffer.puts(*row_num, max_line_num_len + 1, "~ ", Style::Addition); + } + } + } else { + draw_col_separator(buffer, *row_num, max_line_num_len + 1); + } + + // print the suggestion + buffer.append(*row_num, &normalize_whitespace(line), Style::NoStyle); + + // Colorize addition/replacements with green. + for &SubstitutionHighlight { start, end } in highlight_parts { + // Account for tabs when highlighting (#87972). + let tabs: usize = line + .chars() + .take(start) + .map(|ch| match ch { + '\t' => 3, + _ => 0, + }) + .sum(); + buffer.set_style_range( + *row_num, + max_line_num_len + 3 + start + tabs, + max_line_num_len + 3 + end + tabs, + Style::Addition, + true, + ); + } + *row_num += 1; + } +} + +#[derive(Clone, Copy)] +enum DisplaySuggestion { + Underline, + Diff, + None, } impl FileWithAnnotatedLines { From 3c55672795bdc4473bbaa1922c1703916839c4aa Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 13 Jun 2022 18:28:31 +0400 Subject: [PATCH 5/6] Add back MAX_SUGGESTION_HIGHLIGHT_LINES so clippy is happy & buildable --- compiler/rustc_errors/src/emitter.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 690ba14e69975..1329e3a0b959d 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -656,6 +656,11 @@ impl Emitter for SilentEmitter { } } +/// Maximum number of lines we will print for a multiline suggestion; arbitrary. +/// +/// This should be replaced with a more involved mechanism to output multiline suggestions that +/// more closely mimics the regular diagnostic output, where irrelevant code lines are elided. +pub const MAX_SUGGESTION_HIGHLIGHT_LINES: usize = 6; /// Maximum number of suggestions to be shown /// /// Arbitrary, but taken from trait import suggestion limit From e502b9a0ff4ab37176c82a994586e6f11e57e18f Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 16 Jun 2022 18:00:32 +0400 Subject: [PATCH 6/6] bless clippy ui tests --- .../ui/bind_instead_of_map_multipart.stderr | 18 ++++++++ .../shared_at_top_and_bottom.stderr | 3 +- src/tools/clippy/tests/ui/entry.stderr | 41 ++++++++++++++++--- .../clippy/tests/ui/entry_with_else.stderr | 17 ++++++-- src/tools/clippy/tests/ui/let_unit.stderr | 3 +- .../clippy/tests/ui/manual_async_fn.stderr | 9 +++- .../ui/needless_for_each_unfixable.stderr | 3 +- .../tests/ui/new_without_default.stderr | 3 +- src/tools/clippy/tests/ui/ptr_arg.stderr | 3 +- .../ui/significant_drop_in_scrutinee.stderr | 9 +++- src/tools/clippy/tests/ui/unit_arg.stderr | 8 +++- .../clippy/tests/ui/unnecessary_wraps.stderr | 6 ++- 12 files changed, 102 insertions(+), 21 deletions(-) diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr index f822b6f49fa35..0152a93feee42 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr +++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr @@ -56,7 +56,25 @@ LL | if s == "43" { LL ~ return 43; LL | } LL | s == "42" +LL | } { +LL ~ return 45; +LL | } +LL | match s.len() { +LL ~ 10 => 2, +LL | 20 => { ... +LL | if foo() { +LL ~ return 20; +LL | } +LL | println!("foo"); +LL ~ 3 +LL | }; +LL | } +LL ~ 20 +LL | }, +LL ~ 40 => 30, +LL ~ _ => 1, + | error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)` --> $DIR/bind_instead_of_map_multipart.rs:61:13 diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr index 1db2343d3fe97..37fe2f76f4a02 100644 --- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr +++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr @@ -98,7 +98,8 @@ LL + id: e_id, LL + name: "Player 1".to_string(), LL + some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90], LL + }; - ... +LL + process_data(pack); + | error: all if blocks contain the same code at the start and the end. Here at the start --> $DIR/shared_at_top_and_bottom.rs:94:5 diff --git a/src/tools/clippy/tests/ui/entry.stderr b/src/tools/clippy/tests/ui/entry.stderr index 1076500498d32..2ef9966525cef 100644 --- a/src/tools/clippy/tests/ui/entry.stderr +++ b/src/tools/clippy/tests/ui/entry.stderr @@ -28,7 +28,8 @@ LL + v LL + } else { LL + v2 LL + } - ... +LL + }); + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry.rs:38:5 @@ -50,7 +51,8 @@ LL + v LL + } else { LL + v2 LL + } - ... +LL + }); + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry.rs:47:5 @@ -72,7 +74,9 @@ LL + e.insert(v); LL + } else { LL + e.insert(v2); LL + return; - ... +LL + } +LL + } + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry.rs:57:5 @@ -111,7 +115,11 @@ LL + 1 if true => { LL + v LL + }, LL + _ => { - ... +LL + v2 +LL + }, +LL + } +LL + }); + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry.rs:75:5 @@ -133,7 +141,9 @@ LL + 0 => foo(), LL + _ => { LL + e.insert(v2); LL + }, - ... +LL + }; +LL + } + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry.rs:85:5 @@ -155,7 +165,26 @@ LL + match 0 { LL + 0 if false => { LL + v LL + }, - ... +LL + 1 => { +LL + foo(); +LL + v +LL + }, +LL + 2 | 3 => { +LL + for _ in 0..2 { +LL + foo(); +LL + } +LL + if true { +LL + v +LL + } else { +LL + v2 +LL + } +LL + }, +LL + _ => { +LL + v2 +LL + }, +LL + } +LL + }); + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry.rs:119:5 diff --git a/src/tools/clippy/tests/ui/entry_with_else.stderr b/src/tools/clippy/tests/ui/entry_with_else.stderr index 7279efc595959..e0f6671b460ed 100644 --- a/src/tools/clippy/tests/ui/entry_with_else.stderr +++ b/src/tools/clippy/tests/ui/entry_with_else.stderr @@ -17,7 +17,9 @@ LL + e.insert(v); LL + } LL + std::collections::hash_map::Entry::Occupied(mut e) => { LL + e.insert(v2); - ... +LL + } +LL + } + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry_with_else.rs:22:5 @@ -37,7 +39,9 @@ LL + e.insert(v); LL + } LL + std::collections::hash_map::Entry::Vacant(e) => { LL + e.insert(v2); - ... +LL + } +LL + } + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry_with_else.rs:28:5 @@ -95,7 +99,9 @@ LL + e.insert(v); LL + } LL + std::collections::hash_map::Entry::Occupied(mut e) => { LL + e.insert(v2); - ... +LL + } +LL + } + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry_with_else.rs:46:5 @@ -115,7 +121,10 @@ LL + if true { Some(e.insert(v)) } else { Some(e.insert(v2)) } LL + } LL + std::collections::hash_map::Entry::Vacant(e) => { LL + e.insert(v); - ... +LL + None +LL + } +LL ~ }; + | error: usage of `contains_key` followed by `insert` on a `HashMap` --> $DIR/entry_with_else.rs:52:5 diff --git a/src/tools/clippy/tests/ui/let_unit.stderr b/src/tools/clippy/tests/ui/let_unit.stderr index 13ec11a6d33e9..45bf67acdb736 100644 --- a/src/tools/clippy/tests/ui/let_unit.stderr +++ b/src/tools/clippy/tests/ui/let_unit.stderr @@ -32,7 +32,8 @@ LL + .map(|i| i * 2) LL + .filter(|i| i % 2 == 0) LL + .map(|_| ()) LL + .next() - ... +LL + .unwrap(); + | error: this let-binding has unit value --> $DIR/let_unit.rs:80:5 diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr index 7435f46074c81..0a903ed6fd436 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.stderr +++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr @@ -122,7 +122,14 @@ LL + let a = 42; LL + let b = 21; LL + if a < b { LL + let c = 21; - ... +LL + let d = 42; +LL + if c < d { +LL + let _ = 42; +LL + } +LL + } +LL + 42 +LL + } + | error: this function can be simplified using the `async fn` syntax --> $DIR/manual_async_fn.rs:92:1 diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr index f607e0a430e24..7893ff31a6fdb 100644 --- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr +++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr @@ -19,7 +19,8 @@ LL + return; LL + } else { LL + println!("{}", v); LL + } - ... +LL + } + | help: ...and replace `return` with `continue` | LL | continue; diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr index 19572dfe8b075..212a69ab94e65 100644 --- a/src/tools/clippy/tests/ui/new_without_default.stderr +++ b/src/tools/clippy/tests/ui/new_without_default.stderr @@ -117,7 +117,8 @@ LL + Self::new() LL + } LL + } LL + - ... +LL ~ impl Foo { + | error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr index a9613daadde10..7ec4a566ff34b 100644 --- a/src/tools/clippy/tests/ui/ptr_arg.stderr +++ b/src/tools/clippy/tests/ui/ptr_arg.stderr @@ -56,7 +56,8 @@ LL | let f = e.clone(); // OK LL | let g = x; LL ~ let h = g.to_owned(); LL | let i = (e).clone(); - ... +LL ~ x.to_owned() + | error: writing `&String` instead of `&str` involves a new object where a slice will do --> $DIR/ptr_arg.rs:57:18 diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr index 303f3c1df033c..5ce9520441637 100644 --- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr +++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr @@ -188,7 +188,9 @@ LL + _ => mutex2.lock().unwrap(), LL + } LL + .s LL + .len() - ... +LL + > 1; +LL ~ match value + | error: temporary with significant drop in match scrutinee --> $DIR/significant_drop_in_scrutinee.rs:397:11 @@ -211,7 +213,10 @@ LL + } else { LL + mutex2.lock().unwrap() LL + } LL + .s - ... +LL + .len() +LL + > 1; +LL ~ match value + | error: temporary with significant drop in match scrutinee --> $DIR/significant_drop_in_scrutinee.rs:451:11 diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr index 394dee29dc96e..11cfe66a30e85 100644 --- a/src/tools/clippy/tests/ui/unit_arg.stderr +++ b/src/tools/clippy/tests/ui/unit_arg.stderr @@ -137,7 +137,13 @@ LL + foo(1); LL + }; LL + { LL + foo(2); - ... +LL + foo(3); +LL + }; +LL + taking_multiple_units( +LL + (), +LL + (), +LL ~ ); + | error: passing a unit value to a function --> $DIR/unit_arg.rs:85:13 diff --git a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr index 8e31db3950247..a6a0b22cf689f 100644 --- a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr @@ -23,7 +23,8 @@ LL | if a { LL | Some(-1); LL ~ 2 LL | } else { - ... +LL ~ return 1337; + | error: this function's return value is unnecessarily wrapped by `Option` --> $DIR/unnecessary_wraps.rs:21:1 @@ -122,7 +123,8 @@ LL | if a { LL | Some(()); LL ~ LL | } else { - ... +LL ~ return ; + | error: this function's return value is unnecessary --> $DIR/unnecessary_wraps.rs:117:1