Merge #8988
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:
commit
f3cfd8afb6
@ -1,4 +1,4 @@
|
|||||||
use hir::{Impl, Semantics};
|
use hir::{AsAssocItem, Impl, Semantics};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
defs::{Definition, NameClass, NameRefClass},
|
defs::{Definition, NameClass, NameRefClass},
|
||||||
RootDatabase,
|
RootDatabase,
|
||||||
@ -36,6 +36,7 @@ pub(crate) fn goto_implementation(
|
|||||||
}
|
}
|
||||||
ast::NameLike::Lifetime(_) => None,
|
ast::NameLike::Lifetime(_) => None,
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let def = match def {
|
let def = match def {
|
||||||
Definition::ModuleDef(def) => def,
|
Definition::ModuleDef(def) => def,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
@ -48,6 +49,12 @@ pub(crate) fn goto_implementation(
|
|||||||
let module = sema.to_module_def(position.file_id)?;
|
let module = sema.to_module_def(position.file_id)?;
|
||||||
impls_for_ty(&sema, builtin.ty(sema.db, module))
|
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,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some(RangeInfo { range: node.syntax().text_range(), info: navs })
|
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()
|
.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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ide_db::base_db::FileRange;
|
use ide_db::base_db::FileRange;
|
||||||
@ -259,6 +283,26 @@ fn foo(_: bool$0) {{}}
|
|||||||
#[lang = "bool"]
|
#[lang = "bool"]
|
||||||
impl 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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user