From 3e4dfaf97af127ed85ecac809fe4dbaad4c7531c Mon Sep 17 00:00:00 2001 From: Jade Date: Tue, 25 May 2021 05:46:15 -0700 Subject: feat: go to implementation on trait functions Fix #8537. GIF: https://user-images.githubusercontent.com/6652840/119501981-45a45c00-bd1e-11eb-8336-9145f2888643.gif --- crates/ide/src/goto_implementation.rs | 46 ++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index 05130a237..5a8d3c3f9 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs @@ -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, trait_: hir::Trait) -> Vec, + trait_: hir::Trait, + fun_name: hir::Name, +) -> Vec { + 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!"); + } +} "#, ); } -- cgit v1.2.3