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};
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, Copy, PartialEq, Eq, Hash)]
69 pub struct FunctionId(salsa::InternId);
70 impl_intern_key!(FunctionId);
72 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
73 pub struct FunctionLoc {
74 pub container: AssocContainerId,
75 pub ast_id: AstId<ast::FnDef>,
78 impl Intern for FunctionLoc {
80 fn intern(self, db: &impl db::DefDatabase) -> FunctionId {
81 db.intern_function(self)
85 impl Lookup for FunctionId {
86 type Data = FunctionLoc;
87 fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc {
88 db.lookup_intern_function(*self)
92 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
93 pub struct StructId(salsa::InternId);
94 impl_intern_key!(StructId);
96 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
97 pub struct StructLoc {
98 pub container: ContainerId,
99 pub ast_id: AstId<ast::StructDef>,
102 impl Intern for StructLoc {
104 fn intern(self, db: &impl db::DefDatabase) -> StructId {
105 db.intern_struct(self)
109 impl Lookup for StructId {
110 type Data = StructLoc;
111 fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc {
112 db.lookup_intern_struct(*self)
116 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117 pub struct UnionId(salsa::InternId);
118 impl_intern_key!(UnionId);
120 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
121 pub struct UnionLoc {
122 pub container: ContainerId,
123 pub ast_id: AstId<ast::UnionDef>,
126 impl Intern for UnionLoc {
128 fn intern(self, db: &impl db::DefDatabase) -> UnionId {
129 db.intern_union(self)
133 impl Lookup for UnionId {
134 type Data = UnionLoc;
135 fn lookup(&self, db: &impl db::DefDatabase) -> UnionLoc {
136 db.lookup_intern_union(*self)
140 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141 pub struct EnumId(salsa::InternId);
142 impl_intern_key!(EnumId);
144 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
146 pub container: ContainerId,
147 pub ast_id: AstId<ast::EnumDef>,
150 impl Intern for EnumLoc {
152 fn intern(self, db: &impl db::DefDatabase) -> EnumId {
157 impl Lookup for EnumId {
159 fn lookup(&self, db: &impl db::DefDatabase) -> EnumLoc {
160 db.lookup_intern_enum(*self)
164 // FIXME: rename to `VariantId`, only enums can ave variants
165 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
166 pub struct EnumVariantId {
168 pub local_id: LocalEnumVariantId,
171 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
172 pub struct LocalEnumVariantId(RawId);
173 impl_arena_id!(LocalEnumVariantId);
175 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
176 pub struct StructFieldId {
177 pub parent: VariantId,
178 pub local_id: LocalStructFieldId,
181 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
182 pub struct LocalStructFieldId(RawId);
183 impl_arena_id!(LocalStructFieldId);
185 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186 pub struct ConstId(salsa::InternId);
187 impl_intern_key!(ConstId);
188 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
189 pub struct ConstLoc {
190 pub container: AssocContainerId,
191 pub ast_id: AstId<ast::ConstDef>,
194 impl Intern for ConstLoc {
196 fn intern(self, db: &impl db::DefDatabase) -> ConstId {
197 db.intern_const(self)
201 impl Lookup for ConstId {
202 type Data = ConstLoc;
203 fn lookup(&self, db: &impl db::DefDatabase) -> ConstLoc {
204 db.lookup_intern_const(*self)
208 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209 pub struct StaticId(salsa::InternId);
210 impl_intern_key!(StaticId);
212 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
213 pub struct StaticLoc {
214 pub container: ModuleId,
215 pub ast_id: AstId<ast::StaticDef>,
218 impl Intern for StaticLoc {
220 fn intern(self, db: &impl db::DefDatabase) -> StaticId {
221 db.intern_static(self)
225 impl Lookup for StaticId {
226 type Data = StaticLoc;
227 fn lookup(&self, db: &impl db::DefDatabase) -> StaticLoc {
228 db.lookup_intern_static(*self)
232 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233 pub struct TraitId(salsa::InternId);
234 impl_intern_key!(TraitId);
236 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
237 pub struct TraitLoc {
238 pub container: ModuleId,
239 pub ast_id: AstId<ast::TraitDef>,
242 impl Intern for TraitLoc {
244 fn intern(self, db: &impl db::DefDatabase) -> TraitId {
245 db.intern_trait(self)
249 impl Lookup for TraitId {
250 type Data = TraitLoc;
251 fn lookup(&self, db: &impl db::DefDatabase) -> TraitLoc {
252 db.lookup_intern_trait(*self)
256 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
257 pub struct TypeAliasId(salsa::InternId);
258 impl_intern_key!(TypeAliasId);
260 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
261 pub struct TypeAliasLoc {
262 pub container: AssocContainerId,
263 pub ast_id: AstId<ast::TypeAliasDef>,
266 impl Intern for TypeAliasLoc {
267 type ID = TypeAliasId;
268 fn intern(self, db: &impl db::DefDatabase) -> TypeAliasId {
269 db.intern_type_alias(self)
273 impl Lookup for TypeAliasId {
274 type Data = TypeAliasLoc;
275 fn lookup(&self, db: &impl db::DefDatabase) -> TypeAliasLoc {
276 db.lookup_intern_type_alias(*self)
280 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
281 pub struct ImplId(salsa::InternId);
282 impl_intern_key!(ImplId);
284 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
286 pub container: ModuleId,
287 pub ast_id: AstId<ast::ImplBlock>,
290 impl Intern for ImplLoc {
292 fn intern(self, db: &impl db::DefDatabase) -> ImplId {
297 impl Lookup for ImplId {
299 fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc {
300 db.lookup_intern_impl(*self)
304 macro_rules! impl_froms {
305 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
307 impl From<$v> for $e {
308 fn from(it: $v) -> $e {
313 impl From<$sv> for $e {
314 fn from(it: $sv) -> $e {
323 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
324 pub struct TypeParamId {
325 pub parent: GenericDefId,
326 pub local_id: LocalTypeParamId,
329 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
330 pub struct LocalTypeParamId(RawId);
331 impl_arena_id!(LocalTypeParamId);
333 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
334 pub enum ContainerId {
336 DefWithBodyId(DefWithBodyId),
339 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
340 pub enum AssocContainerId {
341 ContainerId(ContainerId),
345 impl_froms!(AssocContainerId: ContainerId);
348 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
354 impl_froms!(AdtId: StructId, UnionId, EnumId);
356 /// The defs which can be visible in the module.
357 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
358 pub enum ModuleDefId {
360 FunctionId(FunctionId),
362 // Can't be directly declared, but can be imported.
363 EnumVariantId(EnumVariantId),
367 TypeAliasId(TypeAliasId),
368 BuiltinType(BuiltinType),
371 ModuleDefId: ModuleId,
373 AdtId(StructId, EnumId, UnionId),
382 /// The defs which have a body.
383 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
384 pub enum DefWithBodyId {
385 FunctionId(FunctionId),
390 impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId);
392 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
393 pub enum AssocItemId {
394 FunctionId(FunctionId),
396 TypeAliasId(TypeAliasId),
398 // FIXME: not every function, ... is actually an assoc item. maybe we should make
399 // sure that you can only turn actual assoc items into AssocItemIds. This would
400 // require not implementing From, and instead having some checked way of
401 // casting them, and somehow making the constructors private, which would be annoying.
402 impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId);
404 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
405 pub enum GenericDefId {
406 FunctionId(FunctionId),
409 TypeAliasId(TypeAliasId),
411 // enum variants cannot have generics themselves, but their parent enums
412 // can, and this makes some code easier to write
413 EnumVariantId(EnumVariantId),
414 // consts can have type parameters from their parents (i.e. associated consts of traits)
418 GenericDefId: FunctionId,
419 AdtId(StructId, EnumId, UnionId),
427 impl From<AssocItemId> for GenericDefId {
428 fn from(item: AssocItemId) -> Self {
430 AssocItemId::FunctionId(f) => f.into(),
431 AssocItemId::ConstId(c) => c.into(),
432 AssocItemId::TypeAliasId(t) => t.into(),
437 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
440 StructFieldId(StructFieldId),
442 FunctionId(FunctionId),
443 EnumVariantId(EnumVariantId),
447 TypeAliasId(TypeAliasId),
448 MacroDefId(MacroDefId),
455 AdtId(StructId, EnumId, UnionId),
466 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
468 EnumVariantId(EnumVariantId),
472 impl_froms!(VariantId: EnumVariantId, StructId);
476 fn intern(self, db: &impl db::DefDatabase) -> Self::ID;
481 fn lookup(&self, db: &impl db::DefDatabase) -> Self::Data;
484 pub trait HasModule {
485 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
488 impl HasModule for ContainerId {
489 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
491 ContainerId::ModuleId(it) => it,
492 ContainerId::DefWithBodyId(it) => it.module(db),
497 impl HasModule for AssocContainerId {
498 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
500 AssocContainerId::ContainerId(it) => it.module(db),
501 AssocContainerId::ImplId(it) => it.lookup(db).container,
502 AssocContainerId::TraitId(it) => it.lookup(db).container,
507 impl HasModule for FunctionLoc {
508 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
509 self.container.module(db)
513 impl HasModule for TypeAliasLoc {
514 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
515 self.container.module(db)
519 impl HasModule for ConstLoc {
520 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
521 self.container.module(db)
525 impl HasModule for AdtId {
526 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
528 AdtId::StructId(it) => it.lookup(db).container,
529 AdtId::UnionId(it) => it.lookup(db).container,
530 AdtId::EnumId(it) => it.lookup(db).container,
536 impl HasModule for DefWithBodyId {
537 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
539 DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
540 DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
541 DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
546 impl HasModule for GenericDefId {
547 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
549 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
550 GenericDefId::AdtId(it) => it.module(db),
551 GenericDefId::TraitId(it) => it.lookup(db).container,
552 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
553 GenericDefId::ImplId(it) => it.lookup(db).container,
554 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
555 GenericDefId::ConstId(it) => it.lookup(db).module(db),
560 impl HasModule for StaticLoc {
561 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId {