aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/lib.rs')
-rw-r--r--crates/hir_def/src/lib.rs187
1 files changed, 96 insertions, 91 deletions
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index b50923747..6d11c5be4 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -57,8 +57,10 @@ use std::{
57 57
58use base_db::{impl_intern_key, salsa, CrateId}; 58use base_db::{impl_intern_key, salsa, CrateId};
59use hir_expand::{ 59use hir_expand::{
60 ast_id_map::FileAstId, eager::expand_eager_macro, hygiene::Hygiene, AstId, HirFileId, InFile, 60 ast_id_map::FileAstId,
61 MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 61 eager::{expand_eager_macro, ErrorEmitted},
62 hygiene::Hygiene,
63 AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
62}; 64};
63use la_arena::Idx; 65use la_arena::Idx;
64use nameres::DefMap; 66use nameres::DefMap;
@@ -95,6 +97,10 @@ impl ModuleId {
95 pub fn krate(&self) -> CrateId { 97 pub fn krate(&self) -> CrateId {
96 self.krate 98 self.krate
97 } 99 }
100
101 pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
102 self.def_map(db).containing_module(self.local_id)
103 }
98} 104}
99 105
100/// An ID of a module, **local** to a specific crate 106/// An ID of a module, **local** to a specific crate
@@ -102,7 +108,7 @@ pub type LocalModuleId = Idx<nameres::ModuleData>;
102 108
103#[derive(Debug)] 109#[derive(Debug)]
104pub struct ItemLoc<N: ItemTreeNode> { 110pub struct ItemLoc<N: ItemTreeNode> {
105 pub container: ContainerId, 111 pub container: ModuleId,
106 pub id: ItemTreeId<N>, 112 pub id: ItemTreeId<N>,
107} 113}
108 114
@@ -273,18 +279,12 @@ pub struct ConstParamId {
273pub type LocalConstParamId = Idx<generics::ConstParamData>; 279pub type LocalConstParamId = Idx<generics::ConstParamData>;
274 280
275#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 281#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
276pub enum ContainerId {
277 ModuleId(ModuleId),
278 DefWithBodyId(DefWithBodyId),
279}
280
281#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
282pub enum AssocContainerId { 282pub enum AssocContainerId {
283 ContainerId(ContainerId), 283 ModuleId(ModuleId),
284 ImplId(ImplId), 284 ImplId(ImplId),
285 TraitId(TraitId), 285 TraitId(TraitId),
286} 286}
287impl_from!(ContainerId for AssocContainerId); 287impl_from!(ModuleId for AssocContainerId);
288 288
289/// A Data Type 289/// A Data Type
290#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 290#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@@ -441,21 +441,12 @@ pub trait HasModule {
441 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId; 441 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
442} 442}
443 443
444impl HasModule for ContainerId {
445 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
446 match *self {
447 ContainerId::ModuleId(it) => it,
448 ContainerId::DefWithBodyId(it) => it.module(db),
449 }
450 }
451}
452
453impl HasModule for AssocContainerId { 444impl HasModule for AssocContainerId {
454 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { 445 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
455 match *self { 446 match *self {
456 AssocContainerId::ContainerId(it) => it.module(db), 447 AssocContainerId::ModuleId(it) => it,
457 AssocContainerId::ImplId(it) => it.lookup(db).container.module(db), 448 AssocContainerId::ImplId(it) => it.lookup(db).container,
458 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db), 449 AssocContainerId::TraitId(it) => it.lookup(db).container,
459 } 450 }
460 } 451 }
461} 452}
@@ -473,16 +464,15 @@ impl HasModule for AdtId {
473 AdtId::UnionId(it) => it.lookup(db).container, 464 AdtId::UnionId(it) => it.lookup(db).container,
474 AdtId::EnumId(it) => it.lookup(db).container, 465 AdtId::EnumId(it) => it.lookup(db).container,
475 } 466 }
476 .module(db)
477 } 467 }
478} 468}
479 469
480impl HasModule for VariantId { 470impl HasModule for VariantId {
481 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { 471 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
482 match self { 472 match self {
483 VariantId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), 473 VariantId::EnumVariantId(it) => it.parent.lookup(db).container,
484 VariantId::StructId(it) => it.lookup(db).container.module(db), 474 VariantId::StructId(it) => it.lookup(db).container,
485 VariantId::UnionId(it) => it.lookup(db).container.module(db), 475 VariantId::UnionId(it) => it.lookup(db).container,
486 } 476 }
487 } 477 }
488} 478}
@@ -512,18 +502,37 @@ impl HasModule for GenericDefId {
512 match self { 502 match self {
513 GenericDefId::FunctionId(it) => it.lookup(db).module(db), 503 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
514 GenericDefId::AdtId(it) => it.module(db), 504 GenericDefId::AdtId(it) => it.module(db),
515 GenericDefId::TraitId(it) => it.lookup(db).container.module(db), 505 GenericDefId::TraitId(it) => it.lookup(db).container,
516 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 506 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
517 GenericDefId::ImplId(it) => it.lookup(db).container.module(db), 507 GenericDefId::ImplId(it) => it.lookup(db).container,
518 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), 508 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
519 GenericDefId::ConstId(it) => it.lookup(db).module(db), 509 GenericDefId::ConstId(it) => it.lookup(db).module(db),
520 } 510 }
521 } 511 }
522} 512}
523 513
524impl HasModule for StaticLoc { 514impl HasModule for StaticLoc {
525 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { 515 fn module(&self, _db: &dyn db::DefDatabase) -> ModuleId {
526 self.container.module(db) 516 self.container
517 }
518}
519
520impl ModuleDefId {
521 /// Returns the module containing `self` (or `self`, if `self` is itself a module).
522 ///
523 /// Returns `None` if `self` refers to a primitive type.
524 pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
525 Some(match self {
526 ModuleDefId::ModuleId(id) => *id,
527 ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
528 ModuleDefId::AdtId(id) => id.module(db),
529 ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
530 ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
531 ModuleDefId::StaticId(id) => id.lookup(db).container,
532 ModuleDefId::TraitId(id) => id.lookup(db).container,
533 ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
534 ModuleDefId::BuiltinType(_) => return None,
535 })
527 } 536 }
528} 537}
529 538
@@ -534,12 +543,12 @@ impl AttrDefId {
534 AttrDefId::FieldId(it) => it.parent.module(db).krate, 543 AttrDefId::FieldId(it) => it.parent.module(db).krate,
535 AttrDefId::AdtId(it) => it.module(db).krate, 544 AttrDefId::AdtId(it) => it.module(db).krate,
536 AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate, 545 AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
537 AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db).krate, 546 AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.krate,
538 AttrDefId::StaticId(it) => it.lookup(db).module(db).krate, 547 AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
539 AttrDefId::ConstId(it) => it.lookup(db).module(db).krate, 548 AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
540 AttrDefId::TraitId(it) => it.lookup(db).container.module(db).krate, 549 AttrDefId::TraitId(it) => it.lookup(db).container.krate,
541 AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate, 550 AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
542 AttrDefId::ImplId(it) => it.lookup(db).container.module(db).krate, 551 AttrDefId::ImplId(it) => it.lookup(db).container.krate,
543 AttrDefId::GenericParamId(it) => { 552 AttrDefId::GenericParamId(it) => {
544 match it { 553 match it {
545 GenericParamId::TypeParamId(it) => it.parent, 554 GenericParamId::TypeParamId(it) => it.parent,
@@ -592,8 +601,15 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
592 error_sink(mbe::ExpandError::Other("malformed macro invocation".into())); 601 error_sink(mbe::ExpandError::Other("malformed macro invocation".into()));
593 } 602 }
594 603
595 AstIdWithPath::new(ast_id.file_id, ast_id.value, path?) 604 macro_call_as_call_id(
596 .as_call_id_with_errors(db, krate, resolver, error_sink) 605 &AstIdWithPath::new(ast_id.file_id, ast_id.value, path?),
606 db,
607 krate,
608 resolver,
609 error_sink,
610 )
611 .ok()?
612 .ok()
597 } 613 }
598} 614}
599 615
@@ -610,61 +626,50 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
610 } 626 }
611} 627}
612 628
613impl AsMacroCall for AstIdWithPath<ast::MacroCall> { 629struct UnresolvedMacro;
614 fn as_call_id_with_errors( 630
615 &self, 631fn macro_call_as_call_id(
616 db: &dyn db::DefDatabase, 632 call: &AstIdWithPath<ast::MacroCall>,
617 krate: CrateId, 633 db: &dyn db::DefDatabase,
618 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 634 krate: CrateId,
619 error_sink: &mut dyn FnMut(mbe::ExpandError), 635 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
620 ) -> Option<MacroCallId> { 636 error_sink: &mut dyn FnMut(mbe::ExpandError),
621 let def: MacroDefId = resolver(self.path.clone()).or_else(|| { 637) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
622 error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path))); 638 let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?;
623 None 639
624 })?; 640 let res = if let MacroDefKind::BuiltInEager(_) = def.kind {
625 641 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
626 if let MacroDefKind::BuiltInEager(_) = def.kind { 642 let hygiene = Hygiene::new(db.upcast(), call.ast_id.file_id);
627 let macro_call = InFile::new(self.ast_id.file_id, self.ast_id.to_node(db.upcast())); 643
628 let hygiene = Hygiene::new(db.upcast(), self.ast_id.file_id); 644 expand_eager_macro(
629 645 db.upcast(),
630 Some( 646 krate,
631 expand_eager_macro( 647 macro_call,
632 db.upcast(), 648 def,
633 krate, 649 &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?),
634 macro_call, 650 error_sink,
635 def, 651 )
636 &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?), 652 .map(MacroCallId::from)
637 error_sink, 653 } else {
638 ) 654 Ok(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(call.ast_id)).into())
639 .ok()? 655 };
640 .into(), 656 Ok(res)
641 )
642 } else {
643 Some(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(self.ast_id)).into())
644 }
645 }
646} 657}
647 658
648impl AsMacroCall for AstIdWithPath<ast::Item> { 659fn item_attr_as_call_id(
649 fn as_call_id_with_errors( 660 item_attr: &AstIdWithPath<ast::Item>,
650 &self, 661 db: &dyn db::DefDatabase,
651 db: &dyn db::DefDatabase, 662 krate: CrateId,
652 krate: CrateId, 663 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
653 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 664) -> Result<MacroCallId, UnresolvedMacro> {
654 error_sink: &mut dyn FnMut(mbe::ExpandError), 665 let def: MacroDefId = resolver(item_attr.path.clone()).ok_or(UnresolvedMacro)?;
655 ) -> Option<MacroCallId> { 666 let last_segment = item_attr.path.segments().last().ok_or(UnresolvedMacro)?;
656 let def: MacroDefId = resolver(self.path.clone()).or_else(|| { 667 let res = def
657 error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path))); 668 .as_lazy_macro(
658 None 669 db.upcast(),
659 })?; 670 krate,
660 671 MacroCallKind::Attr(item_attr.ast_id, last_segment.to_string()),
661 Some(
662 def.as_lazy_macro(
663 db.upcast(),
664 krate,
665 MacroCallKind::Attr(self.ast_id, self.path.segments().last()?.to_string()),
666 )
667 .into(),
668 ) 672 )
669 } 673 .into();
674 Ok(res)
670} 675}