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.rs | 83 |
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()), + } + } } |