Skip to content

Commit

Permalink
Auto merge of #52368 - GuillaumeGomez:intra_doc_link_resolution_failu…
Browse files Browse the repository at this point in the history
…re-documented, r=QuietMisdreavus

Add "self" intra-link support

Fixes #49583.

r? @QuietMisdreavus
  • Loading branch information
bors committed Jul 22, 2018
2 parents aeca042 + 88f2643 commit d3b3bc5
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 4 deletions.
61 changes: 59 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use self::Visibility::{Public, Inherited};

use rustc_target::spec::abi::Abi;
use syntax;
use syntax::ast::{self, AttrStyle, NodeId, Ident};
use syntax::ast::{self, AttrStyle, Name, NodeId, Ident};
use syntax::attr;
use syntax::codemap::{dummy_spanned, Spanned};
use syntax::feature_gate::UnstableFeatures;
Expand All @@ -39,6 +39,7 @@ use rustc::hir::{self, GenericArg, HirVec};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::def_id::DefIndexAddressSpace;
use rustc::hir::map::Node;
use rustc::ty::subst::Substs;
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
use rustc::middle::stability;
Expand Down Expand Up @@ -584,10 +585,23 @@ impl Clean<Item> for doctree::Module {
.next()
.map_or(true, |a| a.style == AttrStyle::Inner) {
// inner doc comment, use the module's own scope for resolution
if self.id != NodeId::new(0) {
*cx.current_item_name.borrow_mut() = Some(cx.tcx.hir.name(self.id));
} else {
*cx.current_item_name.borrow_mut() = None;
}
cx.mod_ids.borrow_mut().push(self.id);
self.attrs.clean(cx)
} else {
// outer doc comment, use its parent's scope
match cx.mod_ids.borrow().last() {
Some(parent) if *parent != NodeId::new(0) => {
*cx.current_item_name.borrow_mut() = Some(cx.tcx.hir.name(*parent));
}
_ => {
*cx.current_item_name.borrow_mut() = None;
}
}
let attrs = self.attrs.clean(cx);
cx.mod_ids.borrow_mut().push(self.id);
attrs
Expand Down Expand Up @@ -1165,11 +1179,17 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option
};

let mut path = if let Some(second) = split.next() {
second
second.to_owned()
} else {
return Err(())
};

if path == "self" || path == "Self" {
if let Some(name) = *cx.current_item_name.borrow() {
path = name.to_string();
}
}

let ty = cx.resolver.borrow_mut()
.with_scope(*id,
|resolver| {
Expand Down Expand Up @@ -2143,6 +2163,8 @@ impl Clean<Item> for doctree::Function {
let (generics, decl) = enter_impl_trait(cx, || {
(self.generics.clean(cx), (&self.decl, self.body).clean(cx))
});

*cx.current_item_name.borrow_mut() = Some(self.name);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -2321,6 +2343,7 @@ pub struct Trait {

impl Clean<Item> for doctree::Trait {
fn clean(&self, cx: &DocContext) -> Item {
*cx.current_item_name.borrow_mut() = Some(self.name);
let attrs = self.attrs.clean(cx);
let is_spotlight = attrs.has_doc_flag("spotlight");
Item {
Expand Down Expand Up @@ -2392,6 +2415,7 @@ impl Clean<Item> for hir::TraitItem {
AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
}
};
*cx.current_item_name.borrow_mut() = Some(self.ident.name);
Item {
name: Some(self.ident.name.clean(cx)),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -2424,6 +2448,7 @@ impl Clean<Item> for hir::ImplItem {
generics: Generics::default(),
}, true),
};
*cx.current_item_name.borrow_mut() = Some(self.ident.name);
Item {
name: Some(self.ident.name.clean(cx)),
source: self.span.clean(cx),
Expand Down Expand Up @@ -3217,6 +3242,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {

impl Clean<Item> for hir::StructField {
fn clean(&self, cx: &DocContext) -> Item {
*cx.current_item_name.borrow_mut() = Some(self.ident.name);
Item {
name: Some(self.ident.name).clean(cx),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -3295,6 +3321,7 @@ impl Clean<Vec<Item>> for doctree::Struct {
let name = self.name.clean(cx);
let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone());

*cx.current_item_name.borrow_mut() = Some(self.name);
ret.push(Item {
name: Some(name),
attrs: self.attrs.clean(cx),
Expand All @@ -3320,6 +3347,7 @@ impl Clean<Vec<Item>> for doctree::Union {
let name = self.name.clean(cx);
let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone());

*cx.current_item_name.borrow_mut() = Some(self.name);
ret.push(Item {
name: Some(name),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -3372,6 +3400,7 @@ impl Clean<Vec<Item>> for doctree::Enum {
let name = self.name.clean(cx);
let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone());

*cx.current_item_name.borrow_mut() = Some(self.name);
ret.push(Item {
name: Some(name),
attrs: self.attrs.clean(cx),
Expand All @@ -3398,6 +3427,7 @@ pub struct Variant {

impl Clean<Item> for doctree::Variant {
fn clean(&self, cx: &DocContext) -> Item {
*cx.current_item_name.borrow_mut() = Some(self.name);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -3693,6 +3723,7 @@ pub struct Typedef {

impl Clean<Item> for doctree::Typedef {
fn clean(&self, cx: &DocContext) -> Item {
*cx.current_item_name.borrow_mut() = Some(self.name);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -3768,6 +3799,7 @@ pub struct Static {
impl Clean<Item> for doctree::Static {
fn clean(&self, cx: &DocContext) -> Item {
debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
*cx.current_item_name.borrow_mut() = Some(self.name);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
Expand All @@ -3793,6 +3825,7 @@ pub struct Constant {

impl Clean<Item> for doctree::Constant {
fn clean(&self, cx: &DocContext) -> Item {
*cx.current_item_name.borrow_mut() = Some(self.name);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -3862,6 +3895,23 @@ pub fn get_auto_traits_with_def_id(cx: &DocContext, id: DefId) -> Vec<Item> {
finder.get_with_def_id(id)
}

fn get_name_if_possible(cx: &DocContext, node: NodeId) -> Option<Name> {
match cx.tcx.hir.get(node) {
Node::NodeItem(_) |
Node::NodeForeignItem(_) |
Node::NodeImplItem(_) |
Node::NodeTraitItem(_) |
Node::NodeVariant(_) |
Node::NodeField(_) |
Node::NodeLifetime(_) |
Node::NodeGenericParam(_) |
Node::NodeBinding(&hir::Pat { node: hir::PatKind::Binding(_,_,_,_), .. }) |
Node::NodeStructCtor(_) => {}
_ => return None,
}
Some(cx.tcx.hir.name(node))
}

impl Clean<Vec<Item>> for doctree::Impl {
fn clean(&self, cx: &DocContext) -> Vec<Item> {
let mut ret = Vec::new();
Expand All @@ -3881,6 +3931,7 @@ impl Clean<Vec<Item>> for doctree::Impl {
.collect()
}).unwrap_or(FxHashSet());

*cx.current_item_name.borrow_mut() = get_name_if_possible(cx, self.for_.id);
ret.push(Item {
name: None,
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -3967,6 +4018,7 @@ fn build_deref_target_impls(cx: &DocContext,

impl Clean<Item> for doctree::ExternCrate {
fn clean(&self, cx: &DocContext) -> Item {
*cx.current_item_name.borrow_mut() = Some(self.name);
Item {
name: None,
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -4013,6 +4065,8 @@ impl Clean<Vec<Item>> for doctree::Import {
}
Import::Simple(name.clean(cx), resolve_use_source(cx, path))
};

*cx.current_item_name.borrow_mut() = Some(self.name);
vec![Item {
name: None,
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -4081,6 +4135,8 @@ impl Clean<Item> for hir::ForeignItem {
ForeignTypeItem
}
};

*cx.current_item_name.borrow_mut() = Some(self.name);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
Expand Down Expand Up @@ -4256,6 +4312,7 @@ pub struct Macro {
impl Clean<Item> for doctree::Macro {
fn clean(&self, cx: &DocContext) -> Item {
let name = self.name.clean(cx);
*cx.current_item_name.borrow_mut() = None;
Item {
name: Some(name.clone()),
attrs: self.attrs.clean(cx),
Expand Down
6 changes: 4 additions & 2 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::CStore;
use rustc_target::spec::TargetTriple;

use syntax::ast::NodeId;
use syntax::ast::{Name, NodeId};
use syntax::codemap;
use syntax::edition::Edition;
use syntax::feature_gate::UnstableFeatures;
Expand Down Expand Up @@ -82,7 +82,8 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
/// Maps (type_id, trait_id) -> auto trait impl
pub generated_synthetics: RefCell<FxHashSet<(DefId, DefId)>>
pub generated_synthetics: RefCell<FxHashSet<(DefId, DefId)>>,
pub current_item_name: RefCell<Option<Name>>,
}

impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> {
Expand Down Expand Up @@ -383,6 +384,7 @@ pub fn run_core(search_paths: SearchPaths,
fake_def_ids: RefCell::new(FxHashMap()),
all_fake_def_ids: RefCell::new(FxHashSet()),
generated_synthetics: RefCell::new(FxHashSet()),
current_item_name: RefCell::new(None),
};
debug!("crate: {:?}", tcx.hir.krate());

Expand Down
39 changes: 39 additions & 0 deletions src/test/rustdoc/intra-link-self.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "foo"]

// @has foo/index.html '//a/@href' '../foo/struct.Foo.html#method.new'
// @has foo/struct.Foo.html '//a/@href' '../foo/struct.Foo.html#method.new'

/// Use [`new`] to create a new instance.
///
/// [`new`]: Self::new
pub struct Foo;

impl Foo {
pub fn new() -> Self {
unimplemented!()
}
}

// @has foo/index.html '//a/@href' '../foo/struct.Bar.html#method.new2'
// @has foo/struct.Bar.html '//a/@href' '../foo/struct.Bar.html#method.new2'

/// Use [`new2`] to create a new instance.
///
/// [`new2`]: Self::new2
pub struct Bar;

impl Bar {
pub fn new2() -> Self {
unimplemented!()
}
}

0 comments on commit d3b3bc5

Please sign in to comment.