Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/nameres/attr_resolution.rs')
-rw-r--r--crates/hir-def/src/nameres/attr_resolution.rs67
1 files changed, 63 insertions, 4 deletions
diff --git a/crates/hir-def/src/nameres/attr_resolution.rs b/crates/hir-def/src/nameres/attr_resolution.rs
index 6288b8366b..1cadae8c87 100644
--- a/crates/hir-def/src/nameres/attr_resolution.rs
+++ b/crates/hir-def/src/nameres/attr_resolution.rs
@@ -1,16 +1,21 @@
//! Post-nameres attribute resolution.
-use hir_expand::{attrs::Attr, MacroCallId};
+use base_db::CrateId;
+use hir_expand::{
+ attrs::{Attr, AttrId, AttrInput},
+ MacroCallId, MacroCallKind, MacroDefId,
+};
+use span::Span;
use syntax::{ast, SmolStr};
+use triomphe::Arc;
use crate::{
attr::builtin::{find_builtin_attr_idx, TOOL_MODULES},
- attr_macro_as_call_id,
db::DefDatabase,
item_scope::BuiltinShadowMode,
nameres::path_resolution::ResolveMode,
- path::{ModPath, PathKind},
- AstIdWithPath, LocalModuleId, UnresolvedMacro,
+ path::{self, ModPath, PathKind},
+ AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro,
};
use super::{DefMap, MacroSubNs};
@@ -93,3 +98,57 @@ impl DefMap {
false
}
}
+
+pub(super) fn attr_macro_as_call_id(
+ db: &dyn DefDatabase,
+ item_attr: &AstIdWithPath<ast::Item>,
+ macro_attr: &Attr,
+ krate: CrateId,
+ def: MacroDefId,
+) -> MacroCallId {
+ let arg = match macro_attr.input.as_deref() {
+ Some(AttrInput::TokenTree(tt)) => {
+ let mut tt = tt.as_ref().clone();
+ tt.delimiter = tt::Delimiter::invisible_spanned(macro_attr.span);
+ Some(tt)
+ }
+
+ _ => None,
+ };
+
+ def.as_lazy_macro(
+ db.upcast(),
+ krate,
+ MacroCallKind::Attr {
+ ast_id: item_attr.ast_id,
+ attr_args: arg.map(Arc::new),
+ invoc_attr_index: macro_attr.id,
+ },
+ macro_attr.span,
+ )
+}
+
+pub(super) fn derive_macro_as_call_id(
+ db: &dyn DefDatabase,
+ item_attr: &AstIdWithPath<ast::Adt>,
+ derive_attr_index: AttrId,
+ derive_pos: u32,
+ call_site: Span,
+ krate: CrateId,
+ resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
+) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
+ let (macro_id, def_id) = resolver(item_attr.path.clone())
+ .filter(|(_, def_id)| def_id.is_derive())
+ .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
+ let call_id = def_id.as_lazy_macro(
+ db.upcast(),
+ krate,
+ MacroCallKind::Derive {
+ ast_id: item_attr.ast_id,
+ derive_index: derive_pos,
+ derive_attr_index,
+ },
+ call_site,
+ );
+ Ok((macro_id, def_id, call_id))
+}