Skip to content

Commit a8c4911

Browse files
Fix invalid trait generation
1 parent 7d68b3d commit a8c4911

File tree

3 files changed

+147
-32
lines changed

3 files changed

+147
-32
lines changed

src/librustdoc/clean/mod.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,43 @@ impl Item {
347347
pub fn stable_since(&self) -> Option<&str> {
348348
self.stability.as_ref().map(|s| &s.since[..])
349349
}
350+
351+
// Huge simplification over item in order to get only information we care about.
352+
pub fn to_resolved_path(&self) -> Option<Type> {
353+
if let Some(ref n) = self.name {
354+
let (lifetimes, ty_params) = match self.inner {
355+
StructItem(ref s) => (s.generics.lifetimes.clone(),
356+
s.generics.type_params.iter().map(|ref x| {
357+
TypeBinding {
358+
name: String::new(),
359+
ty: Type::Generic(x.name.clone()),
360+
}
361+
}).collect()),
362+
_ => (vec!(), vec!())
363+
};
364+
365+
Some(ResolvedPath {
366+
path: Path {
367+
global: false,
368+
segments: vec![
369+
PathSegment {
370+
name: n.clone(),
371+
params: PathParameters::AngleBracketed {
372+
lifetimes: lifetimes,
373+
types: vec!(),
374+
bindings: ty_params,
375+
},
376+
}
377+
],
378+
},
379+
typarams: None,
380+
did: self.def_id,
381+
is_generic: false,
382+
})
383+
} else {
384+
None
385+
}
386+
}
350387
}
351388

352389
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -2903,7 +2940,7 @@ fn lang_struct(cx: &DocContext, did: Option<DefId>,
29032940
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Debug)]
29042941
pub struct TypeBinding {
29052942
pub name: String,
2906-
pub ty: Type
2943+
pub ty: Type,
29072944
}
29082945

