Skip to content

Commit 6e357da

Browse files
committed
hir: resolve associated items in docs
1 parent d987137 commit 6e357da

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
@@ -18,8 +18,8 @@ use syntax::{ast, AstNode};
1818

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

2525
pub trait HasAttrs {
@@ -205,8 +205,9 @@ fn resolve_assoc_or_field(
205205
}
206206
};
207207

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

211212
let variant_def = match ty.as_adt()? {
212213
Adt::Struct(it) => it.into(),
@@ -216,6 +217,35 @@ fn resolve_assoc_or_field(
216217
resolve_field(db, variant_def, name, ns)
217218
}
218219

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

crates/ide/src/doc_links/tests.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -462,14 +462,15 @@ mod module {}
462462
fn doc_links_inherent_impl_items() {
463463
check_doc_links(
464464
r#"
465-
// /// [`Struct::CONST`]
466-
// /// [`Struct::function`]
467-
/// FIXME #9694
465+
/// [`Struct::CONST`]
466+
/// [`Struct::function`]
468467
struct Struct$0;
469468
470469
impl Struct {
471470
const CONST: () = ();
471+
// ^^^^^ Struct::CONST
472472
fn function() {}
473+
// ^^^^^^^^ Struct::function
473474
}
474475
"#,
475476
)

0 commit comments

Comments
 (0)