mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Make intra links work inside trait impl block
This commit is contained in:
parent
750db09fa8
commit
617c7cd9fa
@ -12,7 +12,8 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty;
|
||||
use rustc_resolve::ParentScope;
|
||||
use rustc_session::lint;
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
use std::ops::Range;
|
||||
@ -130,6 +131,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
current_item: &Option<String>,
|
||||
parent_id: Option<hir::HirId>,
|
||||
extra_fragment: &Option<String>,
|
||||
item_opt: Option<&Item>,
|
||||
) -> Result<(Res, Option<String>), ErrorKind> {
|
||||
let cx = self.cx;
|
||||
|
||||
@ -230,16 +232,44 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias,
|
||||
did,
|
||||
) => {
|
||||
let item = cx
|
||||
.tcx
|
||||
.inherent_impls(did)
|
||||
.iter()
|
||||
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
|
||||
.find(|item| item.ident.name == item_name);
|
||||
// We need item's parent to know if it's
|
||||
// trait impl or struct/enum/etc impl
|
||||
let item_parent = item_opt
|
||||
.and_then(|item| self.cx.as_local_hir_id(item.def_id))
|
||||
.and_then(|item_hir| {
|
||||
let parent_hir = self.cx.tcx.hir().get_parent_item(item_hir);
|
||||
self.cx.tcx.hir().find(parent_hir)
|
||||
});
|
||||
let item = match item_parent {
|
||||
Some(hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
|
||||
..
|
||||
})) => {
|
||||
// trait impl
|
||||
cx.tcx
|
||||
.associated_item_def_ids(self_ty.hir_id.owner)
|
||||
.iter()
|
||||
.map(|child| {
|
||||
let associated_item = cx.tcx.associated_item(*child);
|
||||
associated_item
|
||||
})
|
||||
.find(|child| child.ident.name == item_name)
|
||||
}
|
||||
_ => {
|
||||
// struct/enum/etc. impl
|
||||
cx.tcx
|
||||
.inherent_impls(did)
|
||||
.iter()
|
||||
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
|
||||
.find(|item| item.ident.name == item_name)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(item) = item {
|
||||
let out = match item.kind {
|
||||
ty::AssocKind::Fn if ns == ValueNS => "method",
|
||||
ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
|
||||
ty::AssocKind::Type if ns == ValueNS => "associatedtype",
|
||||
_ => return self.variant_field(path_str, current_item, module_id),
|
||||
};
|
||||
if extra_fragment.is_some() {
|
||||
@ -484,8 +514,14 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
|
||||
match kind {
|
||||
Some(ns @ ValueNS) => {
|
||||
match self.resolve(path_str, ns, ¤t_item, base_node, &extra_fragment)
|
||||
{
|
||||
match self.resolve(
|
||||
path_str,
|
||||
ns,
|
||||
¤t_item,
|
||||
base_node,
|
||||
&extra_fragment,
|
||||
None,
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(ErrorKind::ResolutionFailure) => {
|
||||
resolution_failure(cx, &item, path_str, &dox, link_range);
|
||||
@ -501,8 +537,14 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
Some(ns @ TypeNS) => {
|
||||
match self.resolve(path_str, ns, ¤t_item, base_node, &extra_fragment)
|
||||
{
|
||||
match self.resolve(
|
||||
path_str,
|
||||
ns,
|
||||
¤t_item,
|
||||
base_node,
|
||||
&extra_fragment,
|
||||
None,
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(ErrorKind::ResolutionFailure) => {
|
||||
resolution_failure(cx, &item, path_str, &dox, link_range);
|
||||
@ -526,6 +568,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
¤t_item,
|
||||
base_node,
|
||||
&extra_fragment,
|
||||
None,
|
||||
) {
|
||||
Err(ErrorKind::AnchorFailure(msg)) => {
|
||||
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
|
||||
@ -539,6 +582,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
¤t_item,
|
||||
base_node,
|
||||
&extra_fragment,
|
||||
Some(&item),
|
||||
) {
|
||||
Err(ErrorKind::AnchorFailure(msg)) => {
|
||||
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
|
||||
|
35
src/test/rustdoc/intra-link-trait-impl.rs
Normal file
35
src/test/rustdoc/intra-link-trait-impl.rs
Normal file
@ -0,0 +1,35 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
pub struct MyStruct;
|
||||
|
||||
impl MyTrait for MyStruct {
|
||||
|
||||
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedtype.AssoType'
|
||||
|
||||
/// [`AssoType`]
|
||||
///
|
||||
/// [`AssoType`]: MyStruct::AssoType
|
||||
type AssoType = u32;
|
||||
|
||||
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedconstant.ASSO_CONST'
|
||||
|
||||
/// [`ASSO_CONST`]
|
||||
///
|
||||
/// [`ASSO_CONST`]: MyStruct::ASSO_CONST
|
||||
const ASSO_CONST: i32 = 10;
|
||||
|
||||
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#method.trait_fn'
|
||||
|
||||
/// [`trait_fn`]
|
||||
///
|
||||
/// [`trait_fn`]: MyStruct::trait_fn
|
||||
fn trait_fn() { }
|
||||
}
|
||||
|
||||
pub trait MyTrait {
|
||||
type AssoType;
|
||||
const ASSO_CONST: i32 = 1;
|
||||
fn trait_fn();
|
||||
}
|
Loading…
Reference in New Issue
Block a user