aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-03-30 01:08:33 +0100
committerJonas Schievink <[email protected]>2021-03-30 01:09:17 +0100
commit41c7448e1242de8fadf7c46efd3171368b5ff92e (patch)
tree02afde0f2d0406abb3bc4089eae7267924f81899
parentb3ca06e4fd8fe3a3ab081c55ecaa1ec3e79fe18d (diff)
Accurately classify assoc. types in paths
-rw-r--r--crates/ide/src/goto_definition.rs15
-rw-r--r--crates/ide_db/src/defs.rs41
2 files changed, 38 insertions, 18 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index a2c97061f..c6556c487 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -918,6 +918,21 @@ fn f() -> impl Iterator<Item$0 = u8> {}
918 } 918 }
919 919
920 #[test] 920 #[test]
921 #[should_panic = "unresolved reference"]
922 fn unknown_assoc_ty() {
923 check(
924 r#"
925trait Iterator {
926 type Item;
927 //^^^^
928}
929
930fn f() -> impl Iterator<Invalid$0 = u8> {}
931 "#,
932 )
933 }
934
935 #[test]
921 fn goto_def_for_assoc_ty_in_path_multiple() { 936 fn goto_def_for_assoc_ty_in_path_multiple() {
922 check( 937 check(
923 r#" 938 r#"
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index 0d9808d24..de0dc2a40 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -330,25 +330,30 @@ impl NameRefClass {
330 } 330 }
331 } 331 }
332 332
333 if ast::AssocTypeArg::cast(parent.clone()).is_some() { 333 if let Some(assoc_type_arg) = ast::AssocTypeArg::cast(parent.clone()) {
334 // `Trait<Assoc = Ty>` 334 if assoc_type_arg.name_ref().as_ref() == Some(name_ref) {
335 // ^^^^^ 335 // `Trait<Assoc = Ty>`
336 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?; 336 // ^^^^^
337 let resolved = sema.resolve_path(&path)?; 337 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
338 if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved { 338 let resolved = sema.resolve_path(&path)?;
339 if let Some(ty) = tr 339 if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved {
340 .items(sema.db) 340 // FIXME: resolve in supertraits
341 .iter() 341 if let Some(ty) = tr
342 .filter_map(|assoc| match assoc { 342 .items(sema.db)
343 hir::AssocItem::TypeAlias(it) => Some(*it), 343 .iter()
344 _ => None, 344 .filter_map(|assoc| match assoc {
345 }) 345 hir::AssocItem::TypeAlias(it) => Some(*it),
346 .find(|alias| &alias.name(sema.db).to_string() == &name_ref.text()) 346 _ => None,
347 { 347 })
348 return Some(NameRefClass::Definition(Definition::ModuleDef( 348 .find(|alias| &alias.name(sema.db).to_string() == &name_ref.text())
349 ModuleDef::TypeAlias(ty), 349 {
350 ))); 350 return Some(NameRefClass::Definition(Definition::ModuleDef(
351 ModuleDef::TypeAlias(ty),
352 )));
353 }
351 } 354 }
355
356 return None;
352 } 357 }
353 } 358 }
354 359