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