aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs24
-rw-r--r--crates/ra_hir_expand/src/lib.rs15
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs6
3 files changed, 43 insertions, 2 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index df9c151e5..a177cebca 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -26,10 +26,11 @@ use hir_ty::{
26}; 26};
27use ra_db::{CrateId, Edition, FileId}; 27use ra_db::{CrateId, Edition, FileId};
28use ra_prof::profile; 28use ra_prof::profile;
29use ra_syntax::ast; 29use ra_syntax::ast::{self, AttrsOwner};
30 30
31use crate::{ 31use crate::{
32 db::{DefDatabase, HirDatabase}, 32 db::{DefDatabase, HirDatabase},
33 has_source::HasSource,
33 CallableDef, HirDisplay, InFile, Name, 34 CallableDef, HirDisplay, InFile, Name,
34}; 35};
35 36
@@ -805,6 +806,27 @@ impl ImplBlock {
805 pub fn krate(&self, db: &impl DefDatabase) -> Crate { 806 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
806 Crate { id: self.module(db).id.krate } 807 Crate { id: self.module(db).id.krate }
807 } 808 }
809
810 pub fn is_builtin_derive(&self, db: &impl DefDatabase) -> Option<InFile<ast::Attr>> {
811 let src = self.source(db);
812 let item = src.file_id.is_builtin_derive(db)?;
813 let hygenic = hir_expand::hygiene::Hygiene::new(db, item.file_id);
814
815 let attr = item
816 .value
817 .attrs()
818 .filter_map(|it| {
819 let path = hir_def::path::ModPath::from_src(it.path()?, &hygenic)?;
820 if path.as_ident()?.to_string() == "derive" {
821 Some(it)
822 } else {
823 None
824 }
825 })
826 .last()?;
827
828 Some(item.with_value(attr))
829 }
808} 830}
809 831
810#[derive(Clone, PartialEq, Eq, Debug)] 832#[derive(Clone, PartialEq, Eq, Debug)]
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 51c5f9623..7cf3b59a7 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -112,6 +112,21 @@ impl HirFileId {
112 } 112 }
113 } 113 }
114 } 114 }
115
116 /// Indicate it is macro file generated for builtin derive
117 pub fn is_builtin_derive(&self, db: &dyn db::AstDatabase) -> Option<InFile<ast::ModuleItem>> {
118 match self.0 {
119 HirFileIdRepr::FileId(_) => None,
120 HirFileIdRepr::MacroFile(macro_file) => {
121 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
122 let item = match loc.def.kind {
123 MacroDefKind::BuiltInDerive(_) => loc.kind.node(db),
124 _ => return None,
125 };
126 Some(item.with_value(ast::ModuleItem::cast(item.value.clone())?))
127 }
128 }
129 }
115} 130}
116 131
117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 132#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index f2e45fa31..b2af3479c 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -251,7 +251,11 @@ impl ToNav for hir::Module {
251impl ToNav for hir::ImplBlock { 251impl ToNav for hir::ImplBlock {
252 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { 252 fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
253 let src = self.source(db); 253 let src = self.source(db);
254 let frange = original_range(db, src.as_ref().map(|it| it.syntax())); 254 let frange = if let Some(item) = self.is_builtin_derive(db) {
255 original_range(db, item.syntax())
256 } else {
257 original_range(db, src.as_ref().map(|it| it.syntax()))
258 };
255 259
256 NavigationTarget::from_syntax( 260 NavigationTarget::from_syntax(
257 frange.file_id, 261 frange.file_id,