diff options
Diffstat (limited to 'crates/hir_def/src/lib.rs')
-rw-r--r-- | crates/hir_def/src/lib.rs | 187 |
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 | ||
58 | use base_db::{impl_intern_key, salsa, CrateId}; | 58 | use base_db::{impl_intern_key, salsa, CrateId}; |
59 | use hir_expand::{ | 59 | use 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 | }; |
63 | use la_arena::Idx; | 65 | use la_arena::Idx; |
64 | use nameres::DefMap; | 66 | use 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)] |
104 | pub struct ItemLoc<N: ItemTreeNode> { | 110 | pub 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 { | |||
273 | pub type LocalConstParamId = Idx<generics::ConstParamData>; | 279 | pub type LocalConstParamId = Idx<generics::ConstParamData>; |
274 | 280 | ||
275 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 281 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
276 | pub enum ContainerId { | ||
277 | ModuleId(ModuleId), | ||
278 | DefWithBodyId(DefWithBodyId), | ||
279 | } | ||
280 | |||
281 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
282 | pub enum AssocContainerId { | 282 | pub enum AssocContainerId { |
283 | ContainerId(ContainerId), | 283 | ModuleId(ModuleId), |
284 | ImplId(ImplId), | 284 | ImplId(ImplId), |
285 | TraitId(TraitId), | 285 | TraitId(TraitId), |
286 | } | 286 | } |
287 | impl_from!(ContainerId for AssocContainerId); | 287 | impl_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 | ||
444 | impl 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 | |||
453 | impl HasModule for AssocContainerId { | 444 | impl 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 | ||
480 | impl HasModule for VariantId { | 470 | impl 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 | ||
524 | impl HasModule for StaticLoc { | 514 | impl 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 | |||
520 | impl 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 | ||
613 | impl AsMacroCall for AstIdWithPath<ast::MacroCall> { | 629 | struct UnresolvedMacro; |
614 | fn as_call_id_with_errors( | 630 | |
615 | &self, | 631 | fn 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 | ||
648 | impl AsMacroCall for AstIdWithPath<ast::Item> { | 659 | fn 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 | } |