1#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
11
12#[cfg(feature = "in-rust-tree")]
13extern crate rustc_parse_format;
14
15#[cfg(not(feature = "in-rust-tree"))]
16extern crate ra_ap_rustc_parse_format as rustc_parse_format;
17
18extern crate ra_ap_rustc_abi as rustc_abi;
19
20pub mod db;
21
22pub mod attrs;
23pub mod builtin_type;
24pub mod item_scope;
25pub mod per_ns;
26
27pub mod signatures;
28
29pub mod dyn_map;
30
31pub mod item_tree;
32
33pub mod lang_item;
34
35pub mod hir;
36pub use self::hir::type_ref;
37pub mod expr_store;
38pub mod resolver;
39
40pub mod nameres;
41
42pub mod src;
43
44pub mod find_path;
45pub mod import_map;
46pub mod visibility;
47
48use intern::{Interned, Symbol};
49pub use rustc_abi as layout;
50use thin_vec::ThinVec;
51use triomphe::Arc;
52
53pub use crate::signatures::LocalFieldId;
54
55#[cfg(test)]
56mod macro_expansion_tests;
57#[cfg(test)]
58mod test_db;
59
60use std::hash::{Hash, Hasher};
61
62use base_db::{Crate, impl_intern_key};
63use hir_expand::{
64 AstId, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroCallStyles,
65 MacroDefId, MacroDefKind,
66 builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
67 db::ExpandDatabase,
68 eager::expand_eager_macro_input,
69 impl_intern_lookup,
70 mod_path::ModPath,
71 name::Name,
72 proc_macro::{CustomProcMacroExpander, ProcMacroKind},
73};
74use nameres::DefMap;
75use span::{AstIdNode, Edition, FileAstId, SyntaxContext};
76use stdx::impl_from;
77use syntax::{AstNode, ast};
78
79pub use hir_expand::{Intern, Lookup, tt};
80
81use crate::{
82 attrs::AttrFlags,
83 builtin_type::BuiltinType,
84 db::DefDatabase,
85 expr_store::ExpressionStoreSourceMap,
86 hir::generics::{LocalLifetimeParamId, LocalTypeOrConstParamId},
87 nameres::{
88 LocalDefMap,
89 assoc::{ImplItems, TraitItems},
90 block_def_map, crate_def_map, crate_local_def_map,
91 diagnostics::DefDiagnostics,
92 },
93 signatures::{EnumVariants, InactiveEnumVariantCode, VariantFields},
94};
95
96type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
97#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
99pub struct FindPathConfig {
100 pub prefer_no_std: bool,
103 pub prefer_prelude: bool,
105 pub prefer_absolute: bool,
107 pub allow_unstable: bool,
110}
111
112#[derive(Debug)]
113pub struct ItemLoc<N: AstIdNode> {
114 pub container: ModuleId,
115 pub id: AstId<N>,
116}
117
118impl<N: AstIdNode> Clone for ItemLoc<N> {
119 fn clone(&self) -> Self {
120 *self
121 }
122}
123
124impl<N: AstIdNode> Copy for ItemLoc<N> {}
125
126impl<N: AstIdNode> PartialEq for ItemLoc<N> {
127 fn eq(&self, other: &Self) -> bool {
128 self.container == other.container && self.id == other.id
129 }
130}
131
132impl<N: AstIdNode> Eq for ItemLoc<N> {}
133
134impl<N: AstIdNode> Hash for ItemLoc<N> {
135 fn hash<H: Hasher>(&self, state: &mut H) {
136 self.container.hash(state);
137 self.id.hash(state);
138 }
139}
140
141impl<N: AstIdNode> HasModule for ItemLoc<N> {
142 #[inline]
143 fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
144 self.container
145 }
146}
147
148#[derive(Debug)]
149pub struct AssocItemLoc<N: AstIdNode> {
150 pub container: ItemContainerId,
152 pub id: AstId<N>,
153}
154
155impl<N: AstIdNode> Clone for AssocItemLoc<N> {
156 fn clone(&self) -> Self {
157 *self
158 }
159}
160
161impl<N: AstIdNode> Copy for AssocItemLoc<N> {}
162
163impl<N: AstIdNode> PartialEq for AssocItemLoc<N> {
164 fn eq(&self, other: &Self) -> bool {
165 self.container == other.container && self.id == other.id
166 }
167}
168
169impl<N: AstIdNode> Eq for AssocItemLoc<N> {}
170
171impl<N: AstIdNode> Hash for AssocItemLoc<N> {
172 fn hash<H: Hasher>(&self, state: &mut H) {
173 self.container.hash(state);
174 self.id.hash(state);
175 }
176}
177
178impl<N: AstIdNode> HasModule for AssocItemLoc<N> {
179 #[inline]
180 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
181 self.container.module(db)
182 }
183}
184
185pub trait AstIdLoc {
186 type Container;
187 type Ast: AstNode;
188 fn ast_id(&self) -> AstId<Self::Ast>;
189 fn container(&self) -> Self::Container;
190}
191
192impl<N: AstIdNode> AstIdLoc for ItemLoc<N> {
193 type Container = ModuleId;
194 type Ast = N;
195 #[inline]
196 fn ast_id(&self) -> AstId<Self::Ast> {
197 self.id
198 }
199 #[inline]
200 fn container(&self) -> Self::Container {
201 self.container
202 }
203}
204
205impl<N: AstIdNode> AstIdLoc for AssocItemLoc<N> {
206 type Container = ItemContainerId;
207 type Ast = N;
208 #[inline]
209 fn ast_id(&self) -> AstId<Self::Ast> {
210 self.id
211 }
212 #[inline]
213 fn container(&self) -> Self::Container {
214 self.container
215 }
216}
217
218macro_rules! impl_intern {
219 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
220 impl_intern_key!($id, $loc);
221 impl_intern_lookup!(DefDatabase, $id, $loc, $intern, $lookup);
222 };
223}
224
225macro_rules! impl_loc {
226 ($loc:ident, $id:ident: $id_ty:ident, $container:ident: $container_type:ident) => {
227 impl AstIdLoc for $loc {
228 type Container = $container_type;
229 type Ast = ast::$id_ty;
230 fn ast_id(&self) -> AstId<Self::Ast> {
231 self.$id
232 }
233 fn container(&self) -> Self::Container {
234 self.$container
235 }
236 }
237
238 impl HasModule for $loc {
239 #[inline]
240 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
241 self.$container.module(db)
242 }
243 }
244 };
245}
246
247type FunctionLoc = AssocItemLoc<ast::Fn>;
248impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
249
250type StructLoc = ItemLoc<ast::Struct>;
251impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
252
253impl StructId {
254 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
255 VariantFields::firewall(db, self.into())
256 }
257
258 pub fn fields_with_source_map(
259 self,
260 db: &dyn DefDatabase,
261 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
262 VariantFields::query(db, self.into())
263 }
264}
265
266pub type UnionLoc = ItemLoc<ast::Union>;
267impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
268
269impl UnionId {
270 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
271 VariantFields::firewall(db, self.into())
272 }
273
274 pub fn fields_with_source_map(
275 self,
276 db: &dyn DefDatabase,
277 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
278 VariantFields::query(db, self.into())
279 }
280}
281
282pub type EnumLoc = ItemLoc<ast::Enum>;
283impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
284
285impl EnumId {
286 #[inline]
287 pub fn enum_variants(self, db: &dyn DefDatabase) -> &EnumVariants {
288 &self.enum_variants_with_diagnostics(db).0
289 }
290
291 #[inline]
292 pub fn enum_variants_with_diagnostics(
293 self,
294 db: &dyn DefDatabase,
295 ) -> &(EnumVariants, Option<ThinVec<InactiveEnumVariantCode>>) {
296 EnumVariants::of(db, self)
297 }
298}
299
300type ConstLoc = AssocItemLoc<ast::Const>;
301impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
302
303pub type StaticLoc = AssocItemLoc<ast::Static>;
304impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
305
306pub type TraitLoc = ItemLoc<ast::Trait>;
307impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
308
309impl TraitId {
310 #[inline]
311 pub fn trait_items(self, db: &dyn DefDatabase) -> &TraitItems {
312 TraitItems::query(db, self)
313 }
314}
315
316type TypeAliasLoc = AssocItemLoc<ast::TypeAlias>;
317impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
318
319type ImplLoc = ItemLoc<ast::Impl>;
320impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
321
322impl ImplId {
323 #[inline]
324 pub fn impl_items(self, db: &dyn DefDatabase) -> &ImplItems {
325 &self.impl_items_with_diagnostics(db).0
326 }
327
328 #[inline]
329 pub fn impl_items_with_diagnostics(self, db: &dyn DefDatabase) -> &(ImplItems, DefDiagnostics) {
330 ImplItems::of(db, self)
331 }
332}
333
334type UseLoc = ItemLoc<ast::Use>;
335impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
336
337type ExternCrateLoc = ItemLoc<ast::ExternCrate>;
338impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate);
339
340type ExternBlockLoc = ItemLoc<ast::ExternBlock>;
341impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
342
343#[salsa::tracked]
344impl ExternBlockId {
345 #[salsa::tracked]
346 pub fn abi(self, db: &dyn DefDatabase) -> Option<Symbol> {
347 signatures::extern_block_abi(db, self)
348 }
349}
350
351#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
352pub struct EnumVariantLoc {
353 pub id: AstId<ast::Variant>,
354 pub parent: EnumId,
355 pub index: u32,
356}
357impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
358impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId);
359
360impl EnumVariantId {
361 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
362 VariantFields::firewall(db, self.into())
363 }
364
365 pub fn fields_with_source_map(
366 self,
367 db: &dyn DefDatabase,
368 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
369 VariantFields::query(db, self.into())
370 }
371}
372
373#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
374pub struct Macro2Loc {
375 pub container: ModuleId,
376 pub id: AstId<ast::MacroDef>,
377 pub expander: MacroExpander,
378 pub allow_internal_unsafe: bool,
379 pub edition: Edition,
380}
381impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
382impl_loc!(Macro2Loc, id: MacroDef, container: ModuleId);
383
384#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
385pub struct MacroRulesLoc {
386 pub container: ModuleId,
387 pub id: AstId<ast::MacroRules>,
388 pub expander: MacroExpander,
389 pub flags: MacroRulesLocFlags,
390 pub edition: Edition,
391}
392impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
393impl_loc!(MacroRulesLoc, id: MacroRules, container: ModuleId);
394
395bitflags::bitflags! {
396 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
397 pub struct MacroRulesLocFlags: u8 {
398 const ALLOW_INTERNAL_UNSAFE = 1 << 0;
399 const LOCAL_INNER = 1 << 1;
400 }
401}
402
403#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
404pub enum MacroExpander {
405 Declarative { styles: MacroCallStyles },
406 BuiltIn(BuiltinFnLikeExpander),
407 BuiltInAttr(BuiltinAttrExpander),
408 BuiltInDerive(BuiltinDeriveExpander),
409 BuiltInEager(EagerExpander),
410}
411
412#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
413pub struct ProcMacroLoc {
414 pub container: ModuleId,
415 pub id: AstId<ast::Fn>,
416 pub expander: CustomProcMacroExpander,
417 pub kind: ProcMacroKind,
418 pub edition: Edition,
419}
420impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
421impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId);
422
423#[derive(Debug, Hash, PartialEq, Eq, Clone)]
424pub struct BlockLoc {
425 pub ast_id: AstId<ast::BlockExpr>,
426 pub module: ModuleId,
428}
429impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
430
431#[salsa_macros::tracked(debug)]
432#[derive(PartialOrd, Ord)]
433pub struct ModuleIdLt<'db> {
434 pub krate: Crate,
436 pub block: Option<BlockId>,
440}
441pub type ModuleId = ModuleIdLt<'static>;
442
443impl ModuleIdLt<'_> {
444 pub unsafe fn to_static(self) -> ModuleId {
448 unsafe { std::mem::transmute(self) }
449 }
450}
451impl ModuleId {
452 pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> {
456 unsafe { std::mem::transmute(self) }
457 }
458
459 pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
460 match self.block(db) {
461 Some(block) => block_def_map(db, block),
462 None => crate_def_map(db, self.krate(db)),
463 }
464 }
465
466 pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) {
467 match self.block(db) {
468 Some(block) => (block_def_map(db, block), self.only_local_def_map(db)),
469 None => {
470 let def_map = crate_local_def_map(db, self.krate(db));
471 (def_map.def_map(db), def_map.local(db))
472 }
473 }
474 }
475
476 pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap {
477 crate_local_def_map(db, self.krate(db)).local(db)
478 }
479
480 pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap {
481 crate_def_map(db, self.krate(db))
482 }
483
484 pub fn name(self, db: &dyn DefDatabase) -> Option<Name> {
485 let def_map = self.def_map(db);
486 let parent = def_map[self].parent?;
487 def_map[parent].children.iter().find_map(|(name, module_id)| {
488 if *module_id == self { Some(name.clone()) } else { None }
489 })
490 }
491
492 pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> {
495 self.def_map(db).containing_module(self)
496 }
497
498 pub fn is_block_module(self, db: &dyn DefDatabase) -> bool {
499 self.block(db).is_some() && self.def_map(db).root_module_id() == self
500 }
501}
502
503impl HasModule for ModuleId {
504 #[inline]
505 fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
506 *self
507 }
508}
509
510#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
511pub struct FieldId {
512 pub parent: VariantId,
514 pub local_id: LocalFieldId,
515}
516
517#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
518pub struct TupleId(pub u32);
519
520#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
521pub struct TupleFieldId {
522 pub tuple: TupleId,
523 pub index: u32,
524}
525
526#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
527pub struct TypeOrConstParamId {
528 pub parent: GenericDefId,
530 pub local_id: LocalTypeOrConstParamId,
531}
532
533#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
535pub struct TypeParamId(TypeOrConstParamId);
536
537impl TypeParamId {
538 pub fn parent(&self) -> GenericDefId {
539 self.0.parent
540 }
541 pub fn local_id(&self) -> LocalTypeOrConstParamId {
542 self.0.local_id
543 }
544}
545
546impl TypeParamId {
547 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
549 Self(it)
550 }
551}
552
553impl From<TypeParamId> for TypeOrConstParamId {
554 fn from(it: TypeParamId) -> Self {
555 it.0
556 }
557}
558
559#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
561pub struct ConstParamId(TypeOrConstParamId);
562
563impl ConstParamId {
564 pub fn parent(&self) -> GenericDefId {
565 self.0.parent
566 }
567 pub fn local_id(&self) -> LocalTypeOrConstParamId {
568 self.0.local_id
569 }
570}
571
572impl ConstParamId {
573 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
575 Self(it)
576 }
577}
578
579impl From<ConstParamId> for TypeOrConstParamId {
580 fn from(it: ConstParamId) -> Self {
581 it.0
582 }
583}
584
585#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
586pub struct LifetimeParamId {
587 pub parent: GenericDefId,
589 pub local_id: LocalLifetimeParamId,
590}
591
592#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
593pub enum ItemContainerId {
594 ExternBlockId(ExternBlockId),
595 ModuleId(ModuleId),
596 ImplId(ImplId),
597 TraitId(TraitId),
598}
599impl_from!(ModuleId for ItemContainerId);
600
601#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
603pub enum AdtId {
604 StructId(StructId),
605 UnionId(UnionId),
606 EnumId(EnumId),
607}
608impl_from!(StructId, UnionId, EnumId for AdtId);
609
610#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
612pub enum MacroId {
613 Macro2Id(Macro2Id),
614 MacroRulesId(MacroRulesId),
615 ProcMacroId(ProcMacroId),
616}
617impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
618
619impl MacroId {
620 pub fn is_attribute(self, db: &dyn DefDatabase) -> bool {
621 matches!(self, MacroId::ProcMacroId(it) if it.lookup(db).kind == ProcMacroKind::Attr)
622 }
623}
624
625#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
627pub enum GenericParamId {
628 TypeParamId(TypeParamId),
629 ConstParamId(ConstParamId),
630 LifetimeParamId(LifetimeParamId),
631}
632impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
633
634#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
636pub enum ModuleDefId {
637 ModuleId(ModuleId),
638 FunctionId(FunctionId),
639 AdtId(AdtId),
640 EnumVariantId(EnumVariantId),
642 ConstId(ConstId),
643 StaticId(StaticId),
644 TraitId(TraitId),
645 TypeAliasId(TypeAliasId),
646 BuiltinType(BuiltinType),
647 MacroId(MacroId),
648}
649impl_from!(
650 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
651 ModuleId,
652 FunctionId,
653 AdtId(StructId, EnumId, UnionId),
654 EnumVariantId,
655 ConstId,
656 StaticId,
657 TraitId,
658 TypeAliasId,
659 BuiltinType
660 for ModuleDefId
661);
662
663#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
666pub enum GeneralConstId {
667 ConstId(ConstId),
668 StaticId(StaticId),
669}
670
671impl_from!(ConstId, StaticId for GeneralConstId);
672
673impl GeneralConstId {
674 pub fn generic_def(self, _db: &dyn DefDatabase) -> Option<GenericDefId> {
675 match self {
676 GeneralConstId::ConstId(it) => Some(it.into()),
677 GeneralConstId::StaticId(it) => Some(it.into()),
678 }
679 }
680
681 pub fn name(self, db: &dyn DefDatabase) -> String {
682 match self {
683 GeneralConstId::StaticId(it) => {
684 db.static_signature(it).name.display(db, Edition::CURRENT).to_string()
685 }
686 GeneralConstId::ConstId(const_id) => {
687 db.const_signature(const_id).name.as_ref().map_or_else(
688 || "_".to_owned(),
689 |name| name.display(db, Edition::CURRENT).to_string(),
690 )
691 }
692 }
693 }
694}
695
696#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
698pub enum DefWithBodyId {
699 FunctionId(FunctionId),
700 StaticId(StaticId),
701 ConstId(ConstId),
702 VariantId(EnumVariantId),
703 }
710impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
711
712impl From<EnumVariantId> for DefWithBodyId {
713 fn from(id: EnumVariantId) -> Self {
714 DefWithBodyId::VariantId(id)
715 }
716}
717
718impl DefWithBodyId {
719 pub fn as_generic_def_id(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
720 match self {
721 DefWithBodyId::FunctionId(f) => Some(f.into()),
722 DefWithBodyId::StaticId(s) => Some(s.into()),
723 DefWithBodyId::ConstId(c) => Some(c.into()),
724 DefWithBodyId::VariantId(c) => Some(c.lookup(db).parent.into()),
725 }
726 }
727}
728
729#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, salsa_macros::Supertype)]
730pub enum AssocItemId {
731 FunctionId(FunctionId),
732 ConstId(ConstId),
733 TypeAliasId(TypeAliasId),
734}
735
736impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
741
742impl From<AssocItemId> for ModuleDefId {
743 fn from(item: AssocItemId) -> Self {
744 match item {
745 AssocItemId::FunctionId(f) => f.into(),
746 AssocItemId::ConstId(c) => c.into(),
747 AssocItemId::TypeAliasId(t) => t.into(),
748 }
749 }
750}
751
752#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
753pub enum GenericDefId {
754 AdtId(AdtId),
755 ConstId(ConstId),
757 FunctionId(FunctionId),
758 ImplId(ImplId),
759 StaticId(StaticId),
763 TraitId(TraitId),
764 TypeAliasId(TypeAliasId),
765}
766impl_from!(
767 AdtId(StructId, EnumId, UnionId),
768 ConstId,
769 FunctionId,
770 ImplId,
771 StaticId,
772 TraitId,
773 TypeAliasId
774 for GenericDefId
775);
776
777impl GenericDefId {
778 pub fn file_id_and_params_of(
779 self,
780 db: &dyn DefDatabase,
781 ) -> (HirFileId, Option<ast::GenericParamList>) {
782 fn file_id_and_params_of_item_loc<Loc>(
783 db: &dyn DefDatabase,
784 def: impl Lookup<Database = dyn DefDatabase, Data = Loc>,
785 ) -> (HirFileId, Option<ast::GenericParamList>)
786 where
787 Loc: src::HasSource,
788 Loc::Value: ast::HasGenericParams,
789 {
790 let src = def.lookup(db).source(db);
791 (src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
792 }
793
794 match self {
795 GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
796 GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
797 GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
798 GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
799 GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
800 GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
801 GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
802 GenericDefId::ConstId(it) => (it.lookup(db).id.file_id, None),
803 GenericDefId::StaticId(it) => (it.lookup(db).id.file_id, None),
804 }
805 }
806
807 pub fn assoc_trait_container(self, db: &dyn DefDatabase) -> Option<TraitId> {
808 match match self {
809 GenericDefId::FunctionId(f) => f.lookup(db).container,
810 GenericDefId::TypeAliasId(t) => t.lookup(db).container,
811 GenericDefId::ConstId(c) => c.lookup(db).container,
812 _ => return None,
813 } {
814 ItemContainerId::TraitId(trait_) => Some(trait_),
815 _ => None,
816 }
817 }
818
819 pub fn from_callable(db: &dyn DefDatabase, def: CallableDefId) -> GenericDefId {
820 match def {
821 CallableDefId::FunctionId(f) => f.into(),
822 CallableDefId::StructId(s) => s.into(),
823 CallableDefId::EnumVariantId(e) => e.lookup(db).parent.into(),
824 }
825 }
826}
827
828impl From<AssocItemId> for GenericDefId {
829 fn from(item: AssocItemId) -> Self {
830 match item {
831 AssocItemId::FunctionId(f) => f.into(),
832 AssocItemId::ConstId(c) => c.into(),
833 AssocItemId::TypeAliasId(t) => t.into(),
834 }
835 }
836}
837
838#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
839pub enum CallableDefId {
840 FunctionId(FunctionId),
841 StructId(StructId),
842 EnumVariantId(EnumVariantId),
843}
844
845impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
846impl From<CallableDefId> for ModuleDefId {
847 fn from(def: CallableDefId) -> ModuleDefId {
848 match def {
849 CallableDefId::FunctionId(f) => ModuleDefId::FunctionId(f),
850 CallableDefId::StructId(s) => ModuleDefId::AdtId(AdtId::StructId(s)),
851 CallableDefId::EnumVariantId(e) => ModuleDefId::EnumVariantId(e),
852 }
853 }
854}
855
856impl CallableDefId {
857 pub fn krate(self, db: &dyn DefDatabase) -> Crate {
858 match self {
859 CallableDefId::FunctionId(f) => f.krate(db),
860 CallableDefId::StructId(s) => s.krate(db),
861 CallableDefId::EnumVariantId(e) => e.krate(db),
862 }
863 }
864}
865
866#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, salsa_macros::Supertype)]
867pub enum AttrDefId {
868 ModuleId(ModuleId),
869 AdtId(AdtId),
870 FunctionId(FunctionId),
871 EnumVariantId(EnumVariantId),
872 StaticId(StaticId),
873 ConstId(ConstId),
874 TraitId(TraitId),
875 TypeAliasId(TypeAliasId),
876 MacroId(MacroId),
877 ImplId(ImplId),
878 ExternBlockId(ExternBlockId),
879 ExternCrateId(ExternCrateId),
880 UseId(UseId),
881}
882
883impl_from!(
884 AdtId(StructId, EnumId, UnionId),
885 EnumVariantId,
886 StaticId,
887 ConstId,
888 FunctionId,
889 TraitId,
890 TypeAliasId,
891 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
892 ImplId,
893 ExternCrateId,
894 UseId
895 for AttrDefId
896);
897
898impl From<AssocItemId> for AttrDefId {
899 fn from(assoc: AssocItemId) -> Self {
900 match assoc {
901 AssocItemId::FunctionId(it) => AttrDefId::FunctionId(it),
902 AssocItemId::ConstId(it) => AttrDefId::ConstId(it),
903 AssocItemId::TypeAliasId(it) => AttrDefId::TypeAliasId(it),
904 }
905 }
906}
907impl From<VariantId> for AttrDefId {
908 fn from(vid: VariantId) -> Self {
909 match vid {
910 VariantId::EnumVariantId(id) => id.into(),
911 VariantId::StructId(id) => id.into(),
912 VariantId::UnionId(id) => id.into(),
913 }
914 }
915}
916
917#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype, salsa::Update)]
918pub enum VariantId {
919 EnumVariantId(EnumVariantId),
920 StructId(StructId),
921 UnionId(UnionId),
922}
923impl_from!(EnumVariantId, StructId, UnionId for VariantId);
924
925impl VariantId {
926 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
927 VariantFields::firewall(db, self)
928 }
929
930 pub fn fields_with_source_map(
931 self,
932 db: &dyn DefDatabase,
933 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
934 VariantFields::query(db, self)
935 }
936
937 pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId {
938 match self {
939 VariantId::EnumVariantId(it) => it.lookup(db).id.file_id,
940 VariantId::StructId(it) => it.lookup(db).id.file_id,
941 VariantId::UnionId(it) => it.lookup(db).id.file_id,
942 }
943 }
944
945 pub fn adt_id(self, db: &dyn DefDatabase) -> AdtId {
946 match self {
947 VariantId::EnumVariantId(it) => it.lookup(db).parent.into(),
948 VariantId::StructId(it) => it.into(),
949 VariantId::UnionId(it) => it.into(),
950 }
951 }
952}
953
954pub trait HasModule {
955 fn module(&self, db: &dyn DefDatabase) -> ModuleId;
957 #[inline]
959 #[doc(alias = "crate")]
960 fn krate(&self, db: &dyn DefDatabase) -> Crate {
961 self.module(db).krate(db)
962 }
963}
964
965impl<N, ItemId> HasModule for ItemId
980where
981 N: AstIdNode,
982 ItemId: Lookup<Database = dyn DefDatabase, Data = ItemLoc<N>> + Copy,
983{
984 #[inline]
985 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
986 self.lookup(db).container
987 }
988}
989
990#[inline]
1005fn module_for_assoc_item_loc<'db>(
1006 db: &(dyn 'db + DefDatabase),
1007 id: impl Lookup<Database = dyn DefDatabase, Data = AssocItemLoc<impl AstIdNode>>,
1008) -> ModuleId {
1009 id.lookup(db).container.module(db)
1010}
1011
1012impl HasModule for FunctionId {
1013 #[inline]
1014 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1015 module_for_assoc_item_loc(db, *self)
1016 }
1017}
1018
1019impl HasModule for ConstId {
1020 #[inline]
1021 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1022 module_for_assoc_item_loc(db, *self)
1023 }
1024}
1025
1026impl HasModule for StaticId {
1027 #[inline]
1028 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1029 module_for_assoc_item_loc(db, *self)
1030 }
1031}
1032
1033impl HasModule for TypeAliasId {
1034 #[inline]
1035 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1036 module_for_assoc_item_loc(db, *self)
1037 }
1038}
1039impl HasModule for EnumVariantId {
1042 #[inline]
1043 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1044 self.lookup(db).parent.module(db)
1045 }
1046}
1047
1048impl HasModule for MacroRulesId {
1049 #[inline]
1050 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1051 self.lookup(db).container
1052 }
1053}
1054
1055impl HasModule for Macro2Id {
1056 #[inline]
1057 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1058 self.lookup(db).container
1059 }
1060}
1061
1062impl HasModule for ProcMacroId {
1063 #[inline]
1064 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1065 self.lookup(db).container
1066 }
1067}
1068
1069impl HasModule for ItemContainerId {
1070 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1071 match *self {
1072 ItemContainerId::ModuleId(it) => it,
1073 ItemContainerId::ImplId(it) => it.module(db),
1074 ItemContainerId::TraitId(it) => it.module(db),
1075 ItemContainerId::ExternBlockId(it) => it.module(db),
1076 }
1077 }
1078}
1079
1080impl HasModule for AdtId {
1081 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1082 match *self {
1083 AdtId::StructId(it) => it.module(db),
1084 AdtId::UnionId(it) => it.module(db),
1085 AdtId::EnumId(it) => it.module(db),
1086 }
1087 }
1088}
1089
1090impl HasModule for VariantId {
1091 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1092 match *self {
1093 VariantId::EnumVariantId(it) => it.module(db),
1094 VariantId::StructId(it) => it.module(db),
1095 VariantId::UnionId(it) => it.module(db),
1096 }
1097 }
1098}
1099
1100impl HasModule for MacroId {
1101 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1102 match *self {
1103 MacroId::MacroRulesId(it) => it.module(db),
1104 MacroId::Macro2Id(it) => it.module(db),
1105 MacroId::ProcMacroId(it) => it.module(db),
1106 }
1107 }
1108}
1109
1110impl HasModule for DefWithBodyId {
1111 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1112 match self {
1113 DefWithBodyId::FunctionId(it) => it.module(db),
1114 DefWithBodyId::StaticId(it) => it.module(db),
1115 DefWithBodyId::ConstId(it) => it.module(db),
1116 DefWithBodyId::VariantId(it) => it.module(db),
1117 }
1118 }
1119}
1120
1121impl HasModule for GenericDefId {
1122 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1123 match self {
1124 GenericDefId::FunctionId(it) => it.module(db),
1125 GenericDefId::AdtId(it) => it.module(db),
1126 GenericDefId::TraitId(it) => it.module(db),
1127 GenericDefId::TypeAliasId(it) => it.module(db),
1128 GenericDefId::ImplId(it) => it.module(db),
1129 GenericDefId::ConstId(it) => it.module(db),
1130 GenericDefId::StaticId(it) => it.module(db),
1131 }
1132 }
1133}
1134
1135impl HasModule for AttrDefId {
1136 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1137 match self {
1138 AttrDefId::ModuleId(it) => *it,
1139 AttrDefId::AdtId(it) => it.module(db),
1140 AttrDefId::FunctionId(it) => it.module(db),
1141 AttrDefId::EnumVariantId(it) => it.module(db),
1142 AttrDefId::StaticId(it) => it.module(db),
1143 AttrDefId::ConstId(it) => it.module(db),
1144 AttrDefId::TraitId(it) => it.module(db),
1145 AttrDefId::TypeAliasId(it) => it.module(db),
1146 AttrDefId::ImplId(it) => it.module(db),
1147 AttrDefId::ExternBlockId(it) => it.module(db),
1148 AttrDefId::MacroId(it) => it.module(db),
1149 AttrDefId::ExternCrateId(it) => it.module(db),
1150 AttrDefId::UseId(it) => it.module(db),
1151 }
1152 }
1153}
1154
1155impl ModuleDefId {
1156 pub fn module(&self, db: &dyn DefDatabase) -> Option<ModuleId> {
1160 Some(match self {
1161 ModuleDefId::ModuleId(id) => *id,
1162 ModuleDefId::FunctionId(id) => id.module(db),
1163 ModuleDefId::AdtId(id) => id.module(db),
1164 ModuleDefId::EnumVariantId(id) => id.module(db),
1165 ModuleDefId::ConstId(id) => id.module(db),
1166 ModuleDefId::StaticId(id) => id.module(db),
1167 ModuleDefId::TraitId(id) => id.module(db),
1168 ModuleDefId::TypeAliasId(id) => id.module(db),
1169 ModuleDefId::MacroId(id) => id.module(db),
1170 ModuleDefId::BuiltinType(_) => return None,
1171 })
1172 }
1173}
1174#[derive(Clone, Debug, Eq, PartialEq)]
1176struct AstIdWithPath<T: AstIdNode> {
1177 ast_id: AstId<T>,
1178 path: Interned<ModPath>,
1179}
1180
1181impl<T: AstIdNode> AstIdWithPath<T> {
1182 fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: Interned<ModPath>) -> AstIdWithPath<T> {
1183 AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
1184 }
1185}
1186
1187pub fn macro_call_as_call_id(
1188 db: &dyn ExpandDatabase,
1189 ast_id: AstId<ast::MacroCall>,
1190 path: &ModPath,
1191 call_site: SyntaxContext,
1192 expand_to: ExpandTo,
1193 krate: Crate,
1194 resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
1195 eager_callback: &mut dyn FnMut(
1196 InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
1197 MacroCallId,
1198 ),
1199) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
1200 let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
1201
1202 let res = match def.kind {
1203 MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
1204 db,
1205 krate,
1206 &ast_id.to_node(db),
1207 ast_id,
1208 def,
1209 call_site,
1210 &|path| resolver(path).filter(MacroDefId::is_fn_like),
1211 eager_callback,
1212 ),
1213 _ if def.is_fn_like() => ExpandResult {
1214 value: Some(def.make_call(
1215 db,
1216 krate,
1217 MacroCallKind::FnLike { ast_id, expand_to, eager: None },
1218 call_site,
1219 )),
1220 err: None,
1221 },
1222 _ => return Err(UnresolvedMacro { path: path.clone() }),
1223 };
1224 Ok(res)
1225}
1226
1227#[derive(Debug)]
1228pub struct UnresolvedMacro {
1229 pub path: ModPath,
1230}
1231
1232#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
1233pub struct SyntheticSyntax;
1234
1235#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1259pub enum Complete {
1260 Yes,
1262 IgnoreFlyimport,
1264 IgnoreFlyimportMethods,
1266 IgnoreMethods,
1268}
1269
1270impl Complete {
1271 #[inline]
1272 pub fn extract(is_trait: bool, attrs: AttrFlags) -> Complete {
1273 if attrs.contains(AttrFlags::COMPLETE_IGNORE_FLYIMPORT) {
1274 return Complete::IgnoreFlyimport;
1275 } else if is_trait {
1276 if attrs.contains(AttrFlags::COMPLETE_IGNORE_METHODS) {
1277 return Complete::IgnoreMethods;
1278 } else if attrs.contains(AttrFlags::COMPLETE_IGNORE_FLYIMPORT_METHODS) {
1279 return Complete::IgnoreFlyimportMethods;
1280 }
1281 }
1282 Complete::Yes
1283 }
1284
1285 #[inline]
1286 pub fn for_trait_item(trait_attr: Complete, item_attr: Complete) -> Complete {
1287 match (trait_attr, item_attr) {
1288 (
1289 Complete::IgnoreFlyimportMethods
1290 | Complete::IgnoreFlyimport
1291 | Complete::IgnoreMethods,
1292 _,
1293 ) => Complete::IgnoreFlyimport,
1294 _ => item_attr,
1295 }
1296 }
1297}