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
321type TypeAliasLoc = AssocItemLoc<ast::TypeAlias>;
322impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
323
324type ImplLoc = ItemLoc<ast::Impl>;
325impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
326
327impl ImplId {
328 #[inline]
329 pub fn impl_items(self, db: &dyn DefDatabase) -> &ImplItems {
330 &self.impl_items_with_diagnostics(db).0
331 }
332
333 #[inline]
334 pub fn impl_items_with_diagnostics(self, db: &dyn DefDatabase) -> &(ImplItems, DefDiagnostics) {
335 ImplItems::of(db, self)
336 }
337}
338
339type UseLoc = ItemLoc<ast::Use>;
340impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
341
342type ExternCrateLoc = ItemLoc<ast::ExternCrate>;
343impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate);
344
345type ExternBlockLoc = ItemLoc<ast::ExternBlock>;
346impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
347
348#[salsa::tracked]
349impl ExternBlockId {
350 #[salsa::tracked]
351 pub fn abi(self, db: &dyn DefDatabase) -> Option<Symbol> {
352 signatures::extern_block_abi(db, self)
353 }
354}
355
356#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
357pub struct EnumVariantLoc {
358 pub id: AstId<ast::Variant>,
359 pub parent: EnumId,
360 pub index: u32,
361}
362impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
363impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId);
364
365impl EnumVariantId {
366 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
367 VariantFields::firewall(db, self.into())
368 }
369
370 pub fn fields_with_source_map(
371 self,
372 db: &dyn DefDatabase,
373 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
374 VariantFields::query(db, self.into())
375 }
376}
377
378#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
379pub struct Macro2Loc {
380 pub container: ModuleId,
381 pub id: AstId<ast::MacroDef>,
382 pub expander: MacroExpander,
383 pub allow_internal_unsafe: bool,
384 pub edition: Edition,
385}
386impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
387impl_loc!(Macro2Loc, id: MacroDef, container: ModuleId);
388
389#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
390pub struct MacroRulesLoc {
391 pub container: ModuleId,
392 pub id: AstId<ast::MacroRules>,
393 pub expander: MacroExpander,
394 pub flags: MacroRulesLocFlags,
395 pub edition: Edition,
396}
397impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
398impl_loc!(MacroRulesLoc, id: MacroRules, container: ModuleId);
399
400bitflags::bitflags! {
401 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
402 pub struct MacroRulesLocFlags: u8 {
403 const ALLOW_INTERNAL_UNSAFE = 1 << 0;
404 const LOCAL_INNER = 1 << 1;
405 }
406}
407
408#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
409pub enum MacroExpander {
410 Declarative,
411 BuiltIn(BuiltinFnLikeExpander),
412 BuiltInAttr(BuiltinAttrExpander),
413 BuiltInDerive(BuiltinDeriveExpander),
414 BuiltInEager(EagerExpander),
415}
416
417#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
418pub struct ProcMacroLoc {
419 pub container: CrateRootModuleId,
420 pub id: AstId<ast::Fn>,
421 pub expander: CustomProcMacroExpander,
422 pub kind: ProcMacroKind,
423 pub edition: Edition,
424}
425impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
426impl_loc!(ProcMacroLoc, id: Fn, container: CrateRootModuleId);
427
428#[derive(Debug, Hash, PartialEq, Eq, Clone)]
429pub struct BlockLoc {
430 pub ast_id: AstId<ast::BlockExpr>,
431 pub module: ModuleId,
433}
434impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
435
436#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
438pub struct CrateRootModuleId {
439 krate: Crate,
440}
441
442impl CrateRootModuleId {
443 pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
444 crate_def_map(db, self.krate)
445 }
446
447 pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) {
448 let def_map = crate_local_def_map(db, self.krate);
449 (def_map.def_map(db), def_map.local(db))
450 }
451
452 pub fn krate(self) -> Crate {
453 self.krate
454 }
455}
456
457impl HasModule for CrateRootModuleId {
458 #[inline]
459 fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
460 ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT }
461 }
462
463 #[inline]
464 fn krate(&self, _db: &dyn DefDatabase) -> Crate {
465 self.krate
466 }
467}
468
469impl PartialEq<ModuleId> for CrateRootModuleId {
470 fn eq(&self, other: &ModuleId) -> bool {
471 other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate
472 }
473}
474impl PartialEq<CrateRootModuleId> for ModuleId {
475 fn eq(&self, other: &CrateRootModuleId) -> bool {
476 other == self
477 }
478}
479
480impl From<CrateRootModuleId> for ModuleId {
481 fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
482 ModuleId { krate, block: None, local_id: DefMap::ROOT }
483 }
484}
485
486impl From<CrateRootModuleId> for ModuleDefId {
487 fn from(value: CrateRootModuleId) -> Self {
488 ModuleDefId::ModuleId(value.into())
489 }
490}
491
492impl From<Crate> for CrateRootModuleId {
493 fn from(krate: Crate) -> Self {
494 CrateRootModuleId { krate }
495 }
496}
497
498impl TryFrom<ModuleId> for CrateRootModuleId {
499 type Error = ();
500
501 fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> {
502 if block.is_none() && local_id == DefMap::ROOT {
503 Ok(CrateRootModuleId { krate })
504 } else {
505 Err(())
506 }
507 }
508}
509
510#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
511pub struct ModuleId {
512 krate: Crate,
513 block: Option<BlockId>,
517 pub local_id: LocalModuleId,
519}
520
521impl ModuleId {
522 pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
523 match self.block {
524 Some(block) => block_def_map(db, block),
525 None => crate_def_map(db, self.krate),
526 }
527 }
528
529 pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) {
530 match self.block {
531 Some(block) => (block_def_map(db, block), self.only_local_def_map(db)),
532 None => {
533 let def_map = crate_local_def_map(db, self.krate);
534 (def_map.def_map(db), def_map.local(db))
535 }
536 }
537 }
538
539 pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap {
540 crate_local_def_map(db, self.krate).local(db)
541 }
542
543 pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap {
544 crate_def_map(db, self.krate)
545 }
546
547 pub fn krate(self) -> Crate {
548 self.krate
549 }
550
551 pub fn name(self, db: &dyn DefDatabase) -> Option<Name> {
552 let def_map = self.def_map(db);
553 let parent = def_map[self.local_id].parent?;
554 def_map[parent].children.iter().find_map(|(name, module_id)| {
555 if *module_id == self.local_id { Some(name.clone()) } else { None }
556 })
557 }
558
559 pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> {
562 self.def_map(db).containing_module(self.local_id)
563 }
564
565 pub fn containing_block(self) -> Option<BlockId> {
566 self.block
567 }
568
569 pub fn is_block_module(self) -> bool {
570 self.block.is_some() && self.local_id == DefMap::ROOT
571 }
572
573 pub fn is_within_block(self) -> bool {
574 self.block.is_some()
575 }
576
577 pub fn as_crate_root(&self) -> Option<CrateRootModuleId> {
579 if self.local_id == DefMap::ROOT && self.block.is_none() {
580 Some(CrateRootModuleId { krate: self.krate })
581 } else {
582 None
583 }
584 }
585
586 pub fn derive_crate_root(&self) -> CrateRootModuleId {
588 CrateRootModuleId { krate: self.krate }
589 }
590
591 pub fn is_crate_root(&self) -> bool {
593 self.local_id == DefMap::ROOT && self.block.is_none()
594 }
595}
596
597impl HasModule for ModuleId {
598 #[inline]
599 fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
600 *self
601 }
602}
603
604pub type LocalModuleId = Idx<nameres::ModuleData>;
606
607#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
608pub struct FieldId {
609 pub parent: VariantId,
611 pub local_id: LocalFieldId,
612}
613
614#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
615pub struct TupleId(pub u32);
616
617#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
618pub struct TupleFieldId {
619 pub tuple: TupleId,
620 pub index: u32,
621}
622
623#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
624pub struct TypeOrConstParamId {
625 pub parent: GenericDefId,
627 pub local_id: LocalTypeOrConstParamId,
628}
629
630#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
632pub struct TypeParamId(TypeOrConstParamId);
633
634impl TypeParamId {
635 pub fn parent(&self) -> GenericDefId {
636 self.0.parent
637 }
638 pub fn local_id(&self) -> LocalTypeOrConstParamId {
639 self.0.local_id
640 }
641}
642
643impl TypeParamId {
644 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
646 Self(it)
647 }
648}
649
650impl From<TypeParamId> for TypeOrConstParamId {
651 fn from(it: TypeParamId) -> Self {
652 it.0
653 }
654}
655
656#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
658pub struct ConstParamId(TypeOrConstParamId);
659
660impl ConstParamId {
661 pub fn parent(&self) -> GenericDefId {
662 self.0.parent
663 }
664 pub fn local_id(&self) -> LocalTypeOrConstParamId {
665 self.0.local_id
666 }
667}
668
669impl ConstParamId {
670 pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
672 Self(it)
673 }
674}
675
676impl From<ConstParamId> for TypeOrConstParamId {
677 fn from(it: ConstParamId) -> Self {
678 it.0
679 }
680}
681
682#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
683pub struct LifetimeParamId {
684 pub parent: GenericDefId,
686 pub local_id: LocalLifetimeParamId,
687}
688
689#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
690pub enum ItemContainerId {
691 ExternBlockId(ExternBlockId),
692 ModuleId(ModuleId),
693 ImplId(ImplId),
694 TraitId(TraitId),
695}
696impl_from!(ModuleId for ItemContainerId);
697
698#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
700pub enum AdtId {
701 StructId(StructId),
702 UnionId(UnionId),
703 EnumId(EnumId),
704}
705impl_from!(StructId, UnionId, EnumId for AdtId);
706
707#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
709pub enum MacroId {
710 Macro2Id(Macro2Id),
711 MacroRulesId(MacroRulesId),
712 ProcMacroId(ProcMacroId),
713}
714impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
715
716impl MacroId {
717 pub fn is_attribute(self, db: &dyn DefDatabase) -> bool {
718 matches!(self, MacroId::ProcMacroId(it) if it.lookup(db).kind == ProcMacroKind::Attr)
719 }
720}
721
722#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
724pub enum GenericParamId {
725 TypeParamId(TypeParamId),
726 ConstParamId(ConstParamId),
727 LifetimeParamId(LifetimeParamId),
728}
729impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
730
731#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
733pub enum ModuleDefId {
734 ModuleId(ModuleId),
735 FunctionId(FunctionId),
736 AdtId(AdtId),
737 EnumVariantId(EnumVariantId),
739 ConstId(ConstId),
740 StaticId(StaticId),
741 TraitId(TraitId),
742 TypeAliasId(TypeAliasId),
743 BuiltinType(BuiltinType),
744 MacroId(MacroId),
745}
746impl_from!(
747 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
748 ModuleId,
749 FunctionId,
750 AdtId(StructId, EnumId, UnionId),
751 EnumVariantId,
752 ConstId,
753 StaticId,
754 TraitId,
755 TypeAliasId,
756 BuiltinType
757 for ModuleDefId
758);
759
760#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
763pub enum GeneralConstId {
764 ConstId(ConstId),
765 StaticId(StaticId),
766}
767
768impl_from!(ConstId, StaticId for GeneralConstId);
769
770impl GeneralConstId {
771 pub fn generic_def(self, _db: &dyn DefDatabase) -> Option<GenericDefId> {
772 match self {
773 GeneralConstId::ConstId(it) => Some(it.into()),
774 GeneralConstId::StaticId(it) => Some(it.into()),
775 }
776 }
777
778 pub fn name(self, db: &dyn DefDatabase) -> String {
779 match self {
780 GeneralConstId::StaticId(it) => {
781 db.static_signature(it).name.display(db, Edition::CURRENT).to_string()
782 }
783 GeneralConstId::ConstId(const_id) => {
784 db.const_signature(const_id).name.as_ref().map_or_else(
785 || "_".to_owned(),
786 |name| name.display(db, Edition::CURRENT).to_string(),
787 )
788 }
789 }
790 }
791}
792
793#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
795pub enum DefWithBodyId {
796 FunctionId(FunctionId),
797 StaticId(StaticId),
798 ConstId(ConstId),
799 VariantId(EnumVariantId),
800 }
807impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
808
809impl From<EnumVariantId> for DefWithBodyId {
810 fn from(id: EnumVariantId) -> Self {
811 DefWithBodyId::VariantId(id)
812 }
813}
814
815impl DefWithBodyId {
816 pub fn as_generic_def_id(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
817 match self {
818 DefWithBodyId::FunctionId(f) => Some(f.into()),
819 DefWithBodyId::StaticId(s) => Some(s.into()),
820 DefWithBodyId::ConstId(c) => Some(c.into()),
821 DefWithBodyId::VariantId(c) => Some(c.lookup(db).parent.into()),
822 }
823 }
824}
825
826#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, salsa_macros::Supertype)]
827pub enum AssocItemId {
828 FunctionId(FunctionId),
829 ConstId(ConstId),
830 TypeAliasId(TypeAliasId),
831}
832
833impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
838
839impl From<AssocItemId> for ModuleDefId {
840 fn from(item: AssocItemId) -> Self {
841 match item {
842 AssocItemId::FunctionId(f) => f.into(),
843 AssocItemId::ConstId(c) => c.into(),
844 AssocItemId::TypeAliasId(t) => t.into(),
845 }
846 }
847}
848
849#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
850pub enum GenericDefId {
851 AdtId(AdtId),
852 ConstId(ConstId),
854 FunctionId(FunctionId),
855 ImplId(ImplId),
856 StaticId(StaticId),
860 TraitId(TraitId),
861 TypeAliasId(TypeAliasId),
862}
863impl_from!(
864 AdtId(StructId, EnumId, UnionId),
865 ConstId,
866 FunctionId,
867 ImplId,
868 StaticId,
869 TraitId,
870 TypeAliasId
871 for GenericDefId
872);
873
874impl GenericDefId {
875 pub fn file_id_and_params_of(
876 self,
877 db: &dyn DefDatabase,
878 ) -> (HirFileId, Option<ast::GenericParamList>) {
879 fn file_id_and_params_of_item_loc<Loc>(
880 db: &dyn DefDatabase,
881 def: impl Lookup<Database = dyn DefDatabase, Data = Loc>,
882 ) -> (HirFileId, Option<ast::GenericParamList>)
883 where
884 Loc: src::HasSource,
885 Loc::Value: ast::HasGenericParams,
886 {
887 let src = def.lookup(db).source(db);
888 (src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
889 }
890
891 match self {
892 GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
893 GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
894 GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
895 GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
896 GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
897 GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
898 GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
899 GenericDefId::ConstId(it) => (it.lookup(db).id.file_id, None),
900 GenericDefId::StaticId(it) => (it.lookup(db).id.file_id, None),
901 }
902 }
903
904 pub fn assoc_trait_container(self, db: &dyn DefDatabase) -> Option<TraitId> {
905 match match self {
906 GenericDefId::FunctionId(f) => f.lookup(db).container,
907 GenericDefId::TypeAliasId(t) => t.lookup(db).container,
908 GenericDefId::ConstId(c) => c.lookup(db).container,
909 _ => return None,
910 } {
911 ItemContainerId::TraitId(trait_) => Some(trait_),
912 _ => None,
913 }
914 }
915
916 pub fn from_callable(db: &dyn DefDatabase, def: CallableDefId) -> GenericDefId {
917 match def {
918 CallableDefId::FunctionId(f) => f.into(),
919 CallableDefId::StructId(s) => s.into(),
920 CallableDefId::EnumVariantId(e) => e.lookup(db).parent.into(),
921 }
922 }
923}
924
925impl From<AssocItemId> for GenericDefId {
926 fn from(item: AssocItemId) -> Self {
927 match item {
928 AssocItemId::FunctionId(f) => f.into(),
929 AssocItemId::ConstId(c) => c.into(),
930 AssocItemId::TypeAliasId(t) => t.into(),
931 }
932 }
933}
934
935#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
936pub enum CallableDefId {
937 FunctionId(FunctionId),
938 StructId(StructId),
939 EnumVariantId(EnumVariantId),
940}
941
942impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
943impl From<CallableDefId> for ModuleDefId {
944 fn from(def: CallableDefId) -> ModuleDefId {
945 match def {
946 CallableDefId::FunctionId(f) => ModuleDefId::FunctionId(f),
947 CallableDefId::StructId(s) => ModuleDefId::AdtId(AdtId::StructId(s)),
948 CallableDefId::EnumVariantId(e) => ModuleDefId::EnumVariantId(e),
949 }
950 }
951}
952
953impl CallableDefId {
954 pub fn krate(self, db: &dyn DefDatabase) -> Crate {
955 match self {
956 CallableDefId::FunctionId(f) => f.krate(db),
957 CallableDefId::StructId(s) => s.krate(db),
958 CallableDefId::EnumVariantId(e) => e.krate(db),
959 }
960 }
961}
962
963#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
964pub enum AttrDefId {
965 ModuleId(ModuleId),
966 FieldId(FieldId),
967 AdtId(AdtId),
968 FunctionId(FunctionId),
969 EnumVariantId(EnumVariantId),
970 StaticId(StaticId),
971 ConstId(ConstId),
972 TraitId(TraitId),
973 TypeAliasId(TypeAliasId),
974 MacroId(MacroId),
975 ImplId(ImplId),
976 GenericParamId(GenericParamId),
977 ExternBlockId(ExternBlockId),
978 ExternCrateId(ExternCrateId),
979 UseId(UseId),
980}
981
982impl_from!(
983 ModuleId,
984 FieldId,
985 AdtId(StructId, EnumId, UnionId),
986 EnumVariantId,
987 StaticId,
988 ConstId,
989 FunctionId,
990 TraitId,
991 TypeAliasId,
992 MacroId(Macro2Id, MacroRulesId, ProcMacroId),
993 ImplId,
994 GenericParamId,
995 ExternCrateId,
996 UseId
997 for AttrDefId
998);
999
1000impl TryFrom<ModuleDefId> for AttrDefId {
1001 type Error = ();
1002
1003 fn try_from(value: ModuleDefId) -> Result<Self, Self::Error> {
1004 match value {
1005 ModuleDefId::ModuleId(it) => Ok(it.into()),
1006 ModuleDefId::FunctionId(it) => Ok(it.into()),
1007 ModuleDefId::AdtId(it) => Ok(it.into()),
1008 ModuleDefId::EnumVariantId(it) => Ok(it.into()),
1009 ModuleDefId::ConstId(it) => Ok(it.into()),
1010 ModuleDefId::StaticId(it) => Ok(it.into()),
1011 ModuleDefId::TraitId(it) => Ok(it.into()),
1012 ModuleDefId::TypeAliasId(it) => Ok(it.into()),
1013 ModuleDefId::MacroId(id) => Ok(id.into()),
1014 ModuleDefId::BuiltinType(_) => Err(()),
1015 }
1016 }
1017}
1018
1019impl From<ItemContainerId> for AttrDefId {
1020 fn from(acid: ItemContainerId) -> Self {
1021 match acid {
1022 ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
1023 ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
1024 ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
1025 ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
1026 }
1027 }
1028}
1029impl From<AssocItemId> for AttrDefId {
1030 fn from(assoc: AssocItemId) -> Self {
1031 match assoc {
1032 AssocItemId::FunctionId(it) => AttrDefId::FunctionId(it),
1033 AssocItemId::ConstId(it) => AttrDefId::ConstId(it),
1034 AssocItemId::TypeAliasId(it) => AttrDefId::TypeAliasId(it),
1035 }
1036 }
1037}
1038impl From<VariantId> for AttrDefId {
1039 fn from(vid: VariantId) -> Self {
1040 match vid {
1041 VariantId::EnumVariantId(id) => id.into(),
1042 VariantId::StructId(id) => id.into(),
1043 VariantId::UnionId(id) => id.into(),
1044 }
1045 }
1046}
1047
1048#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
1049pub enum VariantId {
1050 EnumVariantId(EnumVariantId),
1051 StructId(StructId),
1052 UnionId(UnionId),
1053}
1054impl_from!(EnumVariantId, StructId, UnionId for VariantId);
1055
1056impl VariantId {
1057 pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
1058 VariantFields::firewall(db, self)
1059 }
1060
1061 pub fn fields_with_source_map(
1062 self,
1063 db: &dyn DefDatabase,
1064 ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
1065 VariantFields::query(db, self)
1066 }
1067
1068 pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId {
1069 match self {
1070 VariantId::EnumVariantId(it) => it.lookup(db).id.file_id,
1071 VariantId::StructId(it) => it.lookup(db).id.file_id,
1072 VariantId::UnionId(it) => it.lookup(db).id.file_id,
1073 }
1074 }
1075
1076 pub fn adt_id(self, db: &dyn DefDatabase) -> AdtId {
1077 match self {
1078 VariantId::EnumVariantId(it) => it.lookup(db).parent.into(),
1079 VariantId::StructId(it) => it.into(),
1080 VariantId::UnionId(it) => it.into(),
1081 }
1082 }
1083}
1084
1085pub trait HasModule {
1086 fn module(&self, db: &dyn DefDatabase) -> ModuleId;
1088 #[inline]
1090 #[doc(alias = "crate")]
1091 fn krate(&self, db: &dyn DefDatabase) -> Crate {
1092 self.module(db).krate
1093 }
1094}
1095
1096impl<N, ItemId> HasModule for ItemId
1111where
1112 N: AstIdNode,
1113 ItemId: Lookup<Database = dyn DefDatabase, Data = ItemLoc<N>> + Copy,
1114{
1115 #[inline]
1116 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1117 self.lookup(db).container
1118 }
1119}
1120
1121#[inline]
1136fn module_for_assoc_item_loc<'db>(
1137 db: &(dyn 'db + DefDatabase),
1138 id: impl Lookup<Database = dyn DefDatabase, Data = AssocItemLoc<impl AstIdNode>>,
1139) -> ModuleId {
1140 id.lookup(db).container.module(db)
1141}
1142
1143impl HasModule for FunctionId {
1144 #[inline]
1145 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1146 module_for_assoc_item_loc(db, *self)
1147 }
1148}
1149
1150impl HasModule for ConstId {
1151 #[inline]
1152 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1153 module_for_assoc_item_loc(db, *self)
1154 }
1155}
1156
1157impl HasModule for StaticId {
1158 #[inline]
1159 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1160 module_for_assoc_item_loc(db, *self)
1161 }
1162}
1163
1164impl HasModule for TypeAliasId {
1165 #[inline]
1166 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1167 module_for_assoc_item_loc(db, *self)
1168 }
1169}
1170impl HasModule for EnumVariantId {
1173 #[inline]
1174 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1175 self.lookup(db).parent.module(db)
1176 }
1177}
1178
1179impl HasModule for MacroRulesId {
1180 #[inline]
1181 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1182 self.lookup(db).container
1183 }
1184}
1185
1186impl HasModule for Macro2Id {
1187 #[inline]
1188 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1189 self.lookup(db).container
1190 }
1191}
1192
1193impl HasModule for ProcMacroId {
1194 #[inline]
1195 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1196 self.lookup(db).container.into()
1197 }
1198}
1199
1200impl HasModule for ItemContainerId {
1201 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1202 match *self {
1203 ItemContainerId::ModuleId(it) => it,
1204 ItemContainerId::ImplId(it) => it.module(db),
1205 ItemContainerId::TraitId(it) => it.module(db),
1206 ItemContainerId::ExternBlockId(it) => it.module(db),
1207 }
1208 }
1209}
1210
1211impl HasModule for AdtId {
1212 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1213 match *self {
1214 AdtId::StructId(it) => it.module(db),
1215 AdtId::UnionId(it) => it.module(db),
1216 AdtId::EnumId(it) => it.module(db),
1217 }
1218 }
1219}
1220
1221impl HasModule for VariantId {
1222 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1223 match *self {
1224 VariantId::EnumVariantId(it) => it.module(db),
1225 VariantId::StructId(it) => it.module(db),
1226 VariantId::UnionId(it) => it.module(db),
1227 }
1228 }
1229}
1230
1231impl HasModule for MacroId {
1232 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1233 match *self {
1234 MacroId::MacroRulesId(it) => it.module(db),
1235 MacroId::Macro2Id(it) => it.module(db),
1236 MacroId::ProcMacroId(it) => it.module(db),
1237 }
1238 }
1239}
1240
1241impl HasModule for DefWithBodyId {
1242 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1243 match self {
1244 DefWithBodyId::FunctionId(it) => it.module(db),
1245 DefWithBodyId::StaticId(it) => it.module(db),
1246 DefWithBodyId::ConstId(it) => it.module(db),
1247 DefWithBodyId::VariantId(it) => it.module(db),
1248 }
1249 }
1250}
1251
1252impl HasModule for GenericDefId {
1253 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1254 match self {
1255 GenericDefId::FunctionId(it) => it.module(db),
1256 GenericDefId::AdtId(it) => it.module(db),
1257 GenericDefId::TraitId(it) => it.module(db),
1258 GenericDefId::TypeAliasId(it) => it.module(db),
1259 GenericDefId::ImplId(it) => it.module(db),
1260 GenericDefId::ConstId(it) => it.module(db),
1261 GenericDefId::StaticId(it) => it.module(db),
1262 }
1263 }
1264}
1265
1266impl HasModule for AttrDefId {
1267 fn module(&self, db: &dyn DefDatabase) -> ModuleId {
1268 match self {
1269 AttrDefId::ModuleId(it) => *it,
1270 AttrDefId::FieldId(it) => it.parent.module(db),
1271 AttrDefId::AdtId(it) => it.module(db),
1272 AttrDefId::FunctionId(it) => it.module(db),
1273 AttrDefId::EnumVariantId(it) => it.module(db),
1274 AttrDefId::StaticId(it) => it.module(db),
1275 AttrDefId::ConstId(it) => it.module(db),
1276 AttrDefId::TraitId(it) => it.module(db),
1277 AttrDefId::TypeAliasId(it) => it.module(db),
1278 AttrDefId::ImplId(it) => it.module(db),
1279 AttrDefId::ExternBlockId(it) => it.module(db),
1280 AttrDefId::GenericParamId(it) => match it {
1281 GenericParamId::TypeParamId(it) => it.parent(),
1282 GenericParamId::ConstParamId(it) => it.parent(),
1283 GenericParamId::LifetimeParamId(it) => it.parent,
1284 }
1285 .module(db),
1286 AttrDefId::MacroId(it) => it.module(db),
1287 AttrDefId::ExternCrateId(it) => it.module(db),
1288 AttrDefId::UseId(it) => it.module(db),
1289 }
1290 }
1291}
1292
1293impl ModuleDefId {
1294 pub fn module(&self, db: &dyn DefDatabase) -> Option<ModuleId> {
1298 Some(match self {
1299 ModuleDefId::ModuleId(id) => *id,
1300 ModuleDefId::FunctionId(id) => id.module(db),
1301 ModuleDefId::AdtId(id) => id.module(db),
1302 ModuleDefId::EnumVariantId(id) => id.module(db),
1303 ModuleDefId::ConstId(id) => id.module(db),
1304 ModuleDefId::StaticId(id) => id.module(db),
1305 ModuleDefId::TraitId(id) => id.module(db),
1306 ModuleDefId::TypeAliasId(id) => id.module(db),
1307 ModuleDefId::MacroId(id) => id.module(db),
1308 ModuleDefId::BuiltinType(_) => return None,
1309 })
1310 }
1311}
1312#[derive(Clone, Debug, Eq, PartialEq)]
1314struct AstIdWithPath<T: AstIdNode> {
1315 ast_id: AstId<T>,
1316 path: Interned<ModPath>,
1317}
1318
1319impl<T: AstIdNode> AstIdWithPath<T> {
1320 fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: Interned<ModPath>) -> AstIdWithPath<T> {
1321 AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
1322 }
1323}
1324
1325pub fn macro_call_as_call_id(
1326 db: &dyn ExpandDatabase,
1327 ast_id: AstId<ast::MacroCall>,
1328 path: &ModPath,
1329 call_site: SyntaxContext,
1330 expand_to: ExpandTo,
1331 krate: Crate,
1332 resolver: impl Fn(&ModPath) -> Option<MacroDefId> + Copy,
1333 eager_callback: &mut dyn FnMut(
1334 InFile<(syntax::AstPtr<ast::MacroCall>, span::FileAstId<ast::MacroCall>)>,
1335 MacroCallId,
1336 ),
1337) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
1338 let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
1339
1340 let res = match def.kind {
1341 MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
1342 db,
1343 krate,
1344 &ast_id.to_node(db),
1345 ast_id,
1346 def,
1347 call_site,
1348 &|path| resolver(path).filter(MacroDefId::is_fn_like),
1349 eager_callback,
1350 ),
1351 _ if def.is_fn_like() => ExpandResult {
1352 value: Some(def.make_call(
1353 db,
1354 krate,
1355 MacroCallKind::FnLike { ast_id, expand_to, eager: None },
1356 call_site,
1357 )),
1358 err: None,
1359 },
1360 _ => return Err(UnresolvedMacro { path: path.clone() }),
1361 };
1362 Ok(res)
1363}
1364
1365#[derive(Debug)]
1366pub struct UnresolvedMacro {
1367 pub path: ModPath,
1368}
1369
1370#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
1371pub struct SyntheticSyntax;
1372
1373#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1397pub enum Complete {
1398 Yes,
1400 IgnoreFlyimport,
1402 IgnoreFlyimportMethods,
1404 IgnoreMethods,
1406}
1407
1408impl Complete {
1409 pub fn extract(is_trait: bool, attrs: &Attrs) -> Complete {
1410 let mut do_not_complete = Complete::Yes;
1411 for ra_attr in attrs.rust_analyzer_tool() {
1412 let segments = ra_attr.path.segments();
1413 if segments.len() != 2 {
1414 continue;
1415 }
1416 let action = segments[1].symbol();
1417 if *action == sym::completions {
1418 match ra_attr.token_tree_value().map(|tt| tt.token_trees().flat_tokens()) {
1419 Some([tt::TokenTree::Leaf(tt::Leaf::Ident(ident))]) => {
1420 if ident.sym == sym::ignore_flyimport {
1421 do_not_complete = Complete::IgnoreFlyimport;
1422 } else if is_trait {
1423 if ident.sym == sym::ignore_methods {
1424 do_not_complete = Complete::IgnoreMethods;
1425 } else if ident.sym == sym::ignore_flyimport_methods {
1426 do_not_complete = Complete::IgnoreFlyimportMethods;
1427 }
1428 }
1429 }
1430 _ => {}
1431 }
1432 }
1433 }
1434 do_not_complete
1435 }
1436
1437 #[inline]
1438 pub fn for_trait_item(trait_attr: Complete, item_attr: Complete) -> Complete {
1439 match (trait_attr, item_attr) {
1440 (
1441 Complete::IgnoreFlyimportMethods
1442 | Complete::IgnoreFlyimport
1443 | Complete::IgnoreMethods,
1444 _,
1445 ) => Complete::IgnoreFlyimport,
1446 _ => item_attr,
1447 }
1448 }
1449}