aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-01-12 11:33:31 +0000
committerGitHub <[email protected]>2020-01-12 11:33:31 +0000
commit8bb2a50ce6adda4d3d8dfb66cd67d302ec108d45 (patch)
treef856e09f543a391916907fd9a19257924eb2bfaf /crates
parent21be386db8e8019d25c2529313d0371f91a15cb3 (diff)
parentdb5f73d261413f03e4e3a4a374f8306fe8ae5578 (diff)
Merge #2807
2807: Use attr location for builtin derive in goto-implementation r=matklad a=edwin0cheng This PR is use attribute location for builtin derive in `ImplBlock`'s NavigationTarget such that the goto-implementation will goto to a correct position. Related to #2531 Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates')
-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
-rw-r--r--crates/ra_ide/src/impls.rs12
4 files changed, 55 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,
diff --git a/crates/ra_ide/src/impls.rs b/crates/ra_ide/src/impls.rs
index 9b165ee2a..31195036e 100644
--- a/crates/ra_ide/src/impls.rs
+++ b/crates/ra_ide/src/impls.rs
@@ -203,4 +203,16 @@ mod tests {
203 ], 203 ],
204 ); 204 );
205 } 205 }
206
207 #[test]
208 fn goto_implementation_to_builtin_derive() {
209 check_goto(
210 "
211 //- /lib.rs
212 #[derive(Copy)]
213 struct Foo<|>;
214 ",
215 &["impl IMPL_BLOCK FileId(1) [0; 15)"],
216 );
217 }
206} 218}