]> git.lizzy.rs Git - rust.git/blob - crates/ra_hir_def/src/lib.rs
Support for nested ADT
[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;
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, Copy, PartialEq, Eq, Hash)]
69 pub struct FunctionId(salsa::InternId);
70 impl_intern_key!(FunctionId);
71
72 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
73 pub struct FunctionLoc {
74     pub container: AssocContainerId,
75     pub ast_id: AstId<ast::FnDef>,
76 }
77
78 impl Intern for FunctionLoc {
79     type ID = FunctionId;
80     fn intern(self, db: &impl db::DefDatabase) -> FunctionId {
81         db.intern_function(self)
82     }
83 }
84
85 impl Lookup for FunctionId {
86     type Data = FunctionLoc;
87     fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc {
88         db.lookup_intern_function(*self)
89     }
90 }
91
92 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
93 pub struct StructId(salsa::InternId);
94 impl_intern_key!(StructId);
95
96 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
97 pub struct StructLoc {
98     pub container: ContainerId,
99     pub ast_id: AstId<ast::StructDef>,
100 }
101
102 impl Intern for StructLoc {
103     type ID = StructId;
104     fn intern(self, db: &impl db::DefDatabase) -> StructId {
105         db.intern_struct(self)
106     }
107 }
108
109 impl Lookup for StructId {
110     type Data = StructLoc;
111     fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc {
112         db.lookup_intern_struct(*self)
113     }
114 }
115
116 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117 pub struct UnionId(salsa::InternId);
118 impl_intern_key!(UnionId);
119
120 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
121 pub struct UnionLoc {
122     pub container: ContainerId,
123     pub ast_id: AstId<ast::UnionDef>,
124 }
125
126 impl Intern for UnionLoc {
127     type ID = UnionId;
128     fn intern(self, db: &impl db::DefDatabase) -> UnionId {
129         db.intern_union(self)
130     }
131 }
132
133 impl Lookup for UnionId {
134     type Data = UnionLoc;
135     fn lookup(&self, db: &impl db::DefDatabase) -> UnionLoc {
136         db.lookup_intern_union(*self)
137     }
138 }
139
140 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141 pub struct EnumId(salsa::InternId);
142 impl_intern_key!(EnumId);
143
144 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
145 pub struct EnumLoc {
146     pub container: ContainerId,
147     pub ast_id: AstId<ast::EnumDef>,
148 }
149
150 impl Intern for EnumLoc {
151     type ID = EnumId;
152     fn intern(self, db: &impl db::DefDatabase) -> EnumId {
153         db.intern_enum(self)
154     }
155 }
156
157 impl Lookup for EnumId {
158     type Data = EnumLoc;
159     fn lookup(&self, db: &impl db::DefDatabase) -> EnumLoc {
160         db.lookup_intern_enum(*self)
161     }
162 }
163
164 // FIXME: rename to `VariantId`, only enums can ave variants
165 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
166 pub struct EnumVariantId {
167     pub parent: EnumId,
168     pub local_id: LocalEnumVariantId,
169 }
170
171 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
172 pub struct LocalEnumVariantId(RawId);
173 impl_arena_id!(LocalEnumVariantId);
174
175 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
176 pub struct StructFieldId {
177     pub parent: VariantId,
178     pub local_id: LocalStructFieldId,
179 }
180
181 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
182 pub struct LocalStructFieldId(RawId);
183 impl_arena_id!(LocalStructFieldId);
184
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>,
192 }
193
194 impl Intern for ConstLoc {
195     type ID = ConstId;
196     fn intern(self, db: &impl db::DefDatabase) -> ConstId {
197         db.intern_const(self)
198     }
199 }
200
201 impl Lookup for ConstId {
202     type Data = ConstLoc;
203     fn lookup(&self, db: &impl db::DefDatabase) -> ConstLoc {
204         db.lookup_intern_const(*self)
205     }
206 }
207
208 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209 pub struct StaticId(salsa::InternId);
210 impl_intern_key!(StaticId);
211
212 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
213 pub struct StaticLoc {
214     pub container: ModuleId,
215     pub ast_id: AstId<ast::StaticDef>,
216 }
217
218 impl Intern for StaticLoc {
219     type ID = StaticId;
220     fn intern(self, db: &impl db::DefDatabase) -> StaticId {
221         db.intern_static(self)
222     }
223 }
224
225 impl Lookup for StaticId {
226     type Data = StaticLoc;
227     fn lookup(&self, db: &impl db::DefDatabase) -> StaticLoc {
228         db.lookup_intern_static(*self)
229     }
230 }
231
232 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233 pub struct TraitId(salsa::InternId);
234 impl_intern_key!(TraitId);
235
236 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
237 pub struct TraitLoc {
238     pub container: ModuleId,
239     pub ast_id: AstId<ast::TraitDef>,
240 }
241
242 impl Intern for TraitLoc {
243     type ID = TraitId;
244     fn intern(self, db: &impl db::DefDatabase) -> TraitId {
245         db.intern_trait(self)
246     }
247 }
248
249 impl Lookup for TraitId {
250     type Data = TraitLoc;
251     fn lookup(&self, db: &impl db::DefDatabase) -> TraitLoc {
252         db.lookup_intern_trait(*self)
253     }
254 }
255
256 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
257 pub struct TypeAliasId(salsa::InternId);
258 impl_intern_key!(TypeAliasId);
259
260 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
261 pub struct TypeAliasLoc {
262     pub container: AssocContainerId,
263     pub ast_id: AstId<ast::TypeAliasDef>,
264 }
265
266 impl Intern for TypeAliasLoc {
267     type ID = TypeAliasId;
268     fn intern(self, db: &impl db::DefDatabase) -> TypeAliasId {
269         db.intern_type_alias(self)
270     }
271 }
272
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)
277     }
278 }
279
280 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
281 pub struct ImplId(salsa::InternId);
282 impl_intern_key!(ImplId);
283
284 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
285 pub struct ImplLoc {
286     pub container: ModuleId,
287     pub ast_id: AstId<ast::ImplBlock>,
288 }
289
290 impl Intern for ImplLoc {
291     type ID = ImplId;
292     fn intern(self, db: &impl db::DefDatabase) -> ImplId {
293         db.intern_impl(self)
294     }
295 }
296
297 impl Lookup for ImplId {
298     type Data = ImplLoc;
299     fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc {
300         db.lookup_intern_impl(*self)
301     }
302 }
303
304 macro_rules! impl_froms {
305     ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
306         $(
307             impl From<$v> for $e {
308                 fn from(it: $v) -> $e {
309                     $e::$v(it)
310                 }
311             }
312             $($(
313                 impl From<$sv> for $e {
314                     fn from(it: $sv) -> $e {
315                         $e::$v($v::$sv(it))
316                     }
317                 }
318             )*)?
319         )*
320     }
321 }
322
323 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
324 pub struct TypeParamId {
325     pub parent: GenericDefId,
326     pub local_id: LocalTypeParamId,
327 }
328
329 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
330 pub struct LocalTypeParamId(RawId);
331 impl_arena_id!(LocalTypeParamId);
332
333 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
334 pub enum ContainerId {
335     ModuleId(ModuleId),
336     DefWithBodyId(DefWithBodyId),
337 }
338
339 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
340 pub enum AssocContainerId {
341     ContainerId(ContainerId),
342     ImplId(ImplId),
343     TraitId(TraitId),
344 }
345 impl_froms!(AssocContainerId: ContainerId);
346
347 /// A Data Type
348 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
349 pub enum AdtId {
350     StructId(StructId),
351     UnionId(UnionId),
352     EnumId(EnumId),
353 }
354 impl_froms!(AdtId: StructId, UnionId, EnumId);
355
356 /// The defs which can be visible in the module.
357 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
358 pub enum ModuleDefId {
359     ModuleId(ModuleId),
360     FunctionId(FunctionId),
361     AdtId(AdtId),
362     // Can't be directly declared, but can be imported.
363     EnumVariantId(EnumVariantId),
364     ConstId(ConstId),
365     StaticId(StaticId),
366     TraitId(TraitId),
367     TypeAliasId(TypeAliasId),
368     BuiltinType(BuiltinType),
369 }
370 impl_froms!(
371     ModuleDefId: ModuleId,
372     FunctionId,
373     AdtId(StructId, EnumId, UnionId),
374     EnumVariantId,
375     ConstId,
376     StaticId,
377     TraitId,
378     TypeAliasId,
379     BuiltinType
380 );
381
382 /// The defs which have a body.
383 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
384 pub enum DefWithBodyId {
385     FunctionId(FunctionId),
386     StaticId(StaticId),
387     ConstId(ConstId),
388 }
389
390 impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId);
391
392 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
393 pub enum AssocItemId {
394     FunctionId(FunctionId),
395     ConstId(ConstId),
396     TypeAliasId(TypeAliasId),
397 }
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);
403
404 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
405 pub enum GenericDefId {
406     FunctionId(FunctionId),
407     AdtId(AdtId),
408     TraitId(TraitId),
409     TypeAliasId(TypeAliasId),
410     ImplId(ImplId),
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)
415     ConstId(ConstId),
416 }
417 impl_froms!(
418     GenericDefId: FunctionId,
419     AdtId(StructId, EnumId, UnionId),
420     TraitId,
421     TypeAliasId,
422     ImplId,
423     EnumVariantId,
424     ConstId
425 );
426
427 impl From<AssocItemId> for GenericDefId {
428     fn from(item: AssocItemId) -> Self {
429         match item {
430             AssocItemId::FunctionId(f) => f.into(),
431             AssocItemId::ConstId(c) => c.into(),
432             AssocItemId::TypeAliasId(t) => t.into(),
433         }
434     }
435 }
436
437 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
438 pub enum AttrDefId {
439     ModuleId(ModuleId),
440     StructFieldId(StructFieldId),
441     AdtId(AdtId),
442     FunctionId(FunctionId),
443     EnumVariantId(EnumVariantId),
444     StaticId(StaticId),
445     ConstId(ConstId),
446     TraitId(TraitId),
447     TypeAliasId(TypeAliasId),
448     MacroDefId(MacroDefId),
449     ImplId(ImplId),
450 }
451
452 impl_froms!(
453     AttrDefId: ModuleId,
454     StructFieldId,
455     AdtId(StructId, EnumId, UnionId),
456     EnumVariantId,
457     StaticId,
458     ConstId,
459     FunctionId,
460     TraitId,
461     TypeAliasId,
462     MacroDefId,
463     ImplId
464 );
465
466 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
467 pub enum VariantId {
468     EnumVariantId(EnumVariantId),
469     StructId(StructId),
470     UnionId(UnionId),
471 }
472 impl_froms!(VariantId: EnumVariantId, StructId);
473
474 trait Intern {
475     type ID;
476     fn intern(self, db: &impl db::DefDatabase) -> Self::ID;
477 }
478
479 pub trait Lookup {
480     type Data;
481     fn lookup(&self, db: &impl db::DefDatabase) -> Self::Data;
482 }
483
484 pub trait HasModule {
485     fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
486 }
487
488 impl HasModule for ContainerId {
489     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
490         match *self {
491             ContainerId::ModuleId(it) => it,
492             ContainerId::DefWithBodyId(it) => it.module(db),
493         }
494     }
495 }
496
497 impl HasModule for AssocContainerId {
498     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
499         match *self {
500             AssocContainerId::ContainerId(it) => it.module(db),
501             AssocContainerId::ImplId(it) => it.lookup(db).container,
502             AssocContainerId::TraitId(it) => it.lookup(db).container,
503         }
504     }
505 }
506
507 impl HasModule for FunctionLoc {
508     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
509         self.container.module(db)
510     }
511 }
512
513 impl HasModule for TypeAliasLoc {
514     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
515         self.container.module(db)
516     }
517 }
518
519 impl HasModule for ConstLoc {
520     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
521         self.container.module(db)
522     }
523 }
524
525 impl HasModule for AdtId {
526     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
527         match self {
528             AdtId::StructId(it) => it.lookup(db).container,
529             AdtId::UnionId(it) => it.lookup(db).container,
530             AdtId::EnumId(it) => it.lookup(db).container,
531         }
532         .module(db)
533     }
534 }
535
536 impl HasModule for DefWithBodyId {
537     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
538         match self {
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),
542         }
543     }
544 }
545
546 impl HasModule for GenericDefId {
547     fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
548         match self {
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),
556         }
557     }
558 }
559
560 impl HasModule for StaticLoc {
561     fn module(&self, _db: &impl db::DefDatabase) -> ModuleId {
562         self.container
563     }
564 }