Fix msg for verbose suggestions with confusable capitalization

When encountering a verbose/multipart suggestion that has changes
that are only caused by different capitalization of ASCII letters that have
little differenciation, expand the message to highlight that fact (like we
already do for inline suggestions).

The logic to do this was already present, but implemented incorrectly.
This commit is contained in:
Esteban Küber 2024-02-14 19:18:28 +00:00
parent eaff1af8fd
commit 8d4d572e4d
9 changed files with 26 additions and 24 deletions

View File

@ -1742,9 +1742,17 @@ impl HumanEmitter {
buffer.append(0, level.to_str(), Style::Level(*level));
buffer.append(0, ": ", Style::HeaderMsg);
let mut msg = vec![(suggestion.msg.to_owned(), Style::NoStyle)];
if suggestions
.iter()
.take(MAX_SUGGESTIONS)
.any(|(_, _, _, only_capitalization)| *only_capitalization)
{
msg.push((" (notice the capitalization difference)".into(), Style::NoStyle));
}
self.msgs_to_buffer(
&mut buffer,
&[(suggestion.msg.to_owned(), Style::NoStyle)],
&msg,
args,
max_line_num_len,
"suggestion",
@ -1753,12 +1761,8 @@ impl HumanEmitter {
let mut row_num = 2;
draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
let mut notice_capitalization = false;
for (complete, parts, highlights, only_capitalization) in
suggestions.iter().take(MAX_SUGGESTIONS)
{
for (complete, parts, highlights, _) in suggestions.iter().take(MAX_SUGGESTIONS) {
debug!(?complete, ?parts, ?highlights);
notice_capitalization |= only_capitalization;
let has_deletion = parts.iter().any(|p| p.is_deletion(sm));
let is_multiline = complete.lines().count() > 1;
@ -2057,9 +2061,6 @@ impl HumanEmitter {
let others = suggestions.len() - MAX_SUGGESTIONS;
let msg = format!("and {} other candidate{}", others, pluralize!(others));
buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
} else if notice_capitalization {
let msg = "notice the capitalization difference";
buffer.puts(row_num, max_line_num_len + 3, msg, Style::NoStyle);
}
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
Ok(())

View File

@ -319,7 +319,9 @@ impl CodeSuggestion {
// We need to keep track of the difference between the existing code and the added
// or deleted code in order to point at the correct column *after* substitution.
let mut acc = 0;
let mut only_capitalization = false;
for part in &substitution.parts {
only_capitalization |= is_case_difference(sm, &part.snippet, part.span);
let cur_lo = sm.lookup_char_pos(part.span.lo());
if prev_hi.line == cur_lo.line {
let mut count =
@ -392,7 +394,6 @@ impl CodeSuggestion {
}
}
highlights.push(std::mem::take(&mut line_highlight));
let only_capitalization = is_case_difference(sm, &buf, bounding_span);
// if the replacement already ends with a newline, don't print the next line
if !buf.ends_with('\n') {
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);

View File

@ -17,7 +17,7 @@ error: this `match` arm has a differing case than its expression
LL | "~!@#$%^&*()-_=+Foo" => {},
| ^^^^^^^^^^^^^^^^^^^^
|
help: consider changing the case of this arm to respect `to_ascii_lowercase`
help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization difference)
|
LL | "~!@#$%^&*()-_=+foo" => {},
| ~~~~~~~~~~~~~~~~~~~~

View File

@ -53,7 +53,7 @@ help: use struct literal syntax instead
|
LL | let f = Foo { a: val };
| ~~~~~~~~~~~~~~
help: a function with a similar name exists
help: a function with a similar name exists (notice the capitalization difference)
|
LL | let f = foo();
| ~~~

View File

@ -4,7 +4,7 @@ error: expected identifier, found keyword `fn`
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^
|
help: use `Fn` to refer to the trait
help: use `Fn` to refer to the trait (notice the capitalization difference)
|
LL | fn _f<F: Fn(), G>(_: impl fn(), _: &dyn fn())
| ~~
@ -15,7 +15,7 @@ error: expected identifier, found keyword `fn`
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^
|
help: use `Fn` to refer to the trait
help: use `Fn` to refer to the trait (notice the capitalization difference)
|
LL | fn _f<F: fn(), G>(_: impl Fn(), _: &dyn fn())
| ~~
@ -26,7 +26,7 @@ error: expected identifier, found keyword `fn`
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^
|
help: use `Fn` to refer to the trait
help: use `Fn` to refer to the trait (notice the capitalization difference)
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn Fn())
| ~~
@ -37,7 +37,7 @@ error: expected identifier, found keyword `fn`
LL | G: fn(),
| ^^
|
help: use `Fn` to refer to the trait
help: use `Fn` to refer to the trait (notice the capitalization difference)
|
LL | G: Fn(),
| ~~

View File

@ -4,7 +4,7 @@ error: expected identifier, found keyword `fn`
LL | fn foo(_: impl fn() -> i32) {}
| ^^
|
help: use `Fn` to refer to the trait
help: use `Fn` to refer to the trait (notice the capitalization difference)
|
LL | fn foo(_: impl Fn() -> i32) {}
| ~~
@ -15,7 +15,7 @@ error: expected identifier, found keyword `fn`
LL | fn foo2<T: fn(i32)>(_: T) {}
| ^^
|
help: use `Fn` to refer to the trait
help: use `Fn` to refer to the trait (notice the capitalization difference)
|
LL | fn foo2<T: Fn(i32)>(_: T) {}
| ~~

View File

@ -4,7 +4,7 @@ error: `const` keyword was mistyped as `Const`
LL | pub fn foo<Const N: u8>() {}
| ^^^^^
|
help: use the `const` keyword
help: use the `const` keyword (notice the capitalization difference)
|
LL | pub fn foo<const N: u8>() {}
| ~~~~~
@ -15,7 +15,7 @@ error: `const` keyword was mistyped as `Const`
LL | pub fn baz<Const N: u8, T>() {}
| ^^^^^
|
help: use the `const` keyword
help: use the `const` keyword (notice the capitalization difference)
|
LL | pub fn baz<const N: u8, T>() {}
| ~~~~~
@ -26,7 +26,7 @@ error: `const` keyword was mistyped as `Const`
LL | pub fn qux<T, Const N: u8>() {}
| ^^^^^
|
help: use the `const` keyword
help: use the `const` keyword (notice the capitalization difference)
|
LL | pub fn qux<T, const N: u8>() {}
| ~~~~~
@ -37,7 +37,7 @@ error: `const` keyword was mistyped as `Const`
LL | pub fn quux<T, Const N: u8, U>() {}
| ^^^^^
|
help: use the `const` keyword
help: use the `const` keyword (notice the capitalization difference)
|
LL | pub fn quux<T, const N: u8, U>() {}
| ~~~~~

View File

@ -8,7 +8,7 @@ LL | let x: i32 = MyS::foo;
|
= note: expected type `i32`
found fn item `fn() -> MyS {MyS::foo}`
help: try referring to the associated const `FOO` instead
help: try referring to the associated const `FOO` instead (notice the capitalization difference)
|
LL | let x: i32 = MyS::FOO;
| ~~~

View File

@ -15,7 +15,7 @@ error[E0425]: cannot find value `False` in this scope
LL | let y = False;
| ^^^^^ not found in this scope
|
help: you may want to use a bool value instead
help: you may want to use a bool value instead (notice the capitalization difference)
|
LL | let y = false;
| ~~~~~