Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/lib.rs')
| -rw-r--r-- | crates/hir-def/src/lib.rs | 76 |
1 files changed, 60 insertions, 16 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 98cff54cc2..44dd0a7b38 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -89,8 +89,8 @@ use crate::{ builtin_type::BuiltinType, data::adt::VariantData, item_tree::{ - Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, ModItem, - Static, Struct, Trait, TraitAlias, TypeAlias, Union, + Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, Static, + Struct, Trait, TraitAlias, TypeAlias, Union, }, }; @@ -476,20 +476,55 @@ impl_from!( for ModuleDefId ); -// FIXME: make this a DefWithBodyId +/// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and +/// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct AnonymousConstId(InternId); impl_intern_key!(AnonymousConstId); +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +pub enum TypeOwnerId { + ModuleId(ModuleId), + DefWithBodyId(DefWithBodyId), + GenericDefId(GenericDefId), +} + +impl TypeOwnerId { + fn as_generic_def_id(self) -> Option<GenericDefId> { + match self { + TypeOwnerId::ModuleId(_) => None, + TypeOwnerId::DefWithBodyId(x) => x.as_generic_def_id(), + TypeOwnerId::GenericDefId(x) => Some(x), + } + } +} + +impl_from!(ModuleId, DefWithBodyId(FunctionId, ConstId, StaticId), GenericDefId(AdtId, TypeAliasId, ImplId) for TypeOwnerId); + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +pub struct InTypeConstId(InternId); +type InTypeConstLoc = (AstId<ast::Expr>, TypeOwnerId); +impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const); + +impl InTypeConstId { + pub fn source(&self, db: &dyn db::DefDatabase) -> ast::Expr { + let src = self.lookup(db).0; + let file_id = src.file_id; + let root = &db.parse_or_expand(file_id); + db.ast_id_map(file_id).get(src.value).to_node(root) + } +} + /// A constant, which might appears as a const item, an annonymous const block in expressions /// or patterns, or as a constant in types with const generics. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum GeneralConstId { ConstId(ConstId), AnonymousConstId(AnonymousConstId), + InTypeConstId(InTypeConstId), } -impl_from!(ConstId, AnonymousConstId for GeneralConstId); +impl_from!(ConstId, AnonymousConstId, InTypeConstId for GeneralConstId); impl GeneralConstId { pub fn generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId> { @@ -499,6 +534,10 @@ impl GeneralConstId { let (parent, _) = db.lookup_intern_anonymous_const(x); parent.as_generic_def_id() } + GeneralConstId::InTypeConstId(x) => { + let (_, parent) = x.lookup(db); + parent.as_generic_def_id() + } } } @@ -512,6 +551,7 @@ impl GeneralConstId { .unwrap_or("_") .to_owned(), GeneralConstId::AnonymousConstId(id) => format!("{{anonymous const {id:?}}}"), + GeneralConstId::InTypeConstId(id) => format!("{{in type const {id:?}}}"), } } } @@ -522,10 +562,11 @@ pub enum DefWithBodyId { FunctionId(FunctionId), StaticId(StaticId), ConstId(ConstId), + InTypeConstId(InTypeConstId), VariantId(EnumVariantId), } -impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); +impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId); impl From<EnumVariantId> for DefWithBodyId { fn from(id: EnumVariantId) -> Self { @@ -540,6 +581,9 @@ impl DefWithBodyId { DefWithBodyId::StaticId(_) => None, DefWithBodyId::ConstId(c) => Some(c.into()), DefWithBodyId::VariantId(c) => Some(c.into()), + // FIXME: stable rust doesn't allow generics in constants, but we should + // use `TypeOwnerId::as_generic_def_id` when it does. + DefWithBodyId::InTypeConstId(_) => None, } } } @@ -734,24 +778,24 @@ impl HasModule for MacroId { } } -impl HasModule for DefWithBodyId { +impl HasModule for TypeOwnerId { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { match self { - DefWithBodyId::FunctionId(it) => it.lookup(db).module(db), - DefWithBodyId::StaticId(it) => it.lookup(db).module(db), - DefWithBodyId::ConstId(it) => it.lookup(db).module(db), - DefWithBodyId::VariantId(it) => it.parent.lookup(db).container, + TypeOwnerId::ModuleId(x) => *x, + TypeOwnerId::DefWithBodyId(x) => x.module(db), + TypeOwnerId::GenericDefId(x) => x.module(db), } } } -impl DefWithBodyId { - pub fn as_mod_item(self, db: &dyn db::DefDatabase) -> ModItem { +impl HasModule for DefWithBodyId { + fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { match self { - DefWithBodyId::FunctionId(it) => it.lookup(db).id.value.into(), - DefWithBodyId::StaticId(it) => it.lookup(db).id.value.into(), - DefWithBodyId::ConstId(it) => it.lookup(db).id.value.into(), - DefWithBodyId::VariantId(it) => it.parent.lookup(db).id.value.into(), + DefWithBodyId::FunctionId(it) => it.lookup(db).module(db), + DefWithBodyId::StaticId(it) => it.lookup(db).module(db), + DefWithBodyId::ConstId(it) => it.lookup(db).module(db), + DefWithBodyId::VariantId(it) => it.parent.lookup(db).container, + DefWithBodyId::InTypeConstId(it) => it.lookup(db).1.module(db), } } } |