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,
};
diagnostics::Diagnostic,
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
source_analyzer::{resolve_hir_path, SourceAnalyzer},
- AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, LifetimeParam, Local,
- MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
- VariantDef,
+ AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label,
+ LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type,
+ TypeAlias, TypeParam, VariantDef,
};
#[derive(Debug, Clone, PartialEq, Eq)]
Local(Local),
/// A generic parameter
TypeParam(TypeParam),
- SelfType(ImplDef),
+ ConstParam(ConstParam),
+ SelfType(Impl),
Macro(MacroDef),
AssocItem(AssocItem),
}
Some(TypeNs::BuiltinType(*builtin))
}
PathResolution::Def(ModuleDef::Const(_))
- | PathResolution::Def(ModuleDef::EnumVariant(_))
+ | PathResolution::Def(ModuleDef::Variant(_))
| PathResolution::Def(ModuleDef::Function(_))
| PathResolution::Def(ModuleDef::Module(_))
| PathResolution::Def(ModuleDef::Static(_))
PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
Some(TypeNs::TypeAliasId((*alias).into()))
}
- PathResolution::Local(_) | PathResolution::Macro(_) => None,
+ PathResolution::Local(_) | PathResolution::Macro(_) | PathResolution::ConstParam(_) => {
+ None
+ }
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
PathResolution::AssocItem(AssocItem::Const(_))
self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
}
- // FIXME: Replace the SyntaxToken with a typed ast Node/Token
- pub fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
- self.imp.resolve_lifetime_param(lifetime_token)
+ pub fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
+ 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> {
.kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
}
- // FIXME: Replace the SyntaxToken with a typed ast Node/Token
- fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
- if lifetime_token.kind() != syntax::SyntaxKind::LIFETIME {
- return None;
- }
- let lifetime_text = lifetime_token.text();
- let lifetime_param = lifetime_token.parent().ancestors().find_map(|syn| {
+ fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
+ let text = lifetime.text();
+ let lifetime_param = lifetime.syntax().ancestors().find_map(|syn| {
let gpl = match_ast! {
match syn {
ast::Fn(it) => it.generic_param_list()?,
}
};
gpl.lifetime_params()
- .find(|tp| tp.lifetime_token().as_ref().map(|lt| lt.text()) == Some(lifetime_text))
+ .find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()) == Some(text))
})?;
let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param);
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)
}
(crate::Enum, ast::Enum, enum_to_def),
(crate::Union, ast::Union, union_to_def),
(crate::Trait, ast::Trait, trait_to_def),
- (crate::ImplDef, ast::Impl, impl_to_def),
+ (crate::Impl, ast::Impl, impl_to_def),
(crate::TypeAlias, ast::TypeAlias, type_alias_to_def),
(crate::Const, ast::Const, const_to_def),
(crate::Static, ast::Static, static_to_def),
(crate::Function, ast::Fn, fn_to_def),
(crate::Field, ast::RecordField, record_field_to_def),
(crate::Field, ast::TupleField, tuple_field_to_def),
- (crate::EnumVariant, ast::Variant, enum_variant_to_def),
+ (crate::Variant, ast::Variant, enum_variant_to_def),
(crate::TypeParam, ast::TypeParam, type_param_to_def),
(crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
+ (crate::ConstParam, ast::ConstParam, const_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 {