mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Correct anchor for links to associated trait items
This commit is contained in:
parent
dc1f6831eb
commit
3e33ef4c42
@ -26,7 +26,7 @@ use rustc::middle::const_eval;
|
|||||||
|
|
||||||
use core::DocContext;
|
use core::DocContext;
|
||||||
use doctree;
|
use doctree;
|
||||||
use clean::{self, Attributes};
|
use clean::{self, Attributes, GetDefId};
|
||||||
|
|
||||||
use super::{Clean, ToSource};
|
use super::{Clean, ToSource};
|
||||||
|
|
||||||
@ -414,15 +414,22 @@ pub fn build_impl(cx: &DocContext,
|
|||||||
clean::RegionBound(..) => unreachable!(),
|
clean::RegionBound(..) => unreachable!(),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if let Some(clean::ResolvedPath { did, .. }) = trait_ {
|
if trait_.def_id() == cx.deref_trait_did.get() {
|
||||||
if Some(did) == cx.deref_trait_did.get() {
|
|
||||||
super::build_deref_target_impls(cx, &trait_items, ret);
|
super::build_deref_target_impls(cx, &trait_items, ret);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
let provided = trait_.def_id().map(|did| {
|
||||||
|
cx.tcx().provided_trait_methods(did)
|
||||||
|
.into_iter()
|
||||||
|
.map(|meth| meth.name.to_string())
|
||||||
|
.collect()
|
||||||
|
}).unwrap_or(HashSet::new());
|
||||||
|
|
||||||
ret.push(clean::Item {
|
ret.push(clean::Item {
|
||||||
inner: clean::ImplItem(clean::Impl {
|
inner: clean::ImplItem(clean::Impl {
|
||||||
unsafety: hir::Unsafety::Normal, // FIXME: this should be decoded
|
unsafety: hir::Unsafety::Normal, // FIXME: this should be decoded
|
||||||
derived: clean::detect_derived(&attrs),
|
derived: clean::detect_derived(&attrs),
|
||||||
|
provided_trait_methods: provided,
|
||||||
trait_: trait_,
|
trait_: trait_,
|
||||||
for_: ty.ty.clean(cx),
|
for_: ty.ty.clean(cx),
|
||||||
generics: (&ty.generics, &predicates, subst::TypeSpace).clean(cx),
|
generics: (&ty.generics, &predicates, subst::TypeSpace).clean(cx),
|
||||||
|
@ -44,7 +44,7 @@ use rustc::middle::stability;
|
|||||||
|
|
||||||
use rustc_front::hir;
|
use rustc_front::hir;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@ -559,15 +559,9 @@ impl TyParamBound {
|
|||||||
fn is_sized_bound(&self, cx: &DocContext) -> bool {
|
fn is_sized_bound(&self, cx: &DocContext) -> bool {
|
||||||
use rustc_front::hir::TraitBoundModifier as TBM;
|
use rustc_front::hir::TraitBoundModifier as TBM;
|
||||||
if let Some(tcx) = cx.tcx_opt() {
|
if let Some(tcx) = cx.tcx_opt() {
|
||||||
let sized_did = match tcx.lang_items.sized_trait() {
|
if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
|
||||||
Some(did) => did,
|
if trait_.def_id() == tcx.lang_items.sized_trait() {
|
||||||
None => return false
|
return true;
|
||||||
};
|
|
||||||
if let TyParamBound::TraitBound(PolyTrait {
|
|
||||||
trait_: Type::ResolvedPath { did, .. }, ..
|
|
||||||
}, TBM::None) = *self {
|
|
||||||
if did == sized_did {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -724,15 +718,18 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TraitBound(PolyTrait {
|
TraitBound(
|
||||||
|
PolyTrait {
|
||||||
trait_: ResolvedPath {
|
trait_: ResolvedPath {
|
||||||
path: path,
|
path: path,
|
||||||
typarams: None,
|
typarams: None,
|
||||||
did: self.def_id,
|
did: self.def_id,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
},
|
},
|
||||||
lifetimes: late_bounds
|
lifetimes: late_bounds,
|
||||||
}, hir::TraitBoundModifier::None)
|
},
|
||||||
|
hir::TraitBoundModifier::None
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -932,7 +929,6 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
|
|||||||
&'a ty::GenericPredicates<'tcx>,
|
&'a ty::GenericPredicates<'tcx>,
|
||||||
subst::ParamSpace) {
|
subst::ParamSpace) {
|
||||||
fn clean(&self, cx: &DocContext) -> Generics {
|
fn clean(&self, cx: &DocContext) -> Generics {
|
||||||
use std::collections::HashSet;
|
|
||||||
use self::WherePredicate as WP;
|
use self::WherePredicate as WP;
|
||||||
|
|
||||||
let (gens, preds, space) = *self;
|
let (gens, preds, space) = *self;
|
||||||
@ -1486,6 +1482,16 @@ pub enum TypeKind {
|
|||||||
TypeTypedef,
|
TypeTypedef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait GetDefId {
|
||||||
|
fn def_id(&self) -> Option<DefId>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: GetDefId> GetDefId for Option<T> {
|
||||||
|
fn def_id(&self) -> Option<DefId> {
|
||||||
|
self.as_ref().and_then(|d| d.def_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
pub fn primitive_type(&self) -> Option<PrimitiveType> {
|
pub fn primitive_type(&self) -> Option<PrimitiveType> {
|
||||||
match *self {
|
match *self {
|
||||||
@ -1499,7 +1505,9 @@ impl Type {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetDefId for Type {
|
||||||
fn def_id(&self) -> Option<DefId> {
|
fn def_id(&self) -> Option<DefId> {
|
||||||
match *self {
|
match *self {
|
||||||
ResolvedPath { did, .. } => Some(did),
|
ResolvedPath { did, .. } => Some(did),
|
||||||
@ -2208,6 +2216,7 @@ impl Clean<ImplPolarity> for hir::ImplPolarity {
|
|||||||
pub struct Impl {
|
pub struct Impl {
|
||||||
pub unsafety: hir::Unsafety,
|
pub unsafety: hir::Unsafety,
|
||||||
pub generics: Generics,
|
pub generics: Generics,
|
||||||
|
pub provided_trait_methods: HashSet<String>,
|
||||||
pub trait_: Option<Type>,
|
pub trait_: Option<Type>,
|
||||||
pub for_: Type,
|
pub for_: Type,
|
||||||
pub items: Vec<Item>,
|
pub items: Vec<Item>,
|
||||||
@ -2227,11 +2236,18 @@ impl Clean<Vec<Item>> for doctree::Impl {
|
|||||||
|
|
||||||
// If this impl block is an implementation of the Deref trait, then we
|
// If this impl block is an implementation of the Deref trait, then we
|
||||||
// need to try inlining the target's inherent impl blocks as well.
|
// need to try inlining the target's inherent impl blocks as well.
|
||||||
if let Some(ResolvedPath { did, .. }) = trait_ {
|
if trait_.def_id() == cx.deref_trait_did.get() {
|
||||||
if Some(did) == cx.deref_trait_did.get() {
|
|
||||||
build_deref_target_impls(cx, &items, &mut ret);
|
build_deref_target_impls(cx, &items, &mut ret);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
let provided = trait_.def_id().and_then(|did| {
|
||||||
|
cx.tcx_opt().map(|tcx| {
|
||||||
|
tcx.provided_trait_methods(did)
|
||||||
|
.into_iter()
|
||||||
|
.map(|meth| meth.name.to_string())
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
}).unwrap_or(HashSet::new());
|
||||||
|
|
||||||
ret.push(Item {
|
ret.push(Item {
|
||||||
name: None,
|
name: None,
|
||||||
@ -2244,6 +2260,7 @@ impl Clean<Vec<Item>> for doctree::Impl {
|
|||||||
inner: ImplItem(Impl {
|
inner: ImplItem(Impl {
|
||||||
unsafety: self.unsafety,
|
unsafety: self.unsafety,
|
||||||
generics: self.generics.clean(cx),
|
generics: self.generics.clean(cx),
|
||||||
|
provided_trait_methods: provided,
|
||||||
trait_: trait_,
|
trait_: trait_,
|
||||||
for_: self.for_.clean(cx),
|
for_: self.for_.clean(cx),
|
||||||
items: items,
|
items: items,
|
||||||
|
@ -62,7 +62,7 @@ use rustc::middle::stability;
|
|||||||
use rustc::session::config::get_unstable_features_setting;
|
use rustc::session::config::get_unstable_features_setting;
|
||||||
use rustc_front::hir;
|
use rustc_front::hir;
|
||||||
|
|
||||||
use clean::{self, SelfTy, Attributes};
|
use clean::{self, SelfTy, Attributes, GetDefId};
|
||||||
use doctree;
|
use doctree;
|
||||||
use fold::DocFolder;
|
use fold::DocFolder;
|
||||||
use html::escape::Escape;
|
use html::escape::Escape;
|
||||||
@ -144,9 +144,7 @@ pub struct Impl {
|
|||||||
|
|
||||||
impl Impl {
|
impl Impl {
|
||||||
fn trait_did(&self) -> Option<DefId> {
|
fn trait_did(&self) -> Option<DefId> {
|
||||||
self.impl_.trait_.as_ref().and_then(|tr| {
|
self.impl_.trait_.def_id()
|
||||||
if let clean::ResolvedPath { did, .. } = *tr {Some(did)} else {None}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,7 +965,7 @@ impl DocFolder for Cache {
|
|||||||
|
|
||||||
// Collect all the implementors of traits.
|
// Collect all the implementors of traits.
|
||||||
if let clean::ImplItem(ref i) = item.inner {
|
if let clean::ImplItem(ref i) = item.inner {
|
||||||
if let Some(clean::ResolvedPath{ did, .. }) = i.trait_ {
|
if let Some(did) = i.trait_.def_id() {
|
||||||
self.implementors.entry(did).or_insert(vec![]).push(Implementor {
|
self.implementors.entry(did).or_insert(vec![]).push(Implementor {
|
||||||
def_id: item.def_id,
|
def_id: item.def_id,
|
||||||
stability: item.stability.clone(),
|
stability: item.stability.clone(),
|
||||||
@ -2066,10 +2064,11 @@ fn render_stability_since(w: &mut fmt::Formatter,
|
|||||||
render_stability_since_raw(w, item.stable_since(), containing_item.stable_since())
|
render_stability_since_raw(w, item.stable_since(), containing_item.stable_since())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
|
fn render_assoc_item(w: &mut fmt::Formatter,
|
||||||
|
item: &clean::Item,
|
||||||
link: AssocItemLink) -> fmt::Result {
|
link: AssocItemLink) -> fmt::Result {
|
||||||
fn method(w: &mut fmt::Formatter,
|
fn method(w: &mut fmt::Formatter,
|
||||||
it: &clean::Item,
|
meth: &clean::Item,
|
||||||
unsafety: hir::Unsafety,
|
unsafety: hir::Unsafety,
|
||||||
constness: hir::Constness,
|
constness: hir::Constness,
|
||||||
abi: abi::Abi,
|
abi: abi::Abi,
|
||||||
@ -2080,12 +2079,20 @@ fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
|
|||||||
-> fmt::Result {
|
-> fmt::Result {
|
||||||
use syntax::abi::Abi;
|
use syntax::abi::Abi;
|
||||||
|
|
||||||
let name = it.name.as_ref().unwrap();
|
let name = meth.name.as_ref().unwrap();
|
||||||
let anchor = format!("#{}.{}", shortty(it), name);
|
let anchor = format!("#{}.{}", shortty(meth), name);
|
||||||
let href = match link {
|
let href = match link {
|
||||||
AssocItemLink::Anchor => anchor,
|
AssocItemLink::Anchor => anchor,
|
||||||
AssocItemLink::GotoSource(did) => {
|
AssocItemLink::GotoSource(did, provided_methods) => {
|
||||||
href(did).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
|
// We're creating a link from an impl-item to the corresponding
|
||||||
|
// trait-item and need to map the anchored type accordingly.
|
||||||
|
let ty = if provided_methods.contains(name) {
|
||||||
|
ItemType::Method
|
||||||
|
} else {
|
||||||
|
ItemType::TyMethod
|
||||||
|
};
|
||||||
|
|
||||||
|
href(did).map(|p| format!("{}#{}.{}", p.0, ty, name)).unwrap_or(anchor)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let vis_constness = match get_unstable_features_setting() {
|
let vis_constness = match get_unstable_features_setting() {
|
||||||
@ -2106,21 +2113,21 @@ fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
|
|||||||
decl = Method(selfty, d),
|
decl = Method(selfty, d),
|
||||||
where_clause = WhereClause(g))
|
where_clause = WhereClause(g))
|
||||||
}
|
}
|
||||||
match meth.inner {
|
match item.inner {
|
||||||
clean::TyMethodItem(ref m) => {
|
clean::TyMethodItem(ref m) => {
|
||||||
method(w, meth, m.unsafety, hir::Constness::NotConst,
|
method(w, item, m.unsafety, hir::Constness::NotConst,
|
||||||
m.abi, &m.generics, &m.self_, &m.decl, link)
|
m.abi, &m.generics, &m.self_, &m.decl, link)
|
||||||
}
|
}
|
||||||
clean::MethodItem(ref m) => {
|
clean::MethodItem(ref m) => {
|
||||||
method(w, meth, m.unsafety, m.constness,
|
method(w, item, m.unsafety, m.constness,
|
||||||
m.abi, &m.generics, &m.self_, &m.decl,
|
m.abi, &m.generics, &m.self_, &m.decl,
|
||||||
link)
|
link)
|
||||||
}
|
}
|
||||||
clean::AssociatedConstItem(ref ty, ref default) => {
|
clean::AssociatedConstItem(ref ty, ref default) => {
|
||||||
assoc_const(w, meth, ty, default.as_ref())
|
assoc_const(w, item, ty, default.as_ref())
|
||||||
}
|
}
|
||||||
clean::AssociatedTypeItem(ref bounds, ref default) => {
|
clean::AssociatedTypeItem(ref bounds, ref default) => {
|
||||||
assoc_type(w, meth, bounds, default)
|
assoc_type(w, item, bounds, default)
|
||||||
}
|
}
|
||||||
_ => panic!("render_assoc_item called on non-associated-item")
|
_ => panic!("render_assoc_item called on non-associated-item")
|
||||||
}
|
}
|
||||||
@ -2338,9 +2345,9 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum AssocItemLink {
|
enum AssocItemLink<'a> {
|
||||||
Anchor,
|
Anchor,
|
||||||
GotoSource(DefId),
|
GotoSource(DefId, &'a HashSet<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AssocItemRender<'a> {
|
enum AssocItemRender<'a> {
|
||||||
@ -2383,12 +2390,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
|
|||||||
}
|
}
|
||||||
if !traits.is_empty() {
|
if !traits.is_empty() {
|
||||||
let deref_impl = traits.iter().find(|t| {
|
let deref_impl = traits.iter().find(|t| {
|
||||||
match *t.impl_.trait_.as_ref().unwrap() {
|
t.impl_.trait_.def_id() == c.deref_trait_did
|
||||||
clean::ResolvedPath { did, .. } => {
|
|
||||||
Some(did) == c.deref_trait_did
|
|
||||||
}
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if let Some(impl_) = deref_impl {
|
if let Some(impl_) = deref_impl {
|
||||||
render_deref_methods(w, cx, impl_, containing_item)?;
|
render_deref_methods(w, cx, impl_, containing_item)?;
|
||||||
@ -2400,8 +2402,8 @@ fn render_assoc_items(w: &mut fmt::Formatter,
|
|||||||
});
|
});
|
||||||
for i in &manual {
|
for i in &manual {
|
||||||
let did = i.trait_did().unwrap();
|
let did = i.trait_did().unwrap();
|
||||||
render_impl(w, cx, i, AssocItemLink::GotoSource(did), true,
|
let assoc_link = AssocItemLink::GotoSource(did, &i.impl_.provided_trait_methods);
|
||||||
containing_item.stable_since())?;
|
render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?;
|
||||||
}
|
}
|
||||||
if !derived.is_empty() {
|
if !derived.is_empty() {
|
||||||
write!(w, "<h3 id='derived_implementations'>\
|
write!(w, "<h3 id='derived_implementations'>\
|
||||||
@ -2409,8 +2411,8 @@ fn render_assoc_items(w: &mut fmt::Formatter,
|
|||||||
</h3>")?;
|
</h3>")?;
|
||||||
for i in &derived {
|
for i in &derived {
|
||||||
let did = i.trait_did().unwrap();
|
let did = i.trait_did().unwrap();
|
||||||
render_impl(w, cx, i, AssocItemLink::GotoSource(did), true,
|
let assoc_link = AssocItemLink::GotoSource(did, &i.impl_.provided_trait_methods);
|
||||||
containing_item.stable_since())?;
|
render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2427,9 +2429,9 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
|
|||||||
}
|
}
|
||||||
}).next().expect("Expected associated type binding");
|
}).next().expect("Expected associated type binding");
|
||||||
let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target };
|
let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target };
|
||||||
match *target {
|
if let Some(did) = target.def_id() {
|
||||||
clean::ResolvedPath { did, .. } => render_assoc_items(w, cx, container_item, did, what),
|
render_assoc_items(w, cx, container_item, did, what)
|
||||||
_ => {
|
} else {
|
||||||
if let Some(prim) = target.primitive_type() {
|
if let Some(prim) = target.primitive_type() {
|
||||||
if let Some(c) = cache().primitive_locations.get(&prim) {
|
if let Some(c) = cache().primitive_locations.get(&prim) {
|
||||||
let did = DefId { krate: *c, index: prim.to_def_index() };
|
let did = DefId { krate: *c, index: prim.to_def_index() };
|
||||||
@ -2438,7 +2440,6 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render_header is false when we are rendering a `Deref` impl and true
|
// Render_header is false when we are rendering a `Deref` impl and true
|
||||||
@ -2521,18 +2522,19 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
|
|
||||||
fn render_default_items(w: &mut fmt::Formatter,
|
fn render_default_items(w: &mut fmt::Formatter,
|
||||||
cx: &Context,
|
cx: &Context,
|
||||||
did: DefId,
|
|
||||||
t: &clean::Trait,
|
t: &clean::Trait,
|
||||||
i: &clean::Impl,
|
i: &clean::Impl,
|
||||||
render_static: bool,
|
render_static: bool,
|
||||||
outer_version: Option<&str>) -> fmt::Result {
|
outer_version: Option<&str>) -> fmt::Result {
|
||||||
for trait_item in &t.items {
|
for trait_item in &t.items {
|
||||||
let n = trait_item.name.clone();
|
let n = trait_item.name.clone();
|
||||||
if i.items.iter().find(|m| { m.name == n }).is_some() {
|
if i.items.iter().find(|m| m.name == n).is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
let did = i.trait_.as_ref().unwrap().def_id().unwrap();
|
||||||
|
let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods);
|
||||||
|
|
||||||
doctraititem(w, cx, trait_item, AssocItemLink::GotoSource(did), render_static,
|
doctraititem(w, cx, trait_item, assoc_link, render_static,
|
||||||
outer_version)?;
|
outer_version)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -2542,9 +2544,9 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
|
|||||||
// default methods which weren't overridden in the implementation block.
|
// default methods which weren't overridden in the implementation block.
|
||||||
// FIXME: this also needs to be done for associated types, whenever defaults
|
// FIXME: this also needs to be done for associated types, whenever defaults
|
||||||
// for them work.
|
// for them work.
|
||||||
if let Some(clean::ResolvedPath { did, .. }) = i.impl_.trait_ {
|
if let Some(did) = i.trait_did() {
|
||||||
if let Some(t) = cache().traits.get(&did) {
|
if let Some(t) = cache().traits.get(&did) {
|
||||||
render_default_items(w, cx, did, t, &i.impl_, render_header, outer_version)?;
|
render_default_items(w, cx, t, &i.impl_, render_header, outer_version)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(w, "</div>")?;
|
write!(w, "</div>")?;
|
||||||
|
@ -16,7 +16,7 @@ use std::string::String;
|
|||||||
use std::usize;
|
use std::usize;
|
||||||
use rustc_front::hir;
|
use rustc_front::hir;
|
||||||
|
|
||||||
use clean::{self, Attributes};
|
use clean::{self, Attributes, GetDefId};
|
||||||
use clean::Item;
|
use clean::Item;
|
||||||
use plugins;
|
use plugins;
|
||||||
use fold;
|
use fold;
|
||||||
@ -74,7 +74,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// Impls of stripped traits also don't need to exist
|
// Impls of stripped traits also don't need to exist
|
||||||
if let Some(clean::ResolvedPath { did, .. }) = *trait_ {
|
if let Some(did) = trait_.def_id() {
|
||||||
if self.stripped.contains(&did) {
|
if self.stripped.contains(&did) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -223,14 +223,11 @@ struct ImplStripper<'a>(&'a DefIdSet);
|
|||||||
impl<'a> fold::DocFolder for ImplStripper<'a> {
|
impl<'a> fold::DocFolder for ImplStripper<'a> {
|
||||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||||
if let clean::ImplItem(ref imp) = i.inner {
|
if let clean::ImplItem(ref imp) = i.inner {
|
||||||
match imp.trait_ {
|
if let Some(did) = imp.trait_.def_id() {
|
||||||
Some(clean::ResolvedPath{ did, .. }) => {
|
|
||||||
if did.is_local() && !self.0.contains(&did) {
|
if did.is_local() && !self.0.contains(&did) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(..) | None => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.fold_item_recur(i)
|
self.fold_item_recur(i)
|
||||||
}
|
}
|
||||||
|
39
src/test/rustdoc/issue-28478.rs
Normal file
39
src/test/rustdoc/issue-28478.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2016 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.
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
#![feature(associated_consts)]
|
||||||
|
|
||||||
|
// @has issue_28478/trait.Bar.html
|
||||||
|
pub trait Bar {
|
||||||
|
// @has - '//*[@id="associatedtype.Bar"]' 'type Bar = ()'
|
||||||
|
type Bar = ();
|
||||||
|
|
||||||
|
// @has - '//*[@id="associatedconstant.Baz"]' 'const Baz: usize = 7'
|
||||||
|
const Baz: usize = 7;
|
||||||
|
// @has - '//*[@id="tymethod.bar"]' 'fn bar'
|
||||||
|
fn bar();
|
||||||
|
// @has - '//*[@id="method.baz"]' 'fn baz'
|
||||||
|
fn baz() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has issue_28478/struct.Foo.html
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
// @has - '//*[@href="#method.foo"]' 'foo'
|
||||||
|
pub fn foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bar for Foo {
|
||||||
|
// @has - '//*[@href="../issue_28478/trait.Bar.html#tymethod.bar"]' 'bar'
|
||||||
|
fn bar() {}
|
||||||
|
// @has - '//*[@href="../issue_28478/trait.Bar.html#method.baz"]' 'baz'
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user