1 //! `hir_def` crate contains everything between macro expansion and type
4 //! It defines various items (structs, enums, traits) which comprises Rust code,
5 //! as well as an algorithm for resolving paths to such entities.
7 //! Note that `hir_def` is a work in progress, so not all of the above is
36 pub mod child_by_source;
45 use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId};
46 use ra_arena::{impl_arena_id, RawId};
47 use ra_db::{impl_intern_key, salsa, CrateId};
48 use ra_syntax::{ast, AstNode};
50 use crate::builtin_type::BuiltinType;
52 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53 pub struct LocalImportId(RawId);
54 impl_arena_id!(LocalImportId);
56 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
59 pub local_id: LocalModuleId,
62 /// An ID of a module, **local** to a specific crate
63 // FIXME: rename to `LocalModuleId`.
64 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
65 pub struct LocalModuleId(RawId);
66 impl_arena_id!(LocalModuleId);
68 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
69 pub struct ItemLoc<N: AstNode> {
70 pub container: ContainerId,
74 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
75 pub struct AssocItemLoc<N: AstNode> {
76 pub container: AssocContainerId,
80 macro_rules! impl_intern {
81 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
82 impl_intern_key!($id);
84 impl Intern for $loc {
86 fn intern(self, db: &impl db::DefDatabase) -> $id {
93 fn lookup(&self, db: &impl db::DefDatabase) -> $loc {
100 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
101 pub struct FunctionId(salsa::InternId);
102 type FunctionLoc = AssocItemLoc<ast::FnDef>;
103 impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
105 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
106 pub struct StructId(salsa::InternId);
107 type StructLoc = ItemLoc<ast::StructDef>;
108 impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
110 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
111 pub struct UnionId(salsa::InternId);
112 pub type UnionLoc = ItemLoc<ast::UnionDef>;
113 impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
115 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
116 pub struct EnumId(salsa::InternId);
117 pub type EnumLoc = ItemLoc<ast::EnumDef>;
118 impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
120 // FIXME: rename to `VariantId`, only enums can ave variants
121 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
122 pub struct EnumVariantId {
124 pub local_id: LocalEnumVariantId,
127 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
128 pub struct LocalEnumVariantId(RawId);
129 impl_arena_id!(LocalEnumVariantId);
131 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
132 pub struct StructFieldId {
133 pub parent: VariantId,
134 pub local_id: LocalStructFieldId,
137 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
138 pub struct LocalStructFieldId(RawId);
139 impl_arena_id!(LocalStructFieldId);
141 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
142 pub struct ConstId(salsa::InternId);
143 type ConstLoc = AssocItemLoc<ast::ConstDef>;
144 impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
146 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
147 pub struct StaticId(salsa::InternId);
148 pub type StaticLoc = ItemLoc<ast::StaticDef>;
149 impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
151 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152 pub struct TraitId(salsa::InternId);
153 pub type TraitLoc = ItemLoc<ast::TraitDef>;
154 impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
156 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
157 pub struct TypeAliasId(salsa::InternId);
158 type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>;
159 impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
161 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
162 pub struct ImplId(salsa::InternId);
163 impl_intern_key!(ImplId);
165 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
167 pub container: ModuleId,
168 pub ast_id: AstId<ast::ImplBlock>,
171 impl Intern for ImplLoc {
173 fn intern(self, db: &impl db::DefDatabase) -> ImplId {
178 impl Lookup for ImplId {
180 fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc {
181 db.lookup_intern_impl(*self)
185 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186 pub struct TypeParamId {
187 pub parent: GenericDefId,
188 pub local_id: LocalTypeParamId,
191 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
192 pub struct LocalTypeParamId(RawId);
193 impl_arena_id!(LocalTypeParamId);
195 macro_rules! impl_froms {
196 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
198 impl From<$v> for $e {
199 fn from(it: $v) -> $e {
204 impl From<$sv> for $e {
205 fn from(it: $sv) -> $e {
214 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
215 pub enum ContainerId {
217 DefWithBodyId(DefWithBodyId),
220 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
221 pub enum AssocContainerId {
222 ContainerId(ContainerId),
226 impl_froms!(AssocContainerId: ContainerId);
229 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
235 impl_froms!(AdtId: StructId, UnionId, EnumId);
237 /// The defs which can be visible in the module.
238 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
239 pub enum ModuleDefId {
241 FunctionId(FunctionId),
243 // Can't be directly declared, but can be imported.
244 EnumVariantId(EnumVariantId),
248 TypeAliasId(TypeAliasId),
249 BuiltinType(BuiltinType),
252 ModuleDefId: ModuleId,
254 AdtId(StructId, EnumId, UnionId),
263 /// The defs which have a body.
264 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
265 pub enum DefWithBodyId {
266 FunctionId(FunctionId),
271 impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId);
273 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
274 pub enum AssocItemId {
275 FunctionId(FunctionId),
277 TypeAliasId(TypeAliasId),
279 // FIXME: not every function, ... is actually an assoc item. maybe we should make
280 // sure that you can only turn actual assoc items into AssocItemIds. This would
281 // require not implementing From, and instead having some checked way of
282 // casting them, and somehow making the constructors private, which would be annoying.
283 impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId);
285 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
286 pub enum GenericDefId {
287 FunctionId(FunctionId),
290 TypeAliasId(TypeAliasId),
292 // enum variants cannot have generics themselves, but their parent enums
293 // can, and this makes some code easier to write
294 EnumVariantId(EnumVariantId),
295 // consts can have type parameters from their parents (i.e. associated consts of traits)
299 GenericDefId: FunctionId,
300 AdtId(StructId, EnumId, UnionId),
308 impl From<AssocItemId> for GenericDefId {
309 fn from(item: AssocItemId) -> Self {
311 AssocItemId::FunctionId(f) => f.into(),
312 AssocItemId::ConstId(c) => c.into(),
313 AssocItemId::TypeAliasId(t) => t.into(),
318 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
321 StructFieldId(StructFieldId),
323 FunctionId(FunctionId),
324 EnumVariantId(EnumVariantId),
328 TypeAliasId(TypeAliasId),
329 MacroDefId(MacroDefId),
336 AdtId(StructId, EnumId, UnionId),
347 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
349 EnumVariantId(EnumVariantId),
353 impl_froms!(VariantId: EnumVariantId, StructId);
357 fn intern(self, db: &impl db::DefDatabase) -> Self::ID;
362 fn lookup(&self, db: &impl db::DefDatabase) -> Self::Data;
365 pub trait HasModule {
366 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
369 impl HasModule for ContainerId {
370 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
372 ContainerId::ModuleId(it) => it,
373 ContainerId::DefWithBodyId(it) => it.module(db),
378 impl HasModule for AssocContainerId {
379 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
381 AssocContainerId::ContainerId(it) => it.module(db),
382 AssocContainerId::ImplId(it) => it.lookup(db).container,
383 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db),
388 impl HasModule for FunctionLoc {
389 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
390 self.container.module(db)
394 impl HasModule for TypeAliasLoc {
395 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
396 self.container.module(db)
400 impl HasModule for ConstLoc {
401 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
402 self.container.module(db)
406 impl HasModule for AdtId {
407 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
409 AdtId::StructId(it) => it.lookup(db).container,
410 AdtId::UnionId(it) => it.lookup(db).container,
411 AdtId::EnumId(it) => it.lookup(db).container,
417 impl HasModule for DefWithBodyId {
418 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
420 DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
421 DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
422 DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
427 impl HasModule for GenericDefId {
428 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
430 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
431 GenericDefId::AdtId(it) => it.module(db),
432 GenericDefId::TraitId(it) => it.lookup(db).container.module(db),
433 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
434 GenericDefId::ImplId(it) => it.lookup(db).container,
435 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
436 GenericDefId::ConstId(it) => it.lookup(db).module(db),
441 impl HasModule for StaticLoc {
442 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
443 self.container.module(db)