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
18pub extern crate ra_ap_rustc_abi as layout;
19pub extern crate ra_ap_rustc_abi as rustc_abi;
20pub extern crate ra_ap_rustc_type_ir as rustc_type_ir;
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 builtin_derive;
34pub mod lang_item;
35pub mod unstable_features;
36
37pub mod expr_store;
38pub mod hir;
39pub mod resolver;
40pub mod upvars;
41
42pub mod nameres;
43
44pub mod src;
45
46pub mod find_path;
47pub mod import_map;
48pub mod visibility;
49
50#[cfg(test)]
51mod macro_expansion_tests;
52#[cfg(test)]
53mod test_db;
54
55use std::{
56 fmt,
57 hash::{Hash, Hasher},
58};
59
60use base_db::{Crate, SourceDatabase, impl_intern_key};
61use hir_expand::{
62 AstId, EditionedFileId, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind,
63 MacroCallStyles, MacroDefId, MacroDefKind,
64 attrs::AttrId,
65 builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
66 eager::expand_eager_macro_input,
67 impl_intern_lookup,
68 mod_path::ModPath,
69 name::Name,
70 proc_macro::{CustomProcMacroExpander, ProcMacroKind},
71};
72use intern::{Interned, sym};
73use nameres::DefMap;
74use rustc_abi::ExternAbi;
75use salsa::{Durability, Setter};
76use span::{AstIdNode, Edition, FileAstId, SyntaxContext};
77use stdx::impl_from;
78use syntax::{AstNode, ast};
79use thin_vec::ThinVec;
80
81use crate::{
82 attrs::AttrFlags,
83 builtin_derive::BuiltinDeriveImplTrait,
84 builtin_type::BuiltinType,
85 expr_store::ExpressionStoreSourceMap,
86 hir::generics::{GenericParams, 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
96pub use crate::{
97 find_path::FindPathConfig, hir::type_ref, item_tree::file_item_tree,
98 lang_item::crate_notable_traits, signatures::LocalFieldId,
99};
100pub use hir_expand::{Intern, Lookup, tt};
101
102type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
103type ThinFxHashMap<K, V> = stdx::thin_map::ThinHashMap<K, V, rustc_hash::FxBuildHasher>;
104type ThinFxHashSet<T> = stdx::thin_map::ThinHashSet<T, rustc_hash::FxBuildHasher>;
105
106#[salsa::input(singleton, debug)]
111pub(crate) struct ExpandProcAttrMacros {
112 #[returns(copy)]
113 pub(crate) enabled: bool,
114}
115
116pub fn set_expand_proc_attr_macros(db: &mut dyn SourceDatabase, enabled: bool) {
117 if let Some(expand_proc_attr_macros) = ExpandProcAttrMacros::try_get(db) {
118 if expand_proc_attr_macros.enabled(db) != enabled {
119 expand_proc_attr_macros.set_enabled(db).with_durability(Durability::HIGH).to(enabled);
120 }
121 } else {
122 _ = ExpandProcAttrMacros::builder(enabled).durability(Durability::HIGH).new(db);
123 }
124}
125
126#[derive(Debug)]
127pub struct ItemLoc<N: AstIdNode> {
128 pub container: ModuleId,
129 pub id: AstId<N>,
130}
131
132impl<N: AstIdNode> Clone for ItemLoc<N> {
133 fn clone(&self) -> Self {
134 *self
135 }
136}
137
138impl<N: AstIdNode> Copy for ItemLoc<N> {}
139
140impl<N: AstIdNode> PartialEq for ItemLoc<N> {
141 fn eq(&self, other: &Self) -> bool {
142 self.container == other.container && self.id == other.id
143 }
144}
145
146impl<N: AstIdNode> Eq for ItemLoc<N> {}
147
148impl<N: AstIdNode> 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
155impl<N: AstIdNode> HasModule for ItemLoc<N> {
156 #[inline]
157 fn module(&self, _db: &dyn SourceDatabase) -> ModuleId {
158 self.container
159 }
160}
161
162#[derive(Debug)]
163pub struct AssocItemLoc<N: AstIdNode> {
164 pub container: ItemContainerId,
166 pub id: AstId<N>,
167}
168
169impl<N: AstIdNode> Clone for AssocItemLoc<N> {
170 fn clone(&self) -> Self {
171 *self
172 }
173}
174
175impl<N: AstIdNode> Copy for AssocItemLoc<N> {}
176
177impl<N: AstIdNode> PartialEq for AssocItemLoc<N> {
178 fn eq(&self, other: &Self) -> bool {
179 self.container == other.container && self.id == other.id
180 }
181}
182
183impl<N: AstIdNode> Eq for AssocItemLoc<N> {}
184
185impl<N: AstIdNode> Hash for AssocItemLoc<N> {
186 fn hash<H: Hasher>(&self, state: &mut H) {
187 self.container.hash(state);
188 self.id.hash(state);
189 }
190}
191
192impl<N: AstIdNode> HasModule for AssocItemLoc<N> {
193 #[inline]
194 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
195 self.container.module(db)
196 }
197}
198
199pub trait AstIdLoc {
200 type Container;
201 type Ast: AstNode;
202 fn ast_id(&self) -> AstId<Self::Ast>;
203 fn container(&self) -> Self::Container;
204}
205
206impl<N: AstIdNode> AstIdLoc for ItemLoc<N> {
207 type Container = ModuleId;
208 type Ast = N;
209 #[inline]
210 fn ast_id(&self) -> AstId<Self::Ast> {
211 self.id
212 }
213 #[inline]
214 fn container(&self) -> Self::Container {
215 self.container
216 }
217}
218
219impl<N: AstIdNode> AstIdLoc for AssocItemLoc<N> {
220 type Container = ItemContainerId;
221 type Ast = N;
222 #[inline]
223 fn ast_id(&self) -> AstId<Self::Ast> {
224 self.id
225 }
226 #[inline]
227 fn container(&self) -> Self::Container {
228 self.container
229 }
230}
231
232macro_rules! impl_intern {
233 ($id:ident, $loc:ident) => {
234 impl_intern_key!($id, $loc);
235 impl_intern_lookup!($id, $loc);
236 };
237}
238
239macro_rules! impl_loc {
240 ($loc:ident, $id:ident: $id_ty:ident, $container:ident: $container_type:ident) => {
241 impl AstIdLoc for $loc {
242 type Container = $container_type;
243 type Ast = ast::$id_ty;
244 fn ast_id(&self) -> AstId<Self::Ast> {
245 self.$id
246 }
247 fn container(&self) -> Self::Container {
248 self.$container
249 }
250 }
251
252 impl HasModule for $loc {
253 #[inline]
254 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
255 self.$container.module(db)
256 }
257 }
258 };
259}
260
261type FunctionLoc = AssocItemLoc<ast::Fn>;
262impl_intern!(FunctionId, FunctionLoc);
263
264type StructLoc = ItemLoc<ast::Struct>;
265impl_intern!(StructId, StructLoc);
266
267impl StructId {
268 pub fn fields(self, db: &dyn SourceDatabase) -> &VariantFields {
269 VariantFields::of(db, self.into())
270 }
271
272 pub fn fields_with_source_map(
273 self,
274 db: &dyn SourceDatabase,
275 ) -> (&VariantFields, &ExpressionStoreSourceMap) {
276 let r = VariantFields::with_source_map(db, self.into());
277 (&r.0, &r.1)
278 }
279}
280
281pub type UnionLoc = ItemLoc<ast::Union>;
282impl_intern!(UnionId, UnionLoc);
283
284impl UnionId {
285 pub fn fields(self, db: &dyn SourceDatabase) -> &VariantFields {
286 VariantFields::of(db, self.into())
287 }
288
289 pub fn fields_with_source_map(
290 self,
291 db: &dyn SourceDatabase,
292 ) -> (&VariantFields, &ExpressionStoreSourceMap) {
293 let r = VariantFields::with_source_map(db, self.into());
294 (&r.0, &r.1)
295 }
296}
297
298pub type EnumLoc = ItemLoc<ast::Enum>;
299impl_intern!(EnumId, EnumLoc);
300
301impl EnumId {
302 #[inline]
303 pub fn enum_variants(self, db: &dyn SourceDatabase) -> &EnumVariants {
304 &self.enum_variants_with_diagnostics(db).0
305 }
306
307 #[inline]
308 pub fn enum_variants_with_diagnostics(
309 self,
310 db: &dyn SourceDatabase,
311 ) -> &(EnumVariants, ThinVec<InactiveEnumVariantCode>) {
312 EnumVariants::of(db, self)
313 }
314}
315
316type ConstLoc = AssocItemLoc<ast::Const>;
317impl_intern!(ConstId, ConstLoc);
318
319pub type StaticLoc = AssocItemLoc<ast::Static>;
320impl_intern!(StaticId, StaticLoc);
321
322pub type TraitLoc = ItemLoc<ast::Trait>;
323impl_intern!(TraitId, TraitLoc);
324
325impl TraitId {
326 #[inline]
327 pub fn trait_items(self, db: &dyn SourceDatabase) -> &TraitItems {
328 TraitItems::query(db, self)
329 }
330}
331
332type TypeAliasLoc = AssocItemLoc<ast::TypeAlias>;
333impl_intern!(TypeAliasId, TypeAliasLoc);
334
335type ImplLoc = ItemLoc<ast::Impl>;
336impl_intern!(ImplId, ImplLoc);
337
338impl ImplId {
339 #[inline]
340 pub fn impl_items(self, db: &dyn SourceDatabase) -> &ImplItems {
341 &self.impl_items_with_diagnostics(db).0
342 }
343
344 #[inline]
345 pub fn impl_items_with_diagnostics(
346 self,
347 db: &dyn SourceDatabase,
348 ) -> &(ImplItems, DefDiagnostics) {
349 ImplItems::of(db, self)
350 }
351}
352
353#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
354pub struct BuiltinDeriveImplLoc {
355 pub adt: AdtId,
356 pub trait_: BuiltinDeriveImplTrait,
357 pub derive_attr_id: AttrId,
358 pub derive_index: u32,
359}
360
361#[salsa::interned(debug, unsafe(no_lifetime), revisions = usize::MAX)]
362#[derive(PartialOrd, Ord)]
363pub struct BuiltinDeriveImplId {
364 #[returns(ref)]
365 pub loc: BuiltinDeriveImplLoc,
366}
367
368type UseLoc = ItemLoc<ast::Use>;
369impl_intern!(UseId, UseLoc);
370
371type ExternCrateLoc = ItemLoc<ast::ExternCrate>;
372impl_intern!(ExternCrateId, ExternCrateLoc);
373
374type ExternBlockLoc = ItemLoc<ast::ExternBlock>;
375impl_intern!(ExternBlockId, ExternBlockLoc);
376
377impl ExternBlockId {
378 pub fn abi(self, db: &dyn SourceDatabase) -> ExternAbi {
379 signatures::extern_block_abi(db, self)
380 }
381}
382
383#[derive(Debug, Clone, PartialEq, Eq, Hash)]
384pub struct EnumVariantLoc {
385 pub id: AstId<ast::Variant>,
386 pub parent: EnumId,
387 pub name: Name,
388}
389impl_intern!(EnumVariantId, EnumVariantLoc);
390impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId);
391
392impl EnumVariantLoc {
393 pub fn index(&self, db: &dyn SourceDatabase) -> usize {
394 self.parent
395 .enum_variants(db)
396 .variants
397 .get_full(&self.name)
398 .expect("parent enum should include this variant")
399 .0
400 }
401}
402
403impl EnumVariantId {
404 pub fn fields(self, db: &dyn SourceDatabase) -> &VariantFields {
405 VariantFields::of(db, self.into())
406 }
407
408 pub fn index(self, db: &dyn SourceDatabase) -> usize {
409 self.loc(db).index(db)
410 }
411
412 pub fn fields_with_source_map(
413 self,
414 db: &dyn SourceDatabase,
415 ) -> (&VariantFields, &ExpressionStoreSourceMap) {
416 let r = VariantFields::with_source_map(db, self.into());
417 (&r.0, &r.1)
418 }
419}
420
421#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
422pub struct Macro2Loc {
423 pub container: ModuleId,
424 pub id: AstId<ast::MacroDef>,
425 pub expander: MacroExpander,
426 pub allow_internal_unsafe: bool,
427 pub edition: Edition,
428}
429impl_intern!(Macro2Id, Macro2Loc);
430impl_loc!(Macro2Loc, id: MacroDef, container: ModuleId);
431
432#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
433pub struct MacroRulesLoc {
434 pub container: ModuleId,
435 pub id: AstId<ast::MacroRules>,
436 pub expander: MacroExpander,
437 pub flags: MacroRulesLocFlags,
438 pub edition: Edition,
439}
440impl_intern!(MacroRulesId, MacroRulesLoc);
441impl_loc!(MacroRulesLoc, id: MacroRules, container: ModuleId);
442
443bitflags::bitflags! {
444 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
445 pub struct MacroRulesLocFlags: u8 {
446 const ALLOW_INTERNAL_UNSAFE = 1 << 0;
447 const LOCAL_INNER = 1 << 1;
448 }
449}
450
451#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
452pub enum MacroExpander {
453 Declarative { styles: MacroCallStyles },
454 BuiltIn(BuiltinFnLikeExpander),
455 BuiltInAttr(BuiltinAttrExpander),
456 BuiltInDerive(BuiltinDeriveExpander),
457 BuiltInEager(EagerExpander),
458 UnimplementedBuiltIn,
459}
460
461#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
462pub struct ProcMacroLoc {
463 pub container: ModuleId,
464 pub id: AstId<ast::Fn>,
465 pub expander: CustomProcMacroExpander,
466 pub kind: ProcMacroKind,
467 pub edition: Edition,
468}
469impl_intern!(ProcMacroId, ProcMacroLoc);
470impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId);
471
472#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::SalsaValue)]
473pub enum LoweringMode {
474 Analysis,
475 Ide,
476}
477
478pub use self::tracked_struct_token::TrackedStructToken;
479mod tracked_struct_token {
480 use super::LoweringMode;
481
482 pub struct TrackedStructToken {
485 _private: (),
487 }
488
489 impl LoweringMode {
490 pub fn allow_tracked_structs(self) -> Option<TrackedStructToken> {
491 match self {
492 LoweringMode::Analysis => Some(TrackedStructToken { _private: () }),
493 LoweringMode::Ide => None,
494 }
495 }
496 }
497}
498
499#[salsa::tracked(constructor = new_)]
500#[derive(PartialOrd, Ord)]
501pub struct BlockIdLt<'db> {
502 #[returns(copy)]
503 pub ast_id: AstId<ast::BlockExpr>,
504 #[returns(copy)]
506 pub module: ModuleIdLt<'db>,
507}
508pub type BlockId = BlockIdLt<'static>;
509
510impl<'db> fmt::Debug for BlockIdLt<'db> {
511 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
512 f.debug_tuple("BlockId").field(&self.0).finish()
513 }
514}
515
516impl<'db> BlockIdLt<'db> {
517 pub fn new(
518 db: &'db dyn SourceDatabase,
519 ast_id: AstId<ast::BlockExpr>,
520 module: ModuleIdLt<'db>,
521 token: TrackedStructToken,
522 ) -> Self {
523 _ = token;
524 BlockIdLt::new_(db, ast_id, module)
525 }
526
527 pub unsafe fn to_static(self) -> BlockId {
531 unsafe { std::mem::transmute(self) }
532 }
533}
534impl BlockId {
535 pub unsafe fn to_db<'db>(self, _db: &'db dyn SourceDatabase) -> BlockIdLt<'db> {
539 unsafe { std::mem::transmute(self) }
540 }
541}
542
543#[salsa::tracked(debug)]
544#[derive(PartialOrd, Ord)]
545pub struct ModuleIdLt<'db> {
546 #[returns(copy)]
548 pub krate: Crate,
549 #[returns(copy)]
553 pub block: Option<BlockIdLt<'db>>,
554 pub containing_module_inside_def_map: Option<ModuleIdLt<'db>>,
557 #[returns(clone)]
559 name_or_empty: Name,
560}
561pub type ModuleId = ModuleIdLt<'static>;
562
563impl<'db> ModuleIdLt<'db> {
564 pub unsafe fn to_static(self) -> ModuleId {
568 unsafe { std::mem::transmute(self) }
569 }
570
571 pub fn def_map(self, db: &'db dyn SourceDatabase) -> &'db DefMap {
572 match self.block(db) {
573 Some(block) => block_def_map(db, block),
574 None => crate_def_map(db, self.krate(db)),
575 }
576 }
577
578 pub(crate) fn local_def_map(
579 self,
580 db: &'db dyn SourceDatabase,
581 ) -> (&'db DefMap, &'db LocalDefMap) {
582 match self.block(db) {
583 Some(block) => (block_def_map(db, block), self.only_local_def_map(db)),
584 None => {
585 let def_map = crate_local_def_map(db, self.krate(db));
586 (def_map.def_map(db), def_map.local(db))
587 }
588 }
589 }
590
591 pub(crate) fn only_local_def_map(self, db: &'db dyn SourceDatabase) -> &'db LocalDefMap {
592 crate_local_def_map(db, self.krate(db)).local(db)
593 }
594
595 pub fn crate_def_map(self, db: &'db dyn SourceDatabase) -> &'db DefMap {
596 crate_def_map(db, self.krate(db))
597 }
598
599 pub fn name(self, db: &dyn SourceDatabase) -> Option<Name> {
600 let name = self.name_or_empty(db);
601 if *name.symbol() == sym::__empty { None } else { Some(name) }
602 }
603
604 pub fn containing_module(self, db: &'db dyn SourceDatabase) -> Option<ModuleIdLt<'db>> {
607 self.containing_module_inside_def_map(db)
608 .or_else(|| self.block(db).map(|block| block.module(db)))
609 }
610
611 pub fn is_block_module(self, db: &dyn SourceDatabase) -> bool {
612 self.block(db).is_some() && self.containing_module_inside_def_map(db).is_none()
613 }
614}
615
616impl ModuleId {
617 pub unsafe fn to_db<'db>(self, _db: &'db dyn SourceDatabase) -> ModuleIdLt<'db> {
621 unsafe { std::mem::transmute(self) }
622 }
623}
624
625impl HasModule for ModuleId {
626 #[inline]
627 fn module(&self, _db: &dyn SourceDatabase) -> ModuleId {
628 *self
629 }
630}
631
632#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::SalsaValue)]
633pub struct FieldId {
634 pub parent: VariantId,
636 pub local_id: LocalFieldId,
637}
638
639#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::SalsaValue)]
640pub struct TupleId(pub u32);
641
642#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::SalsaValue)]
643pub struct TupleFieldId {
644 pub tuple: TupleId,
645 pub index: u32,
646}
647
648#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
649pub struct TypeOrConstParamId {
650 pub parent: GenericDefId,
652 pub local_id: LocalTypeOrConstParamId,
653}
654
655#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
657pub struct TypeParamId(TypeOrConstParamId);
658
659impl TypeParamId {
660 #[inline]
661 pub fn parent(&self) -> GenericDefId {
662 self.0.parent
663 }
664
665 #[inline]
666 pub fn local_id(&self) -> LocalTypeOrConstParamId {
667 self.0.local_id
668 }
669
670 #[inline]
671 pub fn trait_self(trait_: TraitId) -> TypeParamId {
672 TypeParamId::from_unchecked(TypeOrConstParamId {
673 parent: trait_.into(),
674 local_id: GenericParams::SELF_PARAM_ID_IN_SELF,
675 })
676 }
677
678 #[inline]
679 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
681 Self(it)
682 }
683}
684
685impl From<TypeParamId> for TypeOrConstParamId {
686 fn from(it: TypeParamId) -> Self {
687 it.0
688 }
689}
690
691#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
693pub struct ConstParamId(TypeOrConstParamId);
694
695impl ConstParamId {
696 pub fn parent(&self) -> GenericDefId {
697 self.0.parent
698 }
699 pub fn local_id(&self) -> LocalTypeOrConstParamId {
700 self.0.local_id
701 }
702}
703
704impl ConstParamId {
705 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
707 Self(it)
708 }
709}
710
711impl From<ConstParamId> for TypeOrConstParamId {
712 fn from(it: ConstParamId) -> Self {
713 it.0
714 }
715}
716
717#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
718pub struct LifetimeParamId {
719 pub parent: GenericDefId,
721 pub local_id: LocalLifetimeParamId,
722}
723
724#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
725pub struct HrtbLifetimeParamId {
726 pub scope: GenericDefId,
727 pub local_id: usize,
728}
729
730#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
731pub enum ItemContainerId {
732 ExternBlockId(ExternBlockId),
733 ModuleId(ModuleId),
734 ImplId(ImplId),
735 TraitId(TraitId),
736}
737impl_from!(ModuleId for ItemContainerId);
738
739#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
741pub enum AdtId {
742 StructId(StructId),
743 UnionId(UnionId),
744 EnumId(EnumId),
745}
746impl_from!(StructId, UnionId, EnumId for AdtId);
747
748#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
750pub enum MacroId {
751 Macro2Id(Macro2Id),
752 MacroRulesId(MacroRulesId),
753 ProcMacroId(ProcMacroId),
754}
755impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
756
757impl MacroId {
758 pub fn is_attribute(self, db: &dyn SourceDatabase) -> bool {
759 matches!(self, MacroId::ProcMacroId(it) if it.lookup(db).kind == ProcMacroKind::Attr)
760 }
761}
762
763#[salsa::tracked]
764impl MacroId {
765 #[salsa::tracked(returns(copy))]
767 pub fn definition(self, db: &dyn SourceDatabase) -> MacroDefId {
768 let kind = |expander, file_id, m| {
769 let in_file = InFile::new(file_id, m);
770 match expander {
771 MacroExpander::Declarative { styles } => MacroDefKind::Declarative(in_file, styles),
772 MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(in_file, it),
773 MacroExpander::BuiltInAttr(it) => MacroDefKind::BuiltInAttr(in_file, it),
774 MacroExpander::BuiltInDerive(it) => MacroDefKind::BuiltInDerive(in_file, it),
775 MacroExpander::BuiltInEager(it) => MacroDefKind::BuiltInEager(in_file, it),
776 MacroExpander::UnimplementedBuiltIn => MacroDefKind::UnimplementedBuiltIn(in_file),
777 }
778 };
779
780 match self {
781 MacroId::Macro2Id(it) => {
782 let loc = it.lookup(db);
783
784 MacroDefId {
785 krate: loc.container.krate(db),
786 kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()),
787 local_inner: false,
788 allow_internal_unsafe: loc.allow_internal_unsafe,
789 edition: loc.edition,
790 }
791 }
792 MacroId::MacroRulesId(it) => {
793 let loc = it.lookup(db);
794
795 MacroDefId {
796 krate: loc.container.krate(db),
797 kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()),
798 local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER),
799 allow_internal_unsafe: loc
800 .flags
801 .contains(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE),
802 edition: loc.edition,
803 }
804 }
805 MacroId::ProcMacroId(it) => {
806 let loc = it.lookup(db);
807
808 MacroDefId {
809 krate: loc.container.krate(db),
810 kind: MacroDefKind::ProcMacro(loc.id, loc.expander, loc.kind),
811 local_inner: false,
812 allow_internal_unsafe: false,
813 edition: loc.edition,
814 }
815 }
816 }
817 }
818}
819
820#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
822pub enum GenericParamId {
823 TypeParamId(TypeParamId),
824 ConstParamId(ConstParamId),
825 LifetimeParamId(LifetimeParamId),
826}
827impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
828
829#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
831pub enum ModuleDefId {
832 ModuleId(ModuleId),
833 FunctionId(FunctionId),
834 AdtId(AdtId),
835 EnumVariantId(EnumVariantId),
837 ConstId(ConstId),
838 StaticId(StaticId),
839 TraitId(TraitId),
840 TypeAliasId(TypeAliasId),
841 BuiltinType(BuiltinType),
842 MacroId(MacroId),
843}
844impl_from!(
845 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
846 ModuleId,
847 FunctionId,
848 AdtId(StructId, EnumId, UnionId),
849 EnumVariantId,
850 ConstId,
851 StaticId,
852 TraitId,
853 TypeAliasId,
854 BuiltinType
855 for ModuleDefId
856);
857
858impl From<DefWithBodyId> for ModuleDefId {
859 #[inline]
860 fn from(value: DefWithBodyId) -> Self {
861 match value {
862 DefWithBodyId::FunctionId(id) => id.into(),
863 DefWithBodyId::StaticId(id) => id.into(),
864 DefWithBodyId::ConstId(id) => id.into(),
865 DefWithBodyId::VariantId(id) => id.into(),
866 }
867 }
868}
869
870#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
872pub enum DefWithBodyId {
873 FunctionId(FunctionId),
875 StaticId(StaticId),
877 ConstId(ConstId),
879 VariantId(EnumVariantId),
881}
882impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
883
884impl From<EnumVariantId> for DefWithBodyId {
885 fn from(id: EnumVariantId) -> Self {
886 DefWithBodyId::VariantId(id)
887 }
888}
889
890impl DefWithBodyId {
891 pub fn generic_def(self, db: &dyn SourceDatabase) -> GenericDefId {
892 match self {
893 DefWithBodyId::FunctionId(f) => f.into(),
894 DefWithBodyId::StaticId(s) => s.into(),
895 DefWithBodyId::ConstId(c) => c.into(),
896 DefWithBodyId::VariantId(c) => c.lookup(db).parent.into(),
897 }
898 }
899}
900
901#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, salsa::Supertype)]
902pub enum AssocItemId {
903 FunctionId(FunctionId),
904 ConstId(ConstId),
905 TypeAliasId(TypeAliasId),
906}
907
908impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
913
914impl_from!(
915 AssocItemId {
916 FunctionId => FunctionId,
917 ConstId => ConstId,
918 TypeAliasId => TypeAliasId,
919 }
920 for ModuleDefId
921);
922
923#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
924pub enum GenericDefId {
925 AdtId(AdtId),
926 ConstId(ConstId),
928 FunctionId(FunctionId),
929 ImplId(ImplId),
930 StaticId(StaticId),
934 TraitId(TraitId),
935 TypeAliasId(TypeAliasId),
936}
937impl_from!(
938 AdtId(StructId, EnumId, UnionId),
939 ConstId,
940 FunctionId,
941 ImplId,
942 StaticId,
943 TraitId,
944 TypeAliasId
945 for GenericDefId
946);
947
948#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord )]
953pub enum ExpressionStoreOwnerId {
954 Signature(GenericDefId),
955 Body(DefWithBodyId),
959 VariantFields(VariantId),
960}
961
962impl ExpressionStoreOwnerId {
963 pub fn as_def_with_body(self) -> Option<DefWithBodyId> {
965 if let Self::Body(v) = self { Some(v) } else { None }
966 }
967
968 pub fn generic_def(self, db: &dyn SourceDatabase) -> GenericDefId {
969 match self {
970 ExpressionStoreOwnerId::Signature(generic_def_id) => generic_def_id,
971 ExpressionStoreOwnerId::Body(def_with_body_id) => match def_with_body_id {
972 DefWithBodyId::FunctionId(id) => GenericDefId::FunctionId(id),
973 DefWithBodyId::StaticId(id) => GenericDefId::StaticId(id),
974 DefWithBodyId::ConstId(id) => GenericDefId::ConstId(id),
975 DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(),
976 },
977 ExpressionStoreOwnerId::VariantFields(variant_id) => match variant_id {
978 VariantId::EnumVariantId(it) => it.lookup(db).parent.into(),
979 VariantId::StructId(it) => it.into(),
980 VariantId::UnionId(it) => it.into(),
981 },
982 }
983 }
984}
985
986impl From<GenericDefId> for ExpressionStoreOwnerId {
987 fn from(id: GenericDefId) -> Self {
988 ExpressionStoreOwnerId::Signature(id)
989 }
990}
991
992impl From<DefWithBodyId> for ExpressionStoreOwnerId {
993 fn from(id: DefWithBodyId) -> Self {
994 ExpressionStoreOwnerId::Body(id)
995 }
996}
997
998impl From<VariantId> for ExpressionStoreOwnerId {
999 fn from(id: VariantId) -> Self {
1000 ExpressionStoreOwnerId::VariantFields(id)
1001 }
1002}
1003
1004impl From<ImplId> for ExpressionStoreOwnerId {
1005 fn from(id: ImplId) -> Self {
1006 ExpressionStoreOwnerId::Signature(id.into())
1007 }
1008}
1009
1010impl GenericDefId {
1011 pub fn file_id_and_params_of(
1012 self,
1013 db: &dyn SourceDatabase,
1014 ) -> (HirFileId, Option<ast::GenericParamList>) {
1015 fn file_id_and_params_of_item_loc<Loc>(
1016 db: &dyn SourceDatabase,
1017 def: impl Lookup<Data = Loc>,
1018 ) -> (HirFileId, Option<ast::GenericParamList>)
1019 where
1020 Loc: src::HasSource,
1021 Loc::Value: ast::HasGenericParams,
1022 {
1023 let src = def.lookup(db).source(db);
1024 (src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
1025 }
1026
1027 match self {
1028 GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
1029 GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
1030 GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
1031 GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
1032 GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
1033 GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
1034 GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
1035 GenericDefId::ConstId(it) => (it.lookup(db).id.file_id, None),
1036 GenericDefId::StaticId(it) => (it.lookup(db).id.file_id, None),
1037 }
1038 }
1039
1040 pub fn assoc_trait_container(self, db: &dyn SourceDatabase) -> Option<TraitId> {
1041 match match self {
1042 GenericDefId::FunctionId(f) => f.lookup(db).container,
1043 GenericDefId::TypeAliasId(t) => t.lookup(db).container,
1044 GenericDefId::ConstId(c) => c.lookup(db).container,
1045 _ => return None,
1046 } {
1047 ItemContainerId::TraitId(trait_) => Some(trait_),
1048 _ => None,
1049 }
1050 }
1051
1052 pub fn from_callable(db: &dyn SourceDatabase, def: CallableDefId) -> GenericDefId {
1053 match def {
1054 CallableDefId::FunctionId(f) => f.into(),
1055 CallableDefId::StructId(s) => s.into(),
1056 CallableDefId::EnumVariantId(e) => e.lookup(db).parent.into(),
1057 }
1058 }
1059}
1060
1061impl_from!(
1062 AssocItemId {
1063 FunctionId => FunctionId,
1064 ConstId => ConstId,
1065 TypeAliasId => TypeAliasId,
1066 }
1067 for GenericDefId
1068);
1069
1070#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
1071pub enum CallableDefId {
1072 FunctionId(FunctionId),
1073 StructId(StructId),
1074 EnumVariantId(EnumVariantId),
1075}
1076
1077impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1078impl_from!(
1079 CallableDefId {
1080 FunctionId => FunctionId,
1081 StructId => AdtId,
1082 EnumVariantId => EnumVariantId,
1083 }
1084 for ModuleDefId
1085);
1086
1087impl CallableDefId {
1088 pub fn krate(self, db: &dyn SourceDatabase) -> Crate {
1089 match self {
1090 CallableDefId::FunctionId(f) => f.krate(db),
1091 CallableDefId::StructId(s) => s.krate(db),
1092 CallableDefId::EnumVariantId(e) => e.krate(db),
1093 }
1094 }
1095}
1096
1097#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, salsa::Supertype)]
1098pub enum AttrDefId {
1099 ModuleId(ModuleId),
1100 AdtId(AdtId),
1101 FunctionId(FunctionId),
1102 EnumVariantId(EnumVariantId),
1103 StaticId(StaticId),
1104 ConstId(ConstId),
1105 TraitId(TraitId),
1106 TypeAliasId(TypeAliasId),
1107 MacroId(MacroId),
1108 ImplId(ImplId),
1109 ExternBlockId(ExternBlockId),
1110 ExternCrateId(ExternCrateId),
1111 UseId(UseId),
1112}
1113
1114impl_from!(
1115 ModuleId,
1116 AdtId(StructId, EnumId, UnionId),
1117 EnumVariantId,
1118 StaticId,
1119 ConstId,
1120 FunctionId,
1121 TraitId,
1122 TypeAliasId,
1123 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
1124 ImplId,
1125 ExternCrateId,
1126 UseId
1127 for AttrDefId
1128);
1129
1130impl_from!(AssocItemId { FunctionId, ConstId, TypeAliasId } for AttrDefId);
1131impl_from!(
1132 VariantId { EnumVariantId => EnumVariantId, StructId => AdtId, UnionId => AdtId }
1133 for AttrDefId
1134);
1135
1136#[derive(
1137 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa::Supertype, salsa::SalsaValue,
1138)]
1139pub enum VariantId {
1140 EnumVariantId(EnumVariantId),
1141 StructId(StructId),
1142 UnionId(UnionId),
1143}
1144impl_from!(EnumVariantId, StructId, UnionId for VariantId);
1145
1146impl VariantId {
1147 pub fn from_non_enum(adt_id: AdtId) -> Option<Self> {
1148 Some(match adt_id {
1149 AdtId::StructId(struct_id) => struct_id.into(),
1150 AdtId::UnionId(union_id) => union_id.into(),
1151 AdtId::EnumId(_) => return None,
1152 })
1153 }
1154
1155 pub fn fields(self, db: &dyn SourceDatabase) -> &VariantFields {
1156 VariantFields::of(db, self)
1157 }
1158
1159 pub fn fields_with_source_map(
1160 self,
1161 db: &dyn SourceDatabase,
1162 ) -> (&VariantFields, &ExpressionStoreSourceMap) {
1163 let r = VariantFields::with_source_map(db, self);
1164 (&r.0, &r.1)
1165 }
1166
1167 pub fn file_id(self, db: &dyn SourceDatabase) -> HirFileId {
1168 match self {
1169 VariantId::EnumVariantId(it) => it.lookup(db).id.file_id,
1170 VariantId::StructId(it) => it.lookup(db).id.file_id,
1171 VariantId::UnionId(it) => it.lookup(db).id.file_id,
1172 }
1173 }
1174
1175 pub fn adt_id(self, db: &dyn SourceDatabase) -> AdtId {
1176 match self {
1177 VariantId::EnumVariantId(it) => it.lookup(db).parent.into(),
1178 VariantId::StructId(it) => it.into(),
1179 VariantId::UnionId(it) => it.into(),
1180 }
1181 }
1182}
1183
1184pub trait HasModule {
1185 fn module(&self, db: &dyn SourceDatabase) -> ModuleId;
1187 #[inline]
1189 #[doc(alias = "crate")]
1190 fn krate(&self, db: &dyn SourceDatabase) -> Crate {
1191 self.module(db).krate(db)
1192 }
1193}
1194
1195impl<N, ItemId> HasModule for ItemId
1210where
1211 N: AstIdNode,
1212 ItemId: Lookup<Data = ItemLoc<N>> + Copy,
1213{
1214 #[inline]
1215 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1216 self.lookup(db).container
1217 }
1218}
1219
1220#[inline]
1235fn module_for_assoc_item_loc<'db>(
1236 db: &(dyn 'db + SourceDatabase),
1237 id: impl Lookup<Data = AssocItemLoc<impl AstIdNode>>,
1238) -> ModuleId {
1239 id.lookup(db).container.module(db)
1240}
1241
1242impl HasModule for BuiltinDeriveImplLoc {
1243 #[inline]
1244 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1245 self.adt.module(db)
1246 }
1247}
1248
1249impl HasModule for BuiltinDeriveImplId {
1250 #[inline]
1251 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1252 self.loc(db).module(db)
1253 }
1254}
1255
1256impl HasModule for FunctionId {
1257 #[inline]
1258 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1259 module_for_assoc_item_loc(db, *self)
1260 }
1261}
1262
1263impl HasModule for ConstId {
1264 #[inline]
1265 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1266 module_for_assoc_item_loc(db, *self)
1267 }
1268}
1269
1270impl HasModule for StaticId {
1271 #[inline]
1272 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1273 module_for_assoc_item_loc(db, *self)
1274 }
1275}
1276
1277impl HasModule for TypeAliasId {
1278 #[inline]
1279 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1280 module_for_assoc_item_loc(db, *self)
1281 }
1282}
1283impl HasModule for EnumVariantId {
1286 #[inline]
1287 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1288 self.lookup(db).parent.module(db)
1289 }
1290}
1291
1292impl HasModule for MacroRulesId {
1293 #[inline]
1294 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1295 self.lookup(db).container
1296 }
1297}
1298
1299impl HasModule for Macro2Id {
1300 #[inline]
1301 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1302 self.lookup(db).container
1303 }
1304}
1305
1306impl HasModule for ProcMacroId {
1307 #[inline]
1308 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1309 self.lookup(db).container
1310 }
1311}
1312
1313impl HasModule for ItemContainerId {
1314 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1315 match *self {
1316 ItemContainerId::ModuleId(it) => it,
1317 ItemContainerId::ImplId(it) => it.module(db),
1318 ItemContainerId::TraitId(it) => it.module(db),
1319 ItemContainerId::ExternBlockId(it) => it.module(db),
1320 }
1321 }
1322}
1323
1324impl HasModule for AdtId {
1325 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1326 match *self {
1327 AdtId::StructId(it) => it.module(db),
1328 AdtId::UnionId(it) => it.module(db),
1329 AdtId::EnumId(it) => it.module(db),
1330 }
1331 }
1332}
1333
1334impl HasModule for VariantId {
1335 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1336 match *self {
1337 VariantId::EnumVariantId(it) => it.module(db),
1338 VariantId::StructId(it) => it.module(db),
1339 VariantId::UnionId(it) => it.module(db),
1340 }
1341 }
1342}
1343
1344impl HasModule for MacroId {
1345 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1346 match *self {
1347 MacroId::MacroRulesId(it) => it.module(db),
1348 MacroId::Macro2Id(it) => it.module(db),
1349 MacroId::ProcMacroId(it) => it.module(db),
1350 }
1351 }
1352}
1353
1354impl HasModule for DefWithBodyId {
1355 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1356 match self {
1357 DefWithBodyId::FunctionId(it) => it.module(db),
1358 DefWithBodyId::StaticId(it) => it.module(db),
1359 DefWithBodyId::ConstId(it) => it.module(db),
1360 DefWithBodyId::VariantId(it) => it.module(db),
1361 }
1362 }
1363}
1364
1365impl HasModule for ExpressionStoreOwnerId {
1366 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1367 match self {
1368 ExpressionStoreOwnerId::Signature(def) => def.module(db),
1369 ExpressionStoreOwnerId::Body(def) => def.module(db),
1370 ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.module(db),
1371 }
1372 }
1373}
1374
1375impl HasModule for GenericDefId {
1376 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1377 match self {
1378 GenericDefId::FunctionId(it) => it.module(db),
1379 GenericDefId::AdtId(it) => it.module(db),
1380 GenericDefId::TraitId(it) => it.module(db),
1381 GenericDefId::TypeAliasId(it) => it.module(db),
1382 GenericDefId::ImplId(it) => it.module(db),
1383 GenericDefId::ConstId(it) => it.module(db),
1384 GenericDefId::StaticId(it) => it.module(db),
1385 }
1386 }
1387}
1388
1389impl HasModule for AttrDefId {
1390 fn module(&self, db: &dyn SourceDatabase) -> ModuleId {
1391 match self {
1392 AttrDefId::ModuleId(it) => *it,
1393 AttrDefId::AdtId(it) => it.module(db),
1394 AttrDefId::FunctionId(it) => it.module(db),
1395 AttrDefId::EnumVariantId(it) => it.module(db),
1396 AttrDefId::StaticId(it) => it.module(db),
1397 AttrDefId::ConstId(it) => it.module(db),
1398 AttrDefId::TraitId(it) => it.module(db),
1399 AttrDefId::TypeAliasId(it) => it.module(db),
1400 AttrDefId::ImplId(it) => it.module(db),
1401 AttrDefId::ExternBlockId(it) => it.module(db),
1402 AttrDefId::MacroId(it) => it.module(db),
1403 AttrDefId::ExternCrateId(it) => it.module(db),
1404 AttrDefId::UseId(it) => it.module(db),
1405 }
1406 }
1407}
1408
1409impl ModuleDefId {
1410 pub fn module(&self, db: &dyn SourceDatabase) -> Option<ModuleId> {
1414 Some(match self {
1415 ModuleDefId::ModuleId(id) => *id,
1416 ModuleDefId::FunctionId(id) => id.module(db),
1417 ModuleDefId::AdtId(id) => id.module(db),
1418 ModuleDefId::EnumVariantId(id) => id.module(db),
1419 ModuleDefId::ConstId(id) => id.module(db),
1420 ModuleDefId::StaticId(id) => id.module(db),
1421 ModuleDefId::TraitId(id) => id.module(db),
1422 ModuleDefId::TypeAliasId(id) => id.module(db),
1423 ModuleDefId::MacroId(id) => id.module(db),
1424 ModuleDefId::BuiltinType(_) => return None,
1425 })
1426 }
1427}
1428#[derive(Clone, Debug, Eq, PartialEq)]
1430struct AstIdWithPath<T: AstIdNode> {
1431 ast_id: AstId<T>,
1432 path: Interned<ModPath>,
1433}
1434
1435impl<T: AstIdNode> AstIdWithPath<T> {
1436 fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: Interned<ModPath>) -> AstIdWithPath<T> {
1437 AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
1438 }
1439}
1440
1441pub fn macro_call_as_call_id(
1442 db: &dyn SourceDatabase,
1443 ast_id: AstId<ast::MacroCall>,
1444 path: &ModPath,
1445 call_site: SyntaxContext,
1446 expand_to: ExpandTo,
1447 krate: Crate,
1448 macro_depth: u32,
1449 recursion_limit: u32,
1450 resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
1451 eager_callback: &mut dyn FnMut(
1452 InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
1453 MacroCallId,
1454 ),
1455) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
1456 let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
1457
1458 let res = match def.kind {
1459 MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
1460 db,
1461 krate,
1462 &ast_id.to_node(db),
1463 ast_id,
1464 def,
1465 call_site,
1466 macro_depth,
1467 recursion_limit,
1468 &|path| resolver(path).filter(MacroDefId::is_fn_like),
1469 eager_callback,
1470 ),
1471 _ if def.is_fn_like() => ExpandResult {
1472 value: Some(def.make_call(
1473 db,
1474 krate,
1475 MacroCallKind::FnLike { ast_id, expand_to, eager: None },
1476 call_site,
1477 macro_depth,
1478 )),
1479 err: None,
1480 },
1481 _ => return Err(UnresolvedMacro { path: path.clone() }),
1482 };
1483 Ok(res)
1484}
1485
1486#[derive(Debug)]
1487pub struct UnresolvedMacro {
1488 pub path: ModPath,
1489}
1490
1491#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
1492pub struct SyntheticSyntax;
1493
1494#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1518pub enum Complete {
1519 Yes,
1521 IgnoreFlyimport,
1523 IgnoreFlyimportMethods,
1525 IgnoreMethods,
1527}
1528
1529impl Complete {
1530 #[inline]
1531 pub fn extract(is_trait: bool, attrs: AttrFlags) -> Complete {
1532 if attrs.contains(AttrFlags::COMPLETE_IGNORE_FLYIMPORT) {
1533 return Complete::IgnoreFlyimport;
1534 } else if is_trait {
1535 if attrs.contains(AttrFlags::COMPLETE_IGNORE_METHODS) {
1536 return Complete::IgnoreMethods;
1537 } else if attrs.contains(AttrFlags::COMPLETE_IGNORE_FLYIMPORT_METHODS) {
1538 return Complete::IgnoreFlyimportMethods;
1539 }
1540 }
1541 Complete::Yes
1542 }
1543
1544 #[inline]
1545 pub fn for_trait_item(trait_attr: Complete, item_attr: Complete) -> Complete {
1546 match (trait_attr, item_attr) {
1547 (
1548 Complete::IgnoreFlyimportMethods
1549 | Complete::IgnoreFlyimport
1550 | Complete::IgnoreMethods,
1551 _,
1552 ) => Complete::IgnoreFlyimport,
1553 _ => item_attr,
1554 }
1555 }
1556}
1557
1558#[salsa::tracked(returns(ref))]
1560pub fn include_macro_invoc(
1561 db: &dyn SourceDatabase,
1562 krate: Crate,
1563) -> Box<[(MacroCallId, EditionedFileId)]> {
1564 crate_def_map(db, krate)
1565 .modules
1566 .values()
1567 .flat_map(|m| m.scope.iter_macro_invoc())
1568 .filter_map(|(_, &invoc)| invoc.loc(db).include_file_id(db, invoc).map(|x| (invoc, x)))
1569 .collect()
1570}