Skip to content

Commit 1d64673

Browse files
committed
hir: resolve associated items in docs
1 parent 255eed4 commit 1d64673

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

crates/hir/src/attrs.rs

+34-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use syntax::{ast, AstNode};
1414

1515
use crate::{
1616
Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
17-
Field, Function, GenericParam, Impl, LifetimeParam, Macro, Module, ModuleDef, Static, Struct,
18-
Trait, TraitAlias, TypeAlias, TypeParam, Union, Variant, VariantDef,
17+
Field, Function, GenericParam, HasCrate, Impl, LifetimeParam, Macro, Module, ModuleDef, Static,
18+
Struct, Trait, TraitAlias, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
1919
};
2020

2121
pub trait HasAttrs {
@@ -201,8 +201,9 @@ fn resolve_assoc_or_field(
201201
}
202202
};
203203

204-
// FIXME: Resolve associated items here, e.g. `Option::map`. Note that associated items take
205-
// precedence over fields.
204+
if let Some(assoc_item_def) = resolve_assoc_item(db, &ty, &name, ns) {
205+
return Some(assoc_item_def);
206+
}
206207

207208
let variant_def = match ty.as_adt()? {
208209
Adt::Struct(it) => it.into(),
@@ -212,6 +213,35 @@ fn resolve_assoc_or_field(
212213
resolve_field(db, variant_def, name, ns)
213214
}
214215

216+
fn resolve_assoc_item(
217+
db: &dyn HirDatabase,
218+
ty: &Type,
219+
name: &Name,
220+
ns: Option<Namespace>,
221+
) -> Option<DocLinkDef> {
222+
ty.iterate_assoc_items(db, ty.krate(db), move |assoc_item| {
223+
if assoc_item.name(db)? != *name {
224+
return None;
225+
}
226+
227+
let (def, expected_ns) = match assoc_item {
228+
AssocItem::Function(it) => (ModuleDef::Function(it), Namespace::Values),
229+
AssocItem::Const(it) => (ModuleDef::Const(it), Namespace::Values),
230+
AssocItem::TypeAlias(it) => {
231+
// Inherent associated types are supported in nightly:
232+
// https://github.com/rust-lang/rust/issues/8995
233+
(ModuleDef::TypeAlias(it), Namespace::Types)
234+
}
235+
};
236+
237+
if ns.unwrap_or(expected_ns) != expected_ns {
238+
return None;
239+
}
240+
241+
Some(DocLinkDef::ModuleDef(def))
242+
})
243+
}
244+
215245
fn resolve_field(
216246
db: &dyn HirDatabase,
217247
def: VariantDef,

crates/ide/src/doc_links/tests.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -460,14 +460,15 @@ mod module {}
460460
fn doc_links_inherent_impl_items() {
461461
check_doc_links(
462462
r#"
463-
// /// [`Struct::CONST`]
464-
// /// [`Struct::function`]
465-
/// FIXME #9694
463+
/// [`Struct::CONST`]
464+
/// [`Struct::function`]
466465
struct Struct$0;
467466
468467
impl Struct {
469468
const CONST: () = ();
469+
// ^^^^^ Struct::CONST
470470
fn function() {}
471+
// ^^^^^^^^ Struct::function
471472
}
472473
"#,
473474
)

0 commit comments

Comments
 (0)