diff options
Diffstat (limited to 'crates/hir/src/semantics.rs')
-rw-r--r-- | crates/hir/src/semantics.rs | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 25ebf73d8..67cd16e31 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -15,7 +15,7 @@ use itertools::Itertools; | |||
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
16 | use syntax::{ | 16 | use syntax::{ |
17 | algo::find_node_at_offset, | 17 | algo::find_node_at_offset, |
18 | ast::{self, GenericParamsOwner}, | 18 | ast::{self, GenericParamsOwner, LoopBodyOwner}, |
19 | match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize, | 19 | match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize, |
20 | }; | 20 | }; |
21 | 21 | ||
@@ -25,8 +25,8 @@ use crate::{ | |||
25 | diagnostics::Diagnostic, | 25 | diagnostics::Diagnostic, |
26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 26 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 27 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, |
28 | AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, LifetimeParam, Local, | 28 | AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, Label, LifetimeParam, |
29 | MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, | 29 | Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, |
30 | VariantDef, | 30 | VariantDef, |
31 | }; | 31 | }; |
32 | 32 | ||
@@ -182,6 +182,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
182 | self.imp.resolve_lifetime_param(lifetime) | 182 | self.imp.resolve_lifetime_param(lifetime) |
183 | } | 183 | } |
184 | 184 | ||
185 | pub fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> { | ||
186 | self.imp.resolve_label(lifetime) | ||
187 | } | ||
188 | |||
185 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 189 | pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
186 | self.imp.type_of_expr(expr) | 190 | self.imp.type_of_expr(expr) |
187 | } | 191 | } |
@@ -425,6 +429,28 @@ impl<'db> SemanticsImpl<'db> { | |||
425 | ToDef::to_def(self, src) | 429 | ToDef::to_def(self, src) |
426 | } | 430 | } |
427 | 431 | ||
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 | |||
428 | fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { | 454 | fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { |
429 | self.analyze(expr.syntax()).type_of_expr(self.db, expr) | 455 | self.analyze(expr.syntax()).type_of_expr(self.db, expr) |
430 | } | 456 | } |
@@ -720,6 +746,7 @@ to_def_impls![ | |||
720 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), | 746 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), |
721 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), | 747 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), |
722 | (crate::Local, ast::IdentPat, bind_pat_to_def), | 748 | (crate::Local, ast::IdentPat, bind_pat_to_def), |
749 | (crate::Label, ast::Label, label_to_def), | ||
723 | ]; | 750 | ]; |
724 | 751 | ||
725 | fn find_root(node: &SyntaxNode) -> SyntaxNode { | 752 | fn find_root(node: &SyntaxNode) -> SyntaxNode { |