@@ -302,7 +302,57 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
302
302
spans. sort ( ) ;
303
303
if ident == sym:: ferris {
304
304
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 } ) ;
306
356
} else {
307
357
sess. dcx ( ) . emit_err ( errors:: EmojiIdentifier { spans, ident } ) ;
308
358
}
0 commit comments