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