about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-01-02 16:58:21 +0100
committerLukas Wirth <lukastw97@gmail.com>2022-01-02 23:44:26 +0100
commitaeb5d6491246fcf53d6cb11bb3035d30580570e7 (patch)
tree2c88458f266b288b5410be2697eb7422a87dc149
parent6b7b09d329c174590a52ba570e20def528ea216a (diff)
downloadrust-aeb5d6491246fcf53d6cb11bb3035d30580570e7.tar.gz
rust-aeb5d6491246fcf53d6cb11bb3035d30580570e7.zip
Implement ToDef for ast::Attr
-rw-r--r--crates/hir/src/semantics.rs22
-rw-r--r--crates/hir/src/semantics/source_to_def.rs15
2 files changed, 21 insertions, 16 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 077ab40d081..9be1619228c 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -476,12 +476,12 @@ impl<'db> SemanticsImpl<'db> {
     }
 
     fn derive_macro_calls(&self, attr: &ast::Attr) -> Option<Vec<Option<MacroCallId>>> {
-        let item = attr.syntax().parent().and_then(ast::Item::cast)?;
-        let file_id = self.find_file(item.syntax()).file_id;
-        let item = InFile::new(file_id, &item);
+        let adt = attr.syntax().parent().and_then(ast::Adt::cast)?;
+        let file_id = self.find_file(adt.syntax()).file_id;
+        let adt = InFile::new(file_id, &adt);
         let src = InFile::new(file_id, attr.clone());
         self.with_ctx(|ctx| {
-            let res = ctx.attr_to_derive_macro_call(item, src)?;
+            let res = ctx.attr_to_derive_macro_call(adt, src)?;
             Some(res.to_vec())
         })
     }
@@ -909,17 +909,8 @@ impl<'db> SemanticsImpl<'db> {
             return None;
         }
 
-        // Fetch hir::Attr definition
-        // FIXME: Move this to ToDef impl?
-        let adt = attr.syntax().parent().and_then(ast::Adt::cast)?;
-        let attr_pos = adt.attrs().position(|it| it == attr)?;
-        let attrs = {
-            let file_id = self.find_file(adt.syntax()).file_id;
-            let adt = InFile::new(file_id, adt);
-            let def = self.with_ctx(|ctx| ctx.adt_to_def(adt))?;
-            self.db.attrs(def.into())
-        };
-        let attr_def = attrs.get(attr_pos)?;
+        let attr_def =
+            ast::Attr::to_def(self, self.find_file(attr.syntax()).with_value(attr.clone()))?;
 
         let mut derive_paths = attr_def.parse_path_comma_token_tree()?;
         let derives = self.resolve_derive_macro(&attr)?;
@@ -1214,6 +1205,7 @@ to_def_impls![
     (crate::Local, ast::SelfParam, self_param_to_def),
     (crate::Label, ast::Label, label_to_def),
     (crate::Adt, ast::Adt, adt_to_def),
+    (crate::Attr, ast::Attr, attr_to_def),
 ];
 
 fn find_root(node: &SyntaxNode) -> SyntaxNode {
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 495c84e65f4..fbce53eb166 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -210,6 +210,19 @@ impl SourceToDefCtx<'_, '_> {
             ast::Adt::Union(it) => self.union_to_def(InFile::new(file_id, it)).map(AdtId::UnionId),
         }
     }
+    pub(super) fn attr_to_def(
+        &mut self,
+        InFile { file_id, value }: InFile<ast::Attr>,
+    ) -> Option<crate::Attr> {
+        // FIXME: Use dynmap?
+        let adt = value.syntax().parent().and_then(ast::Adt::cast)?;
+        let attr_pos = ast::HasAttrs::attrs(&adt).position(|it| it == value)?;
+        let attrs = {
+            let def = self.adt_to_def(InFile::new(file_id, adt))?;
+            self.db.attrs(def.into())
+        };
+        attrs.get(attr_pos).cloned()
+    }
     pub(super) fn bind_pat_to_def(
         &mut self,
         src: InFile<ast::IdentPat>,
@@ -246,7 +259,7 @@ impl SourceToDefCtx<'_, '_> {
 
     pub(super) fn attr_to_derive_macro_call(
         &mut self,
-        item: InFile<&ast::Item>,
+        item: InFile<&ast::Adt>,
         src: InFile<ast::Attr>,
     ) -> Option<&[Option<MacroCallId>]> {
         let map = self.dyn_map(item)?;