aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/references/rename.rs81
1 files changed, 40 insertions, 41 deletions
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index e1ed6de35..6b3d02bf4 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -86,6 +86,18 @@ pub(crate) fn rename_with_semantics(
86 let syntax = source_file.syntax(); 86 let syntax = source_file.syntax();
87 87
88 let def = find_definition(sema, syntax, position)?; 88 let def = find_definition(sema, syntax, position)?;
89
90 if let Definition::Local(local) = def {
91 if let Some(self_param) = local.as_self_param(sema.db) {
92 cov_mark::hit!(rename_self_to_param);
93 return rename_self_to_param(sema, local, self_param, new_name);
94 }
95 if new_name == "self" {
96 cov_mark::hit!(rename_to_self);
97 return rename_to_self(sema, local);
98 }
99 }
100
89 match def { 101 match def {
90 Definition::ModuleDef(hir::ModuleDef::Module(module)) => rename_mod(sema, module, new_name), 102 Definition::ModuleDef(hir::ModuleDef::Module(module)) => rename_mod(sema, module, new_name),
91 Definition::SelfType(_) => bail!("Cannot rename `Self`"), 103 Definition::SelfType(_) => bail!("Cannot rename `Self`"),
@@ -113,26 +125,26 @@ pub(crate) fn will_rename_file(
113enum IdentifierKind { 125enum IdentifierKind {
114 Ident, 126 Ident,
115 Lifetime, 127 Lifetime,
116 ToSelf,
117 Underscore, 128 Underscore,
118} 129}
119 130
120fn check_identifier(new_name: &str) -> RenameResult<IdentifierKind> { 131impl IdentifierKind {
121 match lex_single_syntax_kind(new_name) { 132 fn classify(new_name: &str) -> RenameResult<IdentifierKind> {
122 Some(res) => match res { 133 match lex_single_syntax_kind(new_name) {
123 (SyntaxKind::IDENT, _) => Ok(IdentifierKind::Ident), 134 Some(res) => match res {
124 (T![_], _) => Ok(IdentifierKind::Underscore), 135 (SyntaxKind::IDENT, _) => Ok(IdentifierKind::Ident),
125 (T![self], _) => Ok(IdentifierKind::ToSelf), 136 (T![_], _) => Ok(IdentifierKind::Underscore),
126 (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => { 137 (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => {
127 Ok(IdentifierKind::Lifetime) 138 Ok(IdentifierKind::Lifetime)
128 } 139 }
129 (SyntaxKind::LIFETIME_IDENT, _) => { 140 (SyntaxKind::LIFETIME_IDENT, _) => {
130 bail!("Invalid name `{}`: not a lifetime identifier", new_name) 141 bail!("Invalid name `{}`: not a lifetime identifier", new_name)
131 } 142 }
132 (_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error), 143 (_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error),
133 (_, None) => bail!("Invalid name `{}`: not an identifier", new_name), 144 (_, None) => bail!("Invalid name `{}`: not an identifier", new_name),
134 }, 145 },
135 None => bail!("Invalid name `{}`: not an identifier", new_name), 146 None => bail!("Invalid name `{}`: not an identifier", new_name),
147 }
136 } 148 }
137} 149}
138 150
@@ -182,7 +194,7 @@ fn rename_mod(
182 module: hir::Module, 194 module: hir::Module,
183 new_name: &str, 195 new_name: &str,
184) -> RenameResult<SourceChange> { 196) -> RenameResult<SourceChange> {
185 if IdentifierKind::Ident != check_identifier(new_name)? { 197 if IdentifierKind::classify(new_name)? != IdentifierKind::Ident {
186 bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); 198 bail!("Invalid name `{0}`: cannot rename module to {0}", new_name);
187 } 199 }
188 200
@@ -227,14 +239,14 @@ fn rename_reference(
227 mut def: Definition, 239 mut def: Definition,
228 new_name: &str, 240 new_name: &str,
229) -> RenameResult<SourceChange> { 241) -> RenameResult<SourceChange> {
230 let ident_kind = check_identifier(new_name)?; 242 let ident_kind = IdentifierKind::classify(new_name)?;
231 243
232 if matches!( 244 if matches!(
233 def, // is target a lifetime? 245 def, // is target a lifetime?
234 Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_) 246 Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_)
235 ) { 247 ) {
236 match ident_kind { 248 match ident_kind {
237 IdentifierKind::Ident | IdentifierKind::ToSelf | IdentifierKind::Underscore => { 249 IdentifierKind::Ident | IdentifierKind::Underscore => {
238 cov_mark::hit!(rename_not_a_lifetime_ident_ref); 250 cov_mark::hit!(rename_not_a_lifetime_ident_ref);
239 bail!("Invalid name `{}`: not a lifetime identifier", new_name); 251 bail!("Invalid name `{}`: not a lifetime identifier", new_name);
240 } 252 }
@@ -246,25 +258,6 @@ fn rename_reference(
246 cov_mark::hit!(rename_not_an_ident_ref); 258 cov_mark::hit!(rename_not_an_ident_ref);
247 bail!("Invalid name `{}`: not an identifier", new_name); 259 bail!("Invalid name `{}`: not an identifier", new_name);
248 } 260 }
249 (IdentifierKind::ToSelf, Definition::Local(local)) => {
250 if local.is_self(sema.db) {
251 // no-op
252 cov_mark::hit!(rename_self_to_self);
253 return Ok(SourceChange::default());
254 } else {
255 cov_mark::hit!(rename_to_self);
256 return rename_to_self(sema, local);
257 }
258 }
259 (ident_kind, Definition::Local(local)) => {
260 if let Some(self_param) = local.as_self_param(sema.db) {
261 cov_mark::hit!(rename_self_to_param);
262 return rename_self_to_param(sema, local, self_param, new_name, ident_kind);
263 } else {
264 cov_mark::hit!(rename_local);
265 }
266 }
267 (IdentifierKind::ToSelf, _) => bail!("Invalid name `{}`: not an identifier", new_name),
268 (IdentifierKind::Ident, _) => cov_mark::hit!(rename_non_local), 261 (IdentifierKind::Ident, _) => cov_mark::hit!(rename_non_local),
269 (IdentifierKind::Underscore, _) => (), 262 (IdentifierKind::Underscore, _) => (),
270 } 263 }
@@ -383,8 +376,15 @@ fn rename_self_to_param(
383 local: hir::Local, 376 local: hir::Local,
384 self_param: hir::SelfParam, 377 self_param: hir::SelfParam,
385 new_name: &str, 378 new_name: &str,
386 identifier_kind: IdentifierKind,
387) -> RenameResult<SourceChange> { 379) -> RenameResult<SourceChange> {
380 if new_name == "self" {
381 // Let's do nothing rather than complain.
382 cov_mark::hit!(rename_self_to_self);
383 return Ok(SourceChange::default());
384 }
385
386 let identifier_kind = IdentifierKind::classify(new_name)?;
387
388 let InFile { file_id, value: self_param } = 388 let InFile { file_id, value: self_param } =
389 self_param.source(sema.db).ok_or_else(|| format_err!("cannot find function source"))?; 389 self_param.source(sema.db).ok_or_else(|| format_err!("cannot find function source"))?;
390 390
@@ -879,7 +879,6 @@ impl Foo {
879 879
880 #[test] 880 #[test]
881 fn test_rename_for_local() { 881 fn test_rename_for_local() {
882 cov_mark::check!(rename_local);
883 check( 882 check(
884 "k", 883 "k",
885 r#" 884 r#"