• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
11 
12 #[allow(unused)]
13 macro_rules! eprintln {
14     ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
15 }
16 
17 pub mod db;
18 
19 pub mod attr;
20 pub mod path;
21 pub mod builtin_type;
22 pub mod per_ns;
23 pub mod item_scope;
24 
25 pub mod lower;
26 pub mod expander;
27 
28 pub mod dyn_map;
29 
30 pub mod item_tree;
31 
32 pub mod data;
33 pub mod generics;
34 pub mod lang_item;
35 
36 pub mod hir;
37 pub use self::hir::type_ref;
38 pub mod body;
39 pub mod resolver;
40 
41 mod trace;
42 pub mod nameres;
43 
44 pub mod src;
45 pub mod child_by_source;
46 
47 pub mod visibility;
48 pub mod find_path;
49 pub mod import_map;
50 
51 pub use rustc_abi as layout;
52 use triomphe::Arc;
53 
54 #[cfg(test)]
55 mod test_db;
56 #[cfg(test)]
57 mod macro_expansion_tests;
58 mod pretty;
59 
60 use std::{
61     hash::{Hash, Hasher},
62     panic::{RefUnwindSafe, UnwindSafe},
63 };
64 
65 use base_db::{impl_intern_key, salsa, CrateId, ProcMacroKind};
66 use hir_expand::{
67     ast_id_map::FileAstId,
68     attrs::{Attr, AttrId, AttrInput},
69     builtin_attr_macro::BuiltinAttrExpander,
70     builtin_derive_macro::BuiltinDeriveExpander,
71     builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
72     db::ExpandDatabase,
73     eager::expand_eager_macro_input,
74     hygiene::Hygiene,
75     proc_macro::ProcMacroExpander,
76     AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind,
77     MacroDefId, MacroDefKind, UnresolvedMacro,
78 };
79 use item_tree::ExternBlock;
80 use la_arena::Idx;
81 use nameres::DefMap;
82 use stdx::impl_from;
83 use syntax::ast;
84 
85 use ::tt::token_id as tt;
86 
87 use crate::{
88     builtin_type::BuiltinType,
89     data::adt::VariantData,
90     item_tree::{
91         Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, Static,
92         Struct, Trait, TraitAlias, TypeAlias, Union,
93     },
94 };
95 
96 /// A `ModuleId` that is always a crate's root module.
97 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
98 pub struct CrateRootModuleId {
99     krate: CrateId,
100 }
101 
102 impl CrateRootModuleId {
def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap>103     pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
104         db.crate_def_map(self.krate)
105     }
106 
krate(self) -> CrateId107     pub fn krate(self) -> CrateId {
108         self.krate
109     }
110 }
111 
112 impl From<CrateRootModuleId> for ModuleId {
113     fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
114         ModuleId { krate, block: None, local_id: DefMap::ROOT }
115     }
116 }
117 
118 impl From<CrateRootModuleId> for ModuleDefId {
from(value: CrateRootModuleId) -> Self119     fn from(value: CrateRootModuleId) -> Self {
120         ModuleDefId::ModuleId(value.into())
121     }
122 }
123 
124 impl TryFrom<ModuleId> for CrateRootModuleId {
125     type Error = ();
126 
127     fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> {
128         if block.is_none() && local_id == DefMap::ROOT {
129             Ok(CrateRootModuleId { krate })
130         } else {
131             Err(())
132         }
133     }
134 }
135 
136 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
137 pub struct ModuleId {
138     krate: CrateId,
139     /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the
140     /// `BlockId` of that block expression. If `None`, this module is part of the crate-level
141     /// `DefMap` of `krate`.
142     block: Option<BlockId>,
143     /// The module's ID in its originating `DefMap`.
144     pub local_id: LocalModuleId,
145 }
146 
147 impl ModuleId {
def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap>148     pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
149         match self.block {
150             Some(block) => db.block_def_map(block),
151             None => db.crate_def_map(self.krate),
152         }
153     }
154 
krate(&self) -> CrateId155     pub fn krate(&self) -> CrateId {
156         self.krate
157     }
158 
containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId>159     pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
160         self.def_map(db).containing_module(self.local_id)
161     }
162 
containing_block(&self) -> Option<BlockId>163     pub fn containing_block(&self) -> Option<BlockId> {
164         self.block
165     }
166 }
167 
168 /// An ID of a module, **local** to a `DefMap`.
169 pub type LocalModuleId = Idx<nameres::ModuleData>;
170 
171 #[derive(Debug)]
172 pub struct ItemLoc<N: ItemTreeNode> {
173     pub container: ModuleId,
174     pub id: ItemTreeId<N>,
175 }
176 
177 impl<N: ItemTreeNode> Clone for ItemLoc<N> {
clone(&self) -> Self178     fn clone(&self) -> Self {
179         Self { container: self.container, id: self.id }
180     }
181 }
182 
183 impl<N: ItemTreeNode> Copy for ItemLoc<N> {}
184 
185 impl<N: ItemTreeNode> PartialEq for ItemLoc<N> {
eq(&self, other: &Self) -> bool186     fn eq(&self, other: &Self) -> bool {
187         self.container == other.container && self.id == other.id
188     }
189 }
190 
191 impl<N: ItemTreeNode> Eq for ItemLoc<N> {}
192 
193 impl<N: ItemTreeNode> Hash for ItemLoc<N> {
hash<H: Hasher>(&self, state: &mut H)194     fn hash<H: Hasher>(&self, state: &mut H) {
195         self.container.hash(state);
196         self.id.hash(state);
197     }
198 }
199 
200 #[derive(Debug)]
201 pub struct AssocItemLoc<N: ItemTreeNode> {
202     pub container: ItemContainerId,
203     pub id: ItemTreeId<N>,
204 }
205 
206 impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
clone(&self) -> Self207     fn clone(&self) -> Self {
208         Self { container: self.container, id: self.id }
209     }
210 }
211 
212 impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
213 
214 impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
eq(&self, other: &Self) -> bool215     fn eq(&self, other: &Self) -> bool {
216         self.container == other.container && self.id == other.id
217     }
218 }
219 
220 impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {}
221 
222 impl<N: ItemTreeNode> Hash for AssocItemLoc<N> {
hash<H: Hasher>(&self, state: &mut H)223     fn hash<H: Hasher>(&self, state: &mut H) {
224         self.container.hash(state);
225         self.id.hash(state);
226     }
227 }
228 
229 macro_rules! impl_intern {
230     ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
231         impl_intern_key!($id);
232 
233         impl Intern for $loc {
234             type ID = $id;
235             fn intern(self, db: &dyn db::DefDatabase) -> $id {
236                 db.$intern(self)
237             }
238         }
239 
240         impl Lookup for $id {
241             type Data = $loc;
242             fn lookup(&self, db: &dyn db::DefDatabase) -> $loc {
243                 db.$lookup(*self)
244             }
245         }
246     };
247 }
248 
249 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
250 pub struct FunctionId(salsa::InternId);
251 type FunctionLoc = AssocItemLoc<Function>;
252 impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
253 
254 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
255 pub struct StructId(salsa::InternId);
256 type StructLoc = ItemLoc<Struct>;
257 impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
258 
259 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
260 pub struct UnionId(salsa::InternId);
261 pub type UnionLoc = ItemLoc<Union>;
262 impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
263 
264 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
265 pub struct EnumId(salsa::InternId);
266 pub type EnumLoc = ItemLoc<Enum>;
267 impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
268 
269 // FIXME: rename to `VariantId`, only enums can ave variants
270 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
271 pub struct EnumVariantId {
272     pub parent: EnumId,
273     pub local_id: LocalEnumVariantId,
274 }
275 
276 pub type LocalEnumVariantId = Idx<data::adt::EnumVariantData>;
277 
278 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
279 pub struct FieldId {
280     pub parent: VariantId,
281     pub local_id: LocalFieldId,
282 }
283 
284 pub type LocalFieldId = Idx<data::adt::FieldData>;
285 
286 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
287 pub struct ConstId(salsa::InternId);
288 type ConstLoc = AssocItemLoc<Const>;
289 impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
290 
291 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
292 pub struct StaticId(salsa::InternId);
293 pub type StaticLoc = AssocItemLoc<Static>;
294 impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
295 
296 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
297 pub struct TraitId(salsa::InternId);
298 pub type TraitLoc = ItemLoc<Trait>;
299 impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
300 
301 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
302 pub struct TraitAliasId(salsa::InternId);
303 pub type TraitAliasLoc = ItemLoc<TraitAlias>;
304 impl_intern!(TraitAliasId, TraitAliasLoc, intern_trait_alias, lookup_intern_trait_alias);
305 
306 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
307 pub struct TypeAliasId(salsa::InternId);
308 type TypeAliasLoc = AssocItemLoc<TypeAlias>;
309 impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
310 
311 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
312 pub struct ImplId(salsa::InternId);
313 type ImplLoc = ItemLoc<Impl>;
314 impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
315 
316 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
317 pub struct ExternBlockId(salsa::InternId);
318 type ExternBlockLoc = ItemLoc<ExternBlock>;
319 impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
320 
321 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
322 pub enum MacroExpander {
323     Declarative,
324     BuiltIn(BuiltinFnLikeExpander),
325     BuiltInAttr(BuiltinAttrExpander),
326     BuiltInDerive(BuiltinDeriveExpander),
327     BuiltInEager(EagerExpander),
328 }
329 
330 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
331 pub struct Macro2Id(salsa::InternId);
332 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
333 pub struct Macro2Loc {
334     pub container: ModuleId,
335     pub id: ItemTreeId<MacroDef>,
336     pub expander: MacroExpander,
337     pub allow_internal_unsafe: bool,
338 }
339 impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
340 
341 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
342 pub struct MacroRulesId(salsa::InternId);
343 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
344 pub struct MacroRulesLoc {
345     pub container: ModuleId,
346     pub id: ItemTreeId<MacroRules>,
347     pub expander: MacroExpander,
348     pub allow_internal_unsafe: bool,
349     pub local_inner: bool,
350 }
351 impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
352 
353 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
354 pub struct ProcMacroId(salsa::InternId);
355 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
356 pub struct ProcMacroLoc {
357     pub container: CrateRootModuleId,
358     pub id: ItemTreeId<Function>,
359     pub expander: ProcMacroExpander,
360     pub kind: ProcMacroKind,
361 }
362 impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
363 
364 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
365 pub struct BlockId(salsa::InternId);
366 #[derive(Debug, Hash, PartialEq, Eq, Clone)]
367 pub struct BlockLoc {
368     ast_id: AstId<ast::BlockExpr>,
369     /// The containing module.
370     module: ModuleId,
371 }
372 impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
373 
374 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
375 pub struct TypeOrConstParamId {
376     pub parent: GenericDefId,
377     pub local_id: LocalTypeOrConstParamId,
378 }
379 
380 /// A TypeOrConstParamId with an invariant that it actually belongs to a type
381 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
382 pub struct TypeParamId(TypeOrConstParamId);
383 
384 impl TypeParamId {
parent(&self) -> GenericDefId385     pub fn parent(&self) -> GenericDefId {
386         self.0.parent
387     }
local_id(&self) -> LocalTypeOrConstParamId388     pub fn local_id(&self) -> LocalTypeOrConstParamId {
389         self.0.local_id
390     }
391 }
392 
393 impl TypeParamId {
394     /// Caller should check if this toc id really belongs to a type
from_unchecked(x: TypeOrConstParamId) -> Self395     pub fn from_unchecked(x: TypeOrConstParamId) -> Self {
396         Self(x)
397     }
398 }
399 
400 impl From<TypeParamId> for TypeOrConstParamId {
from(x: TypeParamId) -> Self401     fn from(x: TypeParamId) -> Self {
402         x.0
403     }
404 }
405 
406 /// A TypeOrConstParamId with an invariant that it actually belongs to a const
407 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
408 pub struct ConstParamId(TypeOrConstParamId);
409 
410 impl ConstParamId {
parent(&self) -> GenericDefId411     pub fn parent(&self) -> GenericDefId {
412         self.0.parent
413     }
local_id(&self) -> LocalTypeOrConstParamId414     pub fn local_id(&self) -> LocalTypeOrConstParamId {
415         self.0.local_id
416     }
417 }
418 
419 impl ConstParamId {
420     /// Caller should check if this toc id really belongs to a const
from_unchecked(x: TypeOrConstParamId) -> Self421     pub fn from_unchecked(x: TypeOrConstParamId) -> Self {
422         Self(x)
423     }
424 }
425 
426 impl From<ConstParamId> for TypeOrConstParamId {
from(x: ConstParamId) -> Self427     fn from(x: ConstParamId) -> Self {
428         x.0
429     }
430 }
431 
432 pub type LocalTypeOrConstParamId = Idx<generics::TypeOrConstParamData>;
433 
434 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
435 pub struct LifetimeParamId {
436     pub parent: GenericDefId,
437     pub local_id: LocalLifetimeParamId,
438 }
439 pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
440 
441 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
442 pub enum ItemContainerId {
443     ExternBlockId(ExternBlockId),
444     ModuleId(ModuleId),
445     ImplId(ImplId),
446     TraitId(TraitId),
447 }
448 impl_from!(ModuleId for ItemContainerId);
449 
450 /// A Data Type
451 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
452 pub enum AdtId {
453     StructId(StructId),
454     UnionId(UnionId),
455     EnumId(EnumId),
456 }
457 impl_from!(StructId, UnionId, EnumId for AdtId);
458 
459 /// A macro
460 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
461 pub enum MacroId {
462     Macro2Id(Macro2Id),
463     MacroRulesId(MacroRulesId),
464     ProcMacroId(ProcMacroId),
465 }
466 impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
467 
468 impl MacroId {
is_attribute(self, db: &dyn db::DefDatabase) -> bool469     pub fn is_attribute(self, db: &dyn db::DefDatabase) -> bool {
470         match self {
471             MacroId::ProcMacroId(it) => it.lookup(db).kind == ProcMacroKind::Attr,
472             _ => false,
473         }
474     }
475 }
476 
477 /// A generic param
478 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
479 pub enum GenericParamId {
480     TypeParamId(TypeParamId),
481     ConstParamId(ConstParamId),
482     LifetimeParamId(LifetimeParamId),
483 }
484 impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
485 
486 /// The defs which can be visible in the module.
487 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
488 pub enum ModuleDefId {
489     ModuleId(ModuleId),
490     FunctionId(FunctionId),
491     AdtId(AdtId),
492     // Can't be directly declared, but can be imported.
493     EnumVariantId(EnumVariantId),
494     ConstId(ConstId),
495     StaticId(StaticId),
496     TraitId(TraitId),
497     TraitAliasId(TraitAliasId),
498     TypeAliasId(TypeAliasId),
499     BuiltinType(BuiltinType),
500     MacroId(MacroId),
501 }
502 impl_from!(
503     MacroId(Macro2Id, MacroRulesId, ProcMacroId),
504     ModuleId,
505     FunctionId,
506     AdtId(StructId, EnumId, UnionId),
507     EnumVariantId,
508     ConstId,
509     StaticId,
510     TraitId,
511     TraitAliasId,
512     TypeAliasId,
513     BuiltinType
514     for ModuleDefId
515 );
516 
517 /// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and
518 /// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent.
519 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
520 pub struct ConstBlockId(salsa::InternId);
521 impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const);
522 
523 #[derive(Debug, Hash, PartialEq, Eq, Clone)]
524 pub struct ConstBlockLoc {
525     /// The parent of the anonymous const block.
526     pub parent: DefWithBodyId,
527     /// The root expression of this const block in the parent body.
528     pub root: hir::ExprId,
529 }
530 
531 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
532 pub enum TypeOwnerId {
533     FunctionId(FunctionId),
534     StaticId(StaticId),
535     ConstId(ConstId),
536     InTypeConstId(InTypeConstId),
537     AdtId(AdtId),
538     TraitId(TraitId),
539     TraitAliasId(TraitAliasId),
540     TypeAliasId(TypeAliasId),
541     ImplId(ImplId),
542     EnumVariantId(EnumVariantId),
543     // FIXME(const-generic-body): ModuleId should not be a type owner. This needs to be fixed to make `TypeOwnerId` actually
544     // useful for assigning ids to in type consts.
545     ModuleId(ModuleId),
546 }
547 
548 impl TypeOwnerId {
as_generic_def_id(self) -> Option<GenericDefId>549     fn as_generic_def_id(self) -> Option<GenericDefId> {
550         Some(match self {
551             TypeOwnerId::FunctionId(x) => GenericDefId::FunctionId(x),
552             TypeOwnerId::ConstId(x) => GenericDefId::ConstId(x),
553             TypeOwnerId::AdtId(x) => GenericDefId::AdtId(x),
554             TypeOwnerId::TraitId(x) => GenericDefId::TraitId(x),
555             TypeOwnerId::TraitAliasId(x) => GenericDefId::TraitAliasId(x),
556             TypeOwnerId::TypeAliasId(x) => GenericDefId::TypeAliasId(x),
557             TypeOwnerId::ImplId(x) => GenericDefId::ImplId(x),
558             TypeOwnerId::EnumVariantId(x) => GenericDefId::EnumVariantId(x),
559             TypeOwnerId::InTypeConstId(_) | TypeOwnerId::ModuleId(_) | TypeOwnerId::StaticId(_) => {
560                 return None
561             }
562         })
563     }
564 }
565 
566 impl_from!(
567     FunctionId,
568     StaticId,
569     ConstId,
570     InTypeConstId,
571     AdtId,
572     TraitId,
573     TraitAliasId,
574     TypeAliasId,
575     ImplId,
576     EnumVariantId,
577     ModuleId
578     for TypeOwnerId
579 );
580 
581 // Every `DefWithBodyId` is a type owner, since bodies can contain type (e.g. `{ let x: Type = _; }`)
582 impl From<DefWithBodyId> for TypeOwnerId {
from(value: DefWithBodyId) -> Self583     fn from(value: DefWithBodyId) -> Self {
584         match value {
585             DefWithBodyId::FunctionId(x) => x.into(),
586             DefWithBodyId::StaticId(x) => x.into(),
587             DefWithBodyId::ConstId(x) => x.into(),
588             DefWithBodyId::InTypeConstId(x) => x.into(),
589             DefWithBodyId::VariantId(x) => x.into(),
590         }
591     }
592 }
593 
594 impl From<GenericDefId> for TypeOwnerId {
from(value: GenericDefId) -> Self595     fn from(value: GenericDefId) -> Self {
596         match value {
597             GenericDefId::FunctionId(x) => x.into(),
598             GenericDefId::AdtId(x) => x.into(),
599             GenericDefId::TraitId(x) => x.into(),
600             GenericDefId::TraitAliasId(x) => x.into(),
601             GenericDefId::TypeAliasId(x) => x.into(),
602             GenericDefId::ImplId(x) => x.into(),
603             GenericDefId::EnumVariantId(x) => x.into(),
604             GenericDefId::ConstId(x) => x.into(),
605         }
606     }
607 }
608 
609 // FIXME: This should not be a thing
610 /// A thing that we want to store in interned ids, but we don't know its type in `hir-def`. This is
611 /// currently only used in `InTypeConstId` for storing the type (which has type `Ty` defined in
612 /// the `hir-ty` crate) of the constant in its id, which is a temporary hack so we may want
613 /// to remove this after removing that.
614 pub trait OpaqueInternableThing:
615     std::any::Any + std::fmt::Debug + Sync + Send + UnwindSafe + RefUnwindSafe
616 {
as_any(&self) -> &dyn std::any::Any617     fn as_any(&self) -> &dyn std::any::Any;
box_any(&self) -> Box<dyn std::any::Any>618     fn box_any(&self) -> Box<dyn std::any::Any>;
dyn_hash(&self, state: &mut dyn Hasher)619     fn dyn_hash(&self, state: &mut dyn Hasher);
dyn_eq(&self, other: &dyn OpaqueInternableThing) -> bool620     fn dyn_eq(&self, other: &dyn OpaqueInternableThing) -> bool;
dyn_clone(&self) -> Box<dyn OpaqueInternableThing>621     fn dyn_clone(&self) -> Box<dyn OpaqueInternableThing>;
622 }
623 
624 impl Hash for dyn OpaqueInternableThing {
hash<H: Hasher>(&self, state: &mut H)625     fn hash<H: Hasher>(&self, state: &mut H) {
626         self.dyn_hash(state);
627     }
628 }
629 
630 impl PartialEq for dyn OpaqueInternableThing {
eq(&self, other: &Self) -> bool631     fn eq(&self, other: &Self) -> bool {
632         self.dyn_eq(other)
633     }
634 }
635 
636 impl Eq for dyn OpaqueInternableThing {}
637 
638 impl Clone for Box<dyn OpaqueInternableThing> {
clone(&self) -> Self639     fn clone(&self) -> Self {
640         self.dyn_clone()
641     }
642 }
643 
644 // FIXME(const-generic-body): Use an stable id for in type consts.
645 //
646 // The current id uses `AstId<ast::ConstArg>` which will be changed by every change in the code. Ideally
647 // we should use an id which is relative to the type owner, so that every change will only invalidate the
648 // id if it happens inside of the type owner.
649 //
650 // The solution probably is to have some query on `TypeOwnerId` to traverse its constant children and store
651 // their `AstId` in a list (vector or arena), and use the index of that list in the id here. That query probably
652 // needs name resolution, and might go far and handles the whole path lowering or type lowering for a `TypeOwnerId`.
653 //
654 // Whatever path the solution takes, it should answer 3 questions at the same time:
655 // * Is the id stable enough?
656 // * How to find a constant id using an ast node / position in the source code? This is needed when we want to
657 //   provide ide functionalities inside an in type const (which we currently don't support) e.g. go to definition
658 //   for a local defined there. A complex id might have some trouble in this reverse mapping.
659 // * How to find the return type of a constant using its id? We have this data when we are doing type lowering
660 //   and the name of the struct that contains this constant is resolved, so a query that only traverses the
661 //   type owner by its syntax tree might have a hard time here.
662 
663 /// A constant in a type as a substitution for const generics (like `Foo<{ 2 + 2 }>`) or as an array
664 /// length (like `[u8; 2 + 2]`). These constants are body owner and are a variant of `DefWithBodyId`. These
665 /// are not called `AnonymousConstId` to prevent confusion with [`ConstBlockId`].
666 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
667 pub struct InTypeConstId(salsa::InternId);
668 impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const);
669 
670 #[derive(Debug, Hash, Eq, Clone)]
671 pub struct InTypeConstLoc {
672     pub id: AstId<ast::ConstArg>,
673     /// The thing this const arg appears in
674     pub owner: TypeOwnerId,
675     pub thing: Box<dyn OpaqueInternableThing>,
676 }
677 
678 impl PartialEq for InTypeConstLoc {
eq(&self, other: &Self) -> bool679     fn eq(&self, other: &Self) -> bool {
680         self.id == other.id && self.owner == other.owner && &*self.thing == &*other.thing
681     }
682 }
683 
684 impl InTypeConstId {
source(&self, db: &dyn db::DefDatabase) -> ast::ConstArg685     pub fn source(&self, db: &dyn db::DefDatabase) -> ast::ConstArg {
686         let src = self.lookup(db).id;
687         let file_id = src.file_id;
688         let root = &db.parse_or_expand(file_id);
689         db.ast_id_map(file_id).get(src.value).to_node(root)
690     }
691 }
692 
693 /// A constant, which might appears as a const item, an annonymous const block in expressions
694 /// or patterns, or as a constant in types with const generics.
695 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
696 pub enum GeneralConstId {
697     ConstId(ConstId),
698     ConstBlockId(ConstBlockId),
699     InTypeConstId(InTypeConstId),
700 }
701 
702 impl_from!(ConstId, ConstBlockId, InTypeConstId for GeneralConstId);
703 
704 impl GeneralConstId {
generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId>705     pub fn generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId> {
706         match self {
707             GeneralConstId::ConstId(it) => Some(it.into()),
708             GeneralConstId::ConstBlockId(it) => it.lookup(db).parent.as_generic_def_id(),
709             GeneralConstId::InTypeConstId(it) => it.lookup(db).owner.as_generic_def_id(),
710         }
711     }
712 
name(self, db: &dyn db::DefDatabase) -> String713     pub fn name(self, db: &dyn db::DefDatabase) -> String {
714         match self {
715             GeneralConstId::ConstId(const_id) => db
716                 .const_data(const_id)
717                 .name
718                 .as_ref()
719                 .and_then(|x| x.as_str())
720                 .unwrap_or("_")
721                 .to_owned(),
722             GeneralConstId::ConstBlockId(id) => format!("{{anonymous const {id:?}}}"),
723             GeneralConstId::InTypeConstId(id) => format!("{{in type const {id:?}}}"),
724         }
725     }
726 }
727 
728 /// The defs which have a body.
729 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
730 pub enum DefWithBodyId {
731     FunctionId(FunctionId),
732     StaticId(StaticId),
733     ConstId(ConstId),
734     InTypeConstId(InTypeConstId),
735     VariantId(EnumVariantId),
736 }
737 
738 impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
739 
740 impl From<EnumVariantId> for DefWithBodyId {
from(id: EnumVariantId) -> Self741     fn from(id: EnumVariantId) -> Self {
742         DefWithBodyId::VariantId(id)
743     }
744 }
745 
746 impl DefWithBodyId {
as_generic_def_id(self) -> Option<GenericDefId>747     pub fn as_generic_def_id(self) -> Option<GenericDefId> {
748         match self {
749             DefWithBodyId::FunctionId(f) => Some(f.into()),
750             DefWithBodyId::StaticId(_) => None,
751             DefWithBodyId::ConstId(c) => Some(c.into()),
752             DefWithBodyId::VariantId(c) => Some(c.into()),
753             // FIXME: stable rust doesn't allow generics in constants, but we should
754             // use `TypeOwnerId::as_generic_def_id` when it does.
755             DefWithBodyId::InTypeConstId(_) => None,
756         }
757     }
758 }
759 
760 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
761 pub enum AssocItemId {
762     FunctionId(FunctionId),
763     ConstId(ConstId),
764     TypeAliasId(TypeAliasId),
765 }
766 // FIXME: not every function, ... is actually an assoc item. maybe we should make
767 // sure that you can only turn actual assoc items into AssocItemIds. This would
768 // require not implementing From, and instead having some checked way of
769 // casting them, and somehow making the constructors private, which would be annoying.
770 impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
771 
772 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
773 pub enum GenericDefId {
774     FunctionId(FunctionId),
775     AdtId(AdtId),
776     TraitId(TraitId),
777     TraitAliasId(TraitAliasId),
778     TypeAliasId(TypeAliasId),
779     ImplId(ImplId),
780     // enum variants cannot have generics themselves, but their parent enums
781     // can, and this makes some code easier to write
782     EnumVariantId(EnumVariantId),
783     // consts can have type parameters from their parents (i.e. associated consts of traits)
784     ConstId(ConstId),
785 }
786 impl_from!(
787     FunctionId,
788     AdtId(StructId, EnumId, UnionId),
789     TraitId,
790     TraitAliasId,
791     TypeAliasId,
792     ImplId,
793     EnumVariantId,
794     ConstId
795     for GenericDefId
796 );
797 
798 impl From<AssocItemId> for GenericDefId {
from(item: AssocItemId) -> Self799     fn from(item: AssocItemId) -> Self {
800         match item {
801             AssocItemId::FunctionId(f) => f.into(),
802             AssocItemId::ConstId(c) => c.into(),
803             AssocItemId::TypeAliasId(t) => t.into(),
804         }
805     }
806 }
807 
808 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
809 pub enum AttrDefId {
810     ModuleId(ModuleId),
811     FieldId(FieldId),
812     AdtId(AdtId),
813     FunctionId(FunctionId),
814     EnumVariantId(EnumVariantId),
815     StaticId(StaticId),
816     ConstId(ConstId),
817     TraitId(TraitId),
818     TraitAliasId(TraitAliasId),
819     TypeAliasId(TypeAliasId),
820     MacroId(MacroId),
821     ImplId(ImplId),
822     GenericParamId(GenericParamId),
823     ExternBlockId(ExternBlockId),
824 }
825 
826 impl_from!(
827     ModuleId,
828     FieldId,
829     AdtId(StructId, EnumId, UnionId),
830     EnumVariantId,
831     StaticId,
832     ConstId,
833     FunctionId,
834     TraitId,
835     TypeAliasId,
836     MacroId(Macro2Id, MacroRulesId, ProcMacroId),
837     ImplId,
838     GenericParamId
839     for AttrDefId
840 );
841 
842 impl From<ItemContainerId> for AttrDefId {
from(acid: ItemContainerId) -> Self843     fn from(acid: ItemContainerId) -> Self {
844         match acid {
845             ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
846             ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
847             ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
848             ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
849         }
850     }
851 }
852 
853 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
854 pub enum VariantId {
855     EnumVariantId(EnumVariantId),
856     StructId(StructId),
857     UnionId(UnionId),
858 }
859 impl_from!(EnumVariantId, StructId, UnionId for VariantId);
860 
861 impl VariantId {
variant_data(self, db: &dyn db::DefDatabase) -> Arc<VariantData>862     pub fn variant_data(self, db: &dyn db::DefDatabase) -> Arc<VariantData> {
863         match self {
864             VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
865             VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
866             VariantId::EnumVariantId(it) => {
867                 db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
868             }
869         }
870     }
871 
file_id(self, db: &dyn db::DefDatabase) -> HirFileId872     pub fn file_id(self, db: &dyn db::DefDatabase) -> HirFileId {
873         match self {
874             VariantId::EnumVariantId(it) => it.parent.lookup(db).id.file_id(),
875             VariantId::StructId(it) => it.lookup(db).id.file_id(),
876             VariantId::UnionId(it) => it.lookup(db).id.file_id(),
877         }
878     }
879 
adt_id(self) -> AdtId880     pub fn adt_id(self) -> AdtId {
881         match self {
882             VariantId::EnumVariantId(it) => it.parent.into(),
883             VariantId::StructId(it) => it.into(),
884             VariantId::UnionId(it) => it.into(),
885         }
886     }
887 }
888 
889 trait Intern {
890     type ID;
intern(self, db: &dyn db::DefDatabase) -> Self::ID891     fn intern(self, db: &dyn db::DefDatabase) -> Self::ID;
892 }
893 
894 pub trait Lookup {
895     type Data;
lookup(&self, db: &dyn db::DefDatabase) -> Self::Data896     fn lookup(&self, db: &dyn db::DefDatabase) -> Self::Data;
897 }
898 
899 pub trait HasModule {
module(&self, db: &dyn db::DefDatabase) -> ModuleId900     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
901 }
902 
903 impl HasModule for ItemContainerId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId904     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
905         match *self {
906             ItemContainerId::ModuleId(it) => it,
907             ItemContainerId::ImplId(it) => it.lookup(db).container,
908             ItemContainerId::TraitId(it) => it.lookup(db).container,
909             ItemContainerId::ExternBlockId(it) => it.lookup(db).container,
910         }
911     }
912 }
913 
914 impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> {
module(&self, db: &dyn db::DefDatabase) -> ModuleId915     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
916         self.container.module(db)
917     }
918 }
919 
920 impl HasModule for AdtId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId921     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
922         match self {
923             AdtId::StructId(it) => it.lookup(db).container,
924             AdtId::UnionId(it) => it.lookup(db).container,
925             AdtId::EnumId(it) => it.lookup(db).container,
926         }
927     }
928 }
929 
930 impl HasModule for VariantId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId931     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
932         match self {
933             VariantId::EnumVariantId(it) => it.parent.lookup(db).container,
934             VariantId::StructId(it) => it.lookup(db).container,
935             VariantId::UnionId(it) => it.lookup(db).container,
936         }
937     }
938 }
939 
940 impl HasModule for MacroId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId941     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
942         match self {
943             MacroId::MacroRulesId(it) => it.lookup(db).container,
944             MacroId::Macro2Id(it) => it.lookup(db).container,
945             MacroId::ProcMacroId(it) => it.lookup(db).container.into(),
946         }
947     }
948 }
949 
950 impl HasModule for TypeOwnerId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId951     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
952         match self {
953             TypeOwnerId::FunctionId(x) => x.lookup(db).module(db),
954             TypeOwnerId::StaticId(x) => x.lookup(db).module(db),
955             TypeOwnerId::ConstId(x) => x.lookup(db).module(db),
956             TypeOwnerId::InTypeConstId(x) => x.lookup(db).owner.module(db),
957             TypeOwnerId::AdtId(x) => x.module(db),
958             TypeOwnerId::TraitId(x) => x.lookup(db).container,
959             TypeOwnerId::TraitAliasId(x) => x.lookup(db).container,
960             TypeOwnerId::TypeAliasId(x) => x.lookup(db).module(db),
961             TypeOwnerId::ImplId(x) => x.lookup(db).container,
962             TypeOwnerId::EnumVariantId(x) => x.parent.lookup(db).container,
963             TypeOwnerId::ModuleId(x) => *x,
964         }
965     }
966 }
967 
968 impl HasModule for DefWithBodyId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId969     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
970         match self {
971             DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
972             DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
973             DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
974             DefWithBodyId::VariantId(it) => it.parent.lookup(db).container,
975             DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
976         }
977     }
978 }
979 
980 impl HasModule for GenericDefId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId981     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
982         match self {
983             GenericDefId::FunctionId(it) => it.lookup(db).module(db),
984             GenericDefId::AdtId(it) => it.module(db),
985             GenericDefId::TraitId(it) => it.lookup(db).container,
986             GenericDefId::TraitAliasId(it) => it.lookup(db).container,
987             GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
988             GenericDefId::ImplId(it) => it.lookup(db).container,
989             GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
990             GenericDefId::ConstId(it) => it.lookup(db).module(db),
991         }
992     }
993 }
994 
995 impl HasModule for TypeAliasId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId996     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
997         self.lookup(db).module(db)
998     }
999 }
1000 
1001 impl HasModule for TraitId {
module(&self, db: &dyn db::DefDatabase) -> ModuleId1002     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
1003         self.lookup(db).container
1004     }
1005 }
1006 
1007 impl ModuleDefId {
1008     /// Returns the module containing `self` (or `self`, if `self` is itself a module).
1009     ///
1010     /// Returns `None` if `self` refers to a primitive type.
module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId>1011     pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
1012         Some(match self {
1013             ModuleDefId::ModuleId(id) => *id,
1014             ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
1015             ModuleDefId::AdtId(id) => id.module(db),
1016             ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
1017             ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
1018             ModuleDefId::StaticId(id) => id.lookup(db).module(db),
1019             ModuleDefId::TraitId(id) => id.lookup(db).container,
1020             ModuleDefId::TraitAliasId(id) => id.lookup(db).container,
1021             ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
1022             ModuleDefId::MacroId(id) => id.module(db),
1023             ModuleDefId::BuiltinType(_) => return None,
1024         })
1025     }
1026 }
1027 
1028 impl AttrDefId {
krate(&self, db: &dyn db::DefDatabase) -> CrateId1029     pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
1030         match self {
1031             AttrDefId::ModuleId(it) => it.krate,
1032             AttrDefId::FieldId(it) => it.parent.module(db).krate,
1033             AttrDefId::AdtId(it) => it.module(db).krate,
1034             AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
1035             AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.krate,
1036             AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
1037             AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
1038             AttrDefId::TraitId(it) => it.lookup(db).container.krate,
1039             AttrDefId::TraitAliasId(it) => it.lookup(db).container.krate,
1040             AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
1041             AttrDefId::ImplId(it) => it.lookup(db).container.krate,
1042             AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate,
1043             AttrDefId::GenericParamId(it) => {
1044                 match it {
1045                     GenericParamId::TypeParamId(it) => it.parent(),
1046                     GenericParamId::ConstParamId(it) => it.parent(),
1047                     GenericParamId::LifetimeParamId(it) => it.parent,
1048                 }
1049                 .module(db)
1050                 .krate
1051             }
1052             AttrDefId::MacroId(it) => it.module(db).krate,
1053         }
1054     }
1055 }
1056 
1057 /// A helper trait for converting to MacroCallId
1058 pub trait AsMacroCall {
as_call_id( &self, db: &dyn ExpandDatabase, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, ) -> Option<MacroCallId>1059     fn as_call_id(
1060         &self,
1061         db: &dyn ExpandDatabase,
1062         krate: CrateId,
1063         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
1064     ) -> Option<MacroCallId> {
1065         self.as_call_id_with_errors(db, krate, resolver).ok()?.value
1066     }
1067 
as_call_id_with_errors( &self, db: &dyn ExpandDatabase, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>1068     fn as_call_id_with_errors(
1069         &self,
1070         db: &dyn ExpandDatabase,
1071         krate: CrateId,
1072         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
1073     ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
1074 }
1075 
1076 impl AsMacroCall for InFile<&ast::MacroCall> {
as_call_id_with_errors( &self, db: &dyn ExpandDatabase, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>1077     fn as_call_id_with_errors(
1078         &self,
1079         db: &dyn ExpandDatabase,
1080         krate: CrateId,
1081         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
1082     ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
1083         let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
1084         let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
1085         let h = Hygiene::new(db, self.file_id);
1086         let path = self.value.path().and_then(|path| path::ModPath::from_src(db, path, &h));
1087 
1088         let Some(path) = path else {
1089             return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
1090         };
1091 
1092         macro_call_as_call_id_(
1093             db,
1094             &AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
1095             expands_to,
1096             krate,
1097             resolver,
1098         )
1099     }
1100 }
1101 
1102 /// Helper wrapper for `AstId` with `ModPath`
1103 #[derive(Clone, Debug, Eq, PartialEq)]
1104 struct AstIdWithPath<T: ast::AstNode> {
1105     ast_id: AstId<T>,
1106     path: path::ModPath,
1107 }
1108 
1109 impl<T: ast::AstNode> AstIdWithPath<T> {
new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T>1110     fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T> {
1111         AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
1112     }
1113 }
1114 
macro_call_as_call_id( db: &dyn ExpandDatabase, call: &AstIdWithPath<ast::MacroCall>, expand_to: ExpandTo, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, ) -> Result<Option<MacroCallId>, UnresolvedMacro>1115 fn macro_call_as_call_id(
1116     db: &dyn ExpandDatabase,
1117     call: &AstIdWithPath<ast::MacroCall>,
1118     expand_to: ExpandTo,
1119     krate: CrateId,
1120     resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
1121 ) -> Result<Option<MacroCallId>, UnresolvedMacro> {
1122     macro_call_as_call_id_(db, call, expand_to, krate, resolver).map(|res| res.value)
1123 }
1124 
macro_call_as_call_id_( db: &dyn ExpandDatabase, call: &AstIdWithPath<ast::MacroCall>, expand_to: ExpandTo, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>1125 fn macro_call_as_call_id_(
1126     db: &dyn ExpandDatabase,
1127     call: &AstIdWithPath<ast::MacroCall>,
1128     expand_to: ExpandTo,
1129     krate: CrateId,
1130     resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
1131 ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
1132     let def =
1133         resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
1134 
1135     let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
1136         let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db));
1137         expand_eager_macro_input(db, krate, macro_call, def, &resolver)?
1138     } else {
1139         ExpandResult {
1140             value: Some(def.as_lazy_macro(
1141                 db,
1142                 krate,
1143                 MacroCallKind::FnLike { ast_id: call.ast_id, expand_to },
1144             )),
1145             err: None,
1146         }
1147     };
1148     Ok(res)
1149 }
1150 
macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId1151 pub fn macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId {
1152     match id {
1153         MacroId::Macro2Id(it) => {
1154             let loc = it.lookup(db);
1155 
1156             let item_tree = loc.id.item_tree(db);
1157             let makro = &item_tree[loc.id.value];
1158             let in_file = |m: FileAstId<ast::MacroDef>| InFile::new(loc.id.file_id(), m.upcast());
1159             MacroDefId {
1160                 krate: loc.container.krate,
1161                 kind: match loc.expander {
1162                     MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
1163                     MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
1164                     MacroExpander::BuiltInAttr(it) => {
1165                         MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
1166                     }
1167                     MacroExpander::BuiltInDerive(it) => {
1168                         MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
1169                     }
1170                     MacroExpander::BuiltInEager(it) => {
1171                         MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
1172                     }
1173                 },
1174                 local_inner: false,
1175                 allow_internal_unsafe: loc.allow_internal_unsafe,
1176             }
1177         }
1178         MacroId::MacroRulesId(it) => {
1179             let loc = it.lookup(db);
1180 
1181             let item_tree = loc.id.item_tree(db);
1182             let makro = &item_tree[loc.id.value];
1183             let in_file = |m: FileAstId<ast::MacroRules>| InFile::new(loc.id.file_id(), m.upcast());
1184             MacroDefId {
1185                 krate: loc.container.krate,
1186                 kind: match loc.expander {
1187                     MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
1188                     MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
1189                     MacroExpander::BuiltInAttr(it) => {
1190                         MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
1191                     }
1192                     MacroExpander::BuiltInDerive(it) => {
1193                         MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
1194                     }
1195                     MacroExpander::BuiltInEager(it) => {
1196                         MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
1197                     }
1198                 },
1199                 local_inner: loc.local_inner,
1200                 allow_internal_unsafe: loc.allow_internal_unsafe,
1201             }
1202         }
1203         MacroId::ProcMacroId(it) => {
1204             let loc = it.lookup(db);
1205 
1206             let item_tree = loc.id.item_tree(db);
1207             let makro = &item_tree[loc.id.value];
1208             MacroDefId {
1209                 krate: loc.container.krate,
1210                 kind: MacroDefKind::ProcMacro(
1211                     loc.expander,
1212                     loc.kind,
1213                     InFile::new(loc.id.file_id(), makro.ast_id),
1214                 ),
1215                 local_inner: false,
1216                 allow_internal_unsafe: false,
1217             }
1218         }
1219     }
1220 }
1221 
derive_macro_as_call_id( db: &dyn db::DefDatabase, item_attr: &AstIdWithPath<ast::Adt>, derive_attr_index: AttrId, derive_pos: u32, krate: CrateId, resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>, ) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro>1222 fn derive_macro_as_call_id(
1223     db: &dyn db::DefDatabase,
1224     item_attr: &AstIdWithPath<ast::Adt>,
1225     derive_attr_index: AttrId,
1226     derive_pos: u32,
1227     krate: CrateId,
1228     resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
1229 ) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
1230     let (macro_id, def_id) = resolver(item_attr.path.clone())
1231         .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
1232     let call_id = def_id.as_lazy_macro(
1233         db.upcast(),
1234         krate,
1235         MacroCallKind::Derive {
1236             ast_id: item_attr.ast_id,
1237             derive_index: derive_pos,
1238             derive_attr_index,
1239         },
1240     );
1241     Ok((macro_id, def_id, call_id))
1242 }
1243 
attr_macro_as_call_id( db: &dyn db::DefDatabase, item_attr: &AstIdWithPath<ast::Item>, macro_attr: &Attr, krate: CrateId, def: MacroDefId, ) -> MacroCallId1244 fn attr_macro_as_call_id(
1245     db: &dyn db::DefDatabase,
1246     item_attr: &AstIdWithPath<ast::Item>,
1247     macro_attr: &Attr,
1248     krate: CrateId,
1249     def: MacroDefId,
1250 ) -> MacroCallId {
1251     let arg = match macro_attr.input.as_deref() {
1252         Some(AttrInput::TokenTree(tt)) => (
1253             {
1254                 let mut tt = tt.0.clone();
1255                 tt.delimiter = tt::Delimiter::UNSPECIFIED;
1256                 tt
1257             },
1258             tt.1.clone(),
1259         ),
1260         _ => (tt::Subtree::empty(), Default::default()),
1261     };
1262 
1263     def.as_lazy_macro(
1264         db.upcast(),
1265         krate,
1266         MacroCallKind::Attr {
1267             ast_id: item_attr.ast_id,
1268             attr_args: Arc::new(arg),
1269             invoc_attr_index: macro_attr.id,
1270         },
1271     )
1272 }
1273 intern::impl_internable!(
1274     crate::type_ref::TypeRef,
1275     crate::type_ref::TraitRef,
1276     crate::type_ref::TypeBound,
1277     crate::path::GenericArgs,
1278     generics::GenericParams,
1279 );
1280