Skip to content

Commit dd90900

Browse files
Resolve type aliases to the type they point to in intra-doc links
1 parent 3044419 commit dd90900

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

+46-5
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,44 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
544544
})
545545
}
546546

547+
/// Convert a DefId to a Res, where possible.
548+
///
549+
/// This is used for resolving type aliases.
550+
fn def_id_to_res(&self, ty_id: DefId) -> Option<Res> {
551+
use PrimitiveType::*;
552+
Some(match *self.cx.tcx.type_of(ty_id).kind() {
553+
ty::Bool => Res::Primitive(Bool),
554+
ty::Char => Res::Primitive(Char),
555+
ty::Int(ity) => Res::Primitive(ity.into()),
556+
ty::Uint(uty) => Res::Primitive(uty.into()),
557+
ty::Float(fty) => Res::Primitive(fty.into()),
558+
ty::Str => Res::Primitive(Str),
559+
ty::Tuple(ref tys) if tys.is_empty() => Res::Primitive(Unit),
560+
ty::Tuple(_) => Res::Primitive(Tuple),
561+
ty::Array(..) => Res::Primitive(Array),
562+
ty::Slice(_) => Res::Primitive(Slice),
563+
ty::RawPtr(_) => Res::Primitive(RawPointer),
564+
ty::Ref(..) => Res::Primitive(Reference),
565+
ty::FnDef(..) => panic!("type alias to a function definition"),
566+
ty::FnPtr(_) => Res::Primitive(Fn),
567+
ty::Never => Res::Primitive(Never),
568+
ty::Adt(&ty::AdtDef { did, .. }, _) | ty::Foreign(did) => {
569+
Res::Def(self.cx.tcx.def_kind(did), did)
570+
}
571+
ty::Projection(_)
572+
| ty::Closure(..)
573+
| ty::Generator(..)
574+
| ty::GeneratorWitness(_)
575+
| ty::Opaque(..)
576+
| ty::Dynamic(..)
577+
| ty::Param(_)
578+
| ty::Bound(..)
579+
| ty::Placeholder(_)
580+
| ty::Infer(_)
581+
| ty::Error(_) => return None,
582+
})
583+
}
584+
547585
/// Returns:
548586
/// - None if no associated item was found
549587
/// - Some((_, _, Some(_))) if an item was found and should go through a side channel
@@ -559,12 +597,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
559597

560598
match root_res {
561599
Res::Primitive(prim) => self.resolve_primitive_associated_item(prim, ns, item_name),
600+
Res::Def(DefKind::TyAlias, did) => {
601+
// Resolve the link on the type the alias points to.
602+
// FIXME: if the associated item is defined directly on the type alias,
603+
// it will show up on its documentation page, we should link there instead.
604+
let res = self.def_id_to_res(did)?;
605+
self.resolve_associated_item(res, item_name, ns, module_id)
606+
}
562607
Res::Def(
563-
DefKind::Struct
564-
| DefKind::Union
565-
| DefKind::Enum
566-
| DefKind::TyAlias
567-
| DefKind::ForeignTy,
608+
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::ForeignTy,
568609
did,
569610
) => {
570611
debug!("looking for associated item named {} for item {:?}", item_name, did);
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Regression test for issue #86120.
2+
3+
#![deny(broken_intra_doc_links)]
4+
#![crate_name = "foo"]
5+
6+
pub struct Foo;
7+
8+
/// You should really try [`Self::bar`]!
9+
pub type Bar = Foo;
10+
11+
impl Bar {
12+
pub fn bar() {}
13+
}
14+
15+
/// The minimum is [`Self::MIN`].
16+
pub type Int = i32;
17+
18+
// @has foo/type.Bar.html '//a[@href="struct.Foo.html#method.bar"]' 'Self::bar'
19+
// @has foo/type.Int.html '//a[@href="{{channel}}/std/primitive.i32.html#associatedconstant.MIN"]' 'Self::MIN'

0 commit comments

Comments
 (0)