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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/doc/style/features/traits/generics.md
Original file line number Diff line number Diff line change
@@ -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
@@ -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.

4 changes: 2 additions & 2 deletions src/libcore/iter.rs
Original file line number Diff line number Diff line change
@@ -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
///
@@ -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.
17 changes: 12 additions & 5 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
@@ -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};

@@ -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),
80 changes: 45 additions & 35 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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;
}
}
}
@@ -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
)
}
}

@@ -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;
@@ -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 {
@@ -1499,7 +1505,9 @@ impl Type {
_ => None,
}
}
}

impl GetDefId for Type {
fn def_id(&self) -> Option<DefId> {
match *self {
ResolvedPath { did, .. } => Some(did),
@@ -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))
)
@@ -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),
@@ -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>,
@@ -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),
@@ -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,
6 changes: 3 additions & 3 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
@@ -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'>\
@@ -654,7 +654,7 @@ mod tests {
<a href='#panics-1'>Panics</a></h1>");
};
test();
reset_ids();
reset_ids(true);
test();
}

Loading