mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 07:04:22 +00:00
Correctly resolve assoc. types in path bindings
This commit is contained in:
parent
23df383433
commit
cab360fe31
2 changed files with 102 additions and 0 deletions
|
@ -881,6 +881,86 @@ pub mod module {
|
|||
macro_rules! _mac { () => { () } }
|
||||
pub use crate::_mac as mac;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_def_for_assoc_ty_in_path() {
|
||||
check(
|
||||
r#"
|
||||
trait Iterator {
|
||||
type Item;
|
||||
//^^^^
|
||||
}
|
||||
|
||||
fn f() -> impl Iterator<Item<|> = u8> {}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_def_for_assoc_ty_in_path_multiple() {
|
||||
check(
|
||||
r#"
|
||||
trait Iterator {
|
||||
type A;
|
||||
//^
|
||||
type B;
|
||||
}
|
||||
|
||||
fn f() -> impl Iterator<A<|> = u8, B = ()> {}
|
||||
"#,
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
trait Iterator {
|
||||
type A;
|
||||
type B;
|
||||
//^
|
||||
}
|
||||
|
||||
fn f() -> impl Iterator<A = u8, B<|> = ()> {}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_def_for_assoc_ty_ufcs() {
|
||||
check(
|
||||
r#"
|
||||
trait Iterator {
|
||||
type Item;
|
||||
//^^^^
|
||||
}
|
||||
|
||||
fn g() -> <() as Iterator<Item<|> = ()>>::Item {}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_def_for_assoc_ty_ufcs_multiple() {
|
||||
check(
|
||||
r#"
|
||||
trait Iterator {
|
||||
type A;
|
||||
//^
|
||||
type B;
|
||||
}
|
||||
|
||||
fn g() -> <() as Iterator<A<|> = (), B = u8>>::B {}
|
||||
"#,
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
trait Iterator {
|
||||
type A;
|
||||
type B;
|
||||
//^
|
||||
}
|
||||
|
||||
fn g() -> <() as Iterator<A = (), B<|> = u8>>::A {}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -254,6 +254,28 @@ pub fn classify_name_ref(
|
|||
}
|
||||
}
|
||||
|
||||
if ast::AssocTypeArg::cast(parent.clone()).is_some() {
|
||||
// `Trait<Assoc = Ty>`
|
||||
// ^^^^^
|
||||
let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
|
||||
let resolved = sema.resolve_path(&path)?;
|
||||
if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved {
|
||||
if let Some(ty) = tr
|
||||
.items(sema.db)
|
||||
.iter()
|
||||
.filter_map(|assoc| match assoc {
|
||||
hir::AssocItem::TypeAlias(it) => Some(*it),
|
||||
_ => None,
|
||||
})
|
||||
.find(|alias| alias.name(sema.db).to_string() == **name_ref.text())
|
||||
{
|
||||
return Some(NameRefClass::Definition(Definition::ModuleDef(
|
||||
ModuleDef::TypeAlias(ty),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
|
||||
if let Some(path) = macro_call.path() {
|
||||
if path.qualifier().is_none() {
|
||||
|
|
Loading…
Reference in a new issue