Repository: rust-lang/rust-clippy (Rust)

Issue:
needless-arbitrary-self-type ignores raw identifiers
### Summary

clippy misses the "#r" in the suggestion which then causes an error 

### Lint Name

needless-arbitrary-self-type

### Reproducer

I tried this code:

```rust
//@ check-pass
//@ edition: 2021

fn foo<'r#struct>() {}

fn hr<T>() where for<'r#struct> T: Into<&'r#struct ()> {}

trait Foo<'r#struct> {}

trait Bar<'r#struct> {
    fn method(&'r#struct self) {}
    fn method2(self: &'r#struct Self) {}
}

fn labeled() {
    'r#struct: loop {
        break 'r#struct;
    }
}

fn main() {}

```

I saw this happen:

```
warning: the type of the `self` parameter does not need to be arbitrary
  --> src/main.rs:12:16
   |
12 |     fn method2(self: &'r#struct Self) {}
   |                ^^^^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'struct self`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type
   = note: `#[warn(clippy::needless_arbitrary_self_type)]` on by default
```

this will cause an error:
```
error: lifetimes cannot use keyword names
  --> src/main.rs:12:17
   |
12 |     fn method2(&'struct self) {}
   |                 ^^^^^^^

error: aborting due to 1 previous error
```

### Version

```text
rustc 1.85.0-nightly (8742e0556 2024-12-28)
binary: rustc
commit-hash: 8742e0556dee3c64f7144de2fb2e88936418865a
commit-date: 2024-12-28
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6
```

### Additional Labels

_No response_


Discussion:

Patch:
diff --git a/clippy_lints/src/needless_arbitrary_self_type.rs b/clippy_lints/src/needless_arbitrary_self_type.rs
index 3c47d0edfdc5..5f7fde30f03f 100644
--- a/clippy_lints/src/needless_arbitrary_self_type.rs
+++ b/clippy_lints/src/needless_arbitrary_self_type.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
 use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Mutability, Param, PatKind, Path, TyKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
@@ -80,7 +81,8 @@ fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mod
                     applicability = Applicability::HasPlaceholders;
                     "&'_ mut self".to_string()
                 } else {
-                    format!("&{} mut self", &lifetime.ident.name)
+                    let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "..", &mut applicability);
+                    format!("&{lt_name} mut self")
                 }
             },
             (Mode::Ref(None), Mutability::Not) => "&self".to_string(),
@@ -89,7 +91,8 @@ fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mod
                     applicability = Applicability::HasPlaceholders;
                     "&'_ self".to_string()
                 } else {
-                    format!("&{} self", &lifetime.ident.name)
+                    let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "..", &mut applicability);
+                    format!("&{lt_name} self")
                 }
             },
             (Mode::Value, Mutability::Mut) => "mut self".to_string(),


Test patch:
diff --git a/tests/ui/needless_arbitrary_self_type.fixed b/tests/ui/needless_arbitrary_self_type.fixed
index 9da60c687d44..530eb77d83d2 100644
--- a/tests/ui/needless_arbitrary_self_type.fixed
+++ b/tests/ui/needless_arbitrary_self_type.fixed
@@ -64,4 +64,9 @@ impl ValType {
     }
 }
 
+trait Foo<'r#struct> {
+    fn f1(&'r#struct self) {}
+    fn f2(&'r#struct mut self) {}
+}
+
 fn main() {}
diff --git a/tests/ui/needless_arbitrary_self_type.rs b/tests/ui/needless_arbitrary_self_type.rs
index fc4ec5cb0b3c..5a1ff96a11cc 100644
--- a/tests/ui/needless_arbitrary_self_type.rs
+++ b/tests/ui/needless_arbitrary_self_type.rs
@@ -64,4 +64,9 @@ impl ValType {
     }
 }
 
+trait Foo<'r#struct> {
+    fn f1(self: &'r#struct Self) {}
+    fn f2(self: &'r#struct mut Self) {}
+}
+
 fn main() {}
diff --git a/tests/ui/needless_arbitrary_self_type.stderr b/tests/ui/needless_arbitrary_self_type.stderr
index c653267f7525..7ebbbaa122f5 100644
--- a/tests/ui/needless_arbitrary_self_type.stderr
+++ b/tests/ui/needless_arbitrary_self_type.stderr
@@ -37,5 +37,17 @@ error: the type of the `self` parameter does not need to be arbitrary
 LL |     pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) {
    |                                          ^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'a mut self`
 
-error: aborting due to 6 previous errors
+error: the type of the `self` parameter does not need to be arbitrary
+  --> tests/ui/needless_arbitrary_self_type.rs:68:11
+   |
+LL |     fn f1(self: &'r#struct Self) {}
+   |           ^^^^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'r#struct self`
+
+error: the type of the `self` parameter does not need to be arbitrary
+  --> tests/ui/needless_arbitrary_self_type.rs:69:11
+   |
+LL |     fn f2(self: &'r#struct mut Self) {}
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'r#struct mut self`
+
+error: aborting due to 8 previous errors