diff options
Diffstat (limited to 'crates/hir_def/src/lib.rs')
-rw-r--r-- | crates/hir_def/src/lib.rs | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index d69116d51..25694f037 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -66,6 +66,7 @@ use hir_expand::{ | |||
66 | }; | 66 | }; |
67 | use la_arena::Idx; | 67 | use la_arena::Idx; |
68 | use nameres::DefMap; | 68 | use nameres::DefMap; |
69 | use path::ModPath; | ||
69 | use syntax::ast; | 70 | use syntax::ast; |
70 | 71 | ||
71 | use crate::builtin_type::BuiltinType; | 72 | use crate::builtin_type::BuiltinType; |
@@ -107,6 +108,18 @@ impl ModuleId { | |||
107 | pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> { | 108 | pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> { |
108 | self.def_map(db).containing_module(self.local_id) | 109 | self.def_map(db).containing_module(self.local_id) |
109 | } | 110 | } |
111 | |||
112 | /// Returns `true` if this module represents a block expression. | ||
113 | /// | ||
114 | /// Returns `false` if this module is a submodule *inside* a block expression | ||
115 | /// (eg. `m` in `{ mod m {} }`). | ||
116 | pub fn is_block_root(&self, db: &dyn db::DefDatabase) -> bool { | ||
117 | if self.block.is_none() { | ||
118 | return false; | ||
119 | } | ||
120 | |||
121 | self.def_map(db)[self.local_id].parent.is_none() | ||
122 | } | ||
110 | } | 123 | } |
111 | 124 | ||
112 | /// An ID of a module, **local** to a specific crate | 125 | /// An ID of a module, **local** to a specific crate |
@@ -435,6 +448,16 @@ impl_from!( | |||
435 | for AttrDefId | 448 | for AttrDefId |
436 | ); | 449 | ); |
437 | 450 | ||
451 | impl From<AssocContainerId> for AttrDefId { | ||
452 | fn from(acid: AssocContainerId) -> Self { | ||
453 | match acid { | ||
454 | AssocContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid), | ||
455 | AssocContainerId::ImplId(iid) => AttrDefId::ImplId(iid), | ||
456 | AssocContainerId::TraitId(tid) => AttrDefId::TraitId(tid), | ||
457 | } | ||
458 | } | ||
459 | } | ||
460 | |||
438 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 461 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
439 | pub enum VariantId { | 462 | pub enum VariantId { |
440 | EnumVariantId(EnumVariantId), | 463 | EnumVariantId(EnumVariantId), |
@@ -665,7 +688,10 @@ impl<T: ast::AstNode> AstIdWithPath<T> { | |||
665 | } | 688 | } |
666 | } | 689 | } |
667 | 690 | ||
668 | pub struct UnresolvedMacro; | 691 | #[derive(Debug)] |
692 | pub struct UnresolvedMacro { | ||
693 | pub path: ModPath, | ||
694 | } | ||
669 | 695 | ||
670 | fn macro_call_as_call_id( | 696 | fn macro_call_as_call_id( |
671 | call: &AstIdWithPath<ast::MacroCall>, | 697 | call: &AstIdWithPath<ast::MacroCall>, |
@@ -674,7 +700,8 @@ fn macro_call_as_call_id( | |||
674 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, | 700 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, |
675 | error_sink: &mut dyn FnMut(mbe::ExpandError), | 701 | error_sink: &mut dyn FnMut(mbe::ExpandError), |
676 | ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { | 702 | ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { |
677 | let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?; | 703 | let def: MacroDefId = |
704 | resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?; | ||
678 | 705 | ||
679 | let res = if let MacroDefKind::BuiltInEager(..) = def.kind { | 706 | let res = if let MacroDefKind::BuiltInEager(..) = def.kind { |
680 | let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast())); | 707 | let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast())); |
@@ -704,8 +731,13 @@ fn derive_macro_as_call_id( | |||
704 | krate: CrateId, | 731 | krate: CrateId, |
705 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, | 732 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, |
706 | ) -> Result<MacroCallId, UnresolvedMacro> { | 733 | ) -> Result<MacroCallId, UnresolvedMacro> { |
707 | let def: MacroDefId = resolver(item_attr.path.clone()).ok_or(UnresolvedMacro)?; | 734 | let def: MacroDefId = resolver(item_attr.path.clone()) |
708 | let last_segment = item_attr.path.segments().last().ok_or(UnresolvedMacro)?; | 735 | .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?; |
736 | let last_segment = item_attr | ||
737 | .path | ||
738 | .segments() | ||
739 | .last() | ||
740 | .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?; | ||
709 | let res = def | 741 | let res = def |
710 | .as_lazy_macro( | 742 | .as_lazy_macro( |
711 | db.upcast(), | 743 | db.upcast(), |