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 attr;
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, sym};
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, MacroDefId,
65 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 la_arena::Idx;
75use nameres::DefMap;
76use span::{AstIdNode, Edition, FileAstId, SyntaxContext};
77use stdx::impl_from;
78use syntax::{AstNode, ast};
79
80pub use hir_expand::{Intern, Lookup, tt};
81
82use crate::{
83 attr::Attrs,
84 builtin_type::BuiltinType,
85 db::DefDatabase,
86 expr_store::ExpressionStoreSourceMap,
87 hir::generics::{LocalLifetimeParamId, LocalTypeOrConstParamId},
88 nameres::{
89 LocalDefMap,
90 assoc::{ImplItems, TraitItems},
91 block_def_map, crate_def_map, crate_local_def_map,
92 diagnostics::DefDiagnostics,
93 },
94 signatures::{EnumVariants, InactiveEnumVariantCode, VariantFields},
95};
96
97type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
98#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
100pub struct FindPathConfig {
101 pub prefer_no_std: bool,
104 pub prefer_prelude: bool,
106 pub prefer_absolute: bool,
108 pub allow_unstable: bool,
111}
112
113#[derive(Debug)]
114pub struct ItemLoc<N: AstIdNode> {
115 pub container: ModuleId,
116 pub id: AstId<N>,
117}
118
119impl<N: AstIdNode> Clone for ItemLoc<N> {
120 fn clone(&self) -> Self {
121 *self
122 }
123}
124
125impl<N: AstIdNode> Copy for ItemLoc<N> {}
126
127impl<N: AstIdNode> PartialEq for ItemLoc<N> {
128 fn eq(&self, other: &Self) -> bool {
129 self.container == other.container && self.id == other.id
130 }
131}
132
133impl<N: AstIdNode> Eq for ItemLoc<N> {}
134
135impl<N: AstIdNode> Hash for ItemLoc<N> {
136 fn hash<H: Hasher>(&self, state: &mut H) {
137 self.container.hash(state);
138 self.id.hash(state);
139 }
140}
141
142impl<N: AstIdNode> HasModule for ItemLoc<N> {
143 #[inline]
144 fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
145 self.container
146 }
147}
148
149#[derive(Debug)]
150pub struct AssocItemLoc<N: AstIdNode> {
151 pub container: ItemContainerId,
153 pub id: AstId<N>,
154}
155
156impl<N: AstIdNode> Clone for AssocItemLoc<N> {
157 fn clone(&self) -> Self {
158 *self
159 }
160}
161
162impl<N: AstIdNode> Copy for AssocItemLoc<N> {}
163
164impl<N: AstIdNode> PartialEq for AssocItemLoc<N> {
165 fn eq(&self, other: &Self) -> bool {
166 self.container == other.container && self.id == other.id
167 }
168}
169
170impl<N: AstIdNode> Eq for AssocItemLoc<N> {}
171
172impl<N: AstIdNode> Hash for AssocItemLoc<N> {
173 fn hash<H: Hasher>(&self, state: &mut H) {
174 self.container.hash(state);
175 self.id.hash(state);
176 }
177}
178
179impl<N: AstIdNode> HasModule for AssocItemLoc<N> {
180 #[inline]
181 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
182 self.container.module(db)
183 }
184}
185
186pub trait AstIdLoc {
187 type Container;
188 type Ast: AstNode;
189 fn ast_id(&self) -> AstId<Self::Ast>;
190 fn container(&self) -> Self::Container;
191}
192
193impl<N: AstIdNode> AstIdLoc for ItemLoc<N> {
194 type Container = ModuleId;
195 type Ast = N;
196 #[inline]
197 fn ast_id(&self) -> AstId<Self::Ast> {
198 self.id
199 }
200 #[inline]
201 fn container(&self) -> Self::Container {
202 self.container
203 }
204}
205
206impl<N: AstIdNode> AstIdLoc for AssocItemLoc<N> {
207 type Container = ItemContainerId;
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
219macro_rules! impl_intern {
220 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
221 impl_intern_key!($id, $loc);
222 impl_intern_lookup!(DefDatabase, $id, $loc, $intern, $lookup);
223 };
224}
225
226macro_rules! impl_loc {
227 ($loc:ident, $id:ident: $id_ty:ident, $container:ident: $container_type:ident) => {
228 impl AstIdLoc for $loc {
229 type Container = $container_type;
230 type Ast = ast::$id_ty;
231 fn ast_id(&self) -> AstId<Self::Ast> {
232 self.$id
233 }
234 fn container(&self) -> Self::Container {
235 self.$container
236 }
237 }
238
239 impl HasModule for $loc {
240 #[inline]
241 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
242 self.$container.module(db)
243 }
244 }
245 };
246}
247
248type FunctionLoc = AssocItemLoc<ast::Fn>;
249impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
250
251type StructLoc = ItemLoc<ast::Struct>;
252impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
253
254impl StructId {
255 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
256 VariantFields::firewall(db, self.into())
257 }
258
259 pub fn fields_with_source_map(
260 self,
261 db: &dyn DefDatabase,
262 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
263 VariantFields::query(db, self.into())
264 }
265}
266
267pub type UnionLoc = ItemLoc<ast::Union>;
268impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
269
270impl UnionId {
271 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
272 VariantFields::firewall(db, self.into())
273 }
274
275 pub fn fields_with_source_map(
276 self,
277 db: &dyn DefDatabase,
278 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
279 VariantFields::query(db, self.into())
280 }
281}
282
283pub type EnumLoc = ItemLoc<ast::Enum>;
284impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
285
286impl EnumId {
287 #[inline]
288 pub fn enum_variants(self, db: &dyn DefDatabase) -> &EnumVariants {
289 &self.enum_variants_with_diagnostics(db).0
290 }
291
292 #[inline]
293 pub fn enum_variants_with_diagnostics(
294 self,
295 db: &dyn DefDatabase,
296 ) -> &(EnumVariants, Option<ThinVec<InactiveEnumVariantCode>>) {
297 EnumVariants::of(db, self)
298 }
299}
300
301type ConstLoc = AssocItemLoc<ast::Const>;
302impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
303
304pub type StaticLoc = AssocItemLoc<ast::Static>;
305impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
306
307pub type TraitLoc = ItemLoc<ast::Trait>;
308impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
309
310impl TraitId {
311 #[inline]
312 pub fn trait_items(self, db: &dyn DefDatabase) -> &TraitItems {
313 TraitItems::query(db, self)
314 }
315}
316
317type TypeAliasLoc = AssocItemLoc<ast::TypeAlias>;
318impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
319
320type ImplLoc = ItemLoc<ast::Impl>;
321impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
322
323impl ImplId {
324 #[inline]
325 pub fn impl_items(self, db: &dyn DefDatabase) -> &ImplItems {
326 &self.impl_items_with_diagnostics(db).0
327 }
328
329 #[inline]
330 pub fn impl_items_with_diagnostics(self, db: &dyn DefDatabase) -> &(ImplItems, DefDiagnostics) {
331 ImplItems::of(db, self)
332 }
333}
334
335type UseLoc = ItemLoc<ast::Use>;
336impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
337
338type ExternCrateLoc = ItemLoc<ast::ExternCrate>;
339impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate);
340
341type ExternBlockLoc = ItemLoc<ast::ExternBlock>;
342impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
343
344#[salsa::tracked]
345impl ExternBlockId {
346 #[salsa::tracked]
347 pub fn abi(self, db: &dyn DefDatabase) -> Option<Symbol> {
348 signatures::extern_block_abi(db, self)
349 }
350}
351
352#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
353pub struct EnumVariantLoc {
354 pub id: AstId<ast::Variant>,
355 pub parent: EnumId,
356 pub index: u32,
357}
358impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
359impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId);
360
361impl EnumVariantId {
362 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
363 VariantFields::firewall(db, self.into())
364 }
365
366 pub fn fields_with_source_map(
367 self,
368 db: &dyn DefDatabase,
369 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
370 VariantFields::query(db, self.into())
371 }
372}
373
374#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
375pub struct Macro2Loc {
376 pub container: ModuleId,
377 pub id: AstId<ast::MacroDef>,
378 pub expander: MacroExpander,
379 pub allow_internal_unsafe: bool,
380 pub edition: Edition,
381}
382impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
383impl_loc!(Macro2Loc, id: MacroDef, container: ModuleId);
384
385#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
386pub struct MacroRulesLoc {
387 pub container: ModuleId,
388 pub id: AstId<ast::MacroRules>,
389 pub expander: MacroExpander,
390 pub flags: MacroRulesLocFlags,
391 pub edition: Edition,
392}
393impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
394impl_loc!(MacroRulesLoc, id: MacroRules, container: ModuleId);
395
396bitflags::bitflags! {
397 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
398 pub struct MacroRulesLocFlags: u8 {
399 const ALLOW_INTERNAL_UNSAFE = 1 << 0;
400 const LOCAL_INNER = 1 << 1;
401 }
402}
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
405pub enum MacroExpander {
406 Declarative,
407 BuiltIn(BuiltinFnLikeExpander),
408 BuiltInAttr(BuiltinAttrExpander),
409 BuiltInDerive(BuiltinDeriveExpander),
410 BuiltInEager(EagerExpander),
411}
412
413#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
414pub struct ProcMacroLoc {
415 pub container: CrateRootModuleId,
416 pub id: AstId<ast::Fn>,
417 pub expander: CustomProcMacroExpander,
418 pub kind: ProcMacroKind,
419 pub edition: Edition,
420}
421impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
422impl_loc!(ProcMacroLoc, id: Fn, container: CrateRootModuleId);
423
424#[derive(Debug, Hash, PartialEq, Eq, Clone)]
425pub struct BlockLoc {
426 pub ast_id: AstId<ast::BlockExpr>,
427 pub module: ModuleId,
429}
430impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
431
432#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
434pub struct CrateRootModuleId {
435 krate: Crate,
436}
437
438impl CrateRootModuleId {
439 pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
440 crate_def_map(db, self.krate)
441 }
442
443 pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) {
444 let def_map = crate_local_def_map(db, self.krate);
445 (def_map.def_map(db), def_map.local(db))
446 }
447
448 pub fn krate(self) -> Crate {
449 self.krate
450 }
451}
452
453impl HasModule for CrateRootModuleId {
454 #[inline]
455 fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
456 ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT }
457 }
458
459 #[inline]
460 fn krate(&self, _db: &dyn DefDatabase) -> Crate {
461 self.krate
462 }
463}
464
465impl PartialEq<ModuleId> for CrateRootModuleId {
466 fn eq(&self, other: &ModuleId) -> bool {
467 other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate
468 }
469}
470impl PartialEq<CrateRootModuleId> for ModuleId {
471 fn eq(&self, other: &CrateRootModuleId) -> bool {
472 other == self
473 }
474}
475
476impl From<CrateRootModuleId> for ModuleId {
477 fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
478 ModuleId { krate, block: None, local_id: DefMap::ROOT }
479 }
480}
481
482impl From<CrateRootModuleId> for ModuleDefId {
483 fn from(value: CrateRootModuleId) -> Self {
484 ModuleDefId::ModuleId(value.into())
485 }
486}
487
488impl From<Crate> for CrateRootModuleId {
489 fn from(krate: Crate) -> Self {
490 CrateRootModuleId { krate }
491 }
492}
493
494impl TryFrom<ModuleId> for CrateRootModuleId {
495 type Error = ();
496
497 fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> {
498 if block.is_none() && local_id == DefMap::ROOT {
499 Ok(CrateRootModuleId { krate })
500 } else {
501 Err(())
502 }
503 }
504}
505
506#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
507pub struct ModuleId {
508 krate: Crate,
509 block: Option<BlockId>,
513 pub local_id: LocalModuleId,
515}
516
517impl ModuleId {
518 pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
519 match self.block {
520 Some(block) => block_def_map(db, block),
521 None => crate_def_map(db, self.krate),
522 }
523 }
524
525 pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) {
526 match self.block {
527 Some(block) => (block_def_map(db, block), self.only_local_def_map(db)),
528 None => {
529 let def_map = crate_local_def_map(db, self.krate);
530 (def_map.def_map(db), def_map.local(db))
531 }
532 }
533 }
534
535 pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap {
536 crate_local_def_map(db, self.krate).local(db)
537 }
538
539 pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap {
540 crate_def_map(db, self.krate)
541 }
542
543 pub fn krate(self) -> Crate {
544 self.krate
545 }
546
547 pub fn name(self, db: &dyn DefDatabase) -> Option<Name> {
548 let def_map = self.def_map(db);
549 let parent = def_map[self.local_id].parent?;
550 def_map[parent].children.iter().find_map(|(name, module_id)| {
551 if *module_id == self.local_id { Some(name.clone()) } else { None }
552 })
553 }
554
555 pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> {
558 self.def_map(db).containing_module(self.local_id)
559 }
560
561 pub fn containing_block(self) -> Option<BlockId> {
562 self.block
563 }
564
565 pub fn is_block_module(self) -> bool {
566 self.block.is_some() && self.local_id == DefMap::ROOT
567 }
568
569 pub fn is_within_block(self) -> bool {
570 self.block.is_some()
571 }
572
573 pub fn as_crate_root(&self) -> Option<CrateRootModuleId> {
575 if self.local_id == DefMap::ROOT && self.block.is_none() {
576 Some(CrateRootModuleId { krate: self.krate })
577 } else {
578 None
579 }
580 }
581
582 pub fn derive_crate_root(&self) -> CrateRootModuleId {
584 CrateRootModuleId { krate: self.krate }
585 }
586
587 pub fn is_crate_root(&self) -> bool {
589 self.local_id == DefMap::ROOT && self.block.is_none()
590 }
591}
592
593impl HasModule for ModuleId {
594 #[inline]
595 fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
596 *self
597 }
598}
599
600pub type LocalModuleId = Idx<nameres::ModuleData>;
602
603#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
604pub struct FieldId {
605 pub parent: VariantId,
607 pub local_id: LocalFieldId,
608}
609
610#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
611pub struct TupleId(pub u32);
612
613#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
614pub struct TupleFieldId {
615 pub tuple: TupleId,
616 pub index: u32,
617}
618
619#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
620pub struct TypeOrConstParamId {
621 pub parent: GenericDefId,
623 pub local_id: LocalTypeOrConstParamId,
624}
625
626#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
628pub struct TypeParamId(TypeOrConstParamId);
629
630impl TypeParamId {
631 pub fn parent(&self) -> GenericDefId {
632 self.0.parent
633 }
634 pub fn local_id(&self) -> LocalTypeOrConstParamId {
635 self.0.local_id
636 }
637}
638
639impl TypeParamId {
640 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
642 Self(it)
643 }
644}
645
646impl From<TypeParamId> for TypeOrConstParamId {
647 fn from(it: TypeParamId) -> Self {
648 it.0
649 }
650}
651
652#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
654pub struct ConstParamId(TypeOrConstParamId);
655
656impl ConstParamId {
657 pub fn parent(&self) -> GenericDefId {
658 self.0.parent
659 }
660 pub fn local_id(&self) -> LocalTypeOrConstParamId {
661 self.0.local_id
662 }
663}
664
665impl ConstParamId {
666 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
668 Self(it)
669 }
670}
671
672impl From<ConstParamId> for TypeOrConstParamId {
673 fn from(it: ConstParamId) -> Self {
674 it.0
675 }
676}
677
678#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
679pub struct LifetimeParamId {
680 pub parent: GenericDefId,
682 pub local_id: LocalLifetimeParamId,
683}
684
685#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
686pub enum ItemContainerId {
687 ExternBlockId(ExternBlockId),
688 ModuleId(ModuleId),
689 ImplId(ImplId),
690 TraitId(TraitId),
691}
692impl_from!(ModuleId for ItemContainerId);
693
694#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
696pub enum AdtId {
697 StructId(StructId),
698 UnionId(UnionId),
699 EnumId(EnumId),
700}
701impl_from!(StructId, UnionId, EnumId for AdtId);
702
703#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
705pub enum MacroId {
706 Macro2Id(Macro2Id),
707 MacroRulesId(MacroRulesId),
708 ProcMacroId(ProcMacroId),
709}
710impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
711
712impl MacroId {
713 pub fn is_attribute(self, db: &dyn DefDatabase) -> bool {
714 matches!(self, MacroId::ProcMacroId(it) if it.lookup(db).kind == ProcMacroKind::Attr)
715 }
716}
717
718#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
720pub enum GenericParamId {
721 TypeParamId(TypeParamId),
722 ConstParamId(ConstParamId),
723 LifetimeParamId(LifetimeParamId),
724}
725impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
726
727#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
729pub enum ModuleDefId {
730 ModuleId(ModuleId),
731 FunctionId(FunctionId),
732 AdtId(AdtId),
733 EnumVariantId(EnumVariantId),
735 ConstId(ConstId),
736 StaticId(StaticId),
737 TraitId(TraitId),
738 TypeAliasId(TypeAliasId),
739 BuiltinType(BuiltinType),
740 MacroId(MacroId),
741}
742impl_from!(
743 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
744 ModuleId,
745 FunctionId,
746 AdtId(StructId, EnumId, UnionId),
747 EnumVariantId,
748 ConstId,
749 StaticId,
750 TraitId,
751 TypeAliasId,
752 BuiltinType
753 for ModuleDefId
754);
755
756#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
759pub enum GeneralConstId {
760 ConstId(ConstId),
761 StaticId(StaticId),
762}
763
764impl_from!(ConstId, StaticId for GeneralConstId);
765
766impl GeneralConstId {
767 pub fn generic_def(self, _db: &dyn DefDatabase) -> Option<GenericDefId> {
768 match self {
769 GeneralConstId::ConstId(it) => Some(it.into()),
770 GeneralConstId::StaticId(it) => Some(it.into()),
771 }
772 }
773
774 pub fn name(self, db: &dyn DefDatabase) -> String {
775 match self {
776 GeneralConstId::StaticId(it) => {
777 db.static_signature(it).name.display(db, Edition::CURRENT).to_string()
778 }
779 GeneralConstId::ConstId(const_id) => {
780 db.const_signature(const_id).name.as_ref().map_or_else(
781 || "_".to_owned(),
782 |name| name.display(db, Edition::CURRENT).to_string(),
783 )
784 }
785 }
786 }
787}
788
789#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
791pub enum DefWithBodyId {
792 FunctionId(FunctionId),
793 StaticId(StaticId),
794 ConstId(ConstId),
795 VariantId(EnumVariantId),
796 }
803impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
804
805impl From<EnumVariantId> for DefWithBodyId {
806 fn from(id: EnumVariantId) -> Self {
807 DefWithBodyId::VariantId(id)
808 }
809}
810
811impl DefWithBodyId {
812 pub fn as_generic_def_id(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
813 match self {
814 DefWithBodyId::FunctionId(f) => Some(f.into()),
815 DefWithBodyId::StaticId(s) => Some(s.into()),
816 DefWithBodyId::ConstId(c) => Some(c.into()),
817 DefWithBodyId::VariantId(c) => Some(c.lookup(db).parent.into()),
818 }
819 }
820}
821
822#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, salsa_macros::Supertype)]
823pub enum AssocItemId {
824 FunctionId(FunctionId),
825 ConstId(ConstId),
826 TypeAliasId(TypeAliasId),
827}
828
829impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
834
835impl From<AssocItemId> for ModuleDefId {
836 fn from(item: AssocItemId) -> Self {
837 match item {
838 AssocItemId::FunctionId(f) => f.into(),
839 AssocItemId::ConstId(c) => c.into(),
840 AssocItemId::TypeAliasId(t) => t.into(),
841 }
842 }
843}
844
845#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
846pub enum GenericDefId {
847 AdtId(AdtId),
848 ConstId(ConstId),
850 FunctionId(FunctionId),
851 ImplId(ImplId),
852 StaticId(StaticId),
856 TraitId(TraitId),
857 TypeAliasId(TypeAliasId),
858}
859impl_from!(
860 AdtId(StructId, EnumId, UnionId),
861 ConstId,
862 FunctionId,
863 ImplId,
864 StaticId,
865 TraitId,
866 TypeAliasId
867 for GenericDefId
868);
869
870impl GenericDefId {
871 pub fn file_id_and_params_of(
872 self,
873 db: &dyn DefDatabase,
874 ) -> (HirFileId, Option<ast::GenericParamList>) {
875 fn file_id_and_params_of_item_loc<Loc>(
876 db: &dyn DefDatabase,
877 def: impl Lookup<Database = dyn DefDatabase, Data = Loc>,
878 ) -> (HirFileId, Option<ast::GenericParamList>)
879 where
880 Loc: src::HasSource,
881 Loc::Value: ast::HasGenericParams,
882 {
883 let src = def.lookup(db).source(db);
884 (src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
885 }
886
887 match self {
888 GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
889 GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
890 GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
891 GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
892 GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
893 GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
894 GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
895 GenericDefId::ConstId(it) => (it.lookup(db).id.file_id, None),
896 GenericDefId::StaticId(it) => (it.lookup(db).id.file_id, None),
897 }
898 }
899
900 pub fn assoc_trait_container(self, db: &dyn DefDatabase) -> Option<TraitId> {
901 match match self {
902 GenericDefId::FunctionId(f) => f.lookup(db).container,
903 GenericDefId::TypeAliasId(t) => t.lookup(db).container,
904 GenericDefId::ConstId(c) => c.lookup(db).container,
905 _ => return None,
906 } {
907 ItemContainerId::TraitId(trait_) => Some(trait_),
908 _ => None,
909 }
910 }
911
912 pub fn from_callable(db: &dyn DefDatabase, def: CallableDefId) -> GenericDefId {
913 match def {
914 CallableDefId::FunctionId(f) => f.into(),
915 CallableDefId::StructId(s) => s.into(),
916 CallableDefId::EnumVariantId(e) => e.lookup(db).parent.into(),
917 }
918 }
919}
920
921impl From<AssocItemId> for GenericDefId {
922 fn from(item: AssocItemId) -> Self {
923 match item {
924 AssocItemId::FunctionId(f) => f.into(),
925 AssocItemId::ConstId(c) => c.into(),
926 AssocItemId::TypeAliasId(t) => t.into(),
927 }
928 }
929}
930
931#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
932pub enum CallableDefId {
933 FunctionId(FunctionId),
934 StructId(StructId),
935 EnumVariantId(EnumVariantId),
936}
937
938impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
939impl From<CallableDefId> for ModuleDefId {
940 fn from(def: CallableDefId) -> ModuleDefId {
941 match def {
942 CallableDefId::FunctionId(f) => ModuleDefId::FunctionId(f),
943 CallableDefId::StructId(s) => ModuleDefId::AdtId(AdtId::StructId(s)),
944 CallableDefId::EnumVariantId(e) => ModuleDefId::EnumVariantId(e),
945 }
946 }
947}
948
949impl CallableDefId {
950 pub fn krate(self, db: &dyn DefDatabase) -> Crate {
951 match self {
952 CallableDefId::FunctionId(f) => f.krate(db),
953 CallableDefId::StructId(s) => s.krate(db),
954 CallableDefId::EnumVariantId(e) => e.krate(db),
955 }
956 }
957}
958
959#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
960pub enum AttrDefId {
961 ModuleId(ModuleId),
962 FieldId(FieldId),
963 AdtId(AdtId),
964 FunctionId(FunctionId),
965 EnumVariantId(EnumVariantId),
966 StaticId(StaticId),
967 ConstId(ConstId),
968 TraitId(TraitId),
969 TypeAliasId(TypeAliasId),
970 MacroId(MacroId),
971 ImplId(ImplId),
972 GenericParamId(GenericParamId),
973 ExternBlockId(ExternBlockId),
974 ExternCrateId(ExternCrateId),
975 UseId(UseId),
976}
977
978impl_from!(
979 ModuleId,
980 FieldId,
981 AdtId(StructId, EnumId, UnionId),
982 EnumVariantId,
983 StaticId,
984 ConstId,
985 FunctionId,
986 TraitId,
987 TypeAliasId,
988 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
989 ImplId,
990 GenericParamId,
991 ExternCrateId,
992 UseId
993 for AttrDefId
994);
995
996impl TryFrom<ModuleDefId> for AttrDefId {
997 type Error = ();
998
999 fn try_from(value: ModuleDefId) -> Result<Self, Self::Error> {
1000 match value {
1001 ModuleDefId::ModuleId(it) => Ok(it.into()),
1002 ModuleDefId::FunctionId(it) => Ok(it.into()),
1003 ModuleDefId::AdtId(it) => Ok(it.into()),
1004 ModuleDefId::EnumVariantId(it) => Ok(it.into()),
1005 ModuleDefId::ConstId(it) => Ok(it.into()),
1006 ModuleDefId::StaticId(it) => Ok(it.into()),
1007 ModuleDefId::TraitId(it) => Ok(it.into()),
1008 ModuleDefId::TypeAliasId(it) => Ok(it.into()),
1009 ModuleDefId::MacroId(id) => Ok(id.into()),
1010 ModuleDefId::BuiltinType(_) => Err(()),
1011 }
1012 }
1013}
1014
1015impl From<ItemContainerId> for AttrDefId {
1016 fn from(acid: ItemContainerId) -> Self {
1017 match acid {
1018 ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
1019 ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
1020 ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
1021 ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
1022 }
1023 }
1024}
1025impl From<AssocItemId> for AttrDefId {
1026 fn from(assoc: AssocItemId) -> Self {
1027 match assoc {
1028 AssocItemId::FunctionId(it) => AttrDefId::FunctionId(it),
1029 AssocItemId::ConstId(it) => AttrDefId::ConstId(it),
1030 AssocItemId::TypeAliasId(it) => AttrDefId::TypeAliasId(it),
1031 }
1032 }
1033}
1034impl From<VariantId> for AttrDefId {
1035 fn from(vid: VariantId) -> Self {
1036 match vid {
1037 VariantId::EnumVariantId(id) => id.into(),
1038 VariantId::StructId(id) => id.into(),
1039 VariantId::UnionId(id) => id.into(),
1040 }
1041 }
1042}
1043
1044#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
1045pub enum VariantId {
1046 EnumVariantId(EnumVariantId),
1047 StructId(StructId),
1048 UnionId(UnionId),
1049}
1050impl_from!(EnumVariantId, StructId, UnionId for VariantId);
1051
1052impl VariantId {
1053 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
1054 VariantFields::firewall(db, self)
1055 }
1056
1057 pub fn fields_with_source_map(
1058 self,
1059 db: &dyn DefDatabase,
1060 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
1061 VariantFields::query(db, self)
1062 }
1063
1064 pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId {
1065 match self {
1066 VariantId::EnumVariantId(it) => it.lookup(db).id.file_id,
1067 VariantId::StructId(it) => it.lookup(db).id.file_id,
1068 VariantId::UnionId(it) => it.lookup(db).id.file_id,
1069 }
1070 }
1071
1072 pub fn adt_id(self, db: &dyn DefDatabase) -> AdtId {
1073 match self {
1074 VariantId::EnumVariantId(it) => it.lookup(db).parent.into(),
1075 VariantId::StructId(it) => it.into(),
1076 VariantId::UnionId(it) => it.into(),
1077 }
1078 }
1079}
1080
1081pub trait HasModule {
1082 fn module(&self, db: &dyn DefDatabase) -> ModuleId;
1084 #[inline]
1086 #[doc(alias = "crate")]
1087 fn krate(&self, db: &dyn DefDatabase) -> Crate {
1088 self.module(db).krate
1089 }
1090}
1091
1092impl<N, ItemId> HasModule for ItemId
1107where
1108 N: AstIdNode,
1109 ItemId: Lookup<Database = dyn DefDatabase, Data = ItemLoc<N>> + Copy,
1110{
1111 #[inline]
1112 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1113 self.lookup(db).container
1114 }
1115}
1116
1117#[inline]
1132fn module_for_assoc_item_loc<'db>(
1133 db: &(dyn 'db + DefDatabase),
1134 id: impl Lookup<Database = dyn DefDatabase, Data = AssocItemLoc<impl AstIdNode>>,
1135) -> ModuleId {
1136 id.lookup(db).container.module(db)
1137}
1138
1139impl HasModule for FunctionId {
1140 #[inline]
1141 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1142 module_for_assoc_item_loc(db, *self)
1143 }
1144}
1145
1146impl HasModule for ConstId {
1147 #[inline]
1148 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1149 module_for_assoc_item_loc(db, *self)
1150 }
1151}
1152
1153impl HasModule for StaticId {
1154 #[inline]
1155 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1156 module_for_assoc_item_loc(db, *self)
1157 }
1158}
1159
1160impl HasModule for TypeAliasId {
1161 #[inline]
1162 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1163 module_for_assoc_item_loc(db, *self)
1164 }
1165}
1166impl HasModule for EnumVariantId {
1169 #[inline]
1170 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1171 self.lookup(db).parent.module(db)
1172 }
1173}
1174
1175impl HasModule for MacroRulesId {
1176 #[inline]
1177 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1178 self.lookup(db).container
1179 }
1180}
1181
1182impl HasModule for Macro2Id {
1183 #[inline]
1184 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1185 self.lookup(db).container
1186 }
1187}
1188
1189impl HasModule for ProcMacroId {
1190 #[inline]
1191 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1192 self.lookup(db).container.into()
1193 }
1194}
1195
1196impl HasModule for ItemContainerId {
1197 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1198 match *self {
1199 ItemContainerId::ModuleId(it) => it,
1200 ItemContainerId::ImplId(it) => it.module(db),
1201 ItemContainerId::TraitId(it) => it.module(db),
1202 ItemContainerId::ExternBlockId(it) => it.module(db),
1203 }
1204 }
1205}
1206
1207impl HasModule for AdtId {
1208 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1209 match *self {
1210 AdtId::StructId(it) => it.module(db),
1211 AdtId::UnionId(it) => it.module(db),
1212 AdtId::EnumId(it) => it.module(db),
1213 }
1214 }
1215}
1216
1217impl HasModule for VariantId {
1218 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1219 match *self {
1220 VariantId::EnumVariantId(it) => it.module(db),
1221 VariantId::StructId(it) => it.module(db),
1222 VariantId::UnionId(it) => it.module(db),
1223 }
1224 }
1225}
1226
1227impl HasModule for MacroId {
1228 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1229 match *self {
1230 MacroId::MacroRulesId(it) => it.module(db),
1231 MacroId::Macro2Id(it) => it.module(db),
1232 MacroId::ProcMacroId(it) => it.module(db),
1233 }
1234 }
1235}
1236
1237impl HasModule for DefWithBodyId {
1238 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1239 match self {
1240 DefWithBodyId::FunctionId(it) => it.module(db),
1241 DefWithBodyId::StaticId(it) => it.module(db),
1242 DefWithBodyId::ConstId(it) => it.module(db),
1243 DefWithBodyId::VariantId(it) => it.module(db),
1244 }
1245 }
1246}
1247
1248impl HasModule for GenericDefId {
1249 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1250 match self {
1251 GenericDefId::FunctionId(it) => it.module(db),
1252 GenericDefId::AdtId(it) => it.module(db),
1253 GenericDefId::TraitId(it) => it.module(db),
1254 GenericDefId::TypeAliasId(it) => it.module(db),
1255 GenericDefId::ImplId(it) => it.module(db),
1256 GenericDefId::ConstId(it) => it.module(db),
1257 GenericDefId::StaticId(it) => it.module(db),
1258 }
1259 }
1260}
1261
1262impl HasModule for AttrDefId {
1263 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1264 match self {
1265 AttrDefId::ModuleId(it) => *it,
1266 AttrDefId::FieldId(it) => it.parent.module(db),
1267 AttrDefId::AdtId(it) => it.module(db),
1268 AttrDefId::FunctionId(it) => it.module(db),
1269 AttrDefId::EnumVariantId(it) => it.module(db),
1270 AttrDefId::StaticId(it) => it.module(db),
1271 AttrDefId::ConstId(it) => it.module(db),
1272 AttrDefId::TraitId(it) => it.module(db),
1273 AttrDefId::TypeAliasId(it) => it.module(db),
1274 AttrDefId::ImplId(it) => it.module(db),
1275 AttrDefId::ExternBlockId(it) => it.module(db),
1276 AttrDefId::GenericParamId(it) => match it {
1277 GenericParamId::TypeParamId(it) => it.parent(),
1278 GenericParamId::ConstParamId(it) => it.parent(),
1279 GenericParamId::LifetimeParamId(it) => it.parent,
1280 }
1281 .module(db),
1282 AttrDefId::MacroId(it) => it.module(db),
1283 AttrDefId::ExternCrateId(it) => it.module(db),
1284 AttrDefId::UseId(it) => it.module(db),
1285 }
1286 }
1287}
1288
1289impl ModuleDefId {
1290 pub fn module(&self, db: &dyn DefDatabase) -> Option<ModuleId> {
1294 Some(match self {
1295 ModuleDefId::ModuleId(id) => *id,
1296 ModuleDefId::FunctionId(id) => id.module(db),
1297 ModuleDefId::AdtId(id) => id.module(db),
1298 ModuleDefId::EnumVariantId(id) => id.module(db),
1299 ModuleDefId::ConstId(id) => id.module(db),
1300 ModuleDefId::StaticId(id) => id.module(db),
1301 ModuleDefId::TraitId(id) => id.module(db),
1302 ModuleDefId::TypeAliasId(id) => id.module(db),
1303 ModuleDefId::MacroId(id) => id.module(db),
1304 ModuleDefId::BuiltinType(_) => return None,
1305 })
1306 }
1307}
1308#[derive(Clone, Debug, Eq, PartialEq)]
1310struct AstIdWithPath<T: AstIdNode> {
1311 ast_id: AstId<T>,
1312 path: Interned<ModPath>,
1313}
1314
1315impl<T: AstIdNode> AstIdWithPath<T> {
1316 fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: Interned<ModPath>) -> AstIdWithPath<T> {
1317 AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
1318 }
1319}
1320
1321pub fn macro_call_as_call_id(
1322 db: &dyn ExpandDatabase,
1323 ast_id: AstId<ast::MacroCall>,
1324 path: &ModPath,
1325 call_site: SyntaxContext,
1326 expand_to: ExpandTo,
1327 krate: Crate,
1328 resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
1329 eager_callback: &mut dyn FnMut(
1330 InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
1331 MacroCallId,
1332 ),
1333) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
1334 let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
1335
1336 let res = match def.kind {
1337 MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
1338 db,
1339 krate,
1340 &ast_id.to_node(db),
1341 ast_id,
1342 def,
1343 call_site,
1344 &|path| resolver(path).filter(MacroDefId::is_fn_like),
1345 eager_callback,
1346 ),
1347 _ if def.is_fn_like() => ExpandResult {
1348 value: Some(def.make_call(
1349 db,
1350 krate,
1351 MacroCallKind::FnLike { ast_id, expand_to, eager: None },
1352 call_site,
1353 )),
1354 err: None,
1355 },
1356 _ => return Err(UnresolvedMacro { path: path.clone() }),
1357 };
1358 Ok(res)
1359}
1360
1361#[derive(Debug)]
1362pub struct UnresolvedMacro {
1363 pub path: ModPath,
1364}
1365
1366#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
1367pub struct SyntheticSyntax;
1368
1369#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1393pub enum Complete {
1394 Yes,
1396 IgnoreFlyimport,
1398 IgnoreFlyimportMethods,
1400 IgnoreMethods,
1402}
1403
1404impl Complete {
1405 pub fn extract(is_trait: bool, attrs: &Attrs) -> Complete {
1406 let mut do_not_complete = Complete::Yes;
1407 for ra_attr in attrs.rust_analyzer_tool() {
1408 let segments = ra_attr.path.segments();
1409 if segments.len() != 2 {
1410 continue;
1411 }
1412 let action = segments[1].symbol();
1413 if *action == sym::completions {
1414 match ra_attr.token_tree_value().map(|tt| tt.token_trees().flat_tokens()) {
1415 Some([tt::TokenTree::Leaf(tt::Leaf::Ident(ident))]) => {
1416 if ident.sym == sym::ignore_flyimport {
1417 do_not_complete = Complete::IgnoreFlyimport;
1418 } else if is_trait {
1419 if ident.sym == sym::ignore_methods {
1420 do_not_complete = Complete::IgnoreMethods;
1421 } else if ident.sym == sym::ignore_flyimport_methods {
1422 do_not_complete = Complete::IgnoreFlyimportMethods;
1423 }
1424 }
1425 }
1426 _ => {}
1427 }
1428 }
1429 }
1430 do_not_complete
1431 }
1432
1433 #[inline]
1434 pub fn for_trait_item(trait_attr: Complete, item_attr: Complete) -> Complete {
1435 match (trait_attr, item_attr) {
1436 (
1437 Complete::IgnoreFlyimportMethods
1438 | Complete::IgnoreFlyimport
1439 | Complete::IgnoreMethods,
1440 _,
1441 ) => Complete::IgnoreFlyimport,
1442 _ => item_attr,
1443 }
1444 }
1445}