]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/lib.rs
Merge #11513
[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};
62 use hir_expand::{
63     ast_id_map::FileAstId,
64     eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
65     hygiene::Hygiene,
66     AstId, ExpandError, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
67     MacroDefKind, UnresolvedMacro,
68 };
69 use item_tree::ExternBlock;
70 use la_arena::Idx;
71 use nameres::DefMap;
72 use stdx::impl_from;
73 use syntax::ast;
74
75 use crate::{
76     adt::VariantData,
77     attr::AttrId,
78     builtin_type::BuiltinType,
79     item_tree::{
80         Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait,
81         TypeAlias, Union,
82     },
83 };
84
85 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
86 pub struct ModuleId {
87     krate: CrateId,
88     /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the
89     /// `BlockId` of that block expression. If `None`, this module is part of the crate-level
90     /// `DefMap` of `krate`.
91     block: Option<BlockId>,
92     /// The module's ID in its originating `DefMap`.
93     pub local_id: LocalModuleId,
94 }
95
96 impl ModuleId {
97     pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
98         match self.block {
99             Some(block) => {
100                 db.block_def_map(block).unwrap_or_else(|| {
101                     // NOTE: This should be unreachable - all `ModuleId`s come from their `DefMap`s,
102                     // so the `DefMap` here must exist.
103                     unreachable!("no `block_def_map` for `ModuleId` {:?}", self);
104                 })
105             }
106             None => db.crate_def_map(self.krate),
107         }
108     }
109
110     pub fn krate(&self) -> CrateId {
111         self.krate
112     }
113
114     pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
115         self.def_map(db).containing_module(self.local_id)
116     }
117
118     pub fn containing_block(&self) -> Option<BlockId> {
119         self.block
120     }
121 }
122
123 /// An ID of a module, **local** to a specific crate
124 pub type LocalModuleId = Idx<nameres::ModuleData>;
125
126 #[derive(Debug)]
127 pub struct ItemLoc<N: ItemTreeNode> {
128     pub container: ModuleId,
129     pub id: ItemTreeId<N>,
130 }
131
132 impl<N: ItemTreeNode> Clone for ItemLoc<N> {
133     fn clone(&self) -> Self {
134         Self { container: self.container, id: self.id }
135     }
136 }
137
138 impl<N: ItemTreeNode> Copy for ItemLoc<N> {}
139
140 impl<N: ItemTreeNode> PartialEq for ItemLoc<N> {
141     fn eq(&self, other: &Self) -> bool {
142         self.container == other.container && self.id == other.id
143     }
144 }
145
146 impl<N: ItemTreeNode> Eq for ItemLoc<N> {}
147
148 impl<N: ItemTreeNode> Hash for ItemLoc<N> {
149     fn hash<H: Hasher>(&self, state: &mut H) {
150         self.container.hash(state);
151         self.id.hash(state);
152     }
153 }
154
155 #[derive(Debug)]
156 pub struct AssocItemLoc<N: ItemTreeNode> {
157     pub container: ItemContainerId,
158     pub id: ItemTreeId<N>,
159 }
160
161 impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
162     fn clone(&self) -> Self {
163         Self { container: self.container, id: self.id }
164     }
165 }
166
167 impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
168
169 impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
170     fn eq(&self, other: &Self) -> bool {
171         self.container == other.container && self.id == other.id
172     }
173 }
174
175 impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {}
176
177 impl<N: ItemTreeNode> Hash for AssocItemLoc<N> {
178     fn hash<H: Hasher>(&self, state: &mut H) {
179         self.container.hash(state);
180         self.id.hash(state);
181     }
182 }
183
184 macro_rules! impl_intern {
185     ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
186         impl_intern_key!($id);
187
188         impl Intern for $loc {
189             type ID = $id;
190             fn intern(self, db: &dyn db::DefDatabase) -> $id {
191                 db.$intern(self)
192             }
193         }
194
195         impl Lookup for $id {
196             type Data = $loc;
197             fn lookup(&self, db: &dyn db::DefDatabase) -> $loc {
198                 db.$lookup(*self)
199             }
200         }
201     };
202 }
203
204 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
205 pub struct FunctionId(salsa::InternId);
206 type FunctionLoc = AssocItemLoc<Function>;
207 impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
208
209 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
210 pub struct StructId(salsa::InternId);
211 type StructLoc = ItemLoc<Struct>;
212 impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
213
214 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
215 pub struct UnionId(salsa::InternId);
216 pub type UnionLoc = ItemLoc<Union>;
217 impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
218
219 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
220 pub struct EnumId(salsa::InternId);
221 pub type EnumLoc = ItemLoc<Enum>;
222 impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
223
224 // FIXME: rename to `VariantId`, only enums can ave variants
225 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
226 pub struct EnumVariantId {
227     pub parent: EnumId,
228     pub local_id: LocalEnumVariantId,
229 }
230
231 pub type LocalEnumVariantId = Idx<adt::EnumVariantData>;
232
233 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
234 pub struct FieldId {
235     pub parent: VariantId,
236     pub local_id: LocalFieldId,
237 }
238
239 pub type LocalFieldId = Idx<adt::FieldData>;
240
241 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
242 pub struct ConstId(salsa::InternId);
243 type ConstLoc = AssocItemLoc<Const>;
244 impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
245
246 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
247 pub struct StaticId(salsa::InternId);
248 pub type StaticLoc = AssocItemLoc<Static>;
249 impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
250
251 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
252 pub struct TraitId(salsa::InternId);
253 pub type TraitLoc = ItemLoc<Trait>;
254 impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
255
256 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
257 pub struct TypeAliasId(salsa::InternId);
258 type TypeAliasLoc = AssocItemLoc<TypeAlias>;
259 impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
260
261 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
262 pub struct ImplId(salsa::InternId);
263 type ImplLoc = ItemLoc<Impl>;
264 impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
265
266 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
267 pub struct ExternBlockId(salsa::InternId);
268 type ExternBlockLoc = ItemLoc<ExternBlock>;
269 impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
270
271 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
272 pub struct BlockId(salsa::InternId);
273 #[derive(Debug, Hash, PartialEq, Eq, Clone)]
274 pub struct BlockLoc {
275     ast_id: AstId<ast::BlockExpr>,
276     /// The containing module.
277     module: ModuleId,
278 }
279 impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
280
281 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
282 pub struct TypeParamId {
283     pub parent: GenericDefId,
284     pub local_id: LocalTypeParamId,
285 }
286
287 pub type LocalTypeParamId = Idx<generics::TypeParamData>;
288
289 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
290 pub struct LifetimeParamId {
291     pub parent: GenericDefId,
292     pub local_id: LocalLifetimeParamId,
293 }
294 pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
295
296 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
297 pub struct ConstParamId {
298     pub parent: GenericDefId,
299     pub local_id: LocalConstParamId,
300 }
301 pub type LocalConstParamId = Idx<generics::ConstParamData>;
302
303 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
304 pub enum ItemContainerId {
305     ExternBlockId(ExternBlockId),
306     ModuleId(ModuleId),
307     ImplId(ImplId),
308     TraitId(TraitId),
309 }
310 impl_from!(ModuleId for ItemContainerId);
311
312 /// A Data Type
313 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
314 pub enum AdtId {
315     StructId(StructId),
316     UnionId(UnionId),
317     EnumId(EnumId),
318 }
319 impl_from!(StructId, UnionId, EnumId for AdtId);
320
321 /// A generic param
322 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
323 pub enum GenericParamId {
324     TypeParamId(TypeParamId),
325     LifetimeParamId(LifetimeParamId),
326     ConstParamId(ConstParamId),
327 }
328 impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
329
330 /// The defs which can be visible in the module.
331 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
332 pub enum ModuleDefId {
333     ModuleId(ModuleId),
334     FunctionId(FunctionId),
335     AdtId(AdtId),
336     // Can't be directly declared, but can be imported.
337     EnumVariantId(EnumVariantId),
338     ConstId(ConstId),
339     StaticId(StaticId),
340     TraitId(TraitId),
341     TypeAliasId(TypeAliasId),
342     BuiltinType(BuiltinType),
343 }
344 impl_from!(
345     ModuleId,
346     FunctionId,
347     AdtId(StructId, EnumId, UnionId),
348     EnumVariantId,
349     ConstId,
350     StaticId,
351     TraitId,
352     TypeAliasId,
353     BuiltinType
354     for ModuleDefId
355 );
356
357 /// The defs which have a body.
358 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
359 pub enum DefWithBodyId {
360     FunctionId(FunctionId),
361     StaticId(StaticId),
362     ConstId(ConstId),
363 }
364
365 impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
366
367 impl DefWithBodyId {
368     pub fn as_generic_def_id(self) -> Option<GenericDefId> {
369         match self {
370             DefWithBodyId::FunctionId(f) => Some(f.into()),
371             DefWithBodyId::StaticId(_) => None,
372             DefWithBodyId::ConstId(c) => Some(c.into()),
373         }
374     }
375 }
376
377 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
378 pub enum AssocItemId {
379     FunctionId(FunctionId),
380     ConstId(ConstId),
381     TypeAliasId(TypeAliasId),
382 }
383 // FIXME: not every function, ... is actually an assoc item. maybe we should make
384 // sure that you can only turn actual assoc items into AssocItemIds. This would
385 // require not implementing From, and instead having some checked way of
386 // casting them, and somehow making the constructors private, which would be annoying.
387 impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
388
389 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
390 pub enum GenericDefId {
391     FunctionId(FunctionId),
392     AdtId(AdtId),
393     TraitId(TraitId),
394     TypeAliasId(TypeAliasId),
395     ImplId(ImplId),
396     // enum variants cannot have generics themselves, but their parent enums
397     // can, and this makes some code easier to write
398     EnumVariantId(EnumVariantId),
399     // consts can have type parameters from their parents (i.e. associated consts of traits)
400     ConstId(ConstId),
401 }
402 impl_from!(
403     FunctionId,
404     AdtId(StructId, EnumId, UnionId),
405     TraitId,
406     TypeAliasId,
407     ImplId,
408     EnumVariantId,
409     ConstId
410     for GenericDefId
411 );
412
413 impl From<AssocItemId> for GenericDefId {
414     fn from(item: AssocItemId) -> Self {
415         match item {
416             AssocItemId::FunctionId(f) => f.into(),
417             AssocItemId::ConstId(c) => c.into(),
418             AssocItemId::TypeAliasId(t) => t.into(),
419         }
420     }
421 }
422
423 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
424 pub enum AttrDefId {
425     ModuleId(ModuleId),
426     FieldId(FieldId),
427     AdtId(AdtId),
428     FunctionId(FunctionId),
429     EnumVariantId(EnumVariantId),
430     StaticId(StaticId),
431     ConstId(ConstId),
432     TraitId(TraitId),
433     TypeAliasId(TypeAliasId),
434     MacroDefId(MacroDefId),
435     ImplId(ImplId),
436     GenericParamId(GenericParamId),
437     ExternBlockId(ExternBlockId),
438 }
439
440 impl_from!(
441     ModuleId,
442     FieldId,
443     AdtId(StructId, EnumId, UnionId),
444     EnumVariantId,
445     StaticId,
446     ConstId,
447     FunctionId,
448     TraitId,
449     TypeAliasId,
450     MacroDefId,
451     ImplId,
452     GenericParamId
453     for AttrDefId
454 );
455
456 impl From<ItemContainerId> for AttrDefId {
457     fn from(acid: ItemContainerId) -> Self {
458         match acid {
459             ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
460             ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
461             ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
462             ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
463         }
464     }
465 }
466
467 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
468 pub enum VariantId {
469     EnumVariantId(EnumVariantId),
470     StructId(StructId),
471     UnionId(UnionId),
472 }
473 impl_from!(EnumVariantId, StructId, UnionId for VariantId);
474
475 impl VariantId {
476     pub fn variant_data(self, db: &dyn db::DefDatabase) -> Arc<VariantData> {
477         match self {
478             VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
479             VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
480             VariantId::EnumVariantId(it) => {
481                 db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
482             }
483         }
484     }
485
486     pub fn file_id(self, db: &dyn db::DefDatabase) -> HirFileId {
487         match self {
488             VariantId::EnumVariantId(it) => it.parent.lookup(db).id.file_id(),
489             VariantId::StructId(it) => it.lookup(db).id.file_id(),
490             VariantId::UnionId(it) => it.lookup(db).id.file_id(),
491         }
492     }
493
494     pub fn adt_id(self) -> AdtId {
495         match self {
496             VariantId::EnumVariantId(it) => it.parent.into(),
497             VariantId::StructId(it) => it.into(),
498             VariantId::UnionId(it) => it.into(),
499         }
500     }
501 }
502
503 trait Intern {
504     type ID;
505     fn intern(self, db: &dyn db::DefDatabase) -> Self::ID;
506 }
507
508 pub trait Lookup {
509     type Data;
510     fn lookup(&self, db: &dyn db::DefDatabase) -> Self::Data;
511 }
512
513 pub trait HasModule {
514     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
515 }
516
517 impl HasModule for ItemContainerId {
518     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
519         match *self {
520             ItemContainerId::ModuleId(it) => it,
521             ItemContainerId::ImplId(it) => it.lookup(db).container,
522             ItemContainerId::TraitId(it) => it.lookup(db).container,
523             ItemContainerId::ExternBlockId(it) => it.lookup(db).container,
524         }
525     }
526 }
527
528 impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> {
529     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
530         self.container.module(db)
531     }
532 }
533
534 impl HasModule for AdtId {
535     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
536         match self {
537             AdtId::StructId(it) => it.lookup(db).container,
538             AdtId::UnionId(it) => it.lookup(db).container,
539             AdtId::EnumId(it) => it.lookup(db).container,
540         }
541     }
542 }
543
544 impl HasModule for VariantId {
545     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
546         match self {
547             VariantId::EnumVariantId(it) => it.parent.lookup(db).container,
548             VariantId::StructId(it) => it.lookup(db).container,
549             VariantId::UnionId(it) => it.lookup(db).container,
550         }
551     }
552 }
553
554 impl HasModule for DefWithBodyId {
555     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
556         match self {
557             DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
558             DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
559             DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
560         }
561     }
562 }
563
564 impl DefWithBodyId {
565     pub fn as_mod_item(self, db: &dyn db::DefDatabase) -> ModItem {
566         match self {
567             DefWithBodyId::FunctionId(it) => it.lookup(db).id.value.into(),
568             DefWithBodyId::StaticId(it) => it.lookup(db).id.value.into(),
569             DefWithBodyId::ConstId(it) => it.lookup(db).id.value.into(),
570         }
571     }
572 }
573
574 impl HasModule for GenericDefId {
575     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
576         match self {
577             GenericDefId::FunctionId(it) => it.lookup(db).module(db),
578             GenericDefId::AdtId(it) => it.module(db),
579             GenericDefId::TraitId(it) => it.lookup(db).container,
580             GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
581             GenericDefId::ImplId(it) => it.lookup(db).container,
582             GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
583             GenericDefId::ConstId(it) => it.lookup(db).module(db),
584         }
585     }
586 }
587
588 impl HasModule for TypeAliasId {
589     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
590         self.lookup(db).module(db)
591     }
592 }
593
594 impl HasModule for TraitId {
595     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
596         self.lookup(db).container
597     }
598 }
599
600 impl ModuleDefId {
601     /// Returns the module containing `self` (or `self`, if `self` is itself a module).
602     ///
603     /// Returns `None` if `self` refers to a primitive type.
604     pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
605         Some(match self {
606             ModuleDefId::ModuleId(id) => *id,
607             ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
608             ModuleDefId::AdtId(id) => id.module(db),
609             ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
610             ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
611             ModuleDefId::StaticId(id) => id.lookup(db).module(db),
612             ModuleDefId::TraitId(id) => id.lookup(db).container,
613             ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
614             ModuleDefId::BuiltinType(_) => return None,
615         })
616     }
617 }
618
619 impl AttrDefId {
620     pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
621         match self {
622             AttrDefId::ModuleId(it) => it.krate,
623             AttrDefId::FieldId(it) => it.parent.module(db).krate,
624             AttrDefId::AdtId(it) => it.module(db).krate,
625             AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
626             AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.krate,
627             AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
628             AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
629             AttrDefId::TraitId(it) => it.lookup(db).container.krate,
630             AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
631             AttrDefId::ImplId(it) => it.lookup(db).container.krate,
632             AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate,
633             AttrDefId::GenericParamId(it) => {
634                 match it {
635                     GenericParamId::TypeParamId(it) => it.parent,
636                     GenericParamId::LifetimeParamId(it) => it.parent,
637                     GenericParamId::ConstParamId(it) => it.parent,
638                 }
639                 .module(db)
640                 .krate
641             }
642             // FIXME: `MacroDefId` should store the defining module, then this can implement
643             // `HasModule`
644             AttrDefId::MacroDefId(it) => it.krate,
645         }
646     }
647 }
648
649 /// A helper trait for converting to MacroCallId
650 pub trait AsMacroCall {
651     fn as_call_id(
652         &self,
653         db: &dyn db::DefDatabase,
654         krate: CrateId,
655         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
656     ) -> Option<MacroCallId> {
657         self.as_call_id_with_errors(db, krate, resolver, &mut |_| ()).ok()?.ok()
658     }
659
660     fn as_call_id_with_errors(
661         &self,
662         db: &dyn db::DefDatabase,
663         krate: CrateId,
664         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
665         error_sink: &mut dyn FnMut(ExpandError),
666     ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro>;
667 }
668
669 impl AsMacroCall for InFile<&ast::MacroCall> {
670     fn as_call_id_with_errors(
671         &self,
672         db: &dyn db::DefDatabase,
673         krate: CrateId,
674         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
675         mut error_sink: &mut dyn FnMut(ExpandError),
676     ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
677         let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
678         let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
679         let h = Hygiene::new(db.upcast(), self.file_id);
680         let path =
681             self.value.path().and_then(|path| path::ModPath::from_src(db.upcast(), path, &h));
682
683         let path = match error_sink
684             .option(path, || ExpandError::Other("malformed macro invocation".into()))
685         {
686             Ok(path) => path,
687             Err(error) => {
688                 return Ok(Err(error));
689             }
690         };
691
692         macro_call_as_call_id(
693             db,
694             &AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
695             expands_to,
696             krate,
697             resolver,
698             error_sink,
699         )
700     }
701 }
702
703 /// Helper wrapper for `AstId` with `ModPath`
704 #[derive(Clone, Debug, Eq, PartialEq)]
705 struct AstIdWithPath<T: ast::AstNode> {
706     ast_id: AstId<T>,
707     path: path::ModPath,
708 }
709
710 impl<T: ast::AstNode> AstIdWithPath<T> {
711     fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T> {
712         AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
713     }
714 }
715
716 fn macro_call_as_call_id(
717     db: &dyn db::DefDatabase,
718     call: &AstIdWithPath<ast::MacroCall>,
719     expand_to: ExpandTo,
720     krate: CrateId,
721     resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
722     error_sink: &mut dyn FnMut(ExpandError),
723 ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
724     let def: MacroDefId =
725         resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
726
727     let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
728         let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
729
730         expand_eager_macro(db.upcast(), krate, macro_call, def, &resolver, error_sink)?
731     } else {
732         Ok(def.as_lazy_macro(
733             db.upcast(),
734             krate,
735             MacroCallKind::FnLike { ast_id: call.ast_id, expand_to },
736         ))
737     };
738     Ok(res)
739 }
740
741 fn derive_macro_as_call_id(
742     db: &dyn db::DefDatabase,
743     item_attr: &AstIdWithPath<ast::Adt>,
744     derive_attr: AttrId,
745     derive_pos: u32,
746     krate: CrateId,
747     resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
748 ) -> Result<MacroCallId, UnresolvedMacro> {
749     let def: MacroDefId = resolver(item_attr.path.clone())
750         .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
751     let res = def.as_lazy_macro(
752         db.upcast(),
753         krate,
754         MacroCallKind::Derive {
755             ast_id: item_attr.ast_id,
756             derive_index: derive_pos,
757             derive_attr_index: derive_attr.ast_index,
758         },
759     );
760     Ok(res)
761 }
762
763 fn attr_macro_as_call_id(
764     db: &dyn db::DefDatabase,
765     item_attr: &AstIdWithPath<ast::Item>,
766     macro_attr: &Attr,
767     krate: CrateId,
768     def: MacroDefId,
769     is_derive: bool,
770 ) -> MacroCallId {
771     let mut arg = match macro_attr.input.as_deref() {
772         Some(attr::AttrInput::TokenTree(tt, map)) => (tt.clone(), map.clone()),
773         _ => Default::default(),
774     };
775
776     // The parentheses are always disposed here.
777     arg.0.delimiter = None;
778
779     let res = def.as_lazy_macro(
780         db.upcast(),
781         krate,
782         MacroCallKind::Attr {
783             ast_id: item_attr.ast_id,
784             attr_args: Arc::new(arg),
785             invoc_attr_index: macro_attr.id.ast_index,
786             is_derive,
787         },
788     );
789     res
790 }