Skip to content

rustdoc: Correct anchor for links to associated trait items #32461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 29, 2016
5 changes: 2 additions & 3 deletions src/doc/style/features/traits/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ explicitly implement to be used by this generic function.
* _Inference_. Since the type parameters to generic functions can usually be
inferred, generic functions can help cut down on verbosity in code where
explicit conversions or other method calls would usually be necessary. See the
[overloading/implicits use case](#use-case-limited-overloading-andor-implicit-conversions)
below.
overloading/implicits use case below.
* _Precise types_. Because generics give a _name_ to the specific type
implementing a trait, it is possible to be precise about places where that
exact type is required or produced. For example, a function
Expand All @@ -51,7 +50,7 @@ explicitly implement to be used by this generic function.
a `Vec<T>` contains elements of a single concrete type (and, indeed, the
vector representation is specialized to lay these out in line). Sometimes
heterogeneous collections are useful; see
[trait objects](#use-case-trait-objects) below.
trait objects below.
* _Signature verbosity_. Heavy use of generics can bloat function signatures.
**[Ed. note]** This problem may be mitigated by some language improvements; stay tuned.

Expand Down
4 changes: 2 additions & 2 deletions src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ pub trait Iterator {
/// `None`. Once `None` is encountered, `count()` returns the number of
/// times it called [`next()`].
///
/// [`next()`]: #method.next
/// [`next()`]: #tymethod.next
///
/// # Overflow Behavior
///
Expand Down Expand Up @@ -497,7 +497,7 @@ pub trait Iterator {
/// This method will evaluate the iterator `n` times, discarding those elements.
/// After it does so, it will call [`next()`] and return its value.
///
/// [`next()`]: #method.next
/// [`next()`]: #tymethod.next
///
/// Like most indexing operations, the count starts from zero, so `nth(0)`
/// returns the first value, `nth(1)` the second, and so on.
Expand Down
17 changes: 12 additions & 5 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use rustc::middle::const_eval;

use core::DocContext;
use doctree;
use clean::{self, Attributes};
use clean::{self, Attributes, GetDefId};

use super::{Clean, ToSource};

Expand Down Expand Up @@ -414,15 +414,22 @@ pub fn build_impl(cx: &DocContext,
clean::RegionBound(..) => unreachable!(),
}
});
if let Some(clean::ResolvedPath { did, .. }) = trait_ {
if Some(did) == cx.deref_trait_did.get() {
super::build_deref_target_impls(cx, &trait_items, ret);
}
if trait_.def_id() == cx.deref_trait_did.get() {
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 {
inner: clean::ImplItem(clean::Impl {
unsafety: hir::Unsafety::Normal, // FIXME: this should be decoded
derived: clean::detect_derived(&attrs),
provided_trait_methods: provided,
trait_: trait_,
for_: ty.ty.clean(cx),
generics: (&ty.generics, &predicates, subst::TypeSpace).clean(cx),
Expand Down
80 changes: 45 additions & 35 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use rustc::middle::stability;

use rustc_front::hir;

use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::path::PathBuf;
use std::rc::Rc;
use std::u32;
Expand Down Expand Up @@ -559,15 +559,9 @@ impl TyParamBound {
fn is_sized_bound(&self, cx: &DocContext) -> bool {
use rustc_front::hir::TraitBoundModifier as TBM;
if let Some(tcx) = cx.tcx_opt() {
let sized_did = match tcx.lang_items.sized_trait() {
Some(did) => did,
None => return false
};
if let TyParamBound::TraitBound(PolyTrait {
trait_: Type::ResolvedPath { did, .. }, ..
}, TBM::None) = *self {
if did == sized_did {
return true
if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
if trait_.def_id() == tcx.lang_items.sized_trait() {
return true;
}
}
}
Expand Down Expand Up @@ -724,15 +718,18 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
}
}

TraitBound(PolyTrait {
trait_: ResolvedPath {
path: path,
typarams: None,
did: self.def_id,
is_generic: false,
TraitBound(
PolyTrait {
trait_: ResolvedPath {
path: path,
typarams: None,
did: self.def_id,
is_generic: false,
},
lifetimes: late_bounds,
},
lifetimes: late_bounds
}, hir::TraitBoundModifier::None)
hir::TraitBoundModifier::None
)
}
}

Expand Down Expand Up @@ -932,7 +929,6 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
&'a ty::GenericPredicates<'tcx>,
subst::ParamSpace) {
fn clean(&self, cx: &DocContext) -> Generics {
use std::collections::HashSet;
use self::WherePredicate as WP;

let (gens, preds, space) = *self;
Expand Down Expand Up @@ -1486,6 +1482,16 @@ pub enum TypeKind {
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 {
pub fn primitive_type(&self) -> Option<PrimitiveType> {
match *self {
Expand All @@ -1499,7 +1505,9 @@ impl Type {
_ => None,
}
}
}

impl GetDefId for Type {
fn def_id(&self) -> Option<DefId> {
match *self {
ResolvedPath { did, .. } => Some(did),
Expand Down Expand Up @@ -1884,18 +1892,11 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
Item {
source: Span::empty(),
name: Some(field.name.clean(cx)),
attrs: Vec::new(),
attrs: cx.tcx().get_attrs(field.did).clean(cx),
visibility: Some(field.vis),
// FIXME: this is not accurate, we need an id for
// the specific field but we're using the id
// for the whole variant. Thus we read the
// stability from the whole variant as well.
// Struct variants are experimental and need
// more infrastructure work before we can get
// at the needed information here.
def_id: self.did,
stability: get_stability(cx, self.did),
deprecation: get_deprecation(cx, self.did),
def_id: field.did,
stability: get_stability(cx, field.did),
deprecation: get_deprecation(cx, field.did),
inner: StructFieldItem(
TypedStructField(field.unsubst_ty().clean(cx))
)
Expand All @@ -1908,7 +1909,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
name: Some(self.name.clean(cx)),
attrs: inline::load_attrs(cx, cx.tcx(), self.did),
source: Span::empty(),
visibility: Some(hir::Public),
visibility: Some(hir::Inherited),
def_id: self.did,
inner: VariantItem(Variant { kind: kind }),
stability: get_stability(cx, self.did),
Expand Down Expand Up @@ -2208,6 +2209,7 @@ impl Clean<ImplPolarity> for hir::ImplPolarity {
pub struct Impl {
pub unsafety: hir::Unsafety,
pub generics: Generics,
pub provided_trait_methods: HashSet<String>,
pub trait_: Option<Type>,
pub for_: Type,
pub items: Vec<Item>,
Expand All @@ -2227,12 +2229,19 @@ impl Clean<Vec<Item>> for doctree::Impl {

// 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.
if let Some(ResolvedPath { did, .. }) = trait_ {
if Some(did) == cx.deref_trait_did.get() {
build_deref_target_impls(cx, &items, &mut ret);
}
if trait_.def_id() == cx.deref_trait_did.get() {
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 {
name: None,
attrs: self.attrs.clean(cx),
Expand All @@ -2244,6 +2253,7 @@ impl Clean<Vec<Item>> for doctree::Impl {
inner: ImplItem(Impl {
unsafety: self.unsafety,
generics: self.generics.clean(cx),
provided_trait_methods: provided,
trait_: trait_,
for_: self.for_.clean(cx),
items: items,
Expand Down
6 changes: 3 additions & 3 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,15 +607,15 @@ mod tests {
fn issue_17736() {
let markdown = "# title";
format!("{}", Markdown(markdown));
reset_ids();
reset_ids(true);
}

#[test]
fn test_header() {
fn t(input: &str, expect: &str) {
let output = format!("{}", Markdown(input));
assert_eq!(output, expect);
reset_ids();
reset_ids(true);
}

t("# Foo bar", "\n<h1 id='foo-bar' class='section-header'>\
Expand Down Expand Up @@ -654,7 +654,7 @@ mod tests {
<a href='#panics-1'>Panics</a></h1>");
};
test();
reset_ids();
reset_ids(true);
test();
}

Expand Down
Loading