Skip to content

Commit 2777f8c

Browse files
Merge #5423
5423: Correctly resolve assoc. types in path bindings r=matklad a=jonas-schievink Previously invoking goto def on `impl Iterator<Item<|> = ()>` would go to `Iterator`, not `Item`. This fixes that. Co-authored-by: Jonas Schievink <[email protected]>
2 parents de8c5fc + cab360f commit 2777f8c

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

crates/ra_ide/src/goto_definition.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,86 @@ pub mod module {
881881
macro_rules! _mac { () => { () } }
882882
pub use crate::_mac as mac;
883883
}
884+
"#,
885+
);
886+
}
887+
888+
#[test]
889+
fn goto_def_for_assoc_ty_in_path() {
890+
check(
891+
r#"
892+
trait Iterator {
893+
type Item;
894+
//^^^^
895+
}
896+
897+
fn f() -> impl Iterator<Item<|> = u8> {}
898+
"#,
899+
);
900+
}
901+
902+
#[test]
903+
fn goto_def_for_assoc_ty_in_path_multiple() {
904+
check(
905+
r#"
906+
trait Iterator {
907+
type A;
908+
//^
909+
type B;
910+
}
911+
912+
fn f() -> impl Iterator<A<|> = u8, B = ()> {}
913+
"#,
914+
);
915+
check(
916+
r#"
917+
trait Iterator {
918+
type A;
919+
type B;
920+
//^
921+
}
922+
923+
fn f() -> impl Iterator<A = u8, B<|> = ()> {}
924+
"#,
925+
);
926+
}
927+
928+
#[test]
929+
fn goto_def_for_assoc_ty_ufcs() {
930+
check(
931+
r#"
932+
trait Iterator {
933+
type Item;
934+
//^^^^
935+
}
936+
937+
fn g() -> <() as Iterator<Item<|> = ()>>::Item {}
938+
"#,
939+
);
940+
}
941+
942+
#[test]
943+
fn goto_def_for_assoc_ty_ufcs_multiple() {
944+
check(
945+
r#"
946+
trait Iterator {
947+
type A;
948+
//^
949+
type B;
950+
}
951+
952+
fn g() -> <() as Iterator<A<|> = (), B = u8>>::B {}
953+
"#,
954+
);
955+
check(
956+
r#"
957+
trait Iterator {
958+
type A;
959+
type B;
960+
//^
961+
}
962+
963+
fn g() -> <() as Iterator<A = (), B<|> = u8>>::A {}
884964
"#,
885965
);
886966
}

crates/ra_ide_db/src/defs.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,28 @@ pub fn classify_name_ref(
254254
}
255255
}
256256

257+
if ast::AssocTypeArg::cast(parent.clone()).is_some() {
258+
// `Trait<Assoc = Ty>`
259+
// ^^^^^
260+
let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
261+
let resolved = sema.resolve_path(&path)?;
262+
if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved {
263+
if let Some(ty) = tr
264+
.items(sema.db)
265+
.iter()
266+
.filter_map(|assoc| match assoc {
267+
hir::AssocItem::TypeAlias(it) => Some(*it),
268+
_ => None,
269+
})
270+
.find(|alias| alias.name(sema.db).to_string() == **name_ref.text())
271+
{
272+
return Some(NameRefClass::Definition(Definition::ModuleDef(
273+
ModuleDef::TypeAlias(ty),
274+
)));
275+
}
276+
}
277+
}
278+
257279
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
258280
if let Some(path) = macro_call.path() {
259281
if path.qualifier().is_none() {

0 commit comments

Comments
 (0)