• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! This module implements a reference search.
2 //! First, the element at the cursor position must be either an `ast::Name`
3 //! or `ast::NameRef`. If it's an `ast::NameRef`, at the classification step we
4 //! try to resolve the direct tree parent of this element, otherwise we
5 //! already have a definition and just need to get its HIR together with
6 //! some information that is needed for further steps of searching.
7 //! After that, we collect files that might contain references and look
8 //! for text occurrences of the identifier. If there's an `ast::NameRef`
9 //! at the index that the match starts at and its tree parent is
10 //! resolved to the search element definition, we get a reference.
11 
12 use hir::{PathResolution, Semantics};
13 use ide_db::{
14     base_db::FileId,
15     defs::{Definition, NameClass, NameRefClass},
16     search::{ReferenceCategory, SearchScope, UsageSearchResult},
17     RootDatabase,
18 };
19 use itertools::Itertools;
20 use nohash_hasher::IntMap;
21 use syntax::{
22     algo::find_node_at_offset,
23     ast::{self, HasName},
24     match_ast, AstNode,
25     SyntaxKind::*,
26     SyntaxNode, TextRange, TextSize, T,
27 };
28 
29 use crate::{FilePosition, NavigationTarget, TryToNav};
30 
31 #[derive(Debug, Clone)]
32 pub struct ReferenceSearchResult {
33     pub declaration: Option<Declaration>,
34     pub references: IntMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
35 }
36 
37 #[derive(Debug, Clone)]
38 pub struct Declaration {
39     pub nav: NavigationTarget,
40     pub is_mut: bool,
41 }
42 
43 // Feature: Find All References
44 //
45 // Shows all references of the item at the cursor location
46 //
47 // |===
48 // | Editor  | Shortcut
49 //
50 // | VS Code | kbd:[Shift+Alt+F12]
51 // |===
52 //
53 // image::https://user-images.githubusercontent.com/48062697/113020670-b7c34f00-917a-11eb-8003-370ac5f2b3cb.gif[]
find_all_refs( sema: &Semantics<'_, RootDatabase>, position: FilePosition, search_scope: Option<SearchScope>, ) -> Option<Vec<ReferenceSearchResult>>54 pub(crate) fn find_all_refs(
55     sema: &Semantics<'_, RootDatabase>,
56     position: FilePosition,
57     search_scope: Option<SearchScope>,
58 ) -> Option<Vec<ReferenceSearchResult>> {
59     let _p = profile::span("find_all_refs");
60     let syntax = sema.parse(position.file_id).syntax().clone();
61     let make_searcher = |literal_search: bool| {
62         move |def: Definition| {
63             let declaration = match def {
64                 Definition::Module(module) => {
65                     Some(NavigationTarget::from_module_to_decl(sema.db, module))
66                 }
67                 def => def.try_to_nav(sema.db),
68             }
69             .map(|nav| {
70                 let decl_range = nav.focus_or_full_range();
71                 Declaration {
72                     is_mut: decl_mutability(&def, sema.parse(nav.file_id).syntax(), decl_range),
73                     nav,
74                 }
75             });
76             let mut usages =
77                 def.usages(sema).set_scope(search_scope.clone()).include_self_refs().all();
78 
79             if literal_search {
80                 retain_adt_literal_usages(&mut usages, def, sema);
81             }
82 
83             let references = usages
84                 .into_iter()
85                 .map(|(file_id, refs)| {
86                     (
87                         file_id,
88                         refs.into_iter()
89                             .map(|file_ref| (file_ref.range, file_ref.category))
90                             .unique()
91                             .collect(),
92                     )
93                 })
94                 .collect();
95 
96             ReferenceSearchResult { declaration, references }
97         }
98     };
99 
100     match name_for_constructor_search(&syntax, position) {
101         Some(name) => {
102             let def = match NameClass::classify(sema, &name)? {
103                 NameClass::Definition(it) | NameClass::ConstReference(it) => it,
104                 NameClass::PatFieldShorthand { local_def: _, field_ref } => {
105                     Definition::Field(field_ref)
106                 }
107             };
108             Some(vec![make_searcher(true)(def)])
109         }
110         None => {
111             let search = make_searcher(false);
112             Some(find_defs(sema, &syntax, position.offset)?.map(search).collect())
113         }
114     }
115 }
116 
find_defs<'a>( sema: &'a Semantics<'_, RootDatabase>, syntax: &SyntaxNode, offset: TextSize, ) -> Option<impl Iterator<Item = Definition> + 'a>117 pub(crate) fn find_defs<'a>(
118     sema: &'a Semantics<'_, RootDatabase>,
119     syntax: &SyntaxNode,
120     offset: TextSize,
121 ) -> Option<impl Iterator<Item = Definition> + 'a> {
122     let token = syntax.token_at_offset(offset).find(|t| {
123         matches!(
124             t.kind(),
125             IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self]
126         )
127     });
128     token.map(|token| {
129         sema.descend_into_macros_with_same_text(token)
130             .into_iter()
131             .filter_map(|it| ast::NameLike::cast(it.parent()?))
132             .filter_map(move |name_like| {
133                 let def = match name_like {
134                     ast::NameLike::NameRef(name_ref) => {
135                         match NameRefClass::classify(sema, &name_ref)? {
136                             NameRefClass::Definition(def) => def,
137                             NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
138                                 Definition::Local(local_ref)
139                             }
140                         }
141                     }
142                     ast::NameLike::Name(name) => match NameClass::classify(sema, &name)? {
143                         NameClass::Definition(it) | NameClass::ConstReference(it) => it,
144                         NameClass::PatFieldShorthand { local_def, field_ref: _ } => {
145                             Definition::Local(local_def)
146                         }
147                     },
148                     ast::NameLike::Lifetime(lifetime) => {
149                         NameRefClass::classify_lifetime(sema, &lifetime)
150                             .and_then(|class| match class {
151                                 NameRefClass::Definition(it) => Some(it),
152                                 _ => None,
153                             })
154                             .or_else(|| {
155                                 NameClass::classify_lifetime(sema, &lifetime)
156                                     .and_then(NameClass::defined)
157                             })?
158                     }
159                 };
160                 Some(def)
161             })
162     })
163 }
164 
decl_mutability(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> bool165 pub(crate) fn decl_mutability(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> bool {
166     match def {
167         Definition::Local(_) | Definition::Field(_) => {}
168         _ => return false,
169     };
170 
171     match find_node_at_offset::<ast::LetStmt>(syntax, range.start()) {
172         Some(stmt) if stmt.initializer().is_some() => match stmt.pat() {
173             Some(ast::Pat::IdentPat(it)) => it.mut_token().is_some(),
174             _ => false,
175         },
176         _ => false,
177     }
178 }
179 
180 /// Filter out all non-literal usages for adt-defs
retain_adt_literal_usages( usages: &mut UsageSearchResult, def: Definition, sema: &Semantics<'_, RootDatabase>, )181 fn retain_adt_literal_usages(
182     usages: &mut UsageSearchResult,
183     def: Definition,
184     sema: &Semantics<'_, RootDatabase>,
185 ) {
186     let refs = usages.references.values_mut();
187     match def {
188         Definition::Adt(hir::Adt::Enum(enum_)) => {
189             refs.for_each(|it| {
190                 it.retain(|reference| {
191                     reference
192                         .name
193                         .as_name_ref()
194                         .map_or(false, |name_ref| is_enum_lit_name_ref(sema, enum_, name_ref))
195                 })
196             });
197             usages.references.retain(|_, it| !it.is_empty());
198         }
199         Definition::Adt(_) | Definition::Variant(_) => {
200             refs.for_each(|it| {
201                 it.retain(|reference| reference.name.as_name_ref().map_or(false, is_lit_name_ref))
202             });
203             usages.references.retain(|_, it| !it.is_empty());
204         }
205         _ => {}
206     }
207 }
208 
209 /// Returns `Some` if the cursor is at a position for an item to search for all its constructor/literal usages
name_for_constructor_search(syntax: &SyntaxNode, position: FilePosition) -> Option<ast::Name>210 fn name_for_constructor_search(syntax: &SyntaxNode, position: FilePosition) -> Option<ast::Name> {
211     let token = syntax.token_at_offset(position.offset).right_biased()?;
212     let token_parent = token.parent()?;
213     let kind = token.kind();
214     if kind == T![;] {
215         ast::Struct::cast(token_parent)
216             .filter(|struct_| struct_.field_list().is_none())
217             .and_then(|struct_| struct_.name())
218     } else if kind == T!['{'] {
219         match_ast! {
220             match token_parent {
221                 ast::RecordFieldList(rfl) => match_ast! {
222                     match (rfl.syntax().parent()?) {
223                         ast::Variant(it) => it.name(),
224                         ast::Struct(it) => it.name(),
225                         ast::Union(it) => it.name(),
226                         _ => None,
227                     }
228                 },
229                 ast::VariantList(vl) => ast::Enum::cast(vl.syntax().parent()?)?.name(),
230                 _ => None,
231             }
232         }
233     } else if kind == T!['('] {
234         let tfl = ast::TupleFieldList::cast(token_parent)?;
235         match_ast! {
236             match (tfl.syntax().parent()?) {
237                 ast::Variant(it) => it.name(),
238                 ast::Struct(it) => it.name(),
239                 _ => None,
240             }
241         }
242     } else {
243         None
244     }
245 }
246 
is_enum_lit_name_ref( sema: &Semantics<'_, RootDatabase>, enum_: hir::Enum, name_ref: &ast::NameRef, ) -> bool247 fn is_enum_lit_name_ref(
248     sema: &Semantics<'_, RootDatabase>,
249     enum_: hir::Enum,
250     name_ref: &ast::NameRef,
251 ) -> bool {
252     let path_is_variant_of_enum = |path: ast::Path| {
253         matches!(
254             sema.resolve_path(&path),
255             Some(PathResolution::Def(hir::ModuleDef::Variant(variant)))
256                 if variant.parent_enum(sema.db) == enum_
257         )
258     };
259     name_ref
260         .syntax()
261         .ancestors()
262         .find_map(|ancestor| {
263             match_ast! {
264                 match ancestor {
265                     ast::PathExpr(path_expr) => path_expr.path().map(path_is_variant_of_enum),
266                     ast::RecordExpr(record_expr) => record_expr.path().map(path_is_variant_of_enum),
267                     _ => None,
268                 }
269             }
270         })
271         .unwrap_or(false)
272 }
273 
path_ends_with(path: Option<ast::Path>, name_ref: &ast::NameRef) -> bool274 fn path_ends_with(path: Option<ast::Path>, name_ref: &ast::NameRef) -> bool {
275     path.and_then(|path| path.segment())
276         .and_then(|segment| segment.name_ref())
277         .map_or(false, |segment| segment == *name_ref)
278 }
279 
is_lit_name_ref(name_ref: &ast::NameRef) -> bool280 fn is_lit_name_ref(name_ref: &ast::NameRef) -> bool {
281     name_ref.syntax().ancestors().find_map(|ancestor| {
282         match_ast! {
283             match ancestor {
284                 ast::PathExpr(path_expr) => Some(path_ends_with(path_expr.path(), name_ref)),
285                 ast::RecordExpr(record_expr) => Some(path_ends_with(record_expr.path(), name_ref)),
286                 _ => None,
287             }
288         }
289     }).unwrap_or(false)
290 }
291 
292 #[cfg(test)]
293 mod tests {
294     use expect_test::{expect, Expect};
295     use ide_db::{base_db::FileId, search::ReferenceCategory};
296     use stdx::format_to;
297 
298     use crate::{fixture, SearchScope};
299 
300     #[test]
test_struct_literal_after_space()301     fn test_struct_literal_after_space() {
302         check(
303             r#"
304 struct Foo $0{
305     a: i32,
306 }
307 impl Foo {
308     fn f() -> i32 { 42 }
309 }
310 fn main() {
311     let f: Foo;
312     f = Foo {a: Foo::f()};
313 }
314 "#,
315             expect![[r#"
316                 Foo Struct FileId(0) 0..26 7..10
317 
318                 FileId(0) 101..104
319             "#]],
320         );
321     }
322 
323     #[test]
test_struct_literal_before_space()324     fn test_struct_literal_before_space() {
325         check(
326             r#"
327 struct Foo$0 {}
328     fn main() {
329     let f: Foo;
330     f = Foo {};
331 }
332 "#,
333             expect![[r#"
334                 Foo Struct FileId(0) 0..13 7..10
335 
336                 FileId(0) 41..44
337                 FileId(0) 54..57
338             "#]],
339         );
340     }
341 
342     #[test]
test_struct_literal_with_generic_type()343     fn test_struct_literal_with_generic_type() {
344         check(
345             r#"
346 struct Foo<T> $0{}
347     fn main() {
348     let f: Foo::<i32>;
349     f = Foo {};
350 }
351 "#,
352             expect![[r#"
353                 Foo Struct FileId(0) 0..16 7..10
354 
355                 FileId(0) 64..67
356             "#]],
357         );
358     }
359 
360     #[test]
test_struct_literal_for_tuple()361     fn test_struct_literal_for_tuple() {
362         check(
363             r#"
364 struct Foo$0(i32);
365 
366 fn main() {
367     let f: Foo;
368     f = Foo(1);
369 }
370 "#,
371             expect![[r#"
372                 Foo Struct FileId(0) 0..16 7..10
373 
374                 FileId(0) 54..57
375             "#]],
376         );
377     }
378 
379     #[test]
test_struct_literal_for_union()380     fn test_struct_literal_for_union() {
381         check(
382             r#"
383 union Foo $0{
384     x: u32
385 }
386 
387 fn main() {
388     let f: Foo;
389     f = Foo { x: 1 };
390 }
391 "#,
392             expect![[r#"
393                 Foo Union FileId(0) 0..24 6..9
394 
395                 FileId(0) 62..65
396             "#]],
397         );
398     }
399 
400     #[test]
test_enum_after_space()401     fn test_enum_after_space() {
402         check(
403             r#"
404 enum Foo $0{
405     A,
406     B(),
407     C{},
408 }
409 fn main() {
410     let f: Foo;
411     f = Foo::A;
412     f = Foo::B();
413     f = Foo::C{};
414 }
415 "#,
416             expect![[r#"
417                 Foo Enum FileId(0) 0..37 5..8
418 
419                 FileId(0) 74..77
420                 FileId(0) 90..93
421                 FileId(0) 108..111
422             "#]],
423         );
424     }
425 
426     #[test]
test_variant_record_after_space()427     fn test_variant_record_after_space() {
428         check(
429             r#"
430 enum Foo {
431     A $0{ n: i32 },
432     B,
433 }
434 fn main() {
435     let f: Foo;
436     f = Foo::B;
437     f = Foo::A { n: 92 };
438 }
439 "#,
440             expect![[r#"
441                 A Variant FileId(0) 15..27 15..16
442 
443                 FileId(0) 95..96
444             "#]],
445         );
446     }
447     #[test]
test_variant_tuple_before_paren()448     fn test_variant_tuple_before_paren() {
449         check(
450             r#"
451 enum Foo {
452     A$0(i32),
453     B,
454 }
455 fn main() {
456     let f: Foo;
457     f = Foo::B;
458     f = Foo::A(92);
459 }
460 "#,
461             expect![[r#"
462                 A Variant FileId(0) 15..21 15..16
463 
464                 FileId(0) 89..90
465             "#]],
466         );
467     }
468 
469     #[test]
test_enum_before_space()470     fn test_enum_before_space() {
471         check(
472             r#"
473 enum Foo$0 {
474     A,
475     B,
476 }
477 fn main() {
478     let f: Foo;
479     f = Foo::A;
480 }
481 "#,
482             expect![[r#"
483                 Foo Enum FileId(0) 0..26 5..8
484 
485                 FileId(0) 50..53
486                 FileId(0) 63..66
487             "#]],
488         );
489     }
490 
491     #[test]
test_enum_with_generic_type()492     fn test_enum_with_generic_type() {
493         check(
494             r#"
495 enum Foo<T> $0{
496     A(T),
497     B,
498 }
499 fn main() {
500     let f: Foo<i8>;
501     f = Foo::A(1);
502 }
503 "#,
504             expect![[r#"
505                 Foo Enum FileId(0) 0..32 5..8
506 
507                 FileId(0) 73..76
508             "#]],
509         );
510     }
511 
512     #[test]
test_enum_for_tuple()513     fn test_enum_for_tuple() {
514         check(
515             r#"
516 enum Foo$0{
517     A(i8),
518     B(i8),
519 }
520 fn main() {
521     let f: Foo;
522     f = Foo::A(1);
523 }
524 "#,
525             expect![[r#"
526                 Foo Enum FileId(0) 0..33 5..8
527 
528                 FileId(0) 70..73
529             "#]],
530         );
531     }
532 
533     #[test]
test_find_all_refs_for_local()534     fn test_find_all_refs_for_local() {
535         check(
536             r#"
537 fn main() {
538     let mut i = 1;
539     let j = 1;
540     i = i$0 + j;
541 
542     {
543         i = 0;
544     }
545 
546     i = 5;
547 }"#,
548             expect![[r#"
549                 i Local FileId(0) 20..25 24..25 Write
550 
551                 FileId(0) 50..51 Write
552                 FileId(0) 54..55 Read
553                 FileId(0) 76..77 Write
554                 FileId(0) 94..95 Write
555             "#]],
556         );
557     }
558 
559     #[test]
search_filters_by_range()560     fn search_filters_by_range() {
561         check(
562             r#"
563 fn foo() {
564     let spam$0 = 92;
565     spam + spam
566 }
567 fn bar() {
568     let spam = 92;
569     spam + spam
570 }
571 "#,
572             expect![[r#"
573                 spam Local FileId(0) 19..23 19..23
574 
575                 FileId(0) 34..38 Read
576                 FileId(0) 41..45 Read
577             "#]],
578         );
579     }
580 
581     #[test]
test_find_all_refs_for_param_inside()582     fn test_find_all_refs_for_param_inside() {
583         check(
584             r#"
585 fn foo(i : u32) -> u32 { i$0 }
586 "#,
587             expect![[r#"
588                 i ValueParam FileId(0) 7..8 7..8
589 
590                 FileId(0) 25..26 Read
591             "#]],
592         );
593     }
594 
595     #[test]
test_find_all_refs_for_fn_param()596     fn test_find_all_refs_for_fn_param() {
597         check(
598             r#"
599 fn foo(i$0 : u32) -> u32 { i }
600 "#,
601             expect![[r#"
602                 i ValueParam FileId(0) 7..8 7..8
603 
604                 FileId(0) 25..26 Read
605             "#]],
606         );
607     }
608 
609     #[test]
test_find_all_refs_field_name()610     fn test_find_all_refs_field_name() {
611         check(
612             r#"
613 //- /lib.rs
614 struct Foo {
615     pub spam$0: u32,
616 }
617 
618 fn main(s: Foo) {
619     let f = s.spam;
620 }
621 "#,
622             expect![[r#"
623                 spam Field FileId(0) 17..30 21..25
624 
625                 FileId(0) 67..71 Read
626             "#]],
627         );
628     }
629 
630     #[test]
test_find_all_refs_impl_item_name()631     fn test_find_all_refs_impl_item_name() {
632         check(
633             r#"
634 struct Foo;
635 impl Foo {
636     fn f$0(&self) {  }
637 }
638 "#,
639             expect![[r#"
640                 f Function FileId(0) 27..43 30..31
641 
642                 (no references)
643             "#]],
644         );
645     }
646 
647     #[test]
test_find_all_refs_enum_var_name()648     fn test_find_all_refs_enum_var_name() {
649         check(
650             r#"
651 enum Foo {
652     A,
653     B$0,
654     C,
655 }
656 "#,
657             expect![[r#"
658                 B Variant FileId(0) 22..23 22..23
659 
660                 (no references)
661             "#]],
662         );
663     }
664 
665     #[test]
test_find_all_refs_enum_var_field()666     fn test_find_all_refs_enum_var_field() {
667         check(
668             r#"
669 enum Foo {
670     A,
671     B { field$0: u8 },
672     C,
673 }
674 "#,
675             expect![[r#"
676                 field Field FileId(0) 26..35 26..31
677 
678                 (no references)
679             "#]],
680         );
681     }
682 
683     #[test]
test_find_all_refs_two_modules()684     fn test_find_all_refs_two_modules() {
685         check(
686             r#"
687 //- /lib.rs
688 pub mod foo;
689 pub mod bar;
690 
691 fn f() {
692     let i = foo::Foo { n: 5 };
693 }
694 
695 //- /foo.rs
696 use crate::bar;
697 
698 pub struct Foo {
699     pub n: u32,
700 }
701 
702 fn f() {
703     let i = bar::Bar { n: 5 };
704 }
705 
706 //- /bar.rs
707 use crate::foo;
708 
709 pub struct Bar {
710     pub n: u32,
711 }
712 
713 fn f() {
714     let i = foo::Foo$0 { n: 5 };
715 }
716 "#,
717             expect![[r#"
718                 Foo Struct FileId(1) 17..51 28..31 foo
719 
720                 FileId(0) 53..56
721                 FileId(2) 79..82
722             "#]],
723         );
724     }
725 
726     #[test]
test_find_all_refs_decl_module()727     fn test_find_all_refs_decl_module() {
728         check(
729             r#"
730 //- /lib.rs
731 mod foo$0;
732 
733 use foo::Foo;
734 
735 fn f() {
736     let i = Foo { n: 5 };
737 }
738 
739 //- /foo.rs
740 pub struct Foo {
741     pub n: u32,
742 }
743 "#,
744             expect![[r#"
745                 foo Module FileId(0) 0..8 4..7
746 
747                 FileId(0) 14..17 Import
748             "#]],
749         );
750     }
751 
752     #[test]
test_find_all_refs_decl_module_on_self()753     fn test_find_all_refs_decl_module_on_self() {
754         check(
755             r#"
756 //- /lib.rs
757 mod foo;
758 
759 //- /foo.rs
760 use self$0;
761 "#,
762             expect![[r#"
763                 foo Module FileId(0) 0..8 4..7
764 
765                 FileId(1) 4..8 Import
766             "#]],
767         );
768     }
769 
770     #[test]
test_find_all_refs_decl_module_on_self_crate_root()771     fn test_find_all_refs_decl_module_on_self_crate_root() {
772         check(
773             r#"
774 //- /lib.rs
775 use self$0;
776 "#,
777             expect![[r#"
778                 Module FileId(0) 0..10
779 
780                 FileId(0) 4..8 Import
781             "#]],
782         );
783     }
784 
785     #[test]
test_find_all_refs_super_mod_vis()786     fn test_find_all_refs_super_mod_vis() {
787         check(
788             r#"
789 //- /lib.rs
790 mod foo;
791 
792 //- /foo.rs
793 mod some;
794 use some::Foo;
795 
796 fn f() {
797     let i = Foo { n: 5 };
798 }
799 
800 //- /foo/some.rs
801 pub(super) struct Foo$0 {
802     pub n: u32,
803 }
804 "#,
805             expect![[r#"
806                 Foo Struct FileId(2) 0..41 18..21 some
807 
808                 FileId(1) 20..23 Import
809                 FileId(1) 47..50
810             "#]],
811         );
812     }
813 
814     #[test]
test_find_all_refs_with_scope()815     fn test_find_all_refs_with_scope() {
816         let code = r#"
817             //- /lib.rs
818             mod foo;
819             mod bar;
820 
821             pub fn quux$0() {}
822 
823             //- /foo.rs
824             fn f() { super::quux(); }
825 
826             //- /bar.rs
827             fn f() { super::quux(); }
828         "#;
829 
830         check_with_scope(
831             code,
832             None,
833             expect![[r#"
834                 quux Function FileId(0) 19..35 26..30
835 
836                 FileId(1) 16..20
837                 FileId(2) 16..20
838             "#]],
839         );
840 
841         check_with_scope(
842             code,
843             Some(SearchScope::single_file(FileId(2))),
844             expect![[r#"
845                 quux Function FileId(0) 19..35 26..30
846 
847                 FileId(2) 16..20
848             "#]],
849         );
850     }
851 
852     #[test]
test_find_all_refs_macro_def()853     fn test_find_all_refs_macro_def() {
854         check(
855             r#"
856 #[macro_export]
857 macro_rules! m1$0 { () => (()) }
858 
859 fn foo() {
860     m1();
861     m1();
862 }
863 "#,
864             expect![[r#"
865                 m1 Macro FileId(0) 0..46 29..31
866 
867                 FileId(0) 63..65
868                 FileId(0) 73..75
869             "#]],
870         );
871     }
872 
873     #[test]
test_basic_highlight_read_write()874     fn test_basic_highlight_read_write() {
875         check(
876             r#"
877 fn foo() {
878     let mut i$0 = 0;
879     i = i + 1;
880 }
881 "#,
882             expect![[r#"
883                 i Local FileId(0) 19..24 23..24 Write
884 
885                 FileId(0) 34..35 Write
886                 FileId(0) 38..39 Read
887             "#]],
888         );
889     }
890 
891     #[test]
test_basic_highlight_field_read_write()892     fn test_basic_highlight_field_read_write() {
893         check(
894             r#"
895 struct S {
896     f: u32,
897 }
898 
899 fn foo() {
900     let mut s = S{f: 0};
901     s.f$0 = 0;
902 }
903 "#,
904             expect![[r#"
905                 f Field FileId(0) 15..21 15..16
906 
907                 FileId(0) 55..56 Read
908                 FileId(0) 68..69 Write
909             "#]],
910         );
911     }
912 
913     #[test]
test_basic_highlight_decl_no_write()914     fn test_basic_highlight_decl_no_write() {
915         check(
916             r#"
917 fn foo() {
918     let i$0;
919     i = 1;
920 }
921 "#,
922             expect![[r#"
923                 i Local FileId(0) 19..20 19..20
924 
925                 FileId(0) 26..27 Write
926             "#]],
927         );
928     }
929 
930     #[test]
test_find_struct_function_refs_outside_module()931     fn test_find_struct_function_refs_outside_module() {
932         check(
933             r#"
934 mod foo {
935     pub struct Foo;
936 
937     impl Foo {
938         pub fn new$0() -> Foo { Foo }
939     }
940 }
941 
942 fn main() {
943     let _f = foo::Foo::new();
944 }
945 "#,
946             expect![[r#"
947                 new Function FileId(0) 54..81 61..64
948 
949                 FileId(0) 126..129
950             "#]],
951         );
952     }
953 
954     #[test]
test_find_all_refs_nested_module()955     fn test_find_all_refs_nested_module() {
956         check(
957             r#"
958 //- /lib.rs
959 mod foo { mod bar; }
960 
961 fn f$0() {}
962 
963 //- /foo/bar.rs
964 use crate::f;
965 
966 fn g() { f(); }
967 "#,
968             expect![[r#"
969                 f Function FileId(0) 22..31 25..26
970 
971                 FileId(1) 11..12 Import
972                 FileId(1) 24..25
973             "#]],
974         );
975     }
976 
977     #[test]
test_find_all_refs_struct_pat()978     fn test_find_all_refs_struct_pat() {
979         check(
980             r#"
981 struct S {
982     field$0: u8,
983 }
984 
985 fn f(s: S) {
986     match s {
987         S { field } => {}
988     }
989 }
990 "#,
991             expect![[r#"
992                 field Field FileId(0) 15..24 15..20
993 
994                 FileId(0) 68..73 Read
995             "#]],
996         );
997     }
998 
999     #[test]
test_find_all_refs_enum_var_pat()1000     fn test_find_all_refs_enum_var_pat() {
1001         check(
1002             r#"
1003 enum En {
1004     Variant {
1005         field$0: u8,
1006     }
1007 }
1008 
1009 fn f(e: En) {
1010     match e {
1011         En::Variant { field } => {}
1012     }
1013 }
1014 "#,
1015             expect![[r#"
1016                 field Field FileId(0) 32..41 32..37
1017 
1018                 FileId(0) 102..107 Read
1019             "#]],
1020         );
1021     }
1022 
1023     #[test]
test_find_all_refs_enum_var_privacy()1024     fn test_find_all_refs_enum_var_privacy() {
1025         check(
1026             r#"
1027 mod m {
1028     pub enum En {
1029         Variant {
1030             field$0: u8,
1031         }
1032     }
1033 }
1034 
1035 fn f() -> m::En {
1036     m::En::Variant { field: 0 }
1037 }
1038 "#,
1039             expect![[r#"
1040                 field Field FileId(0) 56..65 56..61
1041 
1042                 FileId(0) 125..130 Read
1043             "#]],
1044         );
1045     }
1046 
1047     #[test]
test_find_self_refs()1048     fn test_find_self_refs() {
1049         check(
1050             r#"
1051 struct Foo { bar: i32 }
1052 
1053 impl Foo {
1054     fn foo(self) {
1055         let x = self$0.bar;
1056         if true {
1057             let _ = match () {
1058                 () => self,
1059             };
1060         }
1061     }
1062 }
1063 "#,
1064             expect![[r#"
1065                 self SelfParam FileId(0) 47..51 47..51
1066 
1067                 FileId(0) 71..75 Read
1068                 FileId(0) 152..156 Read
1069             "#]],
1070         );
1071     }
1072 
1073     #[test]
test_find_self_refs_decl()1074     fn test_find_self_refs_decl() {
1075         check(
1076             r#"
1077 struct Foo { bar: i32 }
1078 
1079 impl Foo {
1080     fn foo(self$0) {
1081         self;
1082     }
1083 }
1084 "#,
1085             expect![[r#"
1086                 self SelfParam FileId(0) 47..51 47..51
1087 
1088                 FileId(0) 63..67 Read
1089             "#]],
1090         );
1091     }
1092 
check(ra_fixture: &str, expect: Expect)1093     fn check(ra_fixture: &str, expect: Expect) {
1094         check_with_scope(ra_fixture, None, expect)
1095     }
1096 
check_with_scope(ra_fixture: &str, search_scope: Option<SearchScope>, expect: Expect)1097     fn check_with_scope(ra_fixture: &str, search_scope: Option<SearchScope>, expect: Expect) {
1098         let (analysis, pos) = fixture::position(ra_fixture);
1099         let refs = analysis.find_all_refs(pos, search_scope).unwrap().unwrap();
1100 
1101         let mut actual = String::new();
1102         for refs in refs {
1103             actual += "\n\n";
1104 
1105             if let Some(decl) = refs.declaration {
1106                 format_to!(actual, "{}", decl.nav.debug_render());
1107                 if decl.is_mut {
1108                     format_to!(actual, " {:?}", ReferenceCategory::Write)
1109                 }
1110                 actual += "\n\n";
1111             }
1112 
1113             for (file_id, references) in &refs.references {
1114                 for (range, access) in references {
1115                     format_to!(actual, "{:?} {:?}", file_id, range);
1116                     if let Some(access) = access {
1117                         format_to!(actual, " {:?}", access);
1118                     }
1119                     actual += "\n";
1120                 }
1121             }
1122 
1123             if refs.references.is_empty() {
1124                 actual += "(no references)\n";
1125             }
1126         }
1127         expect.assert_eq(actual.trim_start())
1128     }
1129 
1130     #[test]
test_find_lifetimes_function()1131     fn test_find_lifetimes_function() {
1132         check(
1133             r#"
1134 trait Foo<'a> {}
1135 impl<'a> Foo<'a> for &'a () {}
1136 fn foo<'a, 'b: 'a>(x: &'a$0 ()) -> &'a () where &'a (): Foo<'a> {
1137     fn bar<'a>(_: &'a ()) {}
1138     x
1139 }
1140 "#,
1141             expect![[r#"
1142                 'a LifetimeParam FileId(0) 55..57 55..57
1143 
1144                 FileId(0) 63..65
1145                 FileId(0) 71..73
1146                 FileId(0) 82..84
1147                 FileId(0) 95..97
1148                 FileId(0) 106..108
1149             "#]],
1150         );
1151     }
1152 
1153     #[test]
test_find_lifetimes_type_alias()1154     fn test_find_lifetimes_type_alias() {
1155         check(
1156             r#"
1157 type Foo<'a, T> where T: 'a$0 = &'a T;
1158 "#,
1159             expect![[r#"
1160                 'a LifetimeParam FileId(0) 9..11 9..11
1161 
1162                 FileId(0) 25..27
1163                 FileId(0) 31..33
1164             "#]],
1165         );
1166     }
1167 
1168     #[test]
test_find_lifetimes_trait_impl()1169     fn test_find_lifetimes_trait_impl() {
1170         check(
1171             r#"
1172 trait Foo<'a> {
1173     fn foo() -> &'a ();
1174 }
1175 impl<'a> Foo<'a> for &'a () {
1176     fn foo() -> &'a$0 () {
1177         unimplemented!()
1178     }
1179 }
1180 "#,
1181             expect![[r#"
1182                 'a LifetimeParam FileId(0) 47..49 47..49
1183 
1184                 FileId(0) 55..57
1185                 FileId(0) 64..66
1186                 FileId(0) 89..91
1187             "#]],
1188         );
1189     }
1190 
1191     #[test]
test_map_range_to_original()1192     fn test_map_range_to_original() {
1193         check(
1194             r#"
1195 macro_rules! foo {($i:ident) => {$i} }
1196 fn main() {
1197     let a$0 = "test";
1198     foo!(a);
1199 }
1200 "#,
1201             expect![[r#"
1202                 a Local FileId(0) 59..60 59..60
1203 
1204                 FileId(0) 80..81 Read
1205             "#]],
1206         );
1207     }
1208 
1209     #[test]
test_map_range_to_original_ref()1210     fn test_map_range_to_original_ref() {
1211         check(
1212             r#"
1213 macro_rules! foo {($i:ident) => {$i} }
1214 fn main() {
1215     let a = "test";
1216     foo!(a$0);
1217 }
1218 "#,
1219             expect![[r#"
1220                 a Local FileId(0) 59..60 59..60
1221 
1222                 FileId(0) 80..81 Read
1223             "#]],
1224         );
1225     }
1226 
1227     #[test]
test_find_labels()1228     fn test_find_labels() {
1229         check(
1230             r#"
1231 fn foo<'a>() -> &'a () {
1232     'a: loop {
1233         'b: loop {
1234             continue 'a$0;
1235         }
1236         break 'a;
1237     }
1238 }
1239 "#,
1240             expect![[r#"
1241                 'a Label FileId(0) 29..32 29..31
1242 
1243                 FileId(0) 80..82
1244                 FileId(0) 108..110
1245             "#]],
1246         );
1247     }
1248 
1249     #[test]
test_find_const_param()1250     fn test_find_const_param() {
1251         check(
1252             r#"
1253 fn foo<const FOO$0: usize>() -> usize {
1254     FOO
1255 }
1256 "#,
1257             expect![[r#"
1258                 FOO ConstParam FileId(0) 7..23 13..16
1259 
1260                 FileId(0) 42..45
1261             "#]],
1262         );
1263     }
1264 
1265     #[test]
test_trait()1266     fn test_trait() {
1267         check(
1268             r#"
1269 trait Foo$0 where Self: {}
1270 
1271 impl Foo for () {}
1272 "#,
1273             expect![[r#"
1274                 Foo Trait FileId(0) 0..24 6..9
1275 
1276                 FileId(0) 31..34
1277             "#]],
1278         );
1279     }
1280 
1281     #[test]
test_trait_self()1282     fn test_trait_self() {
1283         check(
1284             r#"
1285 trait Foo where Self$0 {
1286     fn f() -> Self;
1287 }
1288 
1289 impl Foo for () {}
1290 "#,
1291             expect![[r#"
1292                 Self TypeParam FileId(0) 0..44 6..9
1293 
1294                 FileId(0) 16..20
1295                 FileId(0) 37..41
1296             "#]],
1297         );
1298     }
1299 
1300     #[test]
test_self_ty()1301     fn test_self_ty() {
1302         check(
1303             r#"
1304         struct $0Foo;
1305 
1306         impl Foo where Self: {
1307             fn f() -> Self;
1308         }
1309         "#,
1310             expect![[r#"
1311                 Foo Struct FileId(0) 0..11 7..10
1312 
1313                 FileId(0) 18..21
1314                 FileId(0) 28..32
1315                 FileId(0) 50..54
1316             "#]],
1317         );
1318         check(
1319             r#"
1320 struct Foo;
1321 
1322 impl Foo where Self: {
1323     fn f() -> Self$0;
1324 }
1325 "#,
1326             expect![[r#"
1327                 impl Impl FileId(0) 13..57 18..21
1328 
1329                 FileId(0) 18..21
1330                 FileId(0) 28..32
1331                 FileId(0) 50..54
1332             "#]],
1333         );
1334     }
1335     #[test]
test_self_variant_with_payload()1336     fn test_self_variant_with_payload() {
1337         check(
1338             r#"
1339 enum Foo { Bar() }
1340 
1341 impl Foo {
1342     fn foo(self) {
1343         match self {
1344             Self::Bar$0() => (),
1345         }
1346     }
1347 }
1348 
1349 "#,
1350             expect![[r#"
1351                 Bar Variant FileId(0) 11..16 11..14
1352 
1353                 FileId(0) 89..92
1354             "#]],
1355         );
1356     }
1357 
1358     #[test]
test_trait_alias()1359     fn test_trait_alias() {
1360         check(
1361             r#"
1362 trait Foo {}
1363 trait Bar$0 = Foo where Self: ;
1364 fn foo<T: Bar>(_: impl Bar, _: &dyn Bar) {}
1365 "#,
1366             expect![[r#"
1367                 Bar TraitAlias FileId(0) 13..42 19..22
1368 
1369                 FileId(0) 53..56
1370                 FileId(0) 66..69
1371                 FileId(0) 79..82
1372             "#]],
1373         );
1374     }
1375 
1376     #[test]
test_trait_alias_self()1377     fn test_trait_alias_self() {
1378         check(
1379             r#"
1380 trait Foo = where Self$0: ;
1381 "#,
1382             expect![[r#"
1383                 Self TypeParam FileId(0) 0..25 6..9
1384 
1385                 FileId(0) 18..22
1386             "#]],
1387         );
1388     }
1389 
1390     #[test]
test_attr_differs_from_fn_with_same_name()1391     fn test_attr_differs_from_fn_with_same_name() {
1392         check(
1393             r#"
1394 #[test]
1395 fn test$0() {
1396     test();
1397 }
1398 "#,
1399             expect![[r#"
1400                 test Function FileId(0) 0..33 11..15
1401 
1402                 FileId(0) 24..28
1403             "#]],
1404         );
1405     }
1406 
1407     #[test]
test_const_in_pattern()1408     fn test_const_in_pattern() {
1409         check(
1410             r#"
1411 const A$0: i32 = 42;
1412 
1413 fn main() {
1414     match A {
1415         A => (),
1416         _ => (),
1417     }
1418     if let A = A {}
1419 }
1420 "#,
1421             expect![[r#"
1422                 A Const FileId(0) 0..18 6..7
1423 
1424                 FileId(0) 42..43
1425                 FileId(0) 54..55
1426                 FileId(0) 97..98
1427                 FileId(0) 101..102
1428             "#]],
1429         );
1430     }
1431 
1432     #[test]
test_primitives()1433     fn test_primitives() {
1434         check(
1435             r#"
1436 fn foo(_: bool) -> bo$0ol { true }
1437 "#,
1438             expect![[r#"
1439                 FileId(0) 10..14
1440                 FileId(0) 19..23
1441             "#]],
1442         );
1443     }
1444 
1445     #[test]
test_transitive()1446     fn test_transitive() {
1447         check(
1448             r#"
1449 //- /level3.rs new_source_root:local crate:level3
1450 pub struct Fo$0o;
1451 //- /level2.rs new_source_root:local crate:level2 deps:level3
1452 pub use level3::Foo;
1453 //- /level1.rs new_source_root:local crate:level1 deps:level2
1454 pub use level2::Foo;
1455 //- /level0.rs new_source_root:local crate:level0 deps:level1
1456 pub use level1::Foo;
1457 "#,
1458             expect![[r#"
1459                 Foo Struct FileId(0) 0..15 11..14
1460 
1461                 FileId(1) 16..19 Import
1462                 FileId(2) 16..19 Import
1463                 FileId(3) 16..19 Import
1464             "#]],
1465         );
1466     }
1467 
1468     #[test]
test_decl_macro_references()1469     fn test_decl_macro_references() {
1470         check(
1471             r#"
1472 //- /lib.rs crate:lib
1473 #[macro_use]
1474 mod qux;
1475 mod bar;
1476 
1477 pub use self::foo;
1478 //- /qux.rs
1479 #[macro_export]
1480 macro_rules! foo$0 {
1481     () => {struct Foo;};
1482 }
1483 //- /bar.rs
1484 foo!();
1485 //- /other.rs crate:other deps:lib new_source_root:local
1486 lib::foo!();
1487 "#,
1488             expect![[r#"
1489                 foo Macro FileId(1) 0..61 29..32
1490 
1491                 FileId(0) 46..49 Import
1492                 FileId(2) 0..3
1493                 FileId(3) 5..8
1494             "#]],
1495         );
1496     }
1497 
1498     #[test]
macro_doesnt_reference_attribute_on_call()1499     fn macro_doesnt_reference_attribute_on_call() {
1500         check(
1501             r#"
1502 macro_rules! m {
1503     () => {};
1504 }
1505 
1506 #[proc_macro_test::attr_noop]
1507 m$0!();
1508 
1509 "#,
1510             expect![[r#"
1511                 m Macro FileId(0) 0..32 13..14
1512 
1513                 FileId(0) 64..65
1514             "#]],
1515         );
1516     }
1517 
1518     #[test]
multi_def()1519     fn multi_def() {
1520         check(
1521             r#"
1522 macro_rules! m {
1523     ($name:ident) => {
1524         mod module {
1525             pub fn $name() {}
1526         }
1527 
1528         pub fn $name() {}
1529     }
1530 }
1531 
1532 m!(func$0);
1533 
1534 fn f() {
1535     func();
1536     module::func();
1537 }
1538             "#,
1539             expect![[r#"
1540                 func Function FileId(0) 137..146 140..144
1541 
1542                 FileId(0) 161..165
1543 
1544 
1545                 func Function FileId(0) 137..146 140..144 module
1546 
1547                 FileId(0) 181..185
1548             "#]],
1549         )
1550     }
1551 
1552     #[test]
attr_expanded()1553     fn attr_expanded() {
1554         check(
1555             r#"
1556 //- proc_macros: identity
1557 #[proc_macros::identity]
1558 fn func$0() {
1559     func();
1560 }
1561 "#,
1562             expect![[r#"
1563                 func Function FileId(0) 25..50 28..32
1564 
1565                 FileId(0) 41..45
1566             "#]],
1567         )
1568     }
1569 
1570     #[test]
attr_assoc_item()1571     fn attr_assoc_item() {
1572         check(
1573             r#"
1574 //- proc_macros: identity
1575 
1576 trait Trait {
1577     #[proc_macros::identity]
1578     fn func() {
1579         Self::func$0();
1580     }
1581 }
1582 "#,
1583             expect![[r#"
1584                 func Function FileId(0) 48..87 51..55 Trait
1585 
1586                 FileId(0) 74..78
1587             "#]],
1588         )
1589     }
1590 
1591     // FIXME: import is classified as function
1592     #[test]
attr()1593     fn attr() {
1594         check(
1595             r#"
1596 //- proc_macros: identity
1597 use proc_macros::identity;
1598 
1599 #[proc_macros::$0identity]
1600 fn func() {}
1601 "#,
1602             expect![[r#"
1603                 identity Attribute FileId(1) 1..107 32..40
1604 
1605                 FileId(0) 43..51
1606             "#]],
1607         );
1608         check(
1609             r#"
1610 #![crate_type="proc-macro"]
1611 #[proc_macro_attribute]
1612 fn func$0() {}
1613 "#,
1614             expect![[r#"
1615                 func Attribute FileId(0) 28..64 55..59
1616 
1617                 (no references)
1618             "#]],
1619         );
1620     }
1621 
1622     // FIXME: import is classified as function
1623     #[test]
proc_macro()1624     fn proc_macro() {
1625         check(
1626             r#"
1627 //- proc_macros: mirror
1628 use proc_macros::mirror;
1629 
1630 mirror$0! {}
1631 "#,
1632             expect![[r#"
1633                 mirror Macro FileId(1) 1..77 22..28
1634 
1635                 FileId(0) 26..32
1636             "#]],
1637         )
1638     }
1639 
1640     #[test]
derive()1641     fn derive() {
1642         check(
1643             r#"
1644 //- proc_macros: derive_identity
1645 //- minicore: derive
1646 use proc_macros::DeriveIdentity;
1647 
1648 #[derive(proc_macros::DeriveIdentity$0)]
1649 struct Foo;
1650 "#,
1651             expect![[r#"
1652                 derive_identity Derive FileId(2) 1..107 45..60
1653 
1654                 FileId(0) 17..31 Import
1655                 FileId(0) 56..70
1656             "#]],
1657         );
1658         check(
1659             r#"
1660 #![crate_type="proc-macro"]
1661 #[proc_macro_derive(Derive, attributes(x))]
1662 pub fn deri$0ve(_stream: TokenStream) -> TokenStream {}
1663 "#,
1664             expect![[r#"
1665                 derive Derive FileId(0) 28..125 79..85
1666 
1667                 (no references)
1668             "#]],
1669         );
1670     }
1671 
1672     #[test]
assoc_items_trait_def()1673     fn assoc_items_trait_def() {
1674         check(
1675             r#"
1676 trait Trait {
1677     const CONST$0: usize;
1678 }
1679 
1680 impl Trait for () {
1681     const CONST: usize = 0;
1682 }
1683 
1684 impl Trait for ((),) {
1685     const CONST: usize = 0;
1686 }
1687 
1688 fn f<T: Trait>() {
1689     let _ = <()>::CONST;
1690 
1691     let _ = T::CONST;
1692 }
1693 "#,
1694             expect![[r#"
1695                 CONST Const FileId(0) 18..37 24..29 Trait
1696 
1697                 FileId(0) 71..76
1698                 FileId(0) 125..130
1699                 FileId(0) 183..188
1700                 FileId(0) 206..211
1701             "#]],
1702         );
1703         check(
1704             r#"
1705 trait Trait {
1706     type TypeAlias$0;
1707 }
1708 
1709 impl Trait for () {
1710     type TypeAlias = ();
1711 }
1712 
1713 impl Trait for ((),) {
1714     type TypeAlias = ();
1715 }
1716 
1717 fn f<T: Trait>() {
1718     let _: <() as Trait>::TypeAlias;
1719 
1720     let _: T::TypeAlias;
1721 }
1722 "#,
1723             expect![[r#"
1724                 TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait
1725 
1726                 FileId(0) 66..75
1727                 FileId(0) 117..126
1728                 FileId(0) 181..190
1729                 FileId(0) 207..216
1730             "#]],
1731         );
1732         check(
1733             r#"
1734 trait Trait {
1735     fn function$0() {}
1736 }
1737 
1738 impl Trait for () {
1739     fn function() {}
1740 }
1741 
1742 impl Trait for ((),) {
1743     fn function() {}
1744 }
1745 
1746 fn f<T: Trait>() {
1747     let _ = <()>::function;
1748 
1749     let _ = T::function;
1750 }
1751 "#,
1752             expect![[r#"
1753                 function Function FileId(0) 18..34 21..29 Trait
1754 
1755                 FileId(0) 65..73
1756                 FileId(0) 112..120
1757                 FileId(0) 166..174
1758                 FileId(0) 192..200
1759             "#]],
1760         );
1761     }
1762 
1763     #[test]
assoc_items_trait_impl_def()1764     fn assoc_items_trait_impl_def() {
1765         check(
1766             r#"
1767 trait Trait {
1768     const CONST: usize;
1769 }
1770 
1771 impl Trait for () {
1772     const CONST$0: usize = 0;
1773 }
1774 
1775 impl Trait for ((),) {
1776     const CONST: usize = 0;
1777 }
1778 
1779 fn f<T: Trait>() {
1780     let _ = <()>::CONST;
1781 
1782     let _ = T::CONST;
1783 }
1784 "#,
1785             expect![[r#"
1786                 CONST Const FileId(0) 65..88 71..76
1787 
1788                 FileId(0) 183..188
1789             "#]],
1790         );
1791         check(
1792             r#"
1793 trait Trait {
1794     type TypeAlias;
1795 }
1796 
1797 impl Trait for () {
1798     type TypeAlias$0 = ();
1799 }
1800 
1801 impl Trait for ((),) {
1802     type TypeAlias = ();
1803 }
1804 
1805 fn f<T: Trait>() {
1806     let _: <() as Trait>::TypeAlias;
1807 
1808     let _: T::TypeAlias;
1809 }
1810 "#,
1811             expect![[r#"
1812                 TypeAlias TypeAlias FileId(0) 61..81 66..75
1813 
1814                 FileId(0) 23..32
1815                 FileId(0) 117..126
1816                 FileId(0) 181..190
1817                 FileId(0) 207..216
1818             "#]],
1819         );
1820         check(
1821             r#"
1822 trait Trait {
1823     fn function() {}
1824 }
1825 
1826 impl Trait for () {
1827     fn function$0() {}
1828 }
1829 
1830 impl Trait for ((),) {
1831     fn function() {}
1832 }
1833 
1834 fn f<T: Trait>() {
1835     let _ = <()>::function;
1836 
1837     let _ = T::function;
1838 }
1839 "#,
1840             expect![[r#"
1841                 function Function FileId(0) 62..78 65..73
1842 
1843                 FileId(0) 166..174
1844             "#]],
1845         );
1846     }
1847 
1848     #[test]
assoc_items_ref()1849     fn assoc_items_ref() {
1850         check(
1851             r#"
1852 trait Trait {
1853     const CONST: usize;
1854 }
1855 
1856 impl Trait for () {
1857     const CONST: usize = 0;
1858 }
1859 
1860 impl Trait for ((),) {
1861     const CONST: usize = 0;
1862 }
1863 
1864 fn f<T: Trait>() {
1865     let _ = <()>::CONST$0;
1866 
1867     let _ = T::CONST;
1868 }
1869 "#,
1870             expect![[r#"
1871                 CONST Const FileId(0) 65..88 71..76
1872 
1873                 FileId(0) 183..188
1874             "#]],
1875         );
1876         check(
1877             r#"
1878 trait Trait {
1879     type TypeAlias;
1880 }
1881 
1882 impl Trait for () {
1883     type TypeAlias = ();
1884 }
1885 
1886 impl Trait for ((),) {
1887     type TypeAlias = ();
1888 }
1889 
1890 fn f<T: Trait>() {
1891     let _: <() as Trait>::TypeAlias$0;
1892 
1893     let _: T::TypeAlias;
1894 }
1895 "#,
1896             expect![[r#"
1897                 TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait
1898 
1899                 FileId(0) 66..75
1900                 FileId(0) 117..126
1901                 FileId(0) 181..190
1902                 FileId(0) 207..216
1903             "#]],
1904         );
1905         check(
1906             r#"
1907 trait Trait {
1908     fn function() {}
1909 }
1910 
1911 impl Trait for () {
1912     fn function() {}
1913 }
1914 
1915 impl Trait for ((),) {
1916     fn function() {}
1917 }
1918 
1919 fn f<T: Trait>() {
1920     let _ = <()>::function$0;
1921 
1922     let _ = T::function;
1923 }
1924 "#,
1925             expect![[r#"
1926                 function Function FileId(0) 62..78 65..73
1927 
1928                 FileId(0) 166..174
1929             "#]],
1930         );
1931     }
1932 
1933     #[test]
name_clashes()1934     fn name_clashes() {
1935         check(
1936             r#"
1937 trait Foo {
1938     fn method$0(&self) -> u8;
1939 }
1940 
1941 struct Bar {
1942     method: u8,
1943 }
1944 
1945 impl Foo for Bar {
1946     fn method(&self) -> u8 {
1947         self.method
1948     }
1949 }
1950 fn method() {}
1951 "#,
1952             expect![[r#"
1953                 method Function FileId(0) 16..39 19..25 Foo
1954 
1955                 FileId(0) 101..107
1956             "#]],
1957         );
1958         check(
1959             r#"
1960 trait Foo {
1961     fn method(&self) -> u8;
1962 }
1963 
1964 struct Bar {
1965     method$0: u8,
1966 }
1967 
1968 impl Foo for Bar {
1969     fn method(&self) -> u8 {
1970         self.method
1971     }
1972 }
1973 fn method() {}
1974 "#,
1975             expect![[r#"
1976                 method Field FileId(0) 60..70 60..66
1977 
1978                 FileId(0) 136..142 Read
1979             "#]],
1980         );
1981         check(
1982             r#"
1983 trait Foo {
1984     fn method(&self) -> u8;
1985 }
1986 
1987 struct Bar {
1988     method: u8,
1989 }
1990 
1991 impl Foo for Bar {
1992     fn method$0(&self) -> u8 {
1993         self.method
1994     }
1995 }
1996 fn method() {}
1997 "#,
1998             expect![[r#"
1999                 method Function FileId(0) 98..148 101..107
2000 
2001                 (no references)
2002             "#]],
2003         );
2004         check(
2005             r#"
2006 trait Foo {
2007     fn method(&self) -> u8;
2008 }
2009 
2010 struct Bar {
2011     method: u8,
2012 }
2013 
2014 impl Foo for Bar {
2015     fn method(&self) -> u8 {
2016         self.method$0
2017     }
2018 }
2019 fn method() {}
2020 "#,
2021             expect![[r#"
2022                 method Field FileId(0) 60..70 60..66
2023 
2024                 FileId(0) 136..142 Read
2025             "#]],
2026         );
2027         check(
2028             r#"
2029 trait Foo {
2030     fn method(&self) -> u8;
2031 }
2032 
2033 struct Bar {
2034     method: u8,
2035 }
2036 
2037 impl Foo for Bar {
2038     fn method(&self) -> u8 {
2039         self.method
2040     }
2041 }
2042 fn method$0() {}
2043 "#,
2044             expect![[r#"
2045                 method Function FileId(0) 151..165 154..160
2046 
2047                 (no references)
2048             "#]],
2049         );
2050     }
2051 
2052     #[test]
raw_identifier()2053     fn raw_identifier() {
2054         check(
2055             r#"
2056 fn r#fn$0() {}
2057 fn main() { r#fn(); }
2058 "#,
2059             expect![[r#"
2060                 r#fn Function FileId(0) 0..12 3..7
2061 
2062                 FileId(0) 25..29
2063             "#]],
2064         );
2065     }
2066 }
2067