From 4b32a49ef154039c79168a7d1edf897266de2473 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 23 Jul 2025 13:40:38 +0800 Subject: [PATCH 1/2] Change rename self to parameter use `Self` type And add `&self` lifetime support Example === Rename to `this` ```rust struct Foo(T); impl Foo { fn foo(&'static self$0) {} } ``` Old: ```rust struct Foo(T); impl Foo { fn foo(this: &Foo) {} } ``` Fixes: ```rust struct Foo(T); impl Foo { fn foo(this: &'static Self) {} } ``` --- crates/ide/src/rename.rs | 77 +++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index fb84e8e6b4..67560fdecb 100644 --- a/crates/ide/src/rename.rs +++ b/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 { - fn target_type_name(impl_def: &ast::Impl) -> Option { - 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(": "); + + 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 "); } - 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()); - - 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 } From 9ecd82be1351c864dc8636ec71d7152efb72f5cd Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Wed, 23 Jul 2025 22:04:59 +0800 Subject: [PATCH 2/2] Remove rename_self_outside_of_methods --- crates/ide/src/rename.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 67560fdecb..a07c647c2c 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -473,12 +473,7 @@ fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: String) -> O replacement_text.push_str("mut "); } - 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('_'); - } + replacement_text.push_str("Self"); Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) } @@ -2124,7 +2119,6 @@ impl<'a> Foo<'a> { #[test] fn test_self_outside_of_methods() { - cov_mark::check!(rename_self_outside_of_methods); check( "foo", r#" @@ -2133,7 +2127,7 @@ fn f($0self) -> i32 { } "#, r#" -fn f(foo: _) -> i32 { +fn f(foo: Self) -> i32 { foo.i } "#,