]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/lib.rs
Add const generics
[rust.git] / crates / 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 #[allow(unused)]
11 macro_rules! eprintln {
12     ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
13 }
14
15 pub mod db;
16
17 pub mod attr;
18 pub mod path;
19 pub mod type_ref;
20 pub mod builtin_type;
21 pub mod builtin_attr;
22 pub mod per_ns;
23 pub mod item_scope;
24
25 pub mod dyn_map;
26 pub mod keys;
27
28 pub mod item_tree;
29 pub mod intern;
30
31 pub mod adt;
32 pub mod data;
33 pub mod generics;
34 pub mod lang_item;
35
36 pub mod expr;
37 pub mod body;
38 pub mod resolver;
39
40 mod trace;
41 pub mod nameres;
42
43 pub mod src;
44 pub mod child_by_source;
45
46 pub mod visibility;
47 pub mod find_path;
48 pub mod import_map;
49
50 #[cfg(test)]
51 mod test_db;
52 #[cfg(test)]
53 mod macro_expansion_tests;
54
55 use std::{
56     hash::{Hash, Hasher},
57     sync::Arc,
58 };
59
60 use attr::Attr;
61 use base_db::{impl_intern_key, salsa, CrateId, ProcMacroKind};
62 use hir_expand::{
63     ast_id_map::FileAstId,
64     builtin_attr_macro::BuiltinAttrExpander,
65     builtin_derive_macro::BuiltinDeriveExpander,
66     builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
67     eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
68     hygiene::Hygiene,
69     proc_macro::ProcMacroExpander,
70     AstId, ExpandError, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
71     MacroDefKind, UnresolvedMacro,
72 };
73 use item_tree::ExternBlock;
74 use la_arena::Idx;
75 use nameres::DefMap;
76 use stdx::impl_from;
77 use syntax::ast;
78
79 use crate::{
80     adt::VariantData,
81     attr::AttrId,
82     builtin_type::BuiltinType,
83     item_tree::{
84         Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, ModItem,
85         Static, Struct, Trait, TypeAlias, Union,
86     },
87 };
88
89 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
90 pub struct ModuleId {
91     krate: CrateId,
92     /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the
93     /// `BlockId` of that block expression. If `None`, this module is part of the crate-level
94     /// `DefMap` of `krate`.
95     block: Option<BlockId>,
96     /// The module's ID in its originating `DefMap`.
97     pub local_id: LocalModuleId,
98 }
99
100 impl ModuleId {
101     pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
102         match self.block {
103             Some(block) => {
104                 db.block_def_map(block).unwrap_or_else(|| {
105                     // NOTE: This should be unreachable - all `ModuleId`s come from their `DefMap`s,
106                     // so the `DefMap` here must exist.
107                     unreachable!("no `block_def_map` for `ModuleId` {:?}", self);
108                 })
109             }
110             None => db.crate_def_map(self.krate),
111         }
112     }
113
114     pub fn krate(&self) -> CrateId {
115         self.krate
116     }
117
118     pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
119         self.def_map(db).containing_module(self.local_id)
120     }
121
122     pub fn containing_block(&self) -> Option<BlockId> {
123         self.block
124     }
125 }
126
127 /// An ID of a module, **local** to a specific crate
128 pub type LocalModuleId = Idx<nameres::ModuleData>;
129
130 #[derive(Debug)]
131 pub struct ItemLoc<N: ItemTreeNode> {
132     pub container: ModuleId,
133     pub id: ItemTreeId<N>,
134 }
135
136 impl<N: ItemTreeNode> Clone for ItemLoc<N> {
137     fn clone(&self) -> Self {
138         Self { container: self.container, id: self.id }
139     }
140 }
141
142 impl<N: ItemTreeNode> Copy for ItemLoc<N> {}
143
144 impl<N: ItemTreeNode> PartialEq for ItemLoc<N> {
145     fn eq(&self, other: &Self) -> bool {
146         self.container == other.container && self.id == other.id
147     }
148 }
149
150 impl<N: ItemTreeNode> Eq for ItemLoc<N> {}
151
152 impl<N: ItemTreeNode> Hash for ItemLoc<N> {
153     fn hash<H: Hasher>(&self, state: &mut H) {
154         self.container.hash(state);
155         self.id.hash(state);
156     }
157 }
158
159 #[derive(Debug)]
160 pub struct AssocItemLoc<N: ItemTreeNode> {
161     pub container: ItemContainerId,
162     pub id: ItemTreeId<N>,
163 }
164
165 impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
166     fn clone(&self) -> Self {
167         Self { container: self.container, id: self.id }
168     }
169 }
170
171 impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
172
173 impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
174     fn eq(&self, other: &Self) -> bool {
175         self.container == other.container && self.id == other.id
176     }
177 }
178
179 impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {}
180
181 impl<N: ItemTreeNode> Hash for AssocItemLoc<N> {
182     fn hash<H: Hasher>(&self, state: &mut H) {
183         self.container.hash(state);
184         self.id.hash(state);
185     }
186 }
187
188 macro_rules! impl_intern {
189     ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
190         impl_intern_key!($id);
191
192         impl Intern for $loc {
193             type ID = $id;
194             fn intern(self, db: &dyn db::DefDatabase) -> $id {
195                 db.$intern(self)
196             }
197         }
198
199         impl Lookup for $id {
200             type Data = $loc;
201             fn lookup(&self, db: &dyn db::DefDatabase) -> $loc {
202                 db.$lookup(*self)
203             }
204         }
205     };
206 }
207
208 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209 pub struct FunctionId(salsa::InternId);
210 type FunctionLoc = AssocItemLoc<Function>;
211 impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
212
213 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
214 pub struct StructId(salsa::InternId);
215 type StructLoc = ItemLoc<Struct>;
216 impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
217
218 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
219 pub struct UnionId(salsa::InternId);
220 pub type UnionLoc = ItemLoc<Union>;
221 impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
222
223 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
224 pub struct EnumId(salsa::InternId);
225 pub type EnumLoc = ItemLoc<Enum>;
226 impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
227
228 // FIXME: rename to `VariantId`, only enums can ave variants
229 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
230 pub struct EnumVariantId {
231     pub parent: EnumId,
232     pub local_id: LocalEnumVariantId,
233 }
234
235 pub type LocalEnumVariantId = Idx<adt::EnumVariantData>;
236
237 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
238 pub struct FieldId {
239     pub parent: VariantId,
240     pub local_id: LocalFieldId,
241 }
242
243 pub type LocalFieldId = Idx<adt::FieldData>;
244
245 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
246 pub struct ConstId(salsa::InternId);
247 type ConstLoc = AssocItemLoc<Const>;
248 impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
249
250 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
251 pub struct StaticId(salsa::InternId);
252 pub type StaticLoc = AssocItemLoc<Static>;
253 impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
254
255 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
256 pub struct TraitId(salsa::InternId);
257 pub type TraitLoc = ItemLoc<Trait>;
258 impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
259
260 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
261 pub struct TypeAliasId(salsa::InternId);
262 type TypeAliasLoc = AssocItemLoc<TypeAlias>;
263 impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
264
265 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
266 pub struct ImplId(salsa::InternId);
267 type ImplLoc = ItemLoc<Impl>;
268 impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
269
270 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
271 pub struct ExternBlockId(salsa::InternId);
272 type ExternBlockLoc = ItemLoc<ExternBlock>;
273 impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
274
275 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
276 pub enum MacroExpander {
277     Declarative,
278     BuiltIn(BuiltinFnLikeExpander),
279     BuiltInAttr(BuiltinAttrExpander),
280     BuiltInDerive(BuiltinDeriveExpander),
281     BuiltInEager(EagerExpander),
282 }
283
284 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
285 pub struct Macro2Id(salsa::InternId);
286 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
287 pub struct Macro2Loc {
288     pub container: ModuleId,
289     pub id: ItemTreeId<MacroDef>,
290     pub expander: MacroExpander,
291 }
292 impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
293
294 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
295 pub struct MacroRulesId(salsa::InternId);
296 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
297 pub struct MacroRulesLoc {
298     pub container: ModuleId,
299     pub id: ItemTreeId<MacroRules>,
300     pub local_inner: bool,
301     pub expander: MacroExpander,
302 }
303 impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
304
305 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
306 pub struct ProcMacroId(salsa::InternId);
307 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
308 pub struct ProcMacroLoc {
309     // FIXME: this should be a crate? or just a crate-root module
310     pub container: ModuleId,
311     pub id: ItemTreeId<Function>,
312     pub expander: ProcMacroExpander,
313     pub kind: ProcMacroKind,
314 }
315 impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
316
317 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
318 pub struct BlockId(salsa::InternId);
319 #[derive(Debug, Hash, PartialEq, Eq, Clone)]
320 pub struct BlockLoc {
321     ast_id: AstId<ast::BlockExpr>,
322     /// The containing module.
323     module: ModuleId,
324 }
325 impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
326
327 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
328 pub struct TypeOrConstParamId {
329     pub parent: GenericDefId,
330     pub local_id: LocalTypeOrConstParamId,
331 }
332
333 /// A TypeOrConstParamId with an invariant that it actually belongs to a type
334 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
335 pub struct TypeParamId(TypeOrConstParamId);
336
337 impl TypeParamId {
338     pub fn parent(&self) -> GenericDefId {
339         self.0.parent
340     }
341     pub fn local_id(&self) -> LocalTypeOrConstParamId {
342         self.0.local_id
343     }
344 }
345
346 impl TypeParamId {
347     /// Caller should check if this toc id really belongs to a type
348     pub fn from_unchecked(x: TypeOrConstParamId) -> Self {
349         Self(x)
350     }
351 }
352
353 impl From<TypeParamId> for TypeOrConstParamId {
354     fn from(x: TypeParamId) -> Self {
355         x.0
356     }
357 }
358
359 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
360 /// A TypeOrConstParamId with an invariant that it actually belongs to a const
361 pub struct ConstParamId(TypeOrConstParamId);
362
363 impl ConstParamId {
364     pub fn parent(&self) -> GenericDefId {
365         self.0.parent
366     }
367     pub fn local_id(&self) -> LocalTypeOrConstParamId {
368         self.0.local_id
369     }
370 }
371
372 impl ConstParamId {
373     /// Caller should check if this toc id really belongs to a const
374     pub fn from_unchecked(x: TypeOrConstParamId) -> Self {
375         Self(x)
376     }
377 }
378
379 impl From<ConstParamId> for TypeOrConstParamId {
380     fn from(x: ConstParamId) -> Self {
381         x.0
382     }
383 }
384
385 pub type LocalTypeOrConstParamId = Idx<generics::TypeOrConstParamData>;
386
387 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
388 pub struct LifetimeParamId {
389     pub parent: GenericDefId,
390     pub local_id: LocalLifetimeParamId,
391 }
392 pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
393
394 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
395 pub enum ItemContainerId {
396     ExternBlockId(ExternBlockId),
397     ModuleId(ModuleId),
398     ImplId(ImplId),
399     TraitId(TraitId),
400 }
401 impl_from!(ModuleId for ItemContainerId);
402
403 /// A Data Type
404 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
405 pub enum AdtId {
406     StructId(StructId),
407     UnionId(UnionId),
408     EnumId(EnumId),
409 }
410 impl_from!(StructId, UnionId, EnumId for AdtId);
411
412 /// A macro
413 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
414 pub enum MacroId {
415     Macro2Id(Macro2Id),
416     MacroRulesId(MacroRulesId),
417     ProcMacroId(ProcMacroId),
418 }
419 impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
420
421 impl MacroId {
422     pub fn is_attribute(self, db: &dyn db::DefDatabase) -> bool {
423         match self {
424             MacroId::ProcMacroId(it) => it.lookup(db).kind == ProcMacroKind::Attr,
425             _ => false,
426         }
427     }
428 }
429
430 /// A generic param
431 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
432 pub enum GenericParamId {
433     TypeParamId(TypeParamId),
434     ConstParamId(ConstParamId),
435     LifetimeParamId(LifetimeParamId),
436 }
437 impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
438
439 /// The defs which can be visible in the module.
440 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
441 pub enum ModuleDefId {
442     ModuleId(ModuleId),
443     FunctionId(FunctionId),
444     AdtId(AdtId),
445     // Can't be directly declared, but can be imported.
446     EnumVariantId(EnumVariantId),
447     ConstId(ConstId),
448     StaticId(StaticId),
449     TraitId(TraitId),
450     TypeAliasId(TypeAliasId),
451     BuiltinType(BuiltinType),
452     MacroId(MacroId),
453 }
454 impl_from!(
455     MacroId(Macro2Id, MacroRulesId, ProcMacroId),
456     ModuleId,
457     FunctionId,
458     AdtId(StructId, EnumId, UnionId),
459     EnumVariantId,
460     ConstId,
461     StaticId,
462     TraitId,
463     TypeAliasId,
464     BuiltinType
465     for ModuleDefId
466 );
467
468 /// The defs which have a body.
469 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
470 pub enum DefWithBodyId {
471     FunctionId(FunctionId),
472     StaticId(StaticId),
473     ConstId(ConstId),
474 }
475
476 impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
477
478 impl DefWithBodyId {
479     pub fn as_generic_def_id(self) -> Option<GenericDefId> {
480         match self {
481             DefWithBodyId::FunctionId(f) => Some(f.into()),
482             DefWithBodyId::StaticId(_) => None,
483             DefWithBodyId::ConstId(c) => Some(c.into()),
484         }
485     }
486 }
487
488 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
489 pub enum AssocItemId {
490     FunctionId(FunctionId),
491     ConstId(ConstId),
492     TypeAliasId(TypeAliasId),
493 }
494 // FIXME: not every function, ... is actually an assoc item. maybe we should make
495 // sure that you can only turn actual assoc items into AssocItemIds. This would
496 // require not implementing From, and instead having some checked way of
497 // casting them, and somehow making the constructors private, which would be annoying.
498 impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
499
500 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
501 pub enum GenericDefId {
502     FunctionId(FunctionId),
503     AdtId(AdtId),
504     TraitId(TraitId),
505     TypeAliasId(TypeAliasId),
506     ImplId(ImplId),
507     // enum variants cannot have generics themselves, but their parent enums
508     // can, and this makes some code easier to write
509     EnumVariantId(EnumVariantId),
510     // consts can have type parameters from their parents (i.e. associated consts of traits)
511     ConstId(ConstId),
512 }
513 impl_from!(
514     FunctionId,
515     AdtId(StructId, EnumId, UnionId),
516     TraitId,
517     TypeAliasId,
518     ImplId,
519     EnumVariantId,
520     ConstId
521     for GenericDefId
522 );
523
524 impl From<AssocItemId> for GenericDefId {
525     fn from(item: AssocItemId) -> Self {
526         match item {
527             AssocItemId::FunctionId(f) => f.into(),
528             AssocItemId::ConstId(c) => c.into(),
529             AssocItemId::TypeAliasId(t) => t.into(),
530         }
531     }
532 }
533
534 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
535 pub enum AttrDefId {
536     ModuleId(ModuleId),
537     FieldId(FieldId),
538     AdtId(AdtId),
539     FunctionId(FunctionId),
540     EnumVariantId(EnumVariantId),
541     StaticId(StaticId),
542     ConstId(ConstId),
543     TraitId(TraitId),
544     TypeAliasId(TypeAliasId),
545     MacroId(MacroId),
546     ImplId(ImplId),
547     GenericParamId(GenericParamId),
548     ExternBlockId(ExternBlockId),
549 }
550
551 impl_from!(
552     ModuleId,
553     FieldId,
554     AdtId(StructId, EnumId, UnionId),
555     EnumVariantId,
556     StaticId,
557     ConstId,
558     FunctionId,
559     TraitId,
560     TypeAliasId,
561     MacroId(Macro2Id, MacroRulesId, ProcMacroId),
562     ImplId,
563     GenericParamId
564     for AttrDefId
565 );
566
567 impl From<ItemContainerId> for AttrDefId {
568     fn from(acid: ItemContainerId) -> Self {
569         match acid {
570             ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
571             ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
572             ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
573             ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
574         }
575     }
576 }
577
578 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
579 pub enum VariantId {
580     EnumVariantId(EnumVariantId),
581     StructId(StructId),
582     UnionId(UnionId),
583 }
584 impl_from!(EnumVariantId, StructId, UnionId for VariantId);
585
586 impl VariantId {
587     pub fn variant_data(self, db: &dyn db::DefDatabase) -> Arc<VariantData> {
588         match self {
589             VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
590             VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
591             VariantId::EnumVariantId(it) => {
592                 db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
593             }
594         }
595     }
596
597     pub fn file_id(self, db: &dyn db::DefDatabase) -> HirFileId {
598         match self {
599             VariantId::EnumVariantId(it) => it.parent.lookup(db).id.file_id(),
600             VariantId::StructId(it) => it.lookup(db).id.file_id(),
601             VariantId::UnionId(it) => it.lookup(db).id.file_id(),
602         }
603     }
604
605     pub fn adt_id(self) -> AdtId {
606         match self {
607             VariantId::EnumVariantId(it) => it.parent.into(),
608             VariantId::StructId(it) => it.into(),
609             VariantId::UnionId(it) => it.into(),
610         }
611     }
612 }
613
614 trait Intern {
615     type ID;
616     fn intern(self, db: &dyn db::DefDatabase) -> Self::ID;
617 }
618
619 pub trait Lookup {
620     type Data;
621     fn lookup(&self, db: &dyn db::DefDatabase) -> Self::Data;
622 }
623
624 pub trait HasModule {
625     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
626 }
627
628 impl HasModule for ItemContainerId {
629     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
630         match *self {
631             ItemContainerId::ModuleId(it) => it,
632             ItemContainerId::ImplId(it) => it.lookup(db).container,
633             ItemContainerId::TraitId(it) => it.lookup(db).container,
634             ItemContainerId::ExternBlockId(it) => it.lookup(db).container,
635         }
636     }
637 }
638
639 impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> {
640     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
641         self.container.module(db)
642     }
643 }
644
645 impl HasModule for AdtId {
646     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
647         match self {
648             AdtId::StructId(it) => it.lookup(db).container,
649             AdtId::UnionId(it) => it.lookup(db).container,
650             AdtId::EnumId(it) => it.lookup(db).container,
651         }
652     }
653 }
654
655 impl HasModule for VariantId {
656     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
657         match self {
658             VariantId::EnumVariantId(it) => it.parent.lookup(db).container,
659             VariantId::StructId(it) => it.lookup(db).container,
660             VariantId::UnionId(it) => it.lookup(db).container,
661         }
662     }
663 }
664
665 impl HasModule for MacroId {
666     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
667         match self {
668             MacroId::MacroRulesId(it) => it.lookup(db).container,
669             MacroId::Macro2Id(it) => it.lookup(db).container,
670             MacroId::ProcMacroId(it) => it.lookup(db).container,
671         }
672     }
673 }
674
675 impl HasModule for DefWithBodyId {
676     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
677         match self {
678             DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
679             DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
680             DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
681         }
682     }
683 }
684
685 impl DefWithBodyId {
686     pub fn as_mod_item(self, db: &dyn db::DefDatabase) -> ModItem {
687         match self {
688             DefWithBodyId::FunctionId(it) => it.lookup(db).id.value.into(),
689             DefWithBodyId::StaticId(it) => it.lookup(db).id.value.into(),
690             DefWithBodyId::ConstId(it) => it.lookup(db).id.value.into(),
691         }
692     }
693 }
694
695 impl HasModule for GenericDefId {
696     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
697         match self {
698             GenericDefId::FunctionId(it) => it.lookup(db).module(db),
699             GenericDefId::AdtId(it) => it.module(db),
700             GenericDefId::TraitId(it) => it.lookup(db).container,
701             GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
702             GenericDefId::ImplId(it) => it.lookup(db).container,
703             GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
704             GenericDefId::ConstId(it) => it.lookup(db).module(db),
705         }
706     }
707 }
708
709 impl HasModule for TypeAliasId {
710     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
711         self.lookup(db).module(db)
712     }
713 }
714
715 impl HasModule for TraitId {
716     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
717         self.lookup(db).container
718     }
719 }
720
721 impl ModuleDefId {
722     /// Returns the module containing `self` (or `self`, if `self` is itself a module).
723     ///
724     /// Returns `None` if `self` refers to a primitive type.
725     pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
726         Some(match self {
727             ModuleDefId::ModuleId(id) => *id,
728             ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
729             ModuleDefId::AdtId(id) => id.module(db),
730             ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
731             ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
732             ModuleDefId::StaticId(id) => id.lookup(db).module(db),
733             ModuleDefId::TraitId(id) => id.lookup(db).container,
734             ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
735             ModuleDefId::MacroId(id) => id.module(db),
736             ModuleDefId::BuiltinType(_) => return None,
737         })
738     }
739 }
740
741 impl AttrDefId {
742     pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
743         match self {
744             AttrDefId::ModuleId(it) => it.krate,
745             AttrDefId::FieldId(it) => it.parent.module(db).krate,
746             AttrDefId::AdtId(it) => it.module(db).krate,
747             AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
748             AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.krate,
749             AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
750             AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
751             AttrDefId::TraitId(it) => it.lookup(db).container.krate,
752             AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
753             AttrDefId::ImplId(it) => it.lookup(db).container.krate,
754             AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate,
755             AttrDefId::GenericParamId(it) => {
756                 match it {
757                     GenericParamId::TypeParamId(it) => it.parent(),
758                     GenericParamId::ConstParamId(it) => it.parent(),
759                     GenericParamId::LifetimeParamId(it) => it.parent,
760                 }
761                 .module(db)
762                 .krate
763             }
764             AttrDefId::MacroId(it) => it.module(db).krate,
765         }
766     }
767 }
768
769 /// A helper trait for converting to MacroCallId
770 pub trait AsMacroCall {
771     fn as_call_id(
772         &self,
773         db: &dyn db::DefDatabase,
774         krate: CrateId,
775         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
776     ) -> Option<MacroCallId> {
777         self.as_call_id_with_errors(db, krate, resolver, &mut |_| ()).ok()?.ok()
778     }
779
780     fn as_call_id_with_errors(
781         &self,
782         db: &dyn db::DefDatabase,
783         krate: CrateId,
784         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
785         error_sink: &mut dyn FnMut(ExpandError),
786     ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro>;
787 }
788
789 impl AsMacroCall for InFile<&ast::MacroCall> {
790     fn as_call_id_with_errors(
791         &self,
792         db: &dyn db::DefDatabase,
793         krate: CrateId,
794         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
795         mut error_sink: &mut dyn FnMut(ExpandError),
796     ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
797         let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
798         let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
799         let h = Hygiene::new(db.upcast(), self.file_id);
800         let path =
801             self.value.path().and_then(|path| path::ModPath::from_src(db.upcast(), path, &h));
802
803         let path = match error_sink
804             .option(path, || ExpandError::Other("malformed macro invocation".into()))
805         {
806             Ok(path) => path,
807             Err(error) => {
808                 return Ok(Err(error));
809             }
810         };
811
812         macro_call_as_call_id(
813             db,
814             &AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
815             expands_to,
816             krate,
817             resolver,
818             error_sink,
819         )
820     }
821 }
822
823 /// Helper wrapper for `AstId` with `ModPath`
824 #[derive(Clone, Debug, Eq, PartialEq)]
825 struct AstIdWithPath<T: ast::AstNode> {
826     ast_id: AstId<T>,
827     path: path::ModPath,
828 }
829
830 impl<T: ast::AstNode> AstIdWithPath<T> {
831     fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T> {
832         AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
833     }
834 }
835
836 fn macro_call_as_call_id(
837     db: &dyn db::DefDatabase,
838     call: &AstIdWithPath<ast::MacroCall>,
839     expand_to: ExpandTo,
840     krate: CrateId,
841     resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
842     error_sink: &mut dyn FnMut(ExpandError),
843 ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
844     let def =
845         resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
846
847     let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
848         let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
849
850         expand_eager_macro(db.upcast(), krate, macro_call, def, &resolver, error_sink)?
851     } else {
852         Ok(def.as_lazy_macro(
853             db.upcast(),
854             krate,
855             MacroCallKind::FnLike { ast_id: call.ast_id, expand_to },
856         ))
857     };
858     Ok(res)
859 }
860
861 pub fn macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId {
862     match id {
863         MacroId::Macro2Id(it) => {
864             let loc = it.lookup(db);
865
866             let item_tree = loc.id.item_tree(db);
867             let makro = &item_tree[loc.id.value];
868             let in_file = |m: FileAstId<ast::MacroDef>| InFile::new(loc.id.file_id(), m.upcast());
869             MacroDefId {
870                 krate: loc.container.krate,
871                 kind: match loc.expander {
872                     MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
873                     MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
874                     MacroExpander::BuiltInAttr(it) => {
875                         MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
876                     }
877                     MacroExpander::BuiltInDerive(it) => {
878                         MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
879                     }
880                     MacroExpander::BuiltInEager(it) => {
881                         MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
882                     }
883                 },
884                 local_inner: false,
885             }
886         }
887         MacroId::MacroRulesId(it) => {
888             let loc = it.lookup(db);
889
890             let item_tree = loc.id.item_tree(db);
891             let makro = &item_tree[loc.id.value];
892             let in_file = |m: FileAstId<ast::MacroRules>| InFile::new(loc.id.file_id(), m.upcast());
893             MacroDefId {
894                 krate: loc.container.krate,
895                 kind: match loc.expander {
896                     MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
897                     MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
898                     MacroExpander::BuiltInAttr(it) => {
899                         MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
900                     }
901                     MacroExpander::BuiltInDerive(it) => {
902                         MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
903                     }
904                     MacroExpander::BuiltInEager(it) => {
905                         MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
906                     }
907                 },
908                 local_inner: loc.local_inner,
909             }
910         }
911         MacroId::ProcMacroId(it) => {
912             let loc = it.lookup(db);
913
914             let item_tree = loc.id.item_tree(db);
915             let makro = &item_tree[loc.id.value];
916             MacroDefId {
917                 krate: loc.container.krate,
918                 kind: MacroDefKind::ProcMacro(
919                     loc.expander,
920                     loc.kind,
921                     InFile::new(loc.id.file_id(), makro.ast_id),
922                 ),
923                 local_inner: false,
924             }
925         }
926     }
927 }
928
929 fn derive_macro_as_call_id(
930     db: &dyn db::DefDatabase,
931     item_attr: &AstIdWithPath<ast::Adt>,
932     derive_attr: AttrId,
933     derive_pos: u32,
934     krate: CrateId,
935     resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
936 ) -> Result<MacroCallId, UnresolvedMacro> {
937     let def: MacroDefId = resolver(item_attr.path.clone())
938         .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
939     let res = def.as_lazy_macro(
940         db.upcast(),
941         krate,
942         MacroCallKind::Derive {
943             ast_id: item_attr.ast_id,
944             derive_index: derive_pos,
945             derive_attr_index: derive_attr.ast_index,
946         },
947     );
948     Ok(res)
949 }
950
951 fn attr_macro_as_call_id(
952     db: &dyn db::DefDatabase,
953     item_attr: &AstIdWithPath<ast::Item>,
954     macro_attr: &Attr,
955     krate: CrateId,
956     def: MacroDefId,
957     is_derive: bool,
958 ) -> MacroCallId {
959     let mut arg = match macro_attr.input.as_deref() {
960         Some(attr::AttrInput::TokenTree(tt, map)) => (tt.clone(), map.clone()),
961         _ => Default::default(),
962     };
963
964     // The parentheses are always disposed here.
965     arg.0.delimiter = None;
966
967     let res = def.as_lazy_macro(
968         db.upcast(),
969         krate,
970         MacroCallKind::Attr {
971             ast_id: item_attr.ast_id,
972             attr_args: Arc::new(arg),
973             invoc_attr_index: macro_attr.id.ast_index,
974             is_derive,
975         },
976     );
977     res
978 }