Skip to content

Commit ca69dc2

Browse files
committedFeb 21, 2025·
fix: naming convention "ferris" suggestion for idents named 🦀
test: add tests for correct ferris capitalization fix: add "struct" style: use rustfmt style: remove newline fix: _ _
1 parent 28b83ee commit ca69dc2

File tree

7 files changed

+80
-2
lines changed

7 files changed

+80
-2
lines changed
 

‎compiler/rustc_interface/src/errors.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ pub(crate) struct CrateNameInvalid<'a> {
2424
pub struct FerrisIdentifier {
2525
#[primary_span]
2626
pub spans: Vec<Span>,
27-
#[suggestion(code = "ferris", applicability = "maybe-incorrect")]
27+
#[suggestion(code = "{ferris_fix}", applicability = "maybe-incorrect")]
2828
pub first_span: Span,
29+
pub ferris_fix: &'static str,
2930
}
3031

3132
#[derive(Diagnostic)]

‎compiler/rustc_interface/src/passes.rs

+51-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,57 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
302302
spans.sort();
303303
if ident == sym::ferris {
304304
let first_span = spans[0];
305-
sess.dcx().emit_err(errors::FerrisIdentifier { spans, first_span });
305+
306+
enum FerrisFix {
307+
SnakeCase,
308+
ScreamingSnakeCase,
309+
PascalCase,
310+
}
311+
312+
impl FerrisFix {
313+
const fn as_str(self) -> &'static str {
314+
match self {
315+
FerrisFix::SnakeCase => "ferris",
316+
FerrisFix::ScreamingSnakeCase => "FERRIS",
317+
FerrisFix::PascalCase => "Ferris",
318+
}
319+
}
320+
}
321+
322+
// Obtain the symbol that is before Ferris.
323+
let symbols = &sess.psess.symbol_gallery.symbols.lock();
324+
let mut symbols: Vec<_> = symbols.iter().collect();
325+
326+
// sort by spans
327+
symbols.sort_unstable_by_key(|k| k.1);
328+
let ferris_fix = match symbols.binary_search_by(|(_, span)| span.cmp(&&first_span))
329+
{
330+
Ok(index) | Err(index) if index > 0 => {
331+
let keyword = symbols[index - 1].0.as_str();
332+
// if we have e.g. `static mut`
333+
if keyword == "mut" {
334+
let keyword_before =
335+
symbols.get(index - 2).map(|s| s.0.as_str()).unwrap_or_default();
336+
if keyword_before == "static" {
337+
FerrisFix::ScreamingSnakeCase
338+
} else {
339+
FerrisFix::SnakeCase
340+
}
341+
} else {
342+
match keyword {
343+
"const" | "static" => FerrisFix::ScreamingSnakeCase,
344+
"struct" | "trait" | "mod" | "union" | "type" | "enum" => {
345+
FerrisFix::PascalCase
346+
}
347+
_ => FerrisFix::SnakeCase,
348+
}
349+
}
350+
}
351+
_ => FerrisFix::SnakeCase,
352+
}
353+
.as_str();
354+
355+
sess.dcx().emit_err(errors::FerrisIdentifier { spans, first_span, ferris_fix });
306356
} else {
307357
sess.dcx().emit_err(errors::EmojiIdentifier { spans, ident });
308358
}

‎test.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
struct 🦀 {}
2+
3+
fn main() {
4+
let a = 4;
5+
}

‎tests/ui/parser/ferris-static-mut.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
static mut 🦀: &str = "ferris!";//~ ERROR Ferris cannot be used as an identifier
2+
3+
fn main() {}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: Ferris cannot be used as an identifier
2+
--> $DIR/ferris-static-mut.rs:1:12
3+
|
4+
LL | static mut 🦀: &str = "ferris!";
5+
| ^^ help: try using their name instead: `FERRIS`
6+
7+
error: aborting due to 1 previous error
8+

‎tests/ui/parser/ferris-struct.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct 🦀 {}//~ ERROR Ferris cannot be used as an identifier
2+
3+
fn main() {}

‎tests/ui/parser/ferris-struct.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: Ferris cannot be used as an identifier
2+
--> $DIR/ferris-struct.rs:1:8
3+
|
4+
LL | struct 🦀 {}
5+
| ^^ help: try using their name instead: `Ferris`
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)