mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
feat: goto def on impl items also goes to the defn in the trait
It was trivial to extend this to associated consts/associated types and I just didn't think of it.
This commit is contained in:
parent
8a57c73640
commit
34ce05781f
1 changed files with 56 additions and 18 deletions
|
@ -57,7 +57,7 @@ pub(crate) fn goto_definition(
|
||||||
},
|
},
|
||||||
ast::Name(name) => {
|
ast::Name(name) => {
|
||||||
let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
|
let def = NameClass::classify(&sema, &name)?.referenced_or_defined(sema.db);
|
||||||
try_find_trait_fn_definition(&sema.db, &def)
|
try_find_trait_item_definition(&sema.db, &def)
|
||||||
.or_else(|| def.try_to_nav(sema.db))
|
.or_else(|| def.try_to_nav(sema.db))
|
||||||
},
|
},
|
||||||
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, <) {
|
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, <) {
|
||||||
|
@ -100,30 +100,32 @@ fn try_lookup_include_path(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// finds the trait definition of an impl'd function
|
/// finds the trait definition of an impl'd item
|
||||||
/// e.g.
|
/// e.g.
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// trait A { fn a(); }
|
/// trait A { fn a(); }
|
||||||
/// struct S;
|
/// struct S;
|
||||||
/// impl A for S { fn a(); } // <-- on this function, will get the location of a() in the trait
|
/// impl A for S { fn a(); } // <-- on this function, will get the location of a() in the trait
|
||||||
/// ```
|
/// ```
|
||||||
fn try_find_trait_fn_definition(db: &RootDatabase, def: &Definition) -> Option<NavigationTarget> {
|
fn try_find_trait_item_definition(db: &RootDatabase, def: &Definition) -> Option<NavigationTarget> {
|
||||||
match def {
|
let name = def.name(db)?;
|
||||||
Definition::ModuleDef(ModuleDef::Function(f)) => {
|
let assoc = match def {
|
||||||
let name = def.name(db)?;
|
Definition::ModuleDef(ModuleDef::Function(f)) => f.as_assoc_item(db),
|
||||||
let assoc = f.as_assoc_item(db)?;
|
Definition::ModuleDef(ModuleDef::Const(c)) => c.as_assoc_item(db),
|
||||||
let imp = match assoc.container(db) {
|
Definition::ModuleDef(ModuleDef::TypeAlias(ty)) => ty.as_assoc_item(db),
|
||||||
hir::AssocItemContainer::Impl(imp) => imp,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
let trait_ = imp.trait_(db)?;
|
|
||||||
trait_
|
|
||||||
.items(db)
|
|
||||||
.iter()
|
|
||||||
.find_map(|itm| (itm.name(db)? == name).then(|| itm.try_to_nav(db)).flatten())
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}?;
|
||||||
|
|
||||||
|
let imp = match assoc.container(db) {
|
||||||
|
hir::AssocItemContainer::Impl(imp) => imp,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let trait_ = imp.trait_(db)?;
|
||||||
|
trait_
|
||||||
|
.items(db)
|
||||||
|
.iter()
|
||||||
|
.find_map(|itm| (itm.name(db)? == name).then(|| itm.try_to_nav(db)).flatten())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
|
fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
|
||||||
|
@ -1304,6 +1306,42 @@ struct Stwuct;
|
||||||
impl Twait for Stwuct {
|
impl Twait for Stwuct {
|
||||||
fn a$0();
|
fn a$0();
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_of_trait_impl_const() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
trait Twait {
|
||||||
|
const NOMS: bool;
|
||||||
|
// ^^^^
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Stwuct;
|
||||||
|
|
||||||
|
impl Twait for Stwuct {
|
||||||
|
const NOMS$0: bool = true;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_def_of_trait_impl_type_alias() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
trait Twait {
|
||||||
|
type IsBad;
|
||||||
|
// ^^^^^
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Stwuct;
|
||||||
|
|
||||||
|
impl Twait for Stwuct {
|
||||||
|
type IsBad$0 = !;
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue