Skip to content

Commit

Permalink
Resolve type aliases to the type they point to in intra-doc links
Browse files Browse the repository at this point in the history
  • Loading branch information
LeSeulArtichaut committed Jun 21, 2021
1 parent 3044419 commit dd90900
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
51 changes: 46 additions & 5 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,44 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
})
}

/// Convert a DefId to a Res, where possible.
///
/// This is used for resolving type aliases.
fn def_id_to_res(&self, ty_id: DefId) -> Option<Res> {
use PrimitiveType::*;
Some(match *self.cx.tcx.type_of(ty_id).kind() {
ty::Bool => Res::Primitive(Bool),
ty::Char => Res::Primitive(Char),
ty::Int(ity) => Res::Primitive(ity.into()),
ty::Uint(uty) => Res::Primitive(uty.into()),
ty::Float(fty) => Res::Primitive(fty.into()),
ty::Str => Res::Primitive(Str),
ty::Tuple(ref tys) if tys.is_empty() => Res::Primitive(Unit),
ty::Tuple(_) => Res::Primitive(Tuple),
ty::Array(..) => Res::Primitive(Array),
ty::Slice(_) => Res::Primitive(Slice),
ty::RawPtr(_) => Res::Primitive(RawPointer),
ty::Ref(..) => Res::Primitive(Reference),
ty::FnDef(..) => panic!("type alias to a function definition"),
ty::FnPtr(_) => Res::Primitive(Fn),
ty::Never => Res::Primitive(Never),
ty::Adt(&ty::AdtDef { did, .. }, _) | ty::Foreign(did) => {
Res::Def(self.cx.tcx.def_kind(did), did)
}
ty::Projection(_)
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(_)
| ty::Opaque(..)
| ty::Dynamic(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(_)
| ty::Error(_) => return None,
})
}

/// Returns:
/// - None if no associated item was found
/// - Some((_, _, Some(_))) if an item was found and should go through a side channel
Expand All @@ -559,12 +597,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {

match root_res {
Res::Primitive(prim) => self.resolve_primitive_associated_item(prim, ns, item_name),
Res::Def(DefKind::TyAlias, did) => {
// Resolve the link on the type the alias points to.
// FIXME: if the associated item is defined directly on the type alias,
// it will show up on its documentation page, we should link there instead.
let res = self.def_id_to_res(did)?;
self.resolve_associated_item(res, item_name, ns, module_id)
}
Res::Def(
DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::TyAlias
| DefKind::ForeignTy,
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::ForeignTy,
did,
) => {
debug!("looking for associated item named {} for item {:?}", item_name, did);
Expand Down
19 changes: 19 additions & 0 deletions src/test/rustdoc/intra-doc/type-alias.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Regression test for issue #86120.

#![deny(broken_intra_doc_links)]
#![crate_name = "foo"]

pub struct Foo;

/// You should really try [`Self::bar`]!
pub type Bar = Foo;

impl Bar {
pub fn bar() {}
}

/// The minimum is [`Self::MIN`].
pub type Int = i32;

// @has foo/type.Bar.html '//a[@href="struct.Foo.html#method.bar"]' 'Self::bar'
// @has foo/type.Int.html '//a[@href="{{channel}}/std/primitive.i32.html#associatedconstant.MIN"]' 'Self::MIN'

0 comments on commit dd90900

Please sign in to comment.