aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/references.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/references.rs')
-rw-r--r--crates/ide/src/references.rs370
1 files changed, 180 insertions, 190 deletions
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 6999dacee..c7cefb3b6 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -11,14 +11,14 @@
11 11
12pub(crate) mod rename; 12pub(crate) mod rename;
13 13
14use either::Either;
15use hir::Semantics; 14use hir::Semantics;
16use ide_db::{ 15use ide_db::{
17 base_db::FileId, 16 base_db::FileId,
18 defs::{Definition, NameClass, NameRefClass}, 17 defs::{Definition, NameClass, NameRefClass},
19 search::{FileReference, ReferenceAccess, ReferenceKind, SearchScope, UsageSearchResult}, 18 search::{ReferenceAccess, SearchScope},
20 RootDatabase, 19 RootDatabase,
21}; 20};
21use rustc_hash::FxHashMap;
22use syntax::{ 22use syntax::{
23 algo::find_node_at_offset, 23 algo::find_node_at_offset,
24 ast::{self, NameOwner}, 24 ast::{self, NameOwner},
@@ -29,52 +29,16 @@ use crate::{display::TryToNav, FilePosition, NavigationTarget};
29 29
30#[derive(Debug, Clone)] 30#[derive(Debug, Clone)]
31pub struct ReferenceSearchResult { 31pub struct ReferenceSearchResult {
32 declaration: Declaration, 32 pub declaration: Declaration,
33 references: UsageSearchResult, 33 pub references: FxHashMap<FileId, Vec<(TextRange, Option<ReferenceAccess>)>>,
34} 34}
35 35
36#[derive(Debug, Clone)] 36#[derive(Debug, Clone)]
37pub struct Declaration { 37pub struct Declaration {
38 pub nav: NavigationTarget, 38 pub nav: NavigationTarget,
39 pub kind: ReferenceKind,
40 pub access: Option<ReferenceAccess>, 39 pub access: Option<ReferenceAccess>,
41} 40}
42 41
43impl ReferenceSearchResult {
44 pub fn references(&self) -> &UsageSearchResult {
45 &self.references
46 }
47
48 pub fn references_with_declaration(mut self) -> UsageSearchResult {
49 let decl_ref = FileReference {
50 range: self.declaration.nav.focus_or_full_range(),
51 kind: self.declaration.kind,
52 access: self.declaration.access,
53 };
54 let file_id = self.declaration.nav.file_id;
55 self.references.references.entry(file_id).or_default().push(decl_ref);
56 self.references
57 }
58
59 /// Total number of references
60 /// At least 1 since all valid references should
61 /// Have a declaration
62 pub fn len(&self) -> usize {
63 self.references.len() + 1
64 }
65}
66
67// allow turning ReferenceSearchResult into an iterator
68// over References
69impl IntoIterator for ReferenceSearchResult {
70 type Item = (FileId, Vec<FileReference>);
71 type IntoIter = std::collections::hash_map::IntoIter<FileId, Vec<FileReference>>;
72
73 fn into_iter(self) -> Self::IntoIter {
74 self.references_with_declaration().into_iter()
75 }
76}
77
78pub(crate) fn find_all_refs( 42pub(crate) fn find_all_refs(
79 sema: &Semantics<RootDatabase>, 43 sema: &Semantics<RootDatabase>,
80 position: FilePosition, 44 position: FilePosition,
@@ -83,83 +47,72 @@ pub(crate) fn find_all_refs(
83 let _p = profile::span("find_all_refs"); 47 let _p = profile::span("find_all_refs");
84 let syntax = sema.parse(position.file_id).syntax().clone(); 48 let syntax = sema.parse(position.file_id).syntax().clone();
85 49
86 let (opt_name, search_kind) = if let Some(name) = 50 let (opt_name, ctor_filter): (_, Option<fn(&_) -> bool>) = if let Some(name) =
87 get_struct_def_name_for_struct_literal_search(&sema, &syntax, position) 51 get_struct_def_name_for_struct_literal_search(&sema, &syntax, position)
88 { 52 {
89 (Some(name), ReferenceKind::StructLiteral) 53 (
54 Some(name),
55 Some(|name_ref| is_record_lit_name_ref(name_ref) || is_call_expr_name_ref(name_ref)),
56 )
90 } else if let Some(name) = get_enum_def_name_for_struct_literal_search(&sema, &syntax, position) 57 } else if let Some(name) = get_enum_def_name_for_struct_literal_search(&sema, &syntax, position)
91 { 58 {
92 (Some(name), ReferenceKind::EnumLiteral) 59 (Some(name), Some(is_enum_lit_name_ref))
93 } else { 60 } else {
94 ( 61 (sema.find_node_at_offset_with_descend::<ast::Name>(&syntax, position.offset), None)
95 sema.find_node_at_offset_with_descend::<ast::Name>(&syntax, position.offset),
96 ReferenceKind::Other,
97 )
98 }; 62 };
99 63
100 let def = find_name(&sema, &syntax, position, opt_name)?; 64 let def = find_def(&sema, &syntax, position, opt_name)?;
101 65
102 let mut usages = def.usages(sema).set_scope(search_scope).all(); 66 let mut usages = def.usages(sema).set_scope(search_scope).all();
103 usages 67 if let Some(ctor_filter) = ctor_filter {
104 .references 68 // filter for constructor-literals
105 .values_mut() 69 usages.references.values_mut().for_each(|it| {
106 .for_each(|it| it.retain(|r| search_kind == ReferenceKind::Other || search_kind == r.kind)); 70 it.retain(|reference| reference.name.as_name_ref().map_or(false, ctor_filter));
107 usages.references.retain(|_, it| !it.is_empty()); 71 });
108 72 usages.references.retain(|_, it| !it.is_empty());
73 }
109 let nav = def.try_to_nav(sema.db)?; 74 let nav = def.try_to_nav(sema.db)?;
110 let decl_range = nav.focus_or_full_range(); 75 let decl_range = nav.focus_or_full_range();
111 76
112 let mut kind = ReferenceKind::Other; 77 let declaration = Declaration { nav, access: decl_access(&def, &syntax, decl_range) };
113 if let Definition::Local(local) = def { 78 let references = usages
114 match local.source(sema.db).value { 79 .into_iter()
115 Either::Left(pat) => { 80 .map(|(file_id, refs)| {
116 if matches!( 81 (file_id, refs.into_iter().map(|file_ref| (file_ref.range, file_ref.access)).collect())
117 pat.syntax().parent().and_then(ast::RecordPatField::cast), 82 })
118 Some(pat_field) if pat_field.name_ref().is_none() 83 .collect();
119 ) {
120 kind = ReferenceKind::FieldShorthandForLocal;
121 }
122 }
123 Either::Right(_) => kind = ReferenceKind::SelfParam,
124 }
125 } else if matches!(
126 def,
127 Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_)
128 ) {
129 kind = ReferenceKind::Lifetime;
130 };
131
132 let declaration = Declaration { nav, kind, access: decl_access(&def, &syntax, decl_range) };
133 84
134 Some(ReferenceSearchResult { declaration, references: usages }) 85 Some(ReferenceSearchResult { declaration, references })
135} 86}
136 87
137fn find_name( 88fn find_def(
138 sema: &Semantics<RootDatabase>, 89 sema: &Semantics<RootDatabase>,
139 syntax: &SyntaxNode, 90 syntax: &SyntaxNode,
140 position: FilePosition, 91 position: FilePosition,
141 opt_name: Option<ast::Name>, 92 opt_name: Option<ast::Name>,
142) -> Option<Definition> { 93) -> Option<Definition> {
143 let def = if let Some(name) = opt_name { 94 if let Some(name) = opt_name {
144 NameClass::classify(sema, &name)?.referenced_or_defined(sema.db) 95 let class = NameClass::classify(sema, &name)?;
96 Some(class.referenced_or_defined(sema.db))
145 } else if let Some(lifetime) = 97 } else if let Some(lifetime) =
146 sema.find_node_at_offset_with_descend::<ast::Lifetime>(&syntax, position.offset) 98 sema.find_node_at_offset_with_descend::<ast::Lifetime>(&syntax, position.offset)
147 { 99 {
148 if let Some(def) = 100 let def = if let Some(def) =
149 NameRefClass::classify_lifetime(sema, &lifetime).map(|class| class.referenced(sema.db)) 101 NameRefClass::classify_lifetime(sema, &lifetime).map(|class| class.referenced(sema.db))
150 { 102 {
151 def 103 def
152 } else { 104 } else {
153 NameClass::classify_lifetime(sema, &lifetime)?.referenced_or_defined(sema.db) 105 NameClass::classify_lifetime(sema, &lifetime)?.referenced_or_defined(sema.db)
154 } 106 };
107 Some(def)
155 } else if let Some(name_ref) = 108 } else if let Some(name_ref) =
156 sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset) 109 sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset)
157 { 110 {
158 NameRefClass::classify(sema, &name_ref)?.referenced(sema.db) 111 let class = NameRefClass::classify(sema, &name_ref)?;
112 Some(class.referenced(sema.db))
159 } else { 113 } else {
160 return None; 114 None
161 }; 115 }
162 Some(def)
163} 116}
164 117
165fn decl_access(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> Option<ReferenceAccess> { 118fn decl_access(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> Option<ReferenceAccess> {
@@ -235,6 +188,43 @@ fn get_enum_def_name_for_struct_literal_search(
235 None 188 None
236} 189}
237 190
191fn is_call_expr_name_ref(name_ref: &ast::NameRef) -> bool {
192 name_ref
193 .syntax()
194 .ancestors()
195 .find_map(ast::CallExpr::cast)
196 .and_then(|c| match c.expr()? {
197 ast::Expr::PathExpr(p) => {
198 Some(p.path()?.segment()?.name_ref().as_ref() == Some(name_ref))
199 }
200 _ => None,
201 })
202 .unwrap_or(false)
203}
204
205fn is_record_lit_name_ref(name_ref: &ast::NameRef) -> bool {
206 name_ref
207 .syntax()
208 .ancestors()
209 .find_map(ast::RecordExpr::cast)
210 .and_then(|l| l.path())
211 .and_then(|p| p.segment())
212 .map(|p| p.name_ref().as_ref() == Some(name_ref))
213 .unwrap_or(false)
214}
215
216fn is_enum_lit_name_ref(name_ref: &ast::NameRef) -> bool {
217 name_ref
218 .syntax()
219 .ancestors()
220 .find_map(ast::PathExpr::cast)
221 .and_then(|p| p.path())
222 .and_then(|p| p.qualifier())
223 .and_then(|p| p.segment())
224 .map(|p| p.name_ref().as_ref() == Some(name_ref))
225 .unwrap_or(false)
226}
227
238#[cfg(test)] 228#[cfg(test)]
239mod tests { 229mod tests {
240 use expect_test::{expect, Expect}; 230 use expect_test::{expect, Expect};
@@ -259,9 +249,9 @@ fn main() {
259} 249}
260"#, 250"#,
261 expect![[r#" 251 expect![[r#"
262 Foo Struct FileId(0) 0..26 7..10 Other 252 Foo Struct FileId(0) 0..26 7..10
263 253
264 FileId(0) 101..104 StructLiteral 254 FileId(0) 101..104
265 "#]], 255 "#]],
266 ); 256 );
267 } 257 }
@@ -277,10 +267,10 @@ struct Foo$0 {}
277} 267}
278"#, 268"#,
279 expect![[r#" 269 expect![[r#"
280 Foo Struct FileId(0) 0..13 7..10 Other 270 Foo Struct FileId(0) 0..13 7..10
281 271
282 FileId(0) 41..44 Other 272 FileId(0) 41..44
283 FileId(0) 54..57 StructLiteral 273 FileId(0) 54..57
284 "#]], 274 "#]],
285 ); 275 );
286 } 276 }
@@ -296,9 +286,9 @@ struct Foo<T> $0{}
296} 286}
297"#, 287"#,
298 expect![[r#" 288 expect![[r#"
299 Foo Struct FileId(0) 0..16 7..10 Other 289 Foo Struct FileId(0) 0..16 7..10
300 290
301 FileId(0) 64..67 StructLiteral 291 FileId(0) 64..67
302 "#]], 292 "#]],
303 ); 293 );
304 } 294 }
@@ -315,9 +305,9 @@ fn main() {
315} 305}
316"#, 306"#,
317 expect![[r#" 307 expect![[r#"
318 Foo Struct FileId(0) 0..16 7..10 Other 308 Foo Struct FileId(0) 0..16 7..10
319 309
320 FileId(0) 54..57 StructLiteral 310 FileId(0) 54..57
321 "#]], 311 "#]],
322 ); 312 );
323 } 313 }
@@ -336,9 +326,9 @@ fn main() {
336} 326}
337"#, 327"#,
338 expect![[r#" 328 expect![[r#"
339 Foo Enum FileId(0) 0..26 5..8 Other 329 Foo Enum FileId(0) 0..26 5..8
340 330
341 FileId(0) 63..66 EnumLiteral 331 FileId(0) 63..66
342 "#]], 332 "#]],
343 ); 333 );
344 } 334 }
@@ -357,10 +347,10 @@ fn main() {
357} 347}
358"#, 348"#,
359 expect![[r#" 349 expect![[r#"
360 Foo Enum FileId(0) 0..26 5..8 Other 350 Foo Enum FileId(0) 0..26 5..8
361 351
362 FileId(0) 50..53 Other 352 FileId(0) 50..53
363 FileId(0) 63..66 EnumLiteral 353 FileId(0) 63..66
364 "#]], 354 "#]],
365 ); 355 );
366 } 356 }
@@ -379,9 +369,9 @@ fn main() {
379} 369}
380"#, 370"#,
381 expect![[r#" 371 expect![[r#"
382 Foo Enum FileId(0) 0..32 5..8 Other 372 Foo Enum FileId(0) 0..32 5..8
383 373
384 FileId(0) 73..76 EnumLiteral 374 FileId(0) 73..76
385 "#]], 375 "#]],
386 ); 376 );
387 } 377 }
@@ -400,9 +390,9 @@ fn main() {
400} 390}
401"#, 391"#,
402 expect![[r#" 392 expect![[r#"
403 Foo Enum FileId(0) 0..33 5..8 Other 393 Foo Enum FileId(0) 0..33 5..8
404 394
405 FileId(0) 70..73 EnumLiteral 395 FileId(0) 70..73
406 "#]], 396 "#]],
407 ); 397 );
408 } 398 }
@@ -423,12 +413,12 @@ fn main() {
423 i = 5; 413 i = 5;
424}"#, 414}"#,
425 expect![[r#" 415 expect![[r#"
426 i Local FileId(0) 20..25 24..25 Other Write 416 i Local FileId(0) 20..25 24..25 Write
427 417
428 FileId(0) 50..51 Other Write 418 FileId(0) 50..51 Write
429 FileId(0) 54..55 Other Read 419 FileId(0) 54..55 Read
430 FileId(0) 76..77 Other Write 420 FileId(0) 76..77 Write
431 FileId(0) 94..95 Other Write 421 FileId(0) 94..95 Write
432 "#]], 422 "#]],
433 ); 423 );
434 } 424 }
@@ -447,10 +437,10 @@ fn bar() {
447} 437}
448"#, 438"#,
449 expect![[r#" 439 expect![[r#"
450 spam Local FileId(0) 19..23 19..23 Other 440 spam Local FileId(0) 19..23 19..23
451 441
452 FileId(0) 34..38 Other Read 442 FileId(0) 34..38 Read
453 FileId(0) 41..45 Other Read 443 FileId(0) 41..45 Read
454 "#]], 444 "#]],
455 ); 445 );
456 } 446 }
@@ -462,9 +452,9 @@ fn bar() {
462fn foo(i : u32) -> u32 { i$0 } 452fn foo(i : u32) -> u32 { i$0 }
463"#, 453"#,
464 expect![[r#" 454 expect![[r#"
465 i ValueParam FileId(0) 7..8 7..8 Other 455 i ValueParam FileId(0) 7..8 7..8
466 456
467 FileId(0) 25..26 Other Read 457 FileId(0) 25..26 Read
468 "#]], 458 "#]],
469 ); 459 );
470 } 460 }
@@ -476,9 +466,9 @@ fn foo(i : u32) -> u32 { i$0 }
476fn foo(i$0 : u32) -> u32 { i } 466fn foo(i$0 : u32) -> u32 { i }
477"#, 467"#,
478 expect![[r#" 468 expect![[r#"
479 i ValueParam FileId(0) 7..8 7..8 Other 469 i ValueParam FileId(0) 7..8 7..8
480 470
481 FileId(0) 25..26 Other Read 471 FileId(0) 25..26 Read
482 "#]], 472 "#]],
483 ); 473 );
484 } 474 }
@@ -497,9 +487,9 @@ fn main(s: Foo) {
497} 487}
498"#, 488"#,
499 expect![[r#" 489 expect![[r#"
500 spam Field FileId(0) 17..30 21..25 Other 490 spam Field FileId(0) 17..30 21..25
501 491
502 FileId(0) 67..71 Other Read 492 FileId(0) 67..71 Read
503 "#]], 493 "#]],
504 ); 494 );
505 } 495 }
@@ -514,7 +504,7 @@ impl Foo {
514} 504}
515"#, 505"#,
516 expect![[r#" 506 expect![[r#"
517 f Function FileId(0) 27..43 30..31 Other 507 f Function FileId(0) 27..43 30..31
518 508
519 "#]], 509 "#]],
520 ); 510 );
@@ -531,7 +521,7 @@ enum Foo {
531} 521}
532"#, 522"#,
533 expect![[r#" 523 expect![[r#"
534 B Variant FileId(0) 22..23 22..23 Other 524 B Variant FileId(0) 22..23 22..23
535 525
536 "#]], 526 "#]],
537 ); 527 );
@@ -548,7 +538,7 @@ enum Foo {
548} 538}
549"#, 539"#,
550 expect![[r#" 540 expect![[r#"
551 field Field FileId(0) 26..35 26..31 Other 541 field Field FileId(0) 26..35 26..31
552 542
553 "#]], 543 "#]],
554 ); 544 );
@@ -589,10 +579,10 @@ fn f() {
589} 579}
590"#, 580"#,
591 expect![[r#" 581 expect![[r#"
592 Foo Struct FileId(1) 17..51 28..31 Other 582 Foo Struct FileId(1) 17..51 28..31
593 583
594 FileId(0) 53..56 StructLiteral 584 FileId(0) 53..56
595 FileId(2) 79..82 StructLiteral 585 FileId(2) 79..82
596 "#]], 586 "#]],
597 ); 587 );
598 } 588 }
@@ -619,9 +609,9 @@ pub struct Foo {
619} 609}
620"#, 610"#,
621 expect![[r#" 611 expect![[r#"
622 foo Module FileId(1) 0..35 Other 612 foo Module FileId(1) 0..35
623 613
624 FileId(0) 14..17 Other 614 FileId(0) 14..17
625 "#]], 615 "#]],
626 ); 616 );
627 } 617 }
@@ -647,10 +637,10 @@ pub(super) struct Foo$0 {
647} 637}
648"#, 638"#,
649 expect![[r#" 639 expect![[r#"
650 Foo Struct FileId(2) 0..41 18..21 Other 640 Foo Struct FileId(2) 0..41 18..21
651 641
652 FileId(1) 20..23 Other 642 FileId(1) 20..23
653 FileId(1) 47..50 StructLiteral 643 FileId(1) 47..50
654 "#]], 644 "#]],
655 ); 645 );
656 } 646 }
@@ -675,10 +665,10 @@ pub(super) struct Foo$0 {
675 code, 665 code,
676 None, 666 None,
677 expect![[r#" 667 expect![[r#"
678 quux Function FileId(0) 19..35 26..30 Other 668 quux Function FileId(0) 19..35 26..30
679 669
680 FileId(1) 16..20 StructLiteral 670 FileId(1) 16..20
681 FileId(2) 16..20 StructLiteral 671 FileId(2) 16..20
682 "#]], 672 "#]],
683 ); 673 );
684 674
@@ -686,9 +676,9 @@ pub(super) struct Foo$0 {
686 code, 676 code,
687 Some(SearchScope::single_file(FileId(2))), 677 Some(SearchScope::single_file(FileId(2))),
688 expect![[r#" 678 expect![[r#"
689 quux Function FileId(0) 19..35 26..30 Other 679 quux Function FileId(0) 19..35 26..30
690 680
691 FileId(2) 16..20 StructLiteral 681 FileId(2) 16..20
692 "#]], 682 "#]],
693 ); 683 );
694 } 684 }
@@ -706,10 +696,10 @@ fn foo() {
706} 696}
707"#, 697"#,
708 expect![[r#" 698 expect![[r#"
709 m1 Macro FileId(0) 0..46 29..31 Other 699 m1 Macro FileId(0) 0..46 29..31
710 700
711 FileId(0) 63..65 StructLiteral 701 FileId(0) 63..65
712 FileId(0) 73..75 StructLiteral 702 FileId(0) 73..75
713 "#]], 703 "#]],
714 ); 704 );
715 } 705 }
@@ -724,10 +714,10 @@ fn foo() {
724} 714}
725"#, 715"#,
726 expect![[r#" 716 expect![[r#"
727 i Local FileId(0) 19..24 23..24 Other Write 717 i Local FileId(0) 19..24 23..24 Write
728 718
729 FileId(0) 34..35 Other Write 719 FileId(0) 34..35 Write
730 FileId(0) 38..39 Other Read 720 FileId(0) 38..39 Read
731 "#]], 721 "#]],
732 ); 722 );
733 } 723 }
@@ -746,10 +736,10 @@ fn foo() {
746} 736}
747"#, 737"#,
748 expect![[r#" 738 expect![[r#"
749 f Field FileId(0) 15..21 15..16 Other 739 f Field FileId(0) 15..21 15..16
750 740
751 FileId(0) 55..56 RecordFieldExprOrPat Read 741 FileId(0) 55..56 Read
752 FileId(0) 68..69 Other Write 742 FileId(0) 68..69 Write
753 "#]], 743 "#]],
754 ); 744 );
755 } 745 }
@@ -764,9 +754,9 @@ fn foo() {
764} 754}
765"#, 755"#,
766 expect![[r#" 756 expect![[r#"
767 i Local FileId(0) 19..20 19..20 Other 757 i Local FileId(0) 19..20 19..20
768 758
769 FileId(0) 26..27 Other Write 759 FileId(0) 26..27 Write
770 "#]], 760 "#]],
771 ); 761 );
772 } 762 }
@@ -788,9 +778,9 @@ fn main() {
788} 778}
789"#, 779"#,
790 expect![[r#" 780 expect![[r#"
791 new Function FileId(0) 54..81 61..64 Other 781 new Function FileId(0) 54..81 61..64
792 782
793 FileId(0) 126..129 StructLiteral 783 FileId(0) 126..129
794 "#]], 784 "#]],
795 ); 785 );
796 } 786 }
@@ -810,10 +800,10 @@ use crate::f;
810fn g() { f(); } 800fn g() { f(); }
811"#, 801"#,
812 expect![[r#" 802 expect![[r#"
813 f Function FileId(0) 22..31 25..26 Other 803 f Function FileId(0) 22..31 25..26
814 804
815 FileId(1) 11..12 Other 805 FileId(1) 11..12
816 FileId(1) 24..25 StructLiteral 806 FileId(1) 24..25
817 "#]], 807 "#]],
818 ); 808 );
819 } 809 }
@@ -833,9 +823,9 @@ fn f(s: S) {
833} 823}
834"#, 824"#,
835 expect![[r#" 825 expect![[r#"
836 field Field FileId(0) 15..24 15..20 Other 826 field Field FileId(0) 15..24 15..20
837 827
838 FileId(0) 68..73 FieldShorthandForField Read 828 FileId(0) 68..73 Read
839 "#]], 829 "#]],
840 ); 830 );
841 } 831 }
@@ -857,9 +847,9 @@ fn f(e: En) {
857} 847}
858"#, 848"#,
859 expect![[r#" 849 expect![[r#"
860 field Field FileId(0) 32..41 32..37 Other 850 field Field FileId(0) 32..41 32..37
861 851
862 FileId(0) 102..107 FieldShorthandForField Read 852 FileId(0) 102..107 Read
863 "#]], 853 "#]],
864 ); 854 );
865 } 855 }
@@ -881,9 +871,9 @@ fn f() -> m::En {
881} 871}
882"#, 872"#,
883 expect![[r#" 873 expect![[r#"
884 field Field FileId(0) 56..65 56..61 Other 874 field Field FileId(0) 56..65 56..61
885 875
886 FileId(0) 125..130 RecordFieldExprOrPat Read 876 FileId(0) 125..130 Read
887 "#]], 877 "#]],
888 ); 878 );
889 } 879 }
@@ -906,10 +896,10 @@ impl Foo {
906} 896}
907"#, 897"#,
908 expect![[r#" 898 expect![[r#"
909 self SelfParam FileId(0) 47..51 47..51 SelfParam 899 self SelfParam FileId(0) 47..51 47..51
910 900
911 FileId(0) 71..75 Other Read 901 FileId(0) 71..75 Read
912 FileId(0) 152..156 Other Read 902 FileId(0) 152..156 Read
913 "#]], 903 "#]],
914 ); 904 );
915 } 905 }
@@ -927,9 +917,9 @@ impl Foo {
927} 917}
928"#, 918"#,
929 expect![[r#" 919 expect![[r#"
930 self SelfParam FileId(0) 47..51 47..51 SelfParam 920 self SelfParam FileId(0) 47..51 47..51
931 921
932 FileId(0) 63..67 Other Read 922 FileId(0) 63..67 Read
933 "#]], 923 "#]],
934 ); 924 );
935 } 925 }
@@ -945,7 +935,7 @@ impl Foo {
945 let mut actual = String::new(); 935 let mut actual = String::new();
946 { 936 {
947 let decl = refs.declaration; 937 let decl = refs.declaration;
948 format_to!(actual, "{} {:?}", decl.nav.debug_render(), decl.kind); 938 format_to!(actual, "{}", decl.nav.debug_render());
949 if let Some(access) = decl.access { 939 if let Some(access) = decl.access {
950 format_to!(actual, " {:?}", access) 940 format_to!(actual, " {:?}", access)
951 } 941 }
@@ -953,9 +943,9 @@ impl Foo {
953 } 943 }
954 944
955 for (file_id, references) in refs.references { 945 for (file_id, references) in refs.references {
956 for r in references { 946 for (range, access) in references {
957 format_to!(actual, "{:?} {:?} {:?}", file_id, r.range, r.kind); 947 format_to!(actual, "{:?} {:?}", file_id, range);
958 if let Some(access) = r.access { 948 if let Some(access) = access {
959 format_to!(actual, " {:?}", access); 949 format_to!(actual, " {:?}", access);
960 } 950 }
961 actual += "\n"; 951 actual += "\n";
@@ -976,13 +966,13 @@ fn foo<'a, 'b: 'a>(x: &'a$0 ()) -> &'a () where &'a (): Foo<'a> {
976} 966}
977"#, 967"#,
978 expect![[r#" 968 expect![[r#"
979 'a LifetimeParam FileId(0) 55..57 55..57 Lifetime 969 'a LifetimeParam FileId(0) 55..57 55..57
980 970
981 FileId(0) 63..65 Lifetime 971 FileId(0) 63..65
982 FileId(0) 71..73 Lifetime 972 FileId(0) 71..73
983 FileId(0) 82..84 Lifetime 973 FileId(0) 82..84
984 FileId(0) 95..97 Lifetime 974 FileId(0) 95..97
985 FileId(0) 106..108 Lifetime 975 FileId(0) 106..108
986 "#]], 976 "#]],
987 ); 977 );
988 } 978 }
@@ -994,10 +984,10 @@ fn foo<'a, 'b: 'a>(x: &'a$0 ()) -> &'a () where &'a (): Foo<'a> {
994type Foo<'a, T> where T: 'a$0 = &'a T; 984type Foo<'a, T> where T: 'a$0 = &'a T;
995"#, 985"#,
996 expect![[r#" 986 expect![[r#"
997 'a LifetimeParam FileId(0) 9..11 9..11 Lifetime 987 'a LifetimeParam FileId(0) 9..11 9..11
998 988
999 FileId(0) 25..27 Lifetime 989 FileId(0) 25..27
1000 FileId(0) 31..33 Lifetime 990 FileId(0) 31..33
1001 "#]], 991 "#]],
1002 ); 992 );
1003 } 993 }
@@ -1016,11 +1006,11 @@ impl<'a> Foo<'a> for &'a () {
1016} 1006}
1017"#, 1007"#,
1018 expect![[r#" 1008 expect![[r#"
1019 'a LifetimeParam FileId(0) 47..49 47..49 Lifetime 1009 'a LifetimeParam FileId(0) 47..49 47..49
1020 1010
1021 FileId(0) 55..57 Lifetime 1011 FileId(0) 55..57
1022 FileId(0) 64..66 Lifetime 1012 FileId(0) 64..66
1023 FileId(0) 89..91 Lifetime 1013 FileId(0) 89..91
1024 "#]], 1014 "#]],
1025 ); 1015 );
1026 } 1016 }
@@ -1036,9 +1026,9 @@ fn main() {
1036} 1026}
1037"#, 1027"#,
1038 expect![[r#" 1028 expect![[r#"
1039 a Local FileId(0) 59..60 59..60 Other 1029 a Local FileId(0) 59..60 59..60
1040 1030
1041 FileId(0) 80..81 Other Read 1031 FileId(0) 80..81 Read
1042 "#]], 1032 "#]],
1043 ); 1033 );
1044 } 1034 }
@@ -1054,9 +1044,9 @@ fn main() {
1054} 1044}
1055"#, 1045"#,
1056 expect![[r#" 1046 expect![[r#"
1057 a Local FileId(0) 59..60 59..60 Other 1047 a Local FileId(0) 59..60 59..60
1058 1048
1059 FileId(0) 80..81 Other Read 1049 FileId(0) 80..81 Read
1060 "#]], 1050 "#]],
1061 ); 1051 );
1062 } 1052 }
@@ -1075,10 +1065,10 @@ fn foo<'a>() -> &'a () {
1075} 1065}
1076"#, 1066"#,
1077 expect![[r#" 1067 expect![[r#"
1078 'a Label FileId(0) 29..32 29..31 Lifetime 1068 'a Label FileId(0) 29..32 29..31
1079 1069
1080 FileId(0) 80..82 Lifetime 1070 FileId(0) 80..82
1081 FileId(0) 108..110 Lifetime 1071 FileId(0) 108..110
1082 "#]], 1072 "#]],
1083 ); 1073 );
1084 } 1074 }
@@ -1092,9 +1082,9 @@ fn foo<const FOO$0: usize>() -> usize {
1092} 1082}
1093"#, 1083"#,
1094 expect![[r#" 1084 expect![[r#"
1095 FOO ConstParam FileId(0) 7..23 13..16 Other 1085 FOO ConstParam FileId(0) 7..23 13..16
1096 1086
1097 FileId(0) 42..45 Other 1087 FileId(0) 42..45
1098 "#]], 1088 "#]],
1099 ); 1089 );
1100 } 1090 }
@@ -1108,9 +1098,9 @@ trait Foo {
1108} 1098}
1109"#, 1099"#,
1110 expect![[r#" 1100 expect![[r#"
1111 Self TypeParam FileId(0) 6..9 6..9 Other 1101 Self TypeParam FileId(0) 6..9 6..9
1112 1102
1113 FileId(0) 26..30 Other 1103 FileId(0) 26..30
1114 "#]], 1104 "#]],
1115 ); 1105 );
1116 } 1106 }
@@ -1131,9 +1121,9 @@ impl Foo {
1131 1121
1132"#, 1122"#,
1133 expect![[r#" 1123 expect![[r#"
1134 Bar Variant FileId(0) 11..16 11..14 Other 1124 Bar Variant FileId(0) 11..16 11..14
1135 1125
1136 FileId(0) 89..92 Other 1126 FileId(0) 89..92
1137 "#]], 1127 "#]],
1138 ); 1128 );
1139 } 1129 }