@@ -15,7 +15,7 @@ use itertools::Itertools;
1515use rustc_hash:: { FxHashMap , FxHashSet } ;
1616use syntax:: {
1717 algo:: find_node_at_offset,
18- ast:: { self , GenericParamsOwner } ,
18+ ast:: { self , GenericParamsOwner , LoopBodyOwner } ,
1919 match_ast, AstNode , SyntaxNode , SyntaxToken , TextSize ,
2020} ;
2121
@@ -25,8 +25,8 @@ use crate::{
2525 diagnostics:: Diagnostic ,
2626 semantics:: source_to_def:: { ChildContainer , SourceToDefCache , SourceToDefCtx } ,
2727 source_analyzer:: { resolve_hir_path, SourceAnalyzer } ,
28- AssocItem , Callable , Crate , Field , Function , HirFileId , Impl , InFile , LifetimeParam , Local ,
29- MacroDef , Module , ModuleDef , Name , Path , ScopeDef , Trait , Type , TypeAlias , TypeParam ,
28+ AssocItem , Callable , Crate , Field , Function , HirFileId , Impl , InFile , Label , LifetimeParam ,
29+ Local , MacroDef , Module , ModuleDef , Name , Path , ScopeDef , Trait , Type , TypeAlias , TypeParam ,
3030 VariantDef ,
3131} ;
3232
@@ -182,6 +182,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
182182 self . imp . resolve_lifetime_param ( lifetime)
183183 }
184184
185+ pub fn resolve_label ( & self , lifetime : & ast:: Lifetime ) -> Option < Label > {
186+ self . imp . resolve_label ( lifetime)
187+ }
188+
185189 pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
186190 self . imp . type_of_expr ( expr)
187191 }
@@ -425,6 +429,28 @@ impl<'db> SemanticsImpl<'db> {
425429 ToDef :: to_def ( self , src)
426430 }
427431
432+ fn resolve_label ( & self , lifetime : & ast:: Lifetime ) -> Option < Label > {
433+ let text = lifetime. text ( ) ;
434+ let label = lifetime. syntax ( ) . ancestors ( ) . find_map ( |syn| {
435+ let label = match_ast ! {
436+ match syn {
437+ ast:: ForExpr ( it) => it. label( ) ,
438+ ast:: WhileExpr ( it) => it. label( ) ,
439+ ast:: LoopExpr ( it) => it. label( ) ,
440+ ast:: EffectExpr ( it) => it. label( ) ,
441+ _ => None ,
442+ }
443+ } ;
444+ label. filter ( |l| {
445+ l. lifetime ( )
446+ . and_then ( |lt| lt. lifetime_ident_token ( ) )
447+ . map_or ( false , |lt| lt. text ( ) == text)
448+ } )
449+ } ) ?;
450+ let src = self . find_file ( label. syntax ( ) . clone ( ) ) . with_value ( label) ;
451+ ToDef :: to_def ( self , src)
452+ }
453+
428454 fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
429455 self . analyze ( expr. syntax ( ) ) . type_of_expr ( self . db , expr)
430456 }
@@ -720,6 +746,7 @@ to_def_impls![
720746 ( crate :: LifetimeParam , ast:: LifetimeParam , lifetime_param_to_def) ,
721747 ( crate :: MacroDef , ast:: MacroRules , macro_rules_to_def) ,
722748 ( crate :: Local , ast:: IdentPat , bind_pat_to_def) ,
749+ ( crate :: Label , ast:: Label , label_to_def) ,
723750] ;
724751
725752fn find_root ( node : & SyntaxNode ) -> SyntaxNode {
0 commit comments