Merge #8250
8250: More accurately classify assoc. types in paths r=jonas-schievink a=jonas-schievink Previously `Iterator<Whoops$0 = ()>` would go to the `Iterator` trait. This fixes that and correctly marks `Whoops` as unresolved. bors r+ Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
commit
904bdff224
@ -917,6 +917,21 @@ fn f() -> impl Iterator<Item$0 = u8> {}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "unresolved reference"]
|
||||
fn unknown_assoc_ty() {
|
||||
check(
|
||||
r#"
|
||||
trait Iterator {
|
||||
type Item;
|
||||
//^^^^
|
||||
}
|
||||
|
||||
fn f() -> impl Iterator<Invalid$0 = u8> {}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_def_for_assoc_ty_in_path_multiple() {
|
||||
check(
|
||||
|
@ -330,25 +330,30 @@ pub fn classify(
|
||||
}
|
||||
}
|
||||
|
||||
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(assoc_type_arg) = ast::AssocTypeArg::cast(parent.clone()) {
|
||||
if assoc_type_arg.name_ref().as_ref() == Some(name_ref) {
|
||||
// `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 {
|
||||
// FIXME: resolve in supertraits
|
||||
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),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user