Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/semantics/source_to_def.rs')
-rw-r--r--crates/hir/src/semantics/source_to_def.rs83
1 files changed, 41 insertions, 42 deletions
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index d222c3dc7e..a9a779a287 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -88,13 +88,14 @@
use either::Either;
use hir_def::{
AdtId, BlockId, BuiltinDeriveImplId, ConstId, ConstParamId, DefWithBodyId, EnumId,
- EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, GenericDefId, GenericParamId,
- ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
- TypeParamId, UnionId, UseId, VariantId,
+ EnumVariantId, ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, FieldId, FunctionId,
+ GenericDefId, GenericParamId, ImplId, LifetimeParamId, Lookup, MacroId, ModuleId, StaticId,
+ StructId, TraitId, TypeAliasId, TypeParamId, UnionId, UseId, VariantId,
dyn_map::{
DynMap,
keys::{self, Key},
},
+ expr_store::{Body, ExpressionStore},
hir::{BindingId, Expr, LabelId},
nameres::{block_def_map, crate_def_map},
};
@@ -334,8 +335,8 @@ impl SourceToDefCtx<'_, '_> {
_ => None,
})
.position(|it| it == *src.value)?;
- let container = self.find_pat_or_label_container(src.syntax_ref())?;
- let source_map = self.db.body_with_source_map(container).1;
+ let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?;
+ let (_, source_map) = ExpressionStore::with_source_map(self.db, container);
let expr = source_map.node_expr(src.with_value(&ast::Expr::AsmExpr(asm)))?.as_expr()?;
Some(InlineAsmOperand { owner: container, expr, index })
}
@@ -343,13 +344,13 @@ impl SourceToDefCtx<'_, '_> {
pub(super) fn bind_pat_to_def(
&mut self,
src: InFile<&ast::IdentPat>,
- ) -> Option<(DefWithBodyId, BindingId)> {
- let container = self.find_pat_or_label_container(src.syntax_ref())?;
- let (body, source_map) = self.db.body_with_source_map(container);
+ ) -> Option<(ExpressionStoreOwnerId, BindingId)> {
+ let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?;
+ let (store, source_map) = ExpressionStore::with_source_map(self.db, container);
let src = src.cloned().map(ast::Pat::from);
let pat_id = source_map.node_pat(src.as_ref())?;
// the pattern could resolve to a constant, verify that this is not the case
- if let crate::Pat::Bind { id, .. } = body[pat_id.as_pat()?] {
+ if let crate::Pat::Bind { id, .. } = store[pat_id.as_pat()?] {
Some((container, id))
} else {
None
@@ -359,17 +360,19 @@ impl SourceToDefCtx<'_, '_> {
&mut self,
src: InFile<&ast::SelfParam>,
) -> Option<(DefWithBodyId, BindingId)> {
- let container = self.find_pat_or_label_container(src.syntax_ref())?;
- let body = self.db.body(container);
+ let container = self
+ .find_container(src.syntax_ref())?
+ .as_expression_store_owner()?
+ .as_def_with_body()?;
+ let body = Body::of(self.db, container);
Some((container, body.self_param?))
}
pub(super) fn label_to_def(
&mut self,
src: InFile<&ast::Label>,
- ) -> Option<(DefWithBodyId, LabelId)> {
- let container = self.find_pat_or_label_container(src.syntax_ref())?;
- let source_map = self.db.body_with_source_map(container).1;
-
+ ) -> Option<(ExpressionStoreOwnerId, LabelId)> {
+ let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?;
+ let (_, source_map) = ExpressionStore::with_source_map(self.db, container);
let label_id = source_map.node_label(src)?;
Some((container, label_id))
}
@@ -377,13 +380,14 @@ impl SourceToDefCtx<'_, '_> {
pub(super) fn label_ref_to_def(
&mut self,
src: InFile<&ast::Lifetime>,
- ) -> Option<(DefWithBodyId, LabelId)> {
+ ) -> Option<(ExpressionStoreOwnerId, LabelId)> {
let break_or_continue = ast::Expr::cast(src.value.syntax().parent()?)?;
- let container = self.find_pat_or_label_container(src.syntax_ref())?;
- let (body, source_map) = self.db.body_with_source_map(container);
+ let container = self.find_container(src.syntax_ref())?.as_expression_store_owner()?;
+ let (store, source_map) = ExpressionStore::with_source_map(self.db, container);
let break_or_continue =
source_map.node_expr(src.with_value(&break_or_continue))?.as_expr()?;
- let (Expr::Break { label, .. } | Expr::Continue { label }) = body[break_or_continue] else {
+ let (Expr::Break { label, .. } | Expr::Continue { label }) = store[break_or_continue]
+ else {
return None;
};
Some((container, label?))
@@ -557,29 +561,6 @@ impl SourceToDefCtx<'_, '_> {
})
}
- // FIXME: Remove this when we do inference in signatures
- fn find_pat_or_label_container(&mut self, src: InFile<&SyntaxNode>) -> Option<DefWithBodyId> {
- self.parent_ancestors_with_macros(src, |this, InFile { file_id, value }, _| {
- let item = match ast::Item::cast(value.clone()) {
- Some(it) => it,
- None => {
- let variant = ast::Variant::cast(value)?;
- return this
- .enum_variant_to_def(InFile::new(file_id, &variant))
- .map(Into::into);
- }
- };
- match &item {
- ast::Item::Fn(it) => this.fn_to_def(InFile::new(file_id, it)).map(Into::into),
- ast::Item::Const(it) => this.const_to_def(InFile::new(file_id, it)).map(Into::into),
- ast::Item::Static(it) => {
- this.static_to_def(InFile::new(file_id, it)).map(Into::into)
- }
- _ => None,
- }
- })
- }
-
/// Skips the attributed item that caused the macro invocation we are climbing up
fn parent_ancestors_with_macros<T>(
&mut self,
@@ -756,4 +737,22 @@ impl ChildContainer {
ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id),
}
}
+
+ pub(crate) fn as_expression_store_owner(self) -> Option<ExpressionStoreOwnerId> {
+ match self {
+ ChildContainer::DefWithBodyId(it) => Some(it.into()),
+ ChildContainer::ModuleId(_) => None,
+ ChildContainer::TraitId(it) => {
+ Some(ExpressionStoreOwnerId::Signature(GenericDefId::TraitId(it)))
+ }
+ ChildContainer::EnumId(it) => {
+ Some(ExpressionStoreOwnerId::Signature(GenericDefId::AdtId(it.into())))
+ }
+ ChildContainer::ImplId(it) => {
+ Some(ExpressionStoreOwnerId::Signature(GenericDefId::ImplId(it)))
+ }
+ ChildContainer::VariantId(_) => None,
+ ChildContainer::GenericDefId(it) => Some(it.into()),
+ }
+ }
}