8988: feat: go to implementation on trait functions r=matklad a=lf-

Fix #8537.

GIF:
![output](https://user-images.githubusercontent.com/6652840/119501981-45a45c00-bd1e-11eb-8336-9145f2888643.gif)

Co-authored-by: Jade <software@lfcode.ca>
This commit is contained in:
bors[bot] 2021-05-25 13:14:34 +00:00 committed by GitHub
commit f3cfd8afb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,4 +1,4 @@
use hir::{Impl, Semantics};
use hir::{AsAssocItem, Impl, Semantics};
use ide_db::{
defs::{Definition, NameClass, NameRefClass},
RootDatabase,
@ -36,6 +36,7 @@ pub(crate) fn goto_implementation(
}
ast::NameLike::Lifetime(_) => None,
}?;
let def = match def {
Definition::ModuleDef(def) => def,
_ => return None,
@ -48,6 +49,12 @@ pub(crate) fn goto_implementation(
let module = sema.to_module_def(position.file_id)?;
impls_for_ty(&sema, builtin.ty(sema.db, module))
}
hir::ModuleDef::Function(f) => {
let assoc = f.as_assoc_item(sema.db)?;
let name = assoc.name(sema.db)?;
let trait_ = assoc.containing_trait(sema.db)?;
impls_for_trait_fn(&sema, trait_, name)
}
_ => return None,
};
Some(RangeInfo { range: node.syntax().text_range(), info: navs })
@ -64,6 +71,23 @@ fn impls_for_trait(sema: &Semantics<RootDatabase>, trait_: hir::Trait) -> Vec<Na
.collect()
}
fn impls_for_trait_fn(
sema: &Semantics<RootDatabase>,
trait_: hir::Trait,
fun_name: hir::Name,
) -> Vec<NavigationTarget> {
Impl::all_for_trait(sema.db, trait_)
.into_iter()
.filter_map(|imp| {
let item = imp.items(sema.db).iter().find_map(|itm| {
let itm_name = itm.name(sema.db)?;
(itm_name == fun_name).then(|| itm.clone())
})?;
item.try_to_nav(sema.db)
})
.collect()
}
#[cfg(test)]
mod tests {
use ide_db::base_db::FileRange;
@ -259,6 +283,26 @@ fn foo(_: bool$0) {{}}
#[lang = "bool"]
impl bool {}
//^^^^
"#,
);
}
#[test]
fn goto_implementation_trait_functions() {
check(
r#"
trait Tr {
fn f$0();
}
struct S;
impl Tr for S {
fn f() {
//^
println!("Hello, world!");
}
}
"#,
);
}