mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
Track labels in the HIR
This commit is contained in:
parent
fd1fcf2c2e
commit
262b9c3982
9 changed files with 167 additions and 68 deletions
|
@ -15,7 +15,7 @@ use itertools::Itertools;
|
|||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use syntax::{
|
||||
algo::find_node_at_offset,
|
||||
ast::{self, GenericParamsOwner},
|
||||
ast::{self, GenericParamsOwner, LoopBodyOwner},
|
||||
match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize,
|
||||
};
|
||||
|
||||
|
@ -25,8 +25,8 @@ use crate::{
|
|||
diagnostics::Diagnostic,
|
||||
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
|
||||
source_analyzer::{resolve_hir_path, SourceAnalyzer},
|
||||
AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, LifetimeParam, Local,
|
||||
MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
|
||||
AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, Label, LifetimeParam,
|
||||
Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
|
||||
VariantDef,
|
||||
};
|
||||
|
||||
|
@ -182,6 +182,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
|||
self.imp.resolve_lifetime_param(lifetime)
|
||||
}
|
||||
|
||||
pub fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
|
||||
self.imp.resolve_label(lifetime)
|
||||
}
|
||||
|
||||
pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
|
||||
self.imp.type_of_expr(expr)
|
||||
}
|
||||
|
@ -425,6 +429,28 @@ impl<'db> SemanticsImpl<'db> {
|
|||
ToDef::to_def(self, src)
|
||||
}
|
||||
|
||||
fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
|
||||
let text = lifetime.text();
|
||||
let label = lifetime.syntax().ancestors().find_map(|syn| {
|
||||
let label = match_ast! {
|
||||
match syn {
|
||||
ast::ForExpr(it) => it.label(),
|
||||
ast::WhileExpr(it) => it.label(),
|
||||
ast::LoopExpr(it) => it.label(),
|
||||
ast::EffectExpr(it) => it.label(),
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
label.filter(|l| {
|
||||
l.lifetime()
|
||||
.and_then(|lt| lt.lifetime_ident_token())
|
||||
.map_or(false, |lt| lt.text() == text)
|
||||
})
|
||||
})?;
|
||||
let src = self.find_file(label.syntax().clone()).with_value(label);
|
||||
ToDef::to_def(self, src)
|
||||
}
|
||||
|
||||
fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
|
||||
self.analyze(expr.syntax()).type_of_expr(self.db, expr)
|
||||
}
|
||||
|
@ -720,6 +746,7 @@ to_def_impls![
|
|||
(crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
|
||||
(crate::MacroDef, ast::MacroRules, macro_rules_to_def),
|
||||
(crate::Local, ast::IdentPat, bind_pat_to_def),
|
||||
(crate::Label, ast::Label, label_to_def),
|
||||
];
|
||||
|
||||
fn find_root(node: &SyntaxNode) -> SyntaxNode {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue