@@ -302,7 +302,52 @@ 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+ Ok ( index) | Err ( index) if index > 0 => {
330+ let keyword = symbols[ index - 1 ] . 0 . as_str ( ) ;
331+ // if we have e.g. `static mut`
332+ if keyword == "mut" {
333+ let keyword_before = symbols. get ( index - 2 ) . map ( |s| s. 0 . as_str ( ) ) . unwrap_or_default ( ) ;
334+ if keyword_before == "static" {
335+ FerrisFix :: ScreamingSnakeCase
336+ } else {
337+ FerrisFix :: SnakeCase
338+ }
339+ } else {
340+ match keyword {
341+ "const" | "static" => FerrisFix :: ScreamingSnakeCase ,
342+ "trait" | "mod" | "union" | "type" | "enum" => FerrisFix :: PascalCase ,
343+ _ => FerrisFix :: SnakeCase ,
344+ }
345+ }
346+ } ,
347+ _ => FerrisFix :: SnakeCase ,
348+ } . as_str ( ) ;
349+
350+ sess. dcx ( ) . emit_err ( errors:: FerrisIdentifier { spans, first_span, ferris_fix } ) ;
306351 } else {
307352 sess. dcx ( ) . emit_err ( errors:: EmojiIdentifier { spans, ident } ) ;
308353 }
0 commit comments