Skip to content

Commit 6dd718c

Browse files
committed
Use heuristics for capitalization warning in suggestions
1 parent 4bb7716 commit 6dd718c

13 files changed

+37
-24
lines changed

src/librustc_errors/emitter.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use syntax_pos::{SourceFile, Span, MultiSpan};
1313

1414
use crate::{
1515
Level, CodeSuggestion, Diagnostic, SubDiagnostic,
16-
SuggestionStyle, SourceMapperDyn, DiagnosticId,
16+
SuggestionStyle, SourceMapper, SourceMapperDyn, DiagnosticId,
1717
};
1818
use crate::Level::Error;
1919
use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style};
@@ -239,11 +239,11 @@ pub trait Emitter {
239239
format!(
240240
"help: {}{}: `{}`",
241241
sugg.msg,
242-
if self.source_map().as_ref().map(|sm| substitution.to_lowercase() == sm
243-
.span_to_snippet(sugg.substitutions[0].parts[0].span)
244-
.unwrap()
245-
.to_lowercase()).unwrap_or(false)
246-
{
242+
if self.source_map().map(|sm| is_case_difference(
243+
&**sm,
244+
substitution,
245+
sugg.substitutions[0].parts[0].span,
246+
)).unwrap_or(false) {
247247
" (notice the capitalization)"
248248
} else {
249249
""
@@ -2058,3 +2058,18 @@ impl<'a> Drop for WritableDst<'a> {
20582058
}
20592059
}
20602060
}
2061+
2062+
/// Whether the original and suggested code are visually similar enough to warrant extra wording.
2063+
pub fn is_case_difference(sm: &dyn SourceMapper, suggested: &str, sp: Span) -> bool {
2064+
// FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode.
2065+
let found = sm.span_to_snippet(sp).unwrap();
2066+
let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
2067+
// There are ASCII chars that are confusable (above) and differ in capitalization:
2068+
let confusable = found.chars().zip(suggested.chars()).any(|(f, s)| {
2069+
(ascii_confusables.contains(&f) || ascii_confusables.contains(&s)) && f != s
2070+
});
2071+
confusable && found.to_lowercase() == suggested.to_lowercase()
2072+
// FIXME: We sometimes suggest the same thing we already have, which is a
2073+
// bug, but be defensive against that here.
2074+
&& found != suggested
2075+
}

src/librustc_errors/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use emitter::ColorConfig;
1313

1414
use Level::*;
1515

16-
use emitter::{Emitter, EmitterWriter};
16+
use emitter::{Emitter, EmitterWriter, is_case_difference};
1717
use registry::Registry;
1818

1919
use rustc_data_structures::sync::{self, Lrc, Lock};
@@ -239,8 +239,7 @@ impl CodeSuggestion {
239239
prev_hi = cm.lookup_char_pos(part.span.hi());
240240
prev_line = fm.get_line(prev_hi.line - 1);
241241
}
242-
let only_capitalization = buf.clone().to_lowercase()
243-
== cm.span_to_snippet(bounding_span).unwrap().to_lowercase();
242+
let only_capitalization = is_case_difference(cm, &buf, bounding_span);
244243
// if the replacement already ends with a newline, don't print the next line
245244
if !buf.ends_with('\n') {
246245
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
@@ -250,7 +249,6 @@ impl CodeSuggestion {
250249
buf.pop();
251250
}
252251
(buf, substitution.parts, only_capitalization)
253-
254252
}).collect()
255253
}
256254
}

src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | use my_core;
55
| ^^^^^^^
66
| |
77
| no `my_core` in the root
8-
| help: a similar name exists in the module (notice the capitalization): `my_core`
8+
| help: a similar name exists in the module: `my_core`
99

1010
error[E0432]: unresolved import `my_core`
1111
--> $DIR/extern-prelude-from-opaque-fail.rs:7:13

src/test/ui/lint/lint-group-nonstandard-style.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ error: static variable `bad` should have an upper case name
4141
--> $DIR/lint-group-nonstandard-style.rs:14:16
4242
|
4343
LL | static bad: isize = 1;
44-
| ^^^ help: convert the identifier to upper case (notice the capitalization): `BAD`
44+
| ^^^ help: convert the identifier to upper case: `BAD`
4545
|
4646
note: lint level defined here
4747
--> $DIR/lint-group-nonstandard-style.rs:10:14

src/test/ui/lint/lint-lowercase-static-const-pattern.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: constant in pattern `a` should have an upper case name
22
--> $DIR/lint-lowercase-static-const-pattern.rs:11:13
33
|
44
LL | (0, a) => 0,
5-
| ^ help: convert the identifier to upper case (notice the capitalization): `A`
5+
| ^ help: convert the identifier to upper case: `A`
66
|
77
note: lint level defined here
88
--> $DIR/lint-lowercase-static-const-pattern.rs:4:9
@@ -14,7 +14,7 @@ error: constant in pattern `aha` should have an upper case name
1414
--> $DIR/lint-lowercase-static-const-pattern.rs:26:13
1515
|
1616
LL | (0, aha) => 0,
17-
| ^^^ help: convert the identifier to upper case (notice the capitalization): `AHA`
17+
| ^^^ help: convert the identifier to upper case: `AHA`
1818

