@@ -130,6 +130,8 @@ pub(crate) fn find_all_refs(
130130 kind = ReferenceKind :: FieldShorthandForLocal ;
131131 }
132132 }
133+ } else if let Definition :: LifetimeParam ( _) = def {
134+ kind = ReferenceKind :: Lifetime ;
133135 } ;
134136
135137 let declaration = Declaration { nav, kind, access : decl_access ( & def, & syntax, decl_range) } ;
@@ -148,11 +150,29 @@ fn find_name(
148150 let range = name. syntax ( ) . text_range ( ) ;
149151 return Some ( RangeInfo :: new ( range, def) ) ;
150152 }
151- let name_ref =
152- sema. find_node_at_offset_with_descend :: < ast:: NameRef > ( & syntax, position. offset ) ?;
153- let def = NameRefClass :: classify ( sema, & name_ref) ?. referenced ( sema. db ) ;
154- let range = name_ref. syntax ( ) . text_range ( ) ;
155- Some ( RangeInfo :: new ( range, def) )
153+
154+ let ( text_range, def) = if let Some ( lifetime) =
155+ sema. find_node_at_offset_with_descend :: < ast:: Lifetime > ( & syntax, position. offset )
156+ {
157+ if let Some ( def) = NameRefClass :: classify_lifetime ( sema, & lifetime)
158+ . map ( |class| NameRefClass :: referenced ( class, sema. db ) )
159+ {
160+ ( lifetime. syntax ( ) . text_range ( ) , def)
161+ } else {
162+ (
163+ lifetime. syntax ( ) . text_range ( ) ,
164+ NameClass :: classify_lifetime ( sema, & lifetime) ?. referenced_or_defined ( sema. db ) ,
165+ )
166+ }
167+ } else {
168+ let name_ref =
169+ sema. find_node_at_offset_with_descend :: < ast:: NameRef > ( & syntax, position. offset ) ?;
170+ (
171+ name_ref. syntax ( ) . text_range ( ) ,
172+ NameRefClass :: classify ( sema, & name_ref) ?. referenced ( sema. db ) ,
173+ )
174+ } ;
175+ Some ( RangeInfo :: new ( text_range, def) )
156176}
157177
158178fn decl_access ( def : & Definition , syntax : & SyntaxNode , range : TextRange ) -> Option < ReferenceAccess > {
@@ -1005,4 +1025,65 @@ impl Foo {
10051025 }
10061026 expect. assert_eq ( & actual)
10071027 }
1028+
1029+ #[ test]
1030+ fn test_find_lifetimes_function ( ) {
1031+ check (
1032+ r#"
1033+ trait Foo<'a> {}
1034+ impl<'a> Foo<'a> for &'a () {}
1035+ fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> {
1036+ fn bar<'a>(_: &'a ()) {}
1037+ x
1038+ }
1039+ "# ,
1040+ expect ! [ [ r#"
1041+ 'a LIFETIME_PARAM FileId(0) 55..57 55..57 Lifetime
1042+
1043+ FileId(0) 63..65 Lifetime
1044+ FileId(0) 71..73 Lifetime
1045+ FileId(0) 82..84 Lifetime
1046+ FileId(0) 95..97 Lifetime
1047+ FileId(0) 106..108 Lifetime
1048+ "# ] ] ,
1049+ ) ;
1050+ }
1051+
1052+ #[ test]
1053+ fn test_find_lifetimes_type_alias ( ) {
1054+ check (
1055+ r#"
1056+ type Foo<'a, T> where T: 'a<|> = &'a T;
1057+ "# ,
1058+ expect ! [ [ r#"
1059+ 'a LIFETIME_PARAM FileId(0) 9..11 9..11 Lifetime
1060+
1061+ FileId(0) 25..27 Lifetime
1062+ FileId(0) 31..33 Lifetime
1063+ "# ] ] ,
1064+ ) ;
1065+ }
1066+
1067+ #[ test]
1068+ fn test_find_lifetimes_trait_impl ( ) {
1069+ check (
1070+ r#"
1071+ trait Foo<'a> {
1072+ fn foo() -> &'a ();
1073+ }
1074+ impl<'a> Foo<'a> for &'a () {
1075+ fn foo() -> &'a<|> () {
1076+ unimplemented!()
1077+ }
1078+ }
1079+ "# ,
1080+ expect ! [ [ r#"
1081+ 'a LIFETIME_PARAM FileId(0) 47..49 47..49 Lifetime
1082+
1083+ FileId(0) 55..57 Lifetime
1084+ FileId(0) 64..66 Lifetime
1085+ FileId(0) 89..91 Lifetime
1086+ "# ] ] ,
1087+ ) ;
1088+ }
10081089}
0 commit comments