about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
authorA4-Tacks <wdsjxhno1001@163.com>2025-07-23 13:40:38 +0800
committerA4-Tacks <wdsjxhno1001@163.com>2025-07-23 13:51:28 +0800
commit1023edc49cef9fee8bd8f6d40de67f76feb367c6 (patch)
tree87222f931c57dd3651e5c56788622c1a84ca577f /src/tools/rust-analyzer
parent8bab91ce35ba457353e261c52fd4968d75060bdb (diff)
downloadrust-1023edc49cef9fee8bd8f6d40de67f76feb367c6.tar.gz
rust-1023edc49cef9fee8bd8f6d40de67f76feb367c6.zip
Change rename self to parameter use `Self` type
And add `&self` lifetime support

Example
===

Rename to `this`

```rust
struct Foo<T>(T);
impl Foo<i32> {
    fn foo(&'static self$0) {}
}
```

Old:

```rust
struct Foo<T>(T);
impl Foo<i32> {
    fn foo(this: &Foo) {}
}
```

Fixes:

```rust
struct Foo<T>(T);
impl Foo<i32> {
    fn foo(this: &'static Self) {}
}
```
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs77
1 files changed, 48 insertions, 29 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index fb84e8e6b47..67560fdecb1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -12,6 +12,7 @@ use ide_db::{
     source_change::SourceChangeBuilder,
 };
 use itertools::Itertools;
+use std::fmt::Write;
 use stdx::{always, never};
 use syntax::{AstNode, SyntaxKind, SyntaxNode, TextRange, TextSize, ast};
 
@@ -459,35 +460,27 @@ fn rename_self_to_param(
 }
 
 fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: String) -> Option<TextEdit> {
-    fn target_type_name(impl_def: &ast::Impl) -> Option<String> {
-        if let Some(ast::Type::PathType(p)) = impl_def.self_ty() {
-            return Some(p.path()?.segment()?.name_ref()?.text().to_string());
-        }
-        None
-    }
+    let mut replacement_text = new_name;
+    replacement_text.push_str(": ");
 
-    match self_param.syntax().ancestors().find_map(ast::Impl::cast) {
-        Some(impl_def) => {
-            let type_name = target_type_name(&impl_def)?;
-
-            let mut replacement_text = new_name;
-            replacement_text.push_str(": ");
-            match (self_param.amp_token(), self_param.mut_token()) {
-                (Some(_), None) => replacement_text.push('&'),
-                (Some(_), Some(_)) => replacement_text.push_str("&mut "),
-                (_, _) => (),
-            };
-            replacement_text.push_str(type_name.as_str());
+    if self_param.amp_token().is_some() {
+        replacement_text.push('&');
+    }
+    if let Some(lifetime) = self_param.lifetime() {
+        write!(replacement_text, "{lifetime} ").unwrap();
+    }
+    if self_param.amp_token().and(self_param.mut_token()).is_some() {
+        replacement_text.push_str("mut ");
+    }
 
-            Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text))
-        }
-        None => {
-            cov_mark::hit!(rename_self_outside_of_methods);
-            let mut replacement_text = new_name;
-            replacement_text.push_str(": _");
-            Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text))
-        }
+    if self_param.syntax().ancestors().find_map(ast::Impl::cast).is_some() {
+        replacement_text.push_str("Self");
+    } else {
+        cov_mark::hit!(rename_self_outside_of_methods);
+        replacement_text.push('_');
     }
+
+    Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text))
 }
 
 #[cfg(test)]
@@ -2069,7 +2062,7 @@ impl Foo {
 struct Foo { i: i32 }
 
 impl Foo {
-    fn f(foo: &mut Foo) -> i32 {
+    fn f(foo: &mut Self) -> i32 {
         foo.i
     }
 }
@@ -2095,7 +2088,33 @@ impl Foo {
 struct Foo { i: i32 }
 
 impl Foo {
-    fn f(foo: Foo) -> i32 {
+    fn f(foo: Self) -> i32 {
+        foo.i
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn test_owned_self_to_parameter_with_lifetime() {
+        cov_mark::check!(rename_self_to_param);
+        check(
+            "foo",
+            r#"
+struct Foo<'a> { i: &'a i32 }
+
+impl<'a> Foo<'a> {
+    fn f(&'a $0self) -> i32 {
+        self.i
+    }
+}
+"#,
+            r#"
+struct Foo<'a> { i: &'a i32 }
+
+impl<'a> Foo<'a> {
+    fn f(foo: &'a Self) -> i32 {
         foo.i
     }
 }
@@ -2159,7 +2178,7 @@ impl Foo {
 struct Foo { i: i32 }
 
 impl Foo {
-    fn f(foo: &Foo) -> i32 {
+    fn f(foo: &Self) -> i32 {
         let self_var = 1;
         foo.i
     }