29092946
impl Clean<TypeBinding> for hir::TypeBinding {

src/librustdoc/html/format.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,11 @@ impl fmt::Display for clean::ViewListIdent {
766766

767767
impl fmt::Display for clean::TypeBinding {
768768
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
769-
write!(f, "{}={}", self.name, self.ty)
769+
if self.name.len() > 0 {
770+
write!(f, "{}={}", self.name, self.ty)
771+
} else {
772+
write!(f, "{}", self.ty)
773+
}
770774
}
771775
}
772776

src/librustdoc/html/render.rs

+104-30
Original file line numberDiff line numberDiff line change
@@ -1965,33 +1965,33 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
19651965
} else {
19661966
// FIXME: we should be using a derived_id for the Anchors here
19671967
write!(w, "{{\n")?;
1968-
for t in &types {
1968+
for ty in &types {
19691969
write!(w, " ")?;
1970-
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
1970+
render_assoc_item(w, ty, AssocItemLink::Anchor(None), it, Some(t))?;
19711971
write!(w, ";\n")?;
19721972
}
19731973
if !types.is_empty() && !consts.is_empty() {
19741974
w.write_str("\n")?;
19751975
}
1976-
for t in &consts {
1976+
for ty in &consts {
19771977
write!(w, " ")?;
1978-
render_assoc_item(w, t, AssocItemLink::Anchor(None))?;
1978+
render_assoc_item(w, ty, AssocItemLink::Anchor(None), it, Some(t))?;
19791979
write!(w, ";\n")?;
19801980
}
19811981
if !consts.is_empty() && !required.is_empty() {
19821982
w.write_str("\n")?;
19831983
}
19841984
for m in &required {
19851985
write!(w, " ")?;
1986-
render_assoc_item(w, m, AssocItemLink::Anchor(None))?;
1986+
render_assoc_item(w, m, AssocItemLink::Anchor(None), it, Some(t))?;
19871987
write!(w, ";\n")?;
19881988
}
19891989
if !required.is_empty() && !provided.is_empty() {
19901990
w.write_str("\n")?;
19911991
}
19921992
for m in &provided {
19931993
write!(w, " ")?;
1994-
render_assoc_item(w, m, AssocItemLink::Anchor(None))?;
1994+
render_assoc_item(w, m, AssocItemLink::Anchor(None), it, Some(t))?;
19951995
write!(w, " {{ ... }}\n")?;
19961996
}
19971997
write!(w, "}}")?;
@@ -2001,16 +2001,17 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
20012001
// Trait documentation
20022002
document(w, cx, it)?;
20032003

2004-
fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::Item)
2004+
fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, item: &clean::Item,
2005+
t: &clean::Trait)
20052006
-> fmt::Result {
20062007
let name = m.name.as_ref().unwrap();
20072008
let id = derive_id(format!("{}.{}", shortty(m), name));
20082009
write!(w, "<h3 id='{id}' class='method stab {stab}'><code>",
20092010
id = id,
20102011
stab = m.stability_class())?;
2011-
render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)))?;
2012+
render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), item, Some(t))?;
20122013
write!(w, "</code>")?;
2013-
render_stability_since(w, m, t)?;
2014+
render_stability_since(w, m, item)?;
20142015
write!(w, "</h3>")?;
20152016
document(w, cx, m)?;
20162017
Ok(())
@@ -2021,8 +2022,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
20212022
<h2 id='associated-types'>Associated Types</h2>
20222023
<div class='methods'>
20232024
")?;
2024-
for t in &types {
2025-
trait_item(w, cx, *t, it)?;
2025+
for ty in &types {
2026+
trait_item(w, cx, *ty, it, t)?;
20262027
}
20272028
write!(w, "</div>")?;
20282029
}
@@ -2032,8 +2033,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
20322033
<h2 id='associated-const'>Associated Constants</h2>
20332034
<div class='methods'>
20342035
")?;
2035-
for t in &consts {
2036-
trait_item(w, cx, *t, it)?;
2036+
for ty in &consts {
2037+
trait_item(w, cx, *ty, it, t)?;
20372038
}
20382039
write!(w, "</div>")?;
20392040
}
@@ -2045,7 +2046,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
20452046
<div class='methods'>
20462047
")?;
20472048
for m in &required {
2048-
trait_item(w, cx, *m, it)?;
2049+
trait_item(w, cx, *m, it, t)?;
20492050
}
20502051
write!(w, "</div>")?;
20512052
}
@@ -2055,7 +2056,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
20552056
<div class='methods'>
20562057
")?;
20572058
for m in &provided {
2058-
trait_item(w, cx, *m, it)?;
2059+
trait_item(w, cx, *m, it, t)?;
20592060
}
20602061
write!(w, "</div>")?;
20612062
}
@@ -2165,18 +2166,23 @@ fn render_stability_since(w: &mut fmt::Formatter,
21652166

21662167
fn render_assoc_item(w: &mut fmt::Formatter,
21672168
item: &clean::Item,
2168-
link: AssocItemLink) -> fmt::Result {
2169+
link: AssocItemLink,
2170+
c: &clean::Item,
2171+
trait_: Option<&clean::Trait>) -> fmt::Result {
21692172
fn method(w: &mut fmt::Formatter,
21702173
meth: &clean::Item,
21712174
unsafety: hir::Unsafety,
21722175
constness: hir::Constness,
21732176
abi: abi::Abi,
21742177
g: &clean::Generics,
21752178
d: &clean::FnDecl,
2176-
link: AssocItemLink)
2179+
link: AssocItemLink,
2180+
trait_: Option<&clean::Trait>,
2181+
item: &clean::Item)
21772182
-> fmt::Result {
21782183
let name = meth.name.as_ref().unwrap();
21792184
let anchor = format!("#{}.{}", shortty(meth), name);
2185+
let mut d = d.clone();
21802186
let href = match link {
21812187
AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
21822188
AssocItemLink::Anchor(None) => anchor,
@@ -2197,6 +2203,69 @@ fn render_assoc_item(w: &mut fmt::Formatter,
21972203
UnstableFeatures::Allow => constness,
21982204
_ => hir::Constness::NotConst
21992205
};
2206+
if let Some(trait_) = trait_ {
2207+
if (item.is_struct() || item.is_enum()) &&
2208+
d.inputs.values.iter().any(|ref x| {
2209+
match x.type_ {
2210+
clean::Type::BorrowedRef { ref type_, .. } => {
2211+
match *type_.clone() {
2212+
clean::Type::Generic(_) => true,
2213+
_ => false,
2214+
}
2215+
}
2216+
clean::Type::Generic(_) => true,
2217+
_ => false,
2218+
}
2219+
}) {
2220+
let generics = &trait_.generics;
2221+
let values = d.inputs.values.clone();
2222+
2223+
d.inputs.values = values.iter().map(|ref x| {
2224+
let mut new_v = None;
2225+
match x.type_ {
2226+
clean::Type::BorrowedRef { ref type_, ref mutability, ref lifetime } => {
2227+
match *type_.clone() {
2228+
clean::Type::Generic(ref name) => {
2229+
for ty in generics.type_params.iter() {
2230+
if &ty.name == name &&
2231+
ty.default == Some(clean::Type::Generic("Self"
2232+
.to_owned())) {
2233+
if let Some(resolved) = item.to_resolved_path() {
2234+
new_v = Some(
2235+
clean::Type::BorrowedRef {
2236+
type_: Box::new(resolved),
2237+
mutability: mutability.clone(),
2238+
lifetime: lifetime.clone(),
2239+
});
2240+
}
2241+
break;
2242+
}
2243+
}
2244+
}
2245+
_ => {},
2246+
}
2247+
}
2248+
clean::Type::Generic(ref name) => {
2249+
for ty in generics.type_params.iter() {
2250+
if &ty.name == name &&
2251+
ty.default == Some(clean::Type::Generic("Self".to_owned())) {
2252+
if let Some(resolved) = item.to_resolved_path() {
2253+
new_v = Some(resolved);
2254+
}
2255+
break;
2256+
}
2257+
}
2258+
}
2259+
_ => {}
2260+
}
2261+
let mut x = (*x).clone();
2262+
if let Some(n) = new_v {
2263+
x.type_ = n;
2264+
}
2265+
x
2266+
}).collect();
2267+
}
2268+
}
22002269
write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
22012270
{generics}{decl}{where_clause}",
22022271
ConstnessSpace(vis_constness),
@@ -2205,19 +2274,19 @@ fn render_assoc_item(w: &mut fmt::Formatter,
22052274
href = href,
22062275
name = name,
22072276
generics = *g,
2208-
decl = Method(d),
2277+
decl = Method(&d),
22092278
where_clause = WhereClause(g))
22102279
}
22112280
match item.inner {
22122281
clean::StrippedItem(..) => Ok(()),
22132282
clean::TyMethodItem(ref m) => {
22142283
method(w, item, m.unsafety, hir::Constness::NotConst,
2215-
m.abi, &m.generics, &m.decl, link)
2284+
m.abi, &m.generics, &m.decl, link, trait_, c)
22162285
}
22172286
clean::MethodItem(ref m) => {
22182287
method(w, item, m.unsafety, m.constness,
22192288
m.abi, &m.generics, &m.decl,
2220-
link)
2289+
link, trait_, c)
22212290
}
22222291
clean::AssociatedConstItem(ref ty, ref default) => {
22232292
assoc_const(w, item, ty, default.as_ref(), link)
@@ -2481,7 +2550,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
24812550
};
24822551
for i in &non_trait {
24832552
render_impl(w, cx, i, AssocItemLink::Anchor(None), render_header,
2484-
containing_item.stable_since())?;
2553+
containing_item)?;
24852554
}
24862555
}
24872556
if let AssocItemRender::DerefFor { .. } = what {
@@ -2502,7 +2571,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
25022571
for i in &manual {
25032572
let did = i.trait_did().unwrap();
25042573
let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
2505-
render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?;
2574+
render_impl(w, cx, i, assoc_link, true, containing_item)?;
25062575
}
25072576
if !derived.is_empty() {
25082577
write!(w, "<h3 id='derived_implementations'>\
@@ -2512,7 +2581,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
25122581
let did = i.trait_did().unwrap();
25132582
let assoc_link = AssocItemLink::GotoSource(did,
25142583
&i.inner_impl().provided_trait_methods);
2515-
render_impl(w, cx, i, assoc_link, true, containing_item.stable_since())?;
2584+
render_impl(w, cx, i, assoc_link, true, containing_item)?;
25162585
}
25172586
}
25182587
}
@@ -2546,7 +2615,8 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
25462615
// otherwise. If render_header is false, we will avoid rendering static
25472616
// methods, since they are not accessible for the type implementing `Deref`
25482617
fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink,
2549-
render_header: bool, outer_version: Option<&str>) -> fmt::Result {
2618+
render_header: bool, item: &clean::Item) -> fmt::Result {
2619+
let outer_version = item.stable_since();
25502620
if render_header {
25512621
write!(w, "<h3 class='impl'><span class='in-band'><code>{}</code>", i.inner_impl())?;
25522622
write!(w, "</span><span class='out-of-band'>")?;
@@ -2570,7 +2640,8 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
25702640
fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
25712641
link: AssocItemLink, render_static: bool,
25722642
is_default_item: bool, outer_version: Option<&str>,
2573-
trait_: Option<&clean::Trait>) -> fmt::Result {
2643+
trait_: Option<&clean::Trait>,
2644+
i: &clean::Item) -> fmt::Result {
25742645
let shortty = shortty(item);
25752646
let name = item.name.as_ref().unwrap();
25762647

@@ -2587,7 +2658,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
25872658
let id = derive_id(format!("{}.{}", shortty, name));
25882659
write!(w, "<h4 id='{}' class='{}'>", id, shortty)?;
25892660
write!(w, "<code>")?;
2590-
render_assoc_item(w, item, link.anchor(&id))?;
2661+
render_assoc_item(w, item, link.anchor(&id), i, trait_)?;
25912662
write!(w, "</code>")?;
25922663
render_stability_since_raw(w, item.stable_since(), outer_version)?;
25932664
write!(w, "</h4>\n")?;
@@ -2649,15 +2720,17 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
26492720
write!(w, "<div class='impl-items'>")?;
26502721
for trait_item in &i.inner_impl().items {
26512722
doctraititem(w, cx, trait_item, link, render_header,
2652-
false, outer_version, trait_)?;
2723+
false, outer_version, trait_, item)?;
26532724
}
26542725

26552726
fn render_default_items(w: &mut fmt::Formatter,
26562727
cx: &Context,
26572728
t: &clean::Trait,
26582729
i: &clean::Impl,
26592730
render_static: bool,
2660-
outer_version: Option<&str>) -> fmt::Result {
2731+
outer_version: Option<&str>,
2732+
trait_: &clean::Trait,
2733+
item: &clean::Item) -> fmt::Result {
26612734
for trait_item in &t.items {
26622735
let n = trait_item.name.clone();
26632736
if i.items.iter().find(|m| m.name == n).is_some() {
@@ -2667,15 +2740,16 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
26672740
let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods);
26682741

26692742
doctraititem(w, cx, trait_item, assoc_link, render_static, true,
2670-
outer_version, None)?;
2743+
outer_version, Some(trait_), item)?;
26712744
}
26722745
Ok(())
26732746
}
26742747

26752748
// If we've implemented a trait, then also emit documentation for all
26762749
// default items which weren't overridden in the implementation block.
26772750
if let Some(t) = trait_ {
2678-
render_default_items(w, cx, t, &i.inner_impl(), render_header, outer_version)?;
2751+
render_default_items(w, cx, t, &i.inner_impl(), render_header, outer_version,
2752+
&t, item)?;
26792753
}
26802754
write!(w, "</div>")?;
26812755
Ok(())

0 commit comments

Comments
 (0)