]> git.lizzy.rs Git - rust.git/blob - crates/ra_hir_def/src/lib.rs
Remove more copy-paste
[rust.git] / crates / ra_hir_def / src / lib.rs
1 //! `hir_def` crate contains everything between macro expansion and type
2 //! inference.
3 //!
4 //! It defines various items (structs, enums, traits) which comprises Rust code,
5 //! as well as an algorithm for resolving paths to such entities.
6 //!
7 //! Note that `hir_def` is a work in progress, so not all of the above is
8 //! actually true.
9
10 pub mod db;
11
12 pub mod attr;
13 pub mod path;
14 pub mod type_ref;
15 pub mod builtin_type;
16 pub mod diagnostics;
17 pub mod per_ns;
18
19 pub mod dyn_map;
20 pub mod keys;
21
22 pub mod adt;
23 pub mod data;
24 pub mod generics;
25 pub mod lang_item;
26 pub mod docs;
27
28 pub mod expr;
29 pub mod body;
30 pub mod resolver;
31
32 mod trace;
33 pub mod nameres;
34
35 pub mod src;
36 pub mod child_by_source;
37
38 #[cfg(test)]
39 mod test_db;
40 #[cfg(test)]
41 mod marks;
42
43 use std::hash::Hash;
44
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};
49
50 use crate::builtin_type::BuiltinType;
51
52 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53 pub struct LocalImportId(RawId);
54 impl_arena_id!(LocalImportId);
55
56 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
57 pub struct ModuleId {
58     pub krate: CrateId,
59     pub local_id: LocalModuleId,
60 }
61
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);
67
68 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
69 pub struct ItemLoc<N: AstNode> {
70     pub container: ContainerId,
71     pub ast_id: AstId<N>,
72 }
73
74 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
75 pub struct AssocItemLoc<N: AstNode> {
76     pub container: AssocContainerId,
77     pub ast_id: AstId<N>,
78 }
79
80 macro_rules! impl_intern {
81     ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
82         impl_intern_key!($id);
83
84         impl Intern for $loc {
85             type ID = $id;
86             fn intern(self, db: &impl db::DefDatabase) -> $id {
87                 db.$intern(self)
88             }
89         }
90
91         impl Lookup for $id {
92             type Data = $loc;
93             fn lookup(&self, db: &impl db::DefDatabase) -> $loc {
94                 db.$lookup(*self)
95             }
96         }
97     };
98 }
99
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);
104
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);
109
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);
114
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);
119
120 // FIXME: rename to `VariantId`, only enums can ave variants
121 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
122 pub struct EnumVariantId {
123     pub parent: EnumId,
124     pub local_id: LocalEnumVariantId,
125 }
126
127 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
128 pub struct LocalEnumVariantId(RawId);
129 impl_arena_id!(LocalEnumVariantId);
130
131 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
132 pub struct StructFieldId {
133     pub parent: VariantId,
134     pub local_id: LocalStructFieldId,
135 }
136
137 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
138 pub struct LocalStructFieldId(RawId);
139 impl_arena_id!(LocalStructFieldId);
140
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);
145
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);
150
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);
155
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);
160
161 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
162 pub struct ImplId(salsa::InternId);
163 impl_intern_key!(ImplId);
164
165 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
166 pub struct ImplLoc {
167     pub container: ModuleId,
168     pub ast_id: AstId<ast::ImplBlock>,
169 }
170
171 impl Intern for ImplLoc {
172     type ID = ImplId;
173     fn intern(self, db: &impl db::DefDatabase) -> ImplId {
174         db.intern_impl(self)
175     }
176 }
177
178 impl Lookup for ImplId {
179     type Data = ImplLoc;
180     fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc {
181         db.lookup_intern_impl(*self)
182     }
183 }
184
185 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186 pub struct TypeParamId {
187     pub parent: GenericDefId,
188     pub local_id: LocalTypeParamId,
189 }
190
191 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
192 pub struct LocalTypeParamId(RawId);
193 impl_arena_id!(LocalTypeParamId);
194
195 macro_rules! impl_froms {
196     ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
197         $(
198             impl From<$v> for $e {
199                 fn from(it: $v) -> $e {
200                     $e::$v(it)
201                 }
202             }
203             $($(
204                 impl From<$sv> for $e {
205                     fn from(it: $sv) -> $e {
206                         $e::$v($v::$sv(it))
207                     }
208                 }
209             )*)?
210         )*
211     }
212 }
213
214 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
215 pub enum ContainerId {
216     ModuleId(ModuleId),
217     DefWithBodyId(DefWithBodyId),
218 }
219
220 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
221 pub enum AssocContainerId {
222     ContainerId(ContainerId),
223     ImplId(ImplId),
224     TraitId(TraitId),
225 }
226 impl_froms!(AssocContainerId: ContainerId);
227
228 /// A Data Type
229 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
230 pub enum AdtId {
231     StructId(StructId),
232     UnionId(UnionId),
233     EnumId(EnumId),
234 }
235 impl_froms!(AdtId: StructId, UnionId, EnumId);
236
237 /// The defs which can be visible in the module.
238 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
239 pub enum ModuleDefId {
240     ModuleId(ModuleId),
241     FunctionId(FunctionId),
242     AdtId(AdtId),
243     // Can't be directly declared, but can be imported.
244     EnumVariantId(EnumVariantId),
245     ConstId(ConstId),
246     StaticId(StaticId),
247     TraitId(TraitId),
248     TypeAliasId(TypeAliasId),
249     BuiltinType(BuiltinType),
250 }
251 impl_froms!(
252     ModuleDefId: ModuleId,
253     FunctionId,
254     AdtId(StructId, EnumId, UnionId),
255     EnumVariantId,
256     ConstId,
257     StaticId,
258     TraitId,
259     TypeAliasId,
260     BuiltinType
261 );
262
263 /// The defs which have a body.
264 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
265 pub enum DefWithBodyId {
266     FunctionId(FunctionId),
267     StaticId(StaticId),
268     ConstId(ConstId),
269 }
270
271 impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId);
272
273 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
274 pub enum AssocItemId {
275     FunctionId(FunctionId),
276     ConstId(ConstId),
277     TypeAliasId(TypeAliasId),
278 }
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);
284
285 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
286 pub enum GenericDefId {
287     FunctionId(FunctionId),
288     AdtId(AdtId),
289     TraitId(TraitId),
290     TypeAliasId(TypeAliasId),
291     ImplId(ImplId),
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)
296     ConstId(ConstId),
297 }
298 impl_froms!(
299     GenericDefId: FunctionId,
300     AdtId(StructId, EnumId, UnionId),
301     TraitId,
302     TypeAliasId,
303     ImplId,
304     EnumVariantId,
305     ConstId
306 );
307
308 impl From<AssocItemId> for GenericDefId {
309     fn from(item: AssocItemId) -> Self {
310         match item {
311             AssocItemId::FunctionId(f) => f.into(),
312             AssocItemId::ConstId(c) => c.into(),
313             AssocItemId::TypeAliasId(t) => t.into(),
314         }
315     }
316 }
317
318 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
319 pub enum AttrDefId {
320     ModuleId(ModuleId),
321     StructFieldId(StructFieldId),
322     AdtId(AdtId),
323     FunctionId(FunctionId),
324     EnumVariantId(EnumVariantId),
325     StaticId(StaticId),
326     ConstId(ConstId),
327     TraitId(TraitId),
328     TypeAliasId(TypeAliasId),
329     MacroDefId(MacroDefId),
330     ImplId(ImplId),
331 }
332
333 impl_froms!(
334     AttrDefId: ModuleId,
335     StructFieldId,
336     AdtId(StructId, EnumId, UnionId),
337     EnumVariantId,
338     StaticId,
339     ConstId,
340     FunctionId,
341     TraitId,
342     TypeAliasId,
343     MacroDefId,
344     ImplId
345 );
346
347 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
348 pub enum VariantId {
349     EnumVariantId(EnumVariantId),
350     StructId(StructId),
351     UnionId(UnionId),
352 }
353 impl_froms!(VariantId: EnumVariantId, StructId);
354
355 trait Intern {
356     type ID;
357     fn intern(self, db: &impl db::DefDatabase) -> Self::ID;
358 }
359
360 pub trait Lookup {
361     type Data;
362     fn lookup(&self, db: &impl db::DefDatabase) -> Self::Data;
363 }
364
365 pub trait HasModule {
366     fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
367 }
368
369 impl HasModule for ContainerId {
370     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
371         match *self {
372             ContainerId::ModuleId(it) => it,
373             ContainerId::DefWithBodyId(it) => it.module(db),
374         }
375     }
376 }
377
378 impl HasModule for AssocContainerId {
379     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
380         match *self {
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),
384         }
385     }
386 }
387
388 impl HasModule for FunctionLoc {
389     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
390         self.container.module(db)
391     }
392 }
393
394 impl HasModule for TypeAliasLoc {
395     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
396         self.container.module(db)
397     }
398 }
399
400 impl HasModule for ConstLoc {
401     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
402         self.container.module(db)
403     }
404 }
405
406 impl HasModule for AdtId {
407     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
408         match self {
409             AdtId::StructId(it) => it.lookup(db).container,
410             AdtId::UnionId(it) => it.lookup(db).container,
411             AdtId::EnumId(it) => it.lookup(db).container,
412         }
413         .module(db)
414     }
415 }
416
417 impl HasModule for DefWithBodyId {
418     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
419         match self {
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),
423         }
424     }
425 }
426
427 impl HasModule for GenericDefId {
428     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
429         match self {
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),
437         }
438     }
439 }
440
441 impl HasModule for StaticLoc {
442     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
443         self.container.module(db)
444     }
445 }