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.rs29
1 files changed, 25 insertions, 4 deletions
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index ffee05500..5ac1670b5 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -66,6 +66,7 @@ use hir_expand::{
66}; 66};
67use la_arena::Idx; 67use la_arena::Idx;
68use nameres::DefMap; 68use nameres::DefMap;
69use path::ModPath;
69use syntax::ast; 70use syntax::ast;
70 71
71use crate::builtin_type::BuiltinType; 72use 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
@@ -675,7 +688,9 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
675 } 688 }
676} 689}
677 690
678pub struct UnresolvedMacro; 691pub struct UnresolvedMacro {
692 pub path: ModPath,
693}
679 694
680fn macro_call_as_call_id( 695fn macro_call_as_call_id(
681 call: &AstIdWithPath<ast::MacroCall>, 696 call: &AstIdWithPath<ast::MacroCall>,
@@ -684,7 +699,8 @@ fn macro_call_as_call_id(
684 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 699 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
685 error_sink: &mut dyn FnMut(mbe::ExpandError), 700 error_sink: &mut dyn FnMut(mbe::ExpandError),
686) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { 701) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
687 let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?; 702 let def: MacroDefId =
703 resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
688 704
689 let res = if let MacroDefKind::BuiltInEager(..) = def.kind { 705 let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
690 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast())); 706 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
@@ -714,8 +730,13 @@ fn derive_macro_as_call_id(
714 krate: CrateId, 730 krate: CrateId,
715 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 731 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
716) -> Result<MacroCallId, UnresolvedMacro> { 732) -> Result<MacroCallId, UnresolvedMacro> {
717 let def: MacroDefId = resolver(item_attr.path.clone()).ok_or(UnresolvedMacro)?; 733 let def: MacroDefId = resolver(item_attr.path.clone())
718 let last_segment = item_attr.path.segments().last().ok_or(UnresolvedMacro)?; 734 .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
735 let last_segment = item_attr
736 .path
737 .segments()
738 .last()
739 .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
719 let res = def 740 let res = def
720 .as_lazy_macro( 741 .as_lazy_macro(
721 db.upcast(), 742 db.upcast(),