]> git.lizzy.rs Git - rust.git/blob - crates/ide/src/rename.rs
Fix syntax highlighting not highlighting derives anymore
[rust.git] / crates / ide / src / rename.rs
1 //! Renaming functionality.
2 //!
3 //! This is mostly front-end for [`ide_db::rename`], but it also includes the
4 //! tests. This module also implements a couple of magic tricks, like renaming
5 //! `self` and to `self` (to switch between associated function and method).
6
7 use hir::{AsAssocItem, InFile, Semantics};
8 use ide_db::{
9     base_db::FileId,
10     defs::{Definition, NameClass, NameRefClass},
11     rename::{bail, format_err, source_edit_from_references, IdentifierKind},
12     RootDatabase,
13 };
14 use itertools::Itertools;
15 use stdx::{always, never};
16 use syntax::{ast, AstNode, SyntaxNode};
17
18 use text_edit::TextEdit;
19
20 use crate::{FilePosition, RangeInfo, SourceChange};
21
22 pub use ide_db::rename::RenameError;
23
24 type RenameResult<T> = Result<T, RenameError>;
25
26 /// Prepares a rename. The sole job of this function is to return the TextRange of the thing that is
27 /// being targeted for a rename.
28 pub(crate) fn prepare_rename(
29     db: &RootDatabase,
30     position: FilePosition,
31 ) -> RenameResult<RangeInfo<()>> {
32     let sema = Semantics::new(db);
33     let source_file = sema.parse(position.file_id);
34     let syntax = source_file.syntax();
35
36     let res = find_definitions(&sema, syntax, position)?
37         .map(|(name_like, def)| {
38             // ensure all ranges are valid
39
40             if def.range_for_rename(&sema).is_none() {
41                 bail!("No references found at position")
42             }
43             let frange = sema.original_range(name_like.syntax());
44
45             always!(
46                 frange.range.contains_inclusive(position.offset)
47                     && frange.file_id == position.file_id
48             );
49             Ok(frange.range)
50         })
51         .reduce(|acc, cur| match (acc, cur) {
52             // ensure all ranges are the same
53             (Ok(acc_inner), Ok(cur_inner)) if acc_inner == cur_inner => Ok(acc_inner),
54             (Err(e), _) => Err(e),
55             _ => bail!("inconsistent text range"),
56         });
57
58     match res {
59         // ensure at least one definition was found
60         Some(res) => res.map(|range| RangeInfo::new(range, ())),
61         None => bail!("No references found at position"),
62     }
63 }
64
65 // Feature: Rename
66 //
67 // Renames the item below the cursor and all of its references
68 //
69 // |===
70 // | Editor  | Shortcut
71 //
72 // | VS Code | kbd:[F2]
73 // |===
74 //
75 // image::https://user-images.githubusercontent.com/48062697/113065582-055aae80-91b1-11eb-8ade-2b58e6d81883.gif[]
76 pub(crate) fn rename(
77     db: &RootDatabase,
78     position: FilePosition,
79     new_name: &str,
80 ) -> RenameResult<SourceChange> {
81     let sema = Semantics::new(db);
82     let source_file = sema.parse(position.file_id);
83     let syntax = source_file.syntax();
84
85     let defs = find_definitions(&sema, syntax, position)?;
86
87     let ops: RenameResult<Vec<SourceChange>> = defs
88         .map(|(_namelike, def)| {
89             if let Definition::Local(local) = def {
90                 if let Some(self_param) = local.as_self_param(sema.db) {
91                     cov_mark::hit!(rename_self_to_param);
92                     return rename_self_to_param(&sema, local, self_param, new_name);
93                 }
94                 if new_name == "self" {
95                     cov_mark::hit!(rename_to_self);
96                     return rename_to_self(&sema, local);
97                 }
98             }
99             def.rename(&sema, new_name)
100         })
101         .collect();
102
103     ops?.into_iter()
104         .reduce(|acc, elem| acc.merge(elem))
105         .ok_or_else(|| format_err!("No references found at position"))
106 }
107
108 /// Called by the client when it is about to rename a file.
109 pub(crate) fn will_rename_file(
110     db: &RootDatabase,
111     file_id: FileId,
112     new_name_stem: &str,
113 ) -> Option<SourceChange> {
114     let sema = Semantics::new(db);
115     let module = sema.to_module_def(file_id)?;
116     let def = Definition::Module(module);
117     let mut change = def.rename(&sema, new_name_stem).ok()?;
118     change.file_system_edits.clear();
119     Some(change)
120 }
121
122 fn find_definitions(
123     sema: &Semantics<RootDatabase>,
124     syntax: &SyntaxNode,
125     position: FilePosition,
126 ) -> RenameResult<impl Iterator<Item = (ast::NameLike, Definition)>> {
127     let symbols = sema
128         .find_nodes_at_offset_with_descend::<ast::NameLike>(syntax, position.offset)
129         .map(|name_like| {
130             let res = match &name_like {
131                 // renaming aliases would rename the item being aliased as the HIR doesn't track aliases yet
132                 ast::NameLike::Name(name)
133                     if name
134                         .syntax()
135                         .parent()
136                         .map_or(false, |it| ast::Rename::can_cast(it.kind())) =>
137                 {
138                     bail!("Renaming aliases is currently unsupported")
139                 }
140                 ast::NameLike::Name(name) => NameClass::classify(sema, name)
141                     .map(|class| match class {
142                         NameClass::Definition(it) | NameClass::ConstReference(it) => it,
143                         NameClass::PatFieldShorthand { local_def, field_ref: _ } => {
144                             Definition::Local(local_def)
145                         }
146                     })
147                     .map(|def| (name_like.clone(), def))
148                     .ok_or_else(|| format_err!("No references found at position")),
149                 ast::NameLike::NameRef(name_ref) => {
150                     NameRefClass::classify(sema, name_ref)
151                         .map(|class| match class {
152                             NameRefClass::Definition(def) => def,
153                             NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
154                                 Definition::Local(local_ref)
155                             }
156                         })
157                         .ok_or_else(|| format_err!("No references found at position"))
158                         .and_then(|def| {
159                             // if the name differs from the definitions name it has to be an alias
160                             if def
161                                 .name(sema.db)
162                                 .map_or(false, |it| it.to_smol_str() != name_ref.text().as_str())
163                             {
164                                 Err(format_err!("Renaming aliases is currently unsupported"))
165                             } else {
166                                 Ok((name_like.clone(), def))
167                             }
168                         })
169                 }
170                 ast::NameLike::Lifetime(lifetime) => {
171                     NameRefClass::classify_lifetime(sema, lifetime)
172                         .and_then(|class| match class {
173                             NameRefClass::Definition(def) => Some(def),
174                             _ => None,
175                         })
176                         .or_else(|| {
177                             NameClass::classify_lifetime(sema, lifetime).and_then(|it| match it {
178                                 NameClass::Definition(it) => Some(it),
179                                 _ => None,
180                             })
181                         })
182                         .map(|def| (name_like, def))
183                         .ok_or_else(|| format_err!("No references found at position"))
184                 }
185             };
186             res
187         });
188
189     let res: RenameResult<Vec<_>> = symbols.collect();
190     match res {
191         Ok(v) => {
192             if v.is_empty() {
193                 // FIXME: some semantic duplication between "empty vec" and "Err()"
194                 Err(format_err!("No references found at position"))
195             } else {
196                 // remove duplicates, comparing `Definition`s
197                 Ok(v.into_iter().unique_by(|t| t.1))
198             }
199         }
200         Err(e) => Err(e),
201     }
202 }
203
204 fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameResult<SourceChange> {
205     if never!(local.is_self(sema.db)) {
206         bail!("rename_to_self invoked on self");
207     }
208
209     let fn_def = match local.parent(sema.db) {
210         hir::DefWithBody::Function(func) => func,
211         _ => bail!("Cannot rename local to self outside of function"),
212     };
213
214     if fn_def.self_param(sema.db).is_some() {
215         bail!("Method already has a self parameter");
216     }
217
218     let params = fn_def.assoc_fn_params(sema.db);
219     let first_param = params
220         .first()
221         .ok_or_else(|| format_err!("Cannot rename local to self unless it is a parameter"))?;
222     if first_param.as_local(sema.db) != local {
223         bail!("Only the first parameter may be renamed to self");
224     }
225
226     let assoc_item = fn_def
227         .as_assoc_item(sema.db)
228         .ok_or_else(|| format_err!("Cannot rename parameter to self for free function"))?;
229     let impl_ = match assoc_item.container(sema.db) {
230         hir::AssocItemContainer::Trait(_) => {
231             bail!("Cannot rename parameter to self for trait functions");
232         }
233         hir::AssocItemContainer::Impl(impl_) => impl_,
234     };
235     let first_param_ty = first_param.ty();
236     let impl_ty = impl_.self_ty(sema.db);
237     let (ty, self_param) = if impl_ty.remove_ref().is_some() {
238         // if the impl is a ref to the type we can just match the `&T` with self directly
239         (first_param_ty.clone(), "self")
240     } else {
241         first_param_ty.remove_ref().map_or((first_param_ty.clone(), "self"), |ty| {
242             (ty, if first_param_ty.is_mutable_reference() { "&mut self" } else { "&self" })
243         })
244     };
245
246     if ty != impl_ty {
247         bail!("Parameter type differs from impl block type");
248     }
249
250     let InFile { file_id, value: param_source } =
251         first_param.source(sema.db).ok_or_else(|| format_err!("No source for parameter found"))?;
252
253     let def = Definition::Local(local);
254     let usages = def.usages(sema).all();
255     let mut source_change = SourceChange::default();
256     source_change.extend(usages.iter().map(|(&file_id, references)| {
257         (file_id, source_edit_from_references(references, def, "self"))
258     }));
259     source_change.insert_source_edit(
260         file_id.original_file(sema.db),
261         TextEdit::replace(param_source.syntax().text_range(), String::from(self_param)),
262     );
263     Ok(source_change)
264 }
265
266 fn rename_self_to_param(
267     sema: &Semantics<RootDatabase>,
268     local: hir::Local,
269     self_param: hir::SelfParam,
270     new_name: &str,
271 ) -> RenameResult<SourceChange> {
272     if new_name == "self" {
273         // Let's do nothing rather than complain.
274         cov_mark::hit!(rename_self_to_self);
275         return Ok(SourceChange::default());
276     }
277
278     let identifier_kind = IdentifierKind::classify(new_name)?;
279
280     let InFile { file_id, value: self_param } =
281         self_param.source(sema.db).ok_or_else(|| format_err!("cannot find function source"))?;
282
283     let def = Definition::Local(local);
284     let usages = def.usages(sema).all();
285     let edit = text_edit_from_self_param(&self_param, new_name)
286         .ok_or_else(|| format_err!("No target type found"))?;
287     if usages.len() > 1 && identifier_kind == IdentifierKind::Underscore {
288         bail!("Cannot rename reference to `_` as it is being referenced multiple times");
289     }
290     let mut source_change = SourceChange::default();
291     source_change.insert_source_edit(file_id.original_file(sema.db), edit);
292     source_change.extend(usages.iter().map(|(&file_id, references)| {
293         (file_id, source_edit_from_references(references, def, new_name))
294     }));
295     Ok(source_change)
296 }
297
298 fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Option<TextEdit> {
299     fn target_type_name(impl_def: &ast::Impl) -> Option<String> {
300         if let Some(ast::Type::PathType(p)) = impl_def.self_ty() {
301             return Some(p.path()?.segment()?.name_ref()?.text().to_string());
302         }
303         None
304     }
305
306     let impl_def = self_param.syntax().ancestors().find_map(ast::Impl::cast)?;
307     let type_name = target_type_name(&impl_def)?;
308
309     let mut replacement_text = String::from(new_name);
310     replacement_text.push_str(": ");
311     match (self_param.amp_token(), self_param.mut_token()) {
312         (Some(_), None) => replacement_text.push('&'),
313         (Some(_), Some(_)) => replacement_text.push_str("&mut "),
314         (_, _) => (),
315     };
316     replacement_text.push_str(type_name.as_str());
317
318     Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text))
319 }
320
321 #[cfg(test)]
322 mod tests {
323     use expect_test::{expect, Expect};
324     use stdx::trim_indent;
325     use test_utils::assert_eq_text;
326     use text_edit::TextEdit;
327
328     use crate::{fixture, FileId};
329
330     use super::{RangeInfo, RenameError};
331
332     #[track_caller]
333     fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
334         let ra_fixture_after = &trim_indent(ra_fixture_after);
335         let (analysis, position) = fixture::position(ra_fixture_before);
336         let rename_result = analysis
337             .rename(position, new_name)
338             .unwrap_or_else(|err| panic!("Rename to '{}' was cancelled: {}", new_name, err));
339         match rename_result {
340             Ok(source_change) => {
341                 let mut text_edit_builder = TextEdit::builder();
342                 let mut file_id: Option<FileId> = None;
343                 for edit in source_change.source_file_edits {
344                     file_id = Some(edit.0);
345                     for indel in edit.1.into_iter() {
346                         text_edit_builder.replace(indel.delete, indel.insert);
347                     }
348                 }
349                 if let Some(file_id) = file_id {
350                     let mut result = analysis.file_text(file_id).unwrap().to_string();
351                     text_edit_builder.finish().apply(&mut result);
352                     assert_eq_text!(ra_fixture_after, &*result);
353                 }
354             }
355             Err(err) => {
356                 if ra_fixture_after.starts_with("error:") {
357                     let error_message = ra_fixture_after
358                         .chars()
359                         .into_iter()
360                         .skip("error:".len())
361                         .collect::<String>();
362                     assert_eq!(error_message.trim(), err.to_string());
363                 } else {
364                     panic!("Rename to '{}' failed unexpectedly: {}", new_name, err)
365                 }
366             }
367         };
368     }
369
370     fn check_expect(new_name: &str, ra_fixture: &str, expect: Expect) {
371         let (analysis, position) = fixture::position(ra_fixture);
372         let source_change =
373             analysis.rename(position, new_name).unwrap().expect("Expect returned a RenameError");
374         expect.assert_debug_eq(&source_change)
375     }
376
377     fn check_prepare(ra_fixture: &str, expect: Expect) {
378         let (analysis, position) = fixture::position(ra_fixture);
379         let result = analysis
380             .prepare_rename(position)
381             .unwrap_or_else(|err| panic!("PrepareRename was cancelled: {}", err));
382         match result {
383             Ok(RangeInfo { range, info: () }) => {
384                 let source = analysis.file_text(position.file_id).unwrap();
385                 expect.assert_eq(&format!("{:?}: {}", range, &source[range]))
386             }
387             Err(RenameError(err)) => expect.assert_eq(&err),
388         };
389     }
390
391     #[test]
392     fn test_prepare_rename_namelikes() {
393         check_prepare(r"fn name$0<'lifetime>() {}", expect![[r#"3..7: name"#]]);
394         check_prepare(r"fn name<'lifetime$0>() {}", expect![[r#"8..17: 'lifetime"#]]);
395         check_prepare(r"fn name<'lifetime>() { name$0(); }", expect![[r#"23..27: name"#]]);
396     }
397
398     #[test]
399     fn test_prepare_rename_in_macro() {
400         check_prepare(
401             r"macro_rules! foo {
402     ($ident:ident) => {
403         pub struct $ident;
404     }
405 }
406 foo!(Foo$0);",
407             expect![[r#"83..86: Foo"#]],
408         );
409     }
410
411     #[test]
412     fn test_prepare_rename_keyword() {
413         check_prepare(r"struct$0 Foo;", expect![[r#"No references found at position"#]]);
414     }
415
416     #[test]
417     fn test_prepare_rename_tuple_field() {
418         check_prepare(
419             r#"
420 struct Foo(i32);
421
422 fn baz() {
423     let mut x = Foo(4);
424     x.0$0 = 5;
425 }
426 "#,
427             expect![[r#"No references found at position"#]],
428         );
429     }
430
431     #[test]
432     fn test_prepare_rename_builtin() {
433         check_prepare(
434             r#"
435 fn foo() {
436     let x: i32$0 = 0;
437 }
438 "#,
439             expect![[r#"No references found at position"#]],
440         );
441     }
442
443     #[test]
444     fn test_prepare_rename_self() {
445         check_prepare(
446             r#"
447 struct Foo {}
448
449 impl Foo {
450     fn foo(self) -> Self$0 {
451         self
452     }
453 }
454 "#,
455             expect![[r#"No references found at position"#]],
456         );
457     }
458
459     #[test]
460     fn test_rename_to_underscore() {
461         check("_", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let _ = 1; }"#);
462     }
463
464     #[test]
465     fn test_rename_to_raw_identifier() {
466         check("r#fn", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let r#fn = 1; }"#);
467     }
468
469     #[test]
470     fn test_rename_to_invalid_identifier1() {
471         check(
472             "invalid!",
473             r#"fn main() { let i$0 = 1; }"#,
474             "error: Invalid name `invalid!`: not an identifier",
475         );
476     }
477
478     #[test]
479     fn test_rename_to_invalid_identifier2() {
480         check(
481             "multiple tokens",
482             r#"fn main() { let i$0 = 1; }"#,
483             "error: Invalid name `multiple tokens`: not an identifier",
484         );
485     }
486
487     #[test]
488     fn test_rename_to_invalid_identifier3() {
489         check(
490             "let",
491             r#"fn main() { let i$0 = 1; }"#,
492             "error: Invalid name `let`: not an identifier",
493         );
494     }
495
496     #[test]
497     fn test_rename_to_invalid_identifier_lifetime() {
498         cov_mark::check!(rename_not_an_ident_ref);
499         check(
500             "'foo",
501             r#"fn main() { let i$0 = 1; }"#,
502             "error: Invalid name `'foo`: not an identifier",
503         );
504     }
505
506     #[test]
507     fn test_rename_to_invalid_identifier_lifetime2() {
508         cov_mark::check!(rename_not_a_lifetime_ident_ref);
509         check(
510             "foo",
511             r#"fn main<'a>(_: &'a$0 ()) {}"#,
512             "error: Invalid name `foo`: not a lifetime identifier",
513         );
514     }
515
516     #[test]
517     fn test_rename_to_underscore_invalid() {
518         cov_mark::check!(rename_underscore_multiple);
519         check(
520             "_",
521             r#"fn main(foo$0: ()) {foo;}"#,
522             "error: Cannot rename reference to `_` as it is being referenced multiple times",
523         );
524     }
525
526     #[test]
527     fn test_rename_mod_invalid() {
528         check(
529             "'foo",
530             r#"mod foo$0 {}"#,
531             "error: Invalid name `'foo`: cannot rename module to 'foo",
532         );
533     }
534
535     #[test]
536     fn test_rename_for_local() {
537         check(
538             "k",
539             r#"
540 fn main() {
541     let mut i = 1;
542     let j = 1;
543     i = i$0 + j;
544
545     { i = 0; }
546
547     i = 5;
548 }
549 "#,
550             r#"
551 fn main() {
552     let mut k = 1;
553     let j = 1;
554     k = k + j;
555
556     { k = 0; }
557
558     k = 5;
559 }
560 "#,
561         );
562     }
563
564     #[test]
565     fn test_rename_unresolved_reference() {
566         check(
567             "new_name",
568             r#"fn main() { let _ = unresolved_ref$0; }"#,
569             "error: No references found at position",
570         );
571     }
572
573     #[test]
574     fn test_rename_macro_multiple_occurrences() {
575         check(
576             "Baaah",
577             r#"macro_rules! foo {
578     ($ident:ident) => {
579         const $ident: () = ();
580         struct $ident {}
581     };
582 }
583
584 foo!($0Foo);
585 const _: () = Foo;
586 const _: Foo = Foo {};
587     "#,
588             r#"
589 macro_rules! foo {
590     ($ident:ident) => {
591         const $ident: () = ();
592         struct $ident {}
593     };
594 }
595
596 foo!(Baaah);
597 const _: () = Baaah;
598 const _: Baaah = Baaah {};
599     "#,
600         )
601     }
602
603     #[test]
604     fn test_rename_for_macro_args() {
605         check(
606             "b",
607             r#"
608 macro_rules! foo {($i:ident) => {$i} }
609 fn main() {
610     let a$0 = "test";
611     foo!(a);
612 }
613 "#,
614             r#"
615 macro_rules! foo {($i:ident) => {$i} }
616 fn main() {
617     let b = "test";
618     foo!(b);
619 }
620 "#,
621         );
622     }
623
624     #[test]
625     fn test_rename_for_macro_args_rev() {
626         check(
627             "b",
628             r#"
629 macro_rules! foo {($i:ident) => {$i} }
630 fn main() {
631     let a = "test";
632     foo!(a$0);
633 }
634 "#,
635             r#"
636 macro_rules! foo {($i:ident) => {$i} }
637 fn main() {
638     let b = "test";
639     foo!(b);
640 }
641 "#,
642         );
643     }
644
645     #[test]
646     fn test_rename_for_macro_define_fn() {
647         check(
648             "bar",
649             r#"
650 macro_rules! define_fn {($id:ident) => { fn $id{} }}
651 define_fn!(foo);
652 fn main() {
653     fo$0o();
654 }
655 "#,
656             r#"
657 macro_rules! define_fn {($id:ident) => { fn $id{} }}
658 define_fn!(bar);
659 fn main() {
660     bar();
661 }
662 "#,
663         );
664     }
665
666     #[test]
667     fn test_rename_for_macro_define_fn_rev() {
668         check(
669             "bar",
670             r#"
671 macro_rules! define_fn {($id:ident) => { fn $id{} }}
672 define_fn!(fo$0o);
673 fn main() {
674     foo();
675 }
676 "#,
677             r#"
678 macro_rules! define_fn {($id:ident) => { fn $id{} }}
679 define_fn!(bar);
680 fn main() {
681     bar();
682 }
683 "#,
684         );
685     }
686
687     #[test]
688     fn test_rename_for_param_inside() {
689         check("j", r#"fn foo(i : u32) -> u32 { i$0 }"#, r#"fn foo(j : u32) -> u32 { j }"#);
690     }
691
692     #[test]
693     fn test_rename_refs_for_fn_param() {
694         check("j", r#"fn foo(i$0 : u32) -> u32 { i }"#, r#"fn foo(j : u32) -> u32 { j }"#);
695     }
696
697     #[test]
698     fn test_rename_for_mut_param() {
699         check("j", r#"fn foo(mut i$0 : u32) -> u32 { i }"#, r#"fn foo(mut j : u32) -> u32 { j }"#);
700     }
701
702     #[test]
703     fn test_rename_struct_field() {
704         check(
705             "foo",
706             r#"
707 struct Foo { field$0: i32 }
708
709 impl Foo {
710     fn new(i: i32) -> Self {
711         Self { field: i }
712     }
713 }
714 "#,
715             r#"
716 struct Foo { foo: i32 }
717
718 impl Foo {
719     fn new(i: i32) -> Self {
720         Self { foo: i }
721     }
722 }
723 "#,
724         );
725     }
726
727     #[test]
728     fn test_rename_field_in_field_shorthand() {
729         cov_mark::check!(test_rename_field_in_field_shorthand);
730         check(
731             "field",
732             r#"
733 struct Foo { foo$0: i32 }
734
735 impl Foo {
736     fn new(foo: i32) -> Self {
737         Self { foo }
738     }
739 }
740 "#,
741             r#"
742 struct Foo { field: i32 }
743
744 impl Foo {
745     fn new(foo: i32) -> Self {
746         Self { field: foo }
747     }
748 }
749 "#,
750         );
751     }
752
753     #[test]
754     fn test_rename_local_in_field_shorthand() {
755         cov_mark::check!(test_rename_local_in_field_shorthand);
756         check(
757             "j",
758             r#"
759 struct Foo { i: i32 }
760
761 impl Foo {
762     fn new(i$0: i32) -> Self {
763         Self { i }
764     }
765 }
766 "#,
767             r#"
768 struct Foo { i: i32 }
769
770 impl Foo {
771     fn new(j: i32) -> Self {
772         Self { i: j }
773     }
774 }
775 "#,
776         );
777     }
778
779     #[test]
780     fn test_field_shorthand_correct_struct() {
781         check(
782             "j",
783             r#"
784 struct Foo { i$0: i32 }
785 struct Bar { i: i32 }
786
787 impl Bar {
788     fn new(i: i32) -> Self {
789         Self { i }
790     }
791 }
792 "#,
793             r#"
794 struct Foo { j: i32 }
795 struct Bar { i: i32 }
796
797 impl Bar {
798     fn new(i: i32) -> Self {
799         Self { i }
800     }
801 }
802 "#,
803         );
804     }
805
806     #[test]
807     fn test_shadow_local_for_struct_shorthand() {
808         check(
809             "j",
810             r#"
811 struct Foo { i: i32 }
812
813 fn baz(i$0: i32) -> Self {
814      let x = Foo { i };
815      {
816          let i = 0;
817          Foo { i }
818      }
819 }
820 "#,
821             r#"
822 struct Foo { i: i32 }
823
824 fn baz(j: i32) -> Self {
825      let x = Foo { i: j };
826      {
827          let i = 0;
828          Foo { i }
829      }
830 }
831 "#,
832         );
833     }
834
835     #[test]
836     fn test_rename_mod() {
837         check_expect(
838             "foo2",
839             r#"
840 //- /lib.rs
841 mod bar;
842
843 //- /bar.rs
844 mod foo$0;
845
846 //- /bar/foo.rs
847 // empty
848 "#,
849             expect![[r#"
850                 SourceChange {
851                     source_file_edits: {
852                         FileId(
853                             1,
854                         ): TextEdit {
855                             indels: [
856                                 Indel {
857                                     insert: "foo2",
858                                     delete: 4..7,
859                                 },
860                             ],
861                         },
862                     },
863                     file_system_edits: [
864                         MoveFile {
865                             src: FileId(
866                                 2,
867                             ),
868                             dst: AnchoredPathBuf {
869                                 anchor: FileId(
870                                     2,
871                                 ),
872                                 path: "foo2.rs",
873                             },
874                         },
875                     ],
876                     is_snippet: false,
877                 }
878             "#]],
879         );
880     }
881
882     #[test]
883     fn test_rename_mod_in_use_tree() {
884         check_expect(
885             "quux",
886             r#"
887 //- /main.rs
888 pub mod foo;
889 pub mod bar;
890 fn main() {}
891
892 //- /foo.rs
893 pub struct FooContent;
894
895 //- /bar.rs
896 use crate::foo$0::FooContent;
897 "#,
898             expect![[r#"
899                 SourceChange {
900                     source_file_edits: {
901                         FileId(
902                             0,
903                         ): TextEdit {
904                             indels: [
905                                 Indel {
906                                     insert: "quux",
907                                     delete: 8..11,
908                                 },
909                             ],
910                         },
911                         FileId(
912                             2,
913                         ): TextEdit {
914                             indels: [
915                                 Indel {
916                                     insert: "quux",
917                                     delete: 11..14,
918                                 },
919                             ],
920                         },
921                     },
922                     file_system_edits: [
923                         MoveFile {
924                             src: FileId(
925                                 1,
926                             ),
927                             dst: AnchoredPathBuf {
928                                 anchor: FileId(
929                                     1,
930                                 ),
931                                 path: "quux.rs",
932                             },
933                         },
934                     ],
935                     is_snippet: false,
936                 }
937             "#]],
938         );
939     }
940
941     #[test]
942     fn test_rename_mod_in_dir() {
943         check_expect(
944             "foo2",
945             r#"
946 //- /lib.rs
947 mod fo$0o;
948 //- /foo/mod.rs
949 // empty
950 "#,
951             expect![[r#"
952                 SourceChange {
953                     source_file_edits: {
954                         FileId(
955                             0,
956                         ): TextEdit {
957                             indels: [
958                                 Indel {
959                                     insert: "foo2",
960                                     delete: 4..7,
961                                 },
962                             ],
963                         },
964                     },
965                     file_system_edits: [
966                         MoveFile {
967                             src: FileId(
968                                 1,
969                             ),
970                             dst: AnchoredPathBuf {
971                                 anchor: FileId(
972                                     1,
973                                 ),
974                                 path: "../foo2/mod.rs",
975                             },
976                         },
977                     ],
978                     is_snippet: false,
979                 }
980             "#]],
981         );
982     }
983
984     #[test]
985     fn test_rename_unusually_nested_mod() {
986         check_expect(
987             "bar",
988             r#"
989 //- /lib.rs
990 mod outer { mod fo$0o; }
991
992 //- /outer/foo.rs
993 // empty
994 "#,
995             expect![[r#"
996                 SourceChange {
997                     source_file_edits: {
998                         FileId(
999                             0,
1000                         ): TextEdit {
1001                             indels: [
1002                                 Indel {
1003                                     insert: "bar",
1004                                     delete: 16..19,
1005                                 },
1006                             ],
1007                         },
1008                     },
1009                     file_system_edits: [
1010                         MoveFile {
1011                             src: FileId(
1012                                 1,
1013                             ),
1014                             dst: AnchoredPathBuf {
1015                                 anchor: FileId(
1016                                     1,
1017                                 ),
1018                                 path: "bar.rs",
1019                             },
1020                         },
1021                     ],
1022                     is_snippet: false,
1023                 }
1024             "#]],
1025         );
1026     }
1027
1028     #[test]
1029     fn test_module_rename_in_path() {
1030         check(
1031             "baz",
1032             r#"
1033 mod $0foo {
1034     pub use self::bar as qux;
1035     pub fn bar() {}
1036 }
1037
1038 fn main() { foo::bar(); }
1039 "#,
1040             r#"
1041 mod baz {
1042     pub use self::bar as qux;
1043     pub fn bar() {}
1044 }
1045
1046 fn main() { baz::bar(); }
1047 "#,
1048         );
1049     }
1050
1051     #[test]
1052     fn test_rename_mod_filename_and_path() {
1053         check_expect(
1054             "foo2",
1055             r#"
1056 //- /lib.rs
1057 mod bar;
1058 fn f() {
1059     bar::foo::fun()
1060 }
1061
1062 //- /bar.rs
1063 pub mod foo$0;
1064
1065 //- /bar/foo.rs
1066 // pub fn fun() {}
1067 "#,
1068             expect![[r#"
1069                 SourceChange {
1070                     source_file_edits: {
1071                         FileId(
1072                             0,
1073                         ): TextEdit {
1074                             indels: [
1075                                 Indel {
1076                                     insert: "foo2",
1077                                     delete: 27..30,
1078                                 },
1079                             ],
1080                         },
1081                         FileId(
1082                             1,
1083                         ): TextEdit {
1084                             indels: [
1085                                 Indel {
1086                                     insert: "foo2",
1087                                     delete: 8..11,
1088                                 },
1089                             ],
1090                         },
1091                     },
1092                     file_system_edits: [
1093                         MoveFile {
1094                             src: FileId(
1095                                 2,
1096                             ),
1097                             dst: AnchoredPathBuf {
1098                                 anchor: FileId(
1099                                     2,
1100                                 ),
1101                                 path: "foo2.rs",
1102                             },
1103                         },
1104                     ],
1105                     is_snippet: false,
1106                 }
1107             "#]],
1108         );
1109     }
1110
1111     #[test]
1112     fn test_rename_mod_ref_by_super() {
1113         check(
1114             "baz",
1115             r#"
1116         mod $0foo {
1117         struct X;
1118
1119         mod bar {
1120             use super::X;
1121         }
1122     }
1123             "#,
1124             r#"
1125         mod baz {
1126         struct X;
1127
1128         mod bar {
1129             use super::X;
1130         }
1131     }
1132             "#,
1133         )
1134     }
1135
1136     #[test]
1137     fn test_rename_mod_in_macro() {
1138         check(
1139             "bar",
1140             r#"
1141 //- /foo.rs
1142
1143 //- /lib.rs
1144 macro_rules! submodule {
1145     ($name:ident) => {
1146         mod $name;
1147     };
1148 }
1149
1150 submodule!($0foo);
1151 "#,
1152             r#"
1153 macro_rules! submodule {
1154     ($name:ident) => {
1155         mod $name;
1156     };
1157 }
1158
1159 submodule!(bar);
1160 "#,
1161         )
1162     }
1163
1164     #[test]
1165     fn test_enum_variant_from_module_1() {
1166         cov_mark::check!(rename_non_local);
1167         check(
1168             "Baz",
1169             r#"
1170 mod foo {
1171     pub enum Foo { Bar$0 }
1172 }
1173
1174 fn func(f: foo::Foo) {
1175     match f {
1176         foo::Foo::Bar => {}
1177     }
1178 }
1179 "#,
1180             r#"
1181 mod foo {
1182     pub enum Foo { Baz }
1183 }
1184
1185 fn func(f: foo::Foo) {
1186     match f {
1187         foo::Foo::Baz => {}
1188     }
1189 }
1190 "#,
1191         );
1192     }
1193
1194     #[test]
1195     fn test_enum_variant_from_module_2() {
1196         check(
1197             "baz",
1198             r#"
1199 mod foo {
1200     pub struct Foo { pub bar$0: uint }
1201 }
1202
1203 fn foo(f: foo::Foo) {
1204     let _ = f.bar;
1205 }
1206 "#,
1207             r#"
1208 mod foo {
1209     pub struct Foo { pub baz: uint }
1210 }
1211
1212 fn foo(f: foo::Foo) {
1213     let _ = f.baz;
1214 }
1215 "#,
1216         );
1217     }
1218
1219     #[test]
1220     fn test_parameter_to_self() {
1221         cov_mark::check!(rename_to_self);
1222         check(
1223             "self",
1224             r#"
1225 struct Foo { i: i32 }
1226
1227 impl Foo {
1228     fn f(foo$0: &mut Foo) -> i32 {
1229         foo.i
1230     }
1231 }
1232 "#,
1233             r#"
1234 struct Foo { i: i32 }
1235
1236 impl Foo {
1237     fn f(&mut self) -> i32 {
1238         self.i
1239     }
1240 }
1241 "#,
1242         );
1243         check(
1244             "self",
1245             r#"
1246 struct Foo { i: i32 }
1247
1248 impl Foo {
1249     fn f(foo$0: Foo) -> i32 {
1250         foo.i
1251     }
1252 }
1253 "#,
1254             r#"
1255 struct Foo { i: i32 }
1256
1257 impl Foo {
1258     fn f(self) -> i32 {
1259         self.i
1260     }
1261 }
1262 "#,
1263         );
1264     }
1265
1266     #[test]
1267     fn test_parameter_to_self_error_no_impl() {
1268         check(
1269             "self",
1270             r#"
1271 struct Foo { i: i32 }
1272
1273 fn f(foo$0: &mut Foo) -> i32 {
1274     foo.i
1275 }
1276 "#,
1277             "error: Cannot rename parameter to self for free function",
1278         );
1279         check(
1280             "self",
1281             r#"
1282 struct Foo { i: i32 }
1283 struct Bar;
1284
1285 impl Bar {
1286     fn f(foo$0: &mut Foo) -> i32 {
1287         foo.i
1288     }
1289 }
1290 "#,
1291             "error: Parameter type differs from impl block type",
1292         );
1293     }
1294
1295     #[test]
1296     fn test_parameter_to_self_error_not_first() {
1297         check(
1298             "self",
1299             r#"
1300 struct Foo { i: i32 }
1301 impl Foo {
1302     fn f(x: (), foo$0: &mut Foo) -> i32 {
1303         foo.i
1304     }
1305 }
1306 "#,
1307             "error: Only the first parameter may be renamed to self",
1308         );
1309     }
1310
1311     #[test]
1312     fn test_parameter_to_self_impl_ref() {
1313         check(
1314             "self",
1315             r#"
1316 struct Foo { i: i32 }
1317 impl &Foo {
1318     fn f(foo$0: &Foo) -> i32 {
1319         foo.i
1320     }
1321 }
1322 "#,
1323             r#"
1324 struct Foo { i: i32 }
1325 impl &Foo {
1326     fn f(self) -> i32 {
1327         self.i
1328     }
1329 }
1330 "#,
1331         );
1332     }
1333
1334     #[test]
1335     fn test_self_to_parameter() {
1336         check(
1337             "foo",
1338             r#"
1339 struct Foo { i: i32 }
1340
1341 impl Foo {
1342     fn f(&mut $0self) -> i32 {
1343         self.i
1344     }
1345 }
1346 "#,
1347             r#"
1348 struct Foo { i: i32 }
1349
1350 impl Foo {
1351     fn f(foo: &mut Foo) -> i32 {
1352         foo.i
1353     }
1354 }
1355 "#,
1356         );
1357     }
1358
1359     #[test]
1360     fn test_owned_self_to_parameter() {
1361         cov_mark::check!(rename_self_to_param);
1362         check(
1363             "foo",
1364             r#"
1365 struct Foo { i: i32 }
1366
1367 impl Foo {
1368     fn f($0self) -> i32 {
1369         self.i
1370     }
1371 }
1372 "#,
1373             r#"
1374 struct Foo { i: i32 }
1375
1376 impl Foo {
1377     fn f(foo: Foo) -> i32 {
1378         foo.i
1379     }
1380 }
1381 "#,
1382         );
1383     }
1384
1385     #[test]
1386     fn test_self_in_path_to_parameter() {
1387         check(
1388             "foo",
1389             r#"
1390 struct Foo { i: i32 }
1391
1392 impl Foo {
1393     fn f(&self) -> i32 {
1394         let self_var = 1;
1395         self$0.i
1396     }
1397 }
1398 "#,
1399             r#"
1400 struct Foo { i: i32 }
1401
1402 impl Foo {
1403     fn f(foo: &Foo) -> i32 {
1404         let self_var = 1;
1405         foo.i
1406     }
1407 }
1408 "#,
1409         );
1410     }
1411
1412     #[test]
1413     fn test_rename_field_put_init_shorthand() {
1414         cov_mark::check!(test_rename_field_put_init_shorthand);
1415         check(
1416             "bar",
1417             r#"
1418 struct Foo { i$0: i32 }
1419
1420 fn foo(bar: i32) -> Foo {
1421     Foo { i: bar }
1422 }
1423 "#,
1424             r#"
1425 struct Foo { bar: i32 }
1426
1427 fn foo(bar: i32) -> Foo {
1428     Foo { bar }
1429 }
1430 "#,
1431         );
1432     }
1433
1434     #[test]
1435     fn test_rename_local_put_init_shorthand() {
1436         cov_mark::check!(test_rename_local_put_init_shorthand);
1437         check(
1438             "i",
1439             r#"
1440 struct Foo { i: i32 }
1441
1442 fn foo(bar$0: i32) -> Foo {
1443     Foo { i: bar }
1444 }
1445 "#,
1446             r#"
1447 struct Foo { i: i32 }
1448
1449 fn foo(i: i32) -> Foo {
1450     Foo { i }
1451 }
1452 "#,
1453         );
1454     }
1455
1456     #[test]
1457     fn test_struct_field_pat_into_shorthand() {
1458         cov_mark::check!(test_rename_field_put_init_shorthand_pat);
1459         check(
1460             "baz",
1461             r#"
1462 struct Foo { i$0: i32 }
1463
1464 fn foo(foo: Foo) {
1465     let Foo { i: ref baz @ qux } = foo;
1466     let _ = qux;
1467 }
1468 "#,
1469             r#"
1470 struct Foo { baz: i32 }
1471
1472 fn foo(foo: Foo) {
1473     let Foo { baz: ref baz @ qux } = foo;
1474     let _ = qux;
1475 }
1476 "#,
1477         );
1478         check(
1479             "baz",
1480             r#"
1481 struct Foo { i$0: i32 }
1482
1483 fn foo(foo: Foo) {
1484     let Foo { i: ref baz } = foo;
1485     let _ = qux;
1486 }
1487 "#,
1488             r#"
1489 struct Foo { baz: i32 }
1490
1491 fn foo(foo: Foo) {
1492     let Foo { ref baz } = foo;
1493     let _ = qux;
1494 }
1495 "#,
1496         );
1497     }
1498
1499     #[test]
1500     fn test_struct_local_pat_into_shorthand() {
1501         cov_mark::check!(test_rename_local_put_init_shorthand_pat);
1502         check(
1503             "field",
1504             r#"
1505 struct Foo { field: i32 }
1506
1507 fn foo(foo: Foo) {
1508     let Foo { field: qux$0 } = foo;
1509     let _ = qux;
1510 }
1511 "#,
1512             r#"
1513 struct Foo { field: i32 }
1514
1515 fn foo(foo: Foo) {
1516     let Foo { field } = foo;
1517     let _ = field;
1518 }
1519 "#,
1520         );
1521         check(
1522             "field",
1523             r#"
1524 struct Foo { field: i32 }
1525
1526 fn foo(foo: Foo) {
1527     let Foo { field: x @ qux$0 } = foo;
1528     let _ = qux;
1529 }
1530 "#,
1531             r#"
1532 struct Foo { field: i32 }
1533
1534 fn foo(foo: Foo) {
1535     let Foo { field: x @ field } = foo;
1536     let _ = field;
1537 }
1538 "#,
1539         );
1540     }
1541
1542     #[test]
1543     fn test_rename_binding_in_destructure_pat() {
1544         let expected_fixture = r#"
1545 struct Foo {
1546     i: i32,
1547 }
1548
1549 fn foo(foo: Foo) {
1550     let Foo { i: bar } = foo;
1551     let _ = bar;
1552 }
1553 "#;
1554         check(
1555             "bar",
1556             r#"
1557 struct Foo {
1558     i: i32,
1559 }
1560
1561 fn foo(foo: Foo) {
1562     let Foo { i: b } = foo;
1563     let _ = b$0;
1564 }
1565 "#,
1566             expected_fixture,
1567         );
1568         check(
1569             "bar",
1570             r#"
1571 struct Foo {
1572     i: i32,
1573 }
1574
1575 fn foo(foo: Foo) {
1576     let Foo { i } = foo;
1577     let _ = i$0;
1578 }
1579 "#,
1580             expected_fixture,
1581         );
1582     }
1583
1584     #[test]
1585     fn test_rename_binding_in_destructure_param_pat() {
1586         check(
1587             "bar",
1588             r#"
1589 struct Foo {
1590     i: i32
1591 }
1592
1593 fn foo(Foo { i }: Foo) -> i32 {
1594     i$0
1595 }
1596 "#,
1597             r#"
1598 struct Foo {
1599     i: i32
1600 }
1601
1602 fn foo(Foo { i: bar }: Foo) -> i32 {
1603     bar
1604 }
1605 "#,
1606         )
1607     }
1608
1609     #[test]
1610     fn test_struct_field_complex_ident_pat() {
1611         cov_mark::check!(rename_record_pat_field_name_split);
1612         check(
1613             "baz",
1614             r#"
1615 struct Foo { i$0: i32 }
1616
1617 fn foo(foo: Foo) {
1618     let Foo { ref i } = foo;
1619 }
1620 "#,
1621             r#"
1622 struct Foo { baz: i32 }
1623
1624 fn foo(foo: Foo) {
1625     let Foo { baz: ref i } = foo;
1626 }
1627 "#,
1628         );
1629     }
1630
1631     #[test]
1632     fn test_rename_lifetimes() {
1633         cov_mark::check!(rename_lifetime);
1634         check(
1635             "'yeeee",
1636             r#"
1637 trait Foo<'a> {
1638     fn foo() -> &'a ();
1639 }
1640 impl<'a> Foo<'a> for &'a () {
1641     fn foo() -> &'a$0 () {
1642         unimplemented!()
1643     }
1644 }
1645 "#,
1646             r#"
1647 trait Foo<'a> {
1648     fn foo() -> &'a ();
1649 }
1650 impl<'yeeee> Foo<'yeeee> for &'yeeee () {
1651     fn foo() -> &'yeeee () {
1652         unimplemented!()
1653     }
1654 }
1655 "#,
1656         )
1657     }
1658
1659     #[test]
1660     fn test_rename_bind_pat() {
1661         check(
1662             "new_name",
1663             r#"
1664 fn main() {
1665     enum CustomOption<T> {
1666         None,
1667         Some(T),
1668     }
1669
1670     let test_variable = CustomOption::Some(22);
1671
1672     match test_variable {
1673         CustomOption::Some(foo$0) if foo == 11 => {}
1674         _ => (),
1675     }
1676 }"#,
1677             r#"
1678 fn main() {
1679     enum CustomOption<T> {
1680         None,
1681         Some(T),
1682     }
1683
1684     let test_variable = CustomOption::Some(22);
1685
1686     match test_variable {
1687         CustomOption::Some(new_name) if new_name == 11 => {}
1688         _ => (),
1689     }
1690 }"#,
1691         );
1692     }
1693
1694     #[test]
1695     fn test_rename_label() {
1696         check(
1697             "'foo",
1698             r#"
1699 fn foo<'a>() -> &'a () {
1700     'a: {
1701         'b: loop {
1702             break 'a$0;
1703         }
1704     }
1705 }
1706 "#,
1707             r#"
1708 fn foo<'a>() -> &'a () {
1709     'foo: {
1710         'b: loop {
1711             break 'foo;
1712         }
1713     }
1714 }
1715 "#,
1716         )
1717     }
1718
1719     #[test]
1720     fn test_self_to_self() {
1721         cov_mark::check!(rename_self_to_self);
1722         check(
1723             "self",
1724             r#"
1725 struct Foo;
1726 impl Foo {
1727     fn foo(self$0) {}
1728 }
1729 "#,
1730             r#"
1731 struct Foo;
1732 impl Foo {
1733     fn foo(self) {}
1734 }
1735 "#,
1736         )
1737     }
1738
1739     #[test]
1740     fn test_rename_field_in_pat_in_macro_doesnt_shorthand() {
1741         // ideally we would be able to make this emit a short hand, but I doubt this is easily possible
1742         check(
1743             "baz",
1744             r#"
1745 macro_rules! foo {
1746     ($pattern:pat) => {
1747         let $pattern = loop {};
1748     };
1749 }
1750 struct Foo {
1751     bar$0: u32,
1752 }
1753 fn foo() {
1754     foo!(Foo { bar: baz });
1755 }
1756 "#,
1757             r#"
1758 macro_rules! foo {
1759     ($pattern:pat) => {
1760         let $pattern = loop {};
1761     };
1762 }
1763 struct Foo {
1764     baz: u32,
1765 }
1766 fn foo() {
1767     foo!(Foo { baz: baz });
1768 }
1769 "#,
1770         )
1771     }
1772
1773     #[test]
1774     fn test_rename_tuple_field() {
1775         check(
1776             "foo",
1777             r#"
1778 struct Foo(i32);
1779
1780 fn baz() {
1781     let mut x = Foo(4);
1782     x.0$0 = 5;
1783 }
1784 "#,
1785             "error: No identifier available to rename",
1786         );
1787     }
1788
1789     #[test]
1790     fn test_rename_builtin() {
1791         check(
1792             "foo",
1793             r#"
1794 fn foo() {
1795     let x: i32$0 = 0;
1796 }
1797 "#,
1798             "error: Cannot rename builtin type",
1799         );
1800     }
1801
1802     #[test]
1803     fn test_rename_self() {
1804         check(
1805             "foo",
1806             r#"
1807 struct Foo {}
1808
1809 impl Foo {
1810     fn foo(self) -> Self$0 {
1811         self
1812     }
1813 }
1814 "#,
1815             "error: Cannot rename `Self`",
1816         );
1817     }
1818
1819     #[test]
1820     fn test_rename_ignores_self_ty() {
1821         check(
1822             "Fo0",
1823             r#"
1824 struct $0Foo;
1825
1826 impl Foo where Self: {}
1827 "#,
1828             r#"
1829 struct Fo0;
1830
1831 impl Fo0 where Self: {}
1832 "#,
1833         );
1834     }
1835
1836     #[test]
1837     fn test_rename_fails_on_aliases() {
1838         check(
1839             "Baz",
1840             r#"
1841 struct Foo;
1842 use Foo as Bar$0;
1843 "#,
1844             "error: Renaming aliases is currently unsupported",
1845         );
1846         check(
1847             "Baz",
1848             r#"
1849 struct Foo;
1850 use Foo as Bar;
1851 use Bar$0;
1852 "#,
1853             "error: Renaming aliases is currently unsupported",
1854         );
1855     }
1856
1857     #[test]
1858     fn test_rename_trait_method() {
1859         let res = r"
1860 trait Foo {
1861     fn foo(&self) {
1862         self.foo();
1863     }
1864 }
1865
1866 impl Foo for () {
1867     fn foo(&self) {
1868         self.foo();
1869     }
1870 }";
1871         check(
1872             "foo",
1873             r#"
1874 trait Foo {
1875     fn bar$0(&self) {
1876         self.bar();
1877     }
1878 }
1879
1880 impl Foo for () {
1881     fn bar(&self) {
1882         self.bar();
1883     }
1884 }"#,
1885             res,
1886         );
1887         check(
1888             "foo",
1889             r#"
1890 trait Foo {
1891     fn bar(&self) {
1892         self.bar$0();
1893     }
1894 }
1895
1896 impl Foo for () {
1897     fn bar(&self) {
1898         self.bar();
1899     }
1900 }"#,
1901             res,
1902         );
1903         check(
1904             "foo",
1905             r#"
1906 trait Foo {
1907     fn bar(&self) {
1908         self.bar();
1909     }
1910 }
1911
1912 impl Foo for () {
1913     fn bar$0(&self) {
1914         self.bar();
1915     }
1916 }"#,
1917             res,
1918         );
1919         check(
1920             "foo",
1921             r#"
1922 trait Foo {
1923     fn bar(&self) {
1924         self.bar();
1925     }
1926 }
1927
1928 impl Foo for () {
1929     fn bar(&self) {
1930         self.bar$0();
1931     }
1932 }"#,
1933             res,
1934         );
1935     }
1936
1937     #[test]
1938     fn test_rename_trait_method_prefix_of_second() {
1939         check(
1940             "qux",
1941             r#"
1942 trait Foo {
1943     fn foo$0() {}
1944     fn foobar() {}
1945 }
1946 "#,
1947             r#"
1948 trait Foo {
1949     fn qux() {}
1950     fn foobar() {}
1951 }
1952 "#,
1953         );
1954     }
1955
1956     #[test]
1957     fn test_rename_trait_const() {
1958         let res = r"
1959 trait Foo {
1960     const FOO: ();
1961 }
1962
1963 impl Foo for () {
1964     const FOO: ();
1965 }
1966 fn f() { <()>::FOO; }";
1967         check(
1968             "FOO",
1969             r#"
1970 trait Foo {
1971     const BAR$0: ();
1972 }
1973
1974 impl Foo for () {
1975     const BAR: ();
1976 }
1977 fn f() { <()>::BAR; }"#,
1978             res,
1979         );
1980         check(
1981             "FOO",
1982             r#"
1983 trait Foo {
1984     const BAR: ();
1985 }
1986
1987 impl Foo for () {
1988     const BAR$0: ();
1989 }
1990 fn f() { <()>::BAR; }"#,
1991             res,
1992         );
1993         check(
1994             "FOO",
1995             r#"
1996 trait Foo {
1997     const BAR: ();
1998 }
1999
2000 impl Foo for () {
2001     const BAR: ();
2002 }
2003 fn f() { <()>::BAR$0; }"#,
2004             res,
2005         );
2006     }
2007
2008     #[test]
2009     fn defs_from_macros_arent_renamed() {
2010         check(
2011             "lol",
2012             r#"
2013 macro_rules! m { () => { fn f() {} } }
2014 m!();
2015 fn main() { f$0()  }
2016 "#,
2017             "error: No identifier available to rename",
2018         )
2019     }
2020
2021     #[test]
2022     fn attributed_item() {
2023         check(
2024             "function",
2025             r#"
2026 //- proc_macros: identity
2027
2028 #[proc_macros::identity]
2029 fn func$0() {
2030     func();
2031 }
2032 "#,
2033             r#"
2034
2035 #[proc_macros::identity]
2036 fn function() {
2037     function();
2038 }
2039 "#,
2040         )
2041     }
2042
2043     #[test]
2044     fn in_macro_multi_mapping() {
2045         check(
2046             "a",
2047             r#"
2048 fn foo() {
2049     macro_rules! match_ast2 {
2050         ($node:ident {
2051             $( $res:expr, )*
2052         }) => {{
2053             $( if $node { $res } else )*
2054             { loop {} }
2055         }};
2056     }
2057     let $0d = 3;
2058     match_ast2! {
2059         d {
2060             d,
2061             d,
2062         }
2063     };
2064 }
2065 "#,
2066             r#"
2067 fn foo() {
2068     macro_rules! match_ast2 {
2069         ($node:ident {
2070             $( $res:expr, )*
2071         }) => {{
2072             $( if $node { $res } else )*
2073             { loop {} }
2074         }};
2075     }
2076     let a = 3;
2077     match_ast2! {
2078         a {
2079             a,
2080             a,
2081         }
2082     };
2083 }
2084 "#,
2085         )
2086     }
2087 }