1919
error: constant in pattern `not_okay` should have an upper case name
2020
--> $DIR/lint-lowercase-static-const-pattern.rs:40:13

src/test/ui/lint/lint-non-camel-case-types.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ error: variant `bar` should have an upper camel case name
3838
--> $DIR/lint-non-camel-case-types.rs:22:5
3939
|
4040
LL | bar
41-
| ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Bar`
41+
| ^^^ help: convert the identifier to upper camel case: `Bar`
4242

4343
error: trait `foo6` should have an upper camel case name
4444
--> $DIR/lint-non-camel-case-types.rs:25:7
@@ -50,7 +50,7 @@ error: type parameter `ty` should have an upper camel case name
5050
--> $DIR/lint-non-camel-case-types.rs:29:6
5151
|
5252
LL | fn f<ty>(_: ty) {}
53-
| ^^ help: convert the identifier to upper camel case (notice the capitalization): `Ty`
53+
| ^^ help: convert the identifier to upper camel case: `Ty`
5454

5555
error: aborting due to 8 previous errors
5656

src/test/ui/lint/lint-non-snake-case-functions.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ error: method `render_HTML` should have a snake case name
2626
--> $DIR/lint-non-snake-case-functions.rs:17:8
2727
|
2828
LL | fn render_HTML() {}
29-
| ^^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `render_html`
29+
| ^^^^^^^^^^^ help: convert the identifier to snake case: `render_html`
3030

3131
error: trait method `ABC` should have a snake case name
3232
--> $DIR/lint-non-snake-case-functions.rs:22:8

src/test/ui/lint/lint-non-uppercase-statics.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ error: static variable `bar` should have an upper case name
1414
--> $DIR/lint-non-uppercase-statics.rs:6:12
1515
|
1616
LL | static mut bar: isize = 1;
17-
| ^^^ help: convert the identifier to upper case (notice the capitalization): `BAR`
17+
| ^^^ help: convert the identifier to upper case: `BAR`
1818

1919
error: aborting due to 2 previous errors
2020

src/test/ui/lint/lint-uppercase-variables.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ error: variable `Test` should have a snake case name
3939
--> $DIR/lint-uppercase-variables.rs:18:9
4040
|
4141
LL | let Test: usize = 0;
42-
| ^^^^ help: convert the identifier to snake case (notice the capitalization): `test`
42+
| ^^^^ help: convert the identifier to snake case: `test`
4343

4444
error: variable `Foo` should have a snake case name
4545
--> $DIR/lint-uppercase-variables.rs:22:9

src/test/ui/resolve/issue-39226.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | handle: Handle
88
| ^^^^^^
99
| |
1010
| did you mean `Handle { /* fields */ }`?
11-
| help: a local variable with a similar name exists (notice the capitalization): `handle`
11+
| help: a local variable with a similar name exists: `handle`
1212

1313
error: aborting due to previous error
1414

src/test/ui/test-attrs/inaccessible-test-modules.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | use main as x;
55
| ----^^^^^
66
| |
77
| no `main` in the root
8-
| help: a similar name exists in the module (notice the capitalization): `main`
8+
| help: a similar name exists in the module: `main`
99

1010
error[E0432]: unresolved import `test`
1111
--> $DIR/inaccessible-test-modules.rs:6:5
@@ -14,7 +14,7 @@ LL | use test as y;
1414
| ----^^^^^
1515
| |
1616
| no `test` in the root
17-
| help: a similar name exists in the module (notice the capitalization): `test`
17+
| help: a similar name exists in the module: `test`
1818

1919
error: aborting due to 2 previous errors
2020

src/test/ui/traits/trait-impl-for-module.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0573]: expected type, found module `a`
22
--> $DIR/trait-impl-for-module.rs:7:12
33
|
44
LL | impl A for a {
5-
| ^ help: a trait with a similar name exists (notice the capitalization): `A`
5+
| ^ help: a trait with a similar name exists: `A`
66

77
error: aborting due to previous error
88

src/test/ui/utf8_idents.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ warning: type parameter `γ` should have an upper camel case name
3838
--> $DIR/utf8_idents.rs:3:5
3939
|
4040
LL | γ
41-
| ^ help: convert the identifier to upper camel case (notice the capitalization): `Γ`
41+
| ^ help: convert the identifier to upper camel case: `Γ`
4242
|
4343
= note: `#[warn(non_camel_case_types)]` on by default
4444

0 commit comments

Comments
 (0)