@@ -13,16 +13,21 @@ use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo};
1313use hir_ty:: associated_type_shorthand_candidates;
1414use itertools:: Itertools ;
1515use rustc_hash:: { FxHashMap , FxHashSet } ;
16- use syntax:: { algo:: find_node_at_offset, ast, AstNode , SyntaxNode , SyntaxToken , TextSize } ;
16+ use syntax:: {
17+ algo:: find_node_at_offset,
18+ ast:: { self , GenericParamsOwner } ,
19+ match_ast, AstNode , SyntaxNode , SyntaxToken , TextSize ,
20+ } ;
1721
1822use crate :: {
1923 code_model:: Access ,
2024 db:: HirDatabase ,
2125 diagnostics:: Diagnostic ,
2226 semantics:: source_to_def:: { ChildContainer , SourceToDefCache , SourceToDefCtx } ,
2327 source_analyzer:: { resolve_hir_path, SourceAnalyzer } ,
24- AssocItem , Callable , Crate , Field , Function , HirFileId , ImplDef , InFile , Local , MacroDef ,
25- Module , ModuleDef , Name , Path , ScopeDef , Trait , Type , TypeAlias , TypeParam , VariantDef ,
28+ AssocItem , Callable , Crate , Field , Function , HirFileId , ImplDef , InFile , LifetimeParam , Local ,
29+ MacroDef , Module , ModuleDef , Name , Path , ScopeDef , Trait , Type , TypeAlias , TypeParam ,
30+ VariantDef ,
2631} ;
2732
2833#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -173,6 +178,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
173178 self . imp . descend_node_at_offset ( node, offset) . find_map ( N :: cast)
174179 }
175180
181+ // FIXME: Replace the SyntaxToken with a typed ast Node/Token
182+ pub fn resolve_lifetime_param ( & self , lifetime_token : & SyntaxToken ) -> Option < LifetimeParam > {
183+ self . imp . resolve_lifetime_param ( lifetime_token)
184+ }
185+
176186 pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
177187 self . imp . type_of_expr ( expr)
178188 }
@@ -392,16 +402,44 @@ impl<'db> SemanticsImpl<'db> {
392402 . kmerge_by ( |node1, node2| node1. text_range ( ) . len ( ) < node2. text_range ( ) . len ( ) )
393403 }
394404
405+ // FIXME: Replace the SyntaxToken with a typed ast Node/Token
406+ fn resolve_lifetime_param ( & self , lifetime_token : & SyntaxToken ) -> Option < LifetimeParam > {
407+ if lifetime_token. kind ( ) != syntax:: SyntaxKind :: LIFETIME {
408+ return None ;
409+ }
410+ let lifetime_text = lifetime_token. text ( ) ;
411+ let lifetime_param = lifetime_token. parent ( ) . ancestors ( ) . find_map ( |syn| {
412+ let gpl = match_ast ! {
413+ match syn {
414+ ast:: Fn ( it) => it. generic_param_list( ) ?,
415+ ast:: TypeAlias ( it) => it. generic_param_list( ) ?,
416+ ast:: Struct ( it) => it. generic_param_list( ) ?,
417+ ast:: Enum ( it) => it. generic_param_list( ) ?,
418+ ast:: Union ( it) => it. generic_param_list( ) ?,
419+ ast:: Trait ( it) => it. generic_param_list( ) ?,
420+ ast:: Impl ( it) => it. generic_param_list( ) ?,
421+ ast:: WherePred ( it) => it. generic_param_list( ) ?,
422+ ast:: ForType ( it) => it. generic_param_list( ) ?,
423+ _ => return None ,
424+ }
425+ } ;
426+ gpl. lifetime_params ( )
427+ . find ( |tp| tp. lifetime_token ( ) . as_ref ( ) . map ( |lt| lt. text ( ) ) == Some ( lifetime_text) )
428+ } ) ?;
429+ let src = self . find_file ( lifetime_param. syntax ( ) . clone ( ) ) . with_value ( lifetime_param) ;
430+ ToDef :: to_def ( self , src)
431+ }
432+
395433 fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
396- self . analyze ( expr. syntax ( ) ) . type_of_expr ( self . db , & expr)
434+ self . analyze ( expr. syntax ( ) ) . type_of_expr ( self . db , expr)
397435 }
398436
399437 fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < Type > {
400- self . analyze ( pat. syntax ( ) ) . type_of_pat ( self . db , & pat)
438+ self . analyze ( pat. syntax ( ) ) . type_of_pat ( self . db , pat)
401439 }
402440
403441 fn type_of_self ( & self , param : & ast:: SelfParam ) -> Option < Type > {
404- self . analyze ( param. syntax ( ) ) . type_of_self ( self . db , & param)
442+ self . analyze ( param. syntax ( ) ) . type_of_self ( self . db , param)
405443 }
406444
407445 fn resolve_method_call ( & self , call : & ast:: MethodCallExpr ) -> Option < FunctionId > {
@@ -684,6 +722,7 @@ to_def_impls![
684722 ( crate :: Field , ast:: TupleField , tuple_field_to_def) ,
685723 ( crate :: EnumVariant , ast:: Variant , enum_variant_to_def) ,
686724 ( crate :: TypeParam , ast:: TypeParam , type_param_to_def) ,
725+ ( crate :: LifetimeParam , ast:: LifetimeParam , lifetime_param_to_def) ,
687726 ( crate :: MacroDef , ast:: MacroCall , macro_call_to_def) , // this one is dubious, not all calls are macros
688727 ( crate :: Local , ast:: IdentPat , bind_pat_to_def) ,
689728] ;
0 commit comments