about summary refs log tree commit diff
path: root/compiler/rustc_interface/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2025-02-22 11:36:44 +0100
committerGitHub <noreply@github.com>2025-02-22 11:36:44 +0100
commit72e41e5d650a392914a6faa56b81072a2fe16ea2 (patch)
tree7c0ba6ee1278477de69beaeaf15e88b8bfcbdfc8 /compiler/rustc_interface/src
parent37e0d138cffd8d3b3d9b9da75f2645e1ba87dacb (diff)
parentec88bc2e00985e99923ff3de966a947daa63c567 (diff)
downloadrust-72e41e5d650a392914a6faa56b81072a2fe16ea2.tar.gz
rust-72e41e5d650a392914a6faa56b81072a2fe16ea2.zip
Rollup merge of #137356 - nik-rev:FERRIS, r=compiler-errors
Ferris 🦀 Identifier naming conventions

You cannot use Ferris as an identifier in Rust, this code will suggest to correct the  🦀 to `ferris`:

```rs
fn main() {
  let  🦀 = 4;
}
```

But it also suggests to correct to `ferris` in these cases, too:

```rs
struct  🦀 {}
fn main() {}
```

^ suggests: `ferris`
~ with this PR: `Ferris`

```rs
static 🦀: &str = "ferris!";
fn main() {}
```

^ suggests: `ferris`
~ with this PR: `FERRIS`

This is my first pull requests here!
Diffstat (limited to 'compiler/rustc_interface/src')
-rw-r--r--compiler/rustc_interface/src/errors.rs3
-rw-r--r--compiler/rustc_interface/src/passes.rs35
2 files changed, 36 insertions, 2 deletions
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
index ca4e556dcdb..eed729a1777 100644
--- a/compiler/rustc_interface/src/errors.rs
+++ b/compiler/rustc_interface/src/errors.rs
@@ -24,8 +24,9 @@ pub(crate) struct CrateNameInvalid<'a> {
 pub struct FerrisIdentifier {
     #[primary_span]
     pub spans: Vec<Span>,
-    #[suggestion(code = "ferris", applicability = "maybe-incorrect")]
+    #[suggestion(code = "{ferris_fix}", applicability = "maybe-incorrect")]
     pub first_span: Span,
+    pub ferris_fix: &'static str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 2d3c7f834e9..553215ca0af 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -305,8 +305,41 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
         for (ident, mut spans) in identifiers.drain(..) {
             spans.sort();
             if ident == sym::ferris {
+                enum FerrisFix {
+                    SnakeCase,
+                    ScreamingSnakeCase,
+                    PascalCase,
+                }
+
+                impl FerrisFix {
+                    const fn as_str(self) -> &'static str {
+                        match self {
+                            FerrisFix::SnakeCase => "ferris",
+                            FerrisFix::ScreamingSnakeCase => "FERRIS",
+                            FerrisFix::PascalCase => "Ferris",
+                        }
+                    }
+                }
+
                 let first_span = spans[0];
-                sess.dcx().emit_err(errors::FerrisIdentifier { spans, first_span });
+                let prev_source = sess.psess.source_map().span_to_prev_source(first_span);
+                let ferris_fix = prev_source
+                    .map_or(FerrisFix::SnakeCase, |source| {
+                        let mut source_before_ferris = source.trim_end().split_whitespace().rev();
+                        match source_before_ferris.next() {
+                            Some("struct" | "trait" | "mod" | "union" | "type" | "enum") => {
+                                FerrisFix::PascalCase
+                            }
+                            Some("const" | "static") => FerrisFix::ScreamingSnakeCase,
+                            Some("mut") if source_before_ferris.next() == Some("static") => {
+                                FerrisFix::ScreamingSnakeCase
+                            }
+                            _ => FerrisFix::SnakeCase,
+                        }
+                    })
+                    .as_str();
+
+                sess.dcx().emit_err(errors::FerrisIdentifier { spans, first_span, ferris_fix });
             } else {
                 sess.dcx().emit_err(errors::EmojiIdentifier { spans, ident });
             }