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