Skip to content

Commit 59d1382

Browse files
committed
rustdoc: Render Sized? on traits and generics
Both `trait Foo for Sized?` and `<Sized? T>` are handled correctly. Fix #18515
1 parent de94f0a commit 59d1382

File tree

6 files changed

+43
-10
lines changed

6 files changed

+43
-10
lines changed

src/librustdoc/clean/inline.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,12 @@ pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
159159
}
160160
});
161161
let trait_def = ty::lookup_trait_def(tcx, did);
162-
let bounds = trait_def.bounds.clean(cx);
162+
let (bounds, default_unbound) = trait_def.bounds.clean(cx);
163163
clean::Trait {
164164
generics: (&def.generics, subst::TypeSpace).clean(cx),
165165
items: items.collect(),
166166
bounds: bounds,
167+
default_unbound: default_unbound
167168
}
168169
}
169170

src/librustdoc/clean/mod.rs

+29-8
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,9 @@ pub struct TyParam {
464464
pub name: String,
465465
pub did: ast::DefId,
466466
pub bounds: Vec<TyParamBound>,
467-
pub default: Option<Type>
467+
pub default: Option<Type>,
468+
/// An optional default bound on the parameter which is unbound, like `Sized?`
469+
pub default_unbound: Option<Type>
468470
}
469471

470472
impl Clean<TyParam> for ast::TyParam {
@@ -473,7 +475,8 @@ impl Clean<TyParam> for ast::TyParam {
473475
name: self.ident.clean(cx),
474476
did: ast::DefId { krate: ast::LOCAL_CRATE, node: self.id },
475477
bounds: self.bounds.clean(cx),
476-
default: self.default.clean(cx)
478+
default: self.default.clean(cx),
479+
default_unbound: self.unbound.clean(cx)
477480
}
478481
}
479482
}
@@ -482,11 +485,13 @@ impl<'tcx> Clean<TyParam> for ty::TypeParameterDef<'tcx> {
482485
fn clean(&self, cx: &DocContext) -> TyParam {
483486
cx.external_typarams.borrow_mut().as_mut().unwrap()
484487
.insert(self.def_id, self.name.clean(cx));
488+
let (bounds, default_unbound) = self.bounds.clean(cx);
485489
TyParam {
486490
name: self.name.clean(cx),
487491
did: self.def_id,
488-
bounds: self.bounds.clean(cx),
489-
default: self.default.clean(cx)
492+
bounds: bounds,
493+
default: self.default.clean(cx),
494+
default_unbound: default_unbound
490495
}
491496
}
492497
}
@@ -588,12 +593,16 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
588593
}
589594
}
590595

591-
impl<'tcx> Clean<Vec<TyParamBound>> for ty::ParamBounds<'tcx> {
592-
fn clean(&self, cx: &DocContext) -> Vec<TyParamBound> {
596+
// Returns (bounds, default_unbound)
597+
impl<'tcx> Clean<(Vec<TyParamBound>, Option<Type>)> for ty::ParamBounds<'tcx> {
598+
fn clean(&self, cx: &DocContext) -> (Vec<TyParamBound>, Option<Type>) {
593599
let mut v = Vec::new();
600+
let mut has_sized_bound = false;
594601
for b in self.builtin_bounds.iter() {
595602
if b != ty::BoundSized {
596603
v.push(b.clean(cx));
604+
} else {
605+
has_sized_bound = true;
597606
}
598607
}
599608
for t in self.trait_bounds.iter() {
@@ -602,7 +611,15 @@ impl<'tcx> Clean<Vec<TyParamBound>> for ty::ParamBounds<'tcx> {
602611
for r in self.region_bounds.iter().filter_map(|r| r.clean(cx)) {
603612
v.push(RegionBound(r));
604613
}
605-
return v;
614+
if has_sized_bound {
615+
(v, None)
616+
} else {
617+
let ty = match ty::BoundSized.clean(cx) {
618+
TraitBound(ty) => ty,
619+
_ => unreachable!()
620+
};
621+
(v, Some(ty))
622+
}
606623
}
607624
}
608625

@@ -950,6 +967,8 @@ pub struct Trait {
950967
pub items: Vec<TraitMethod>,
951968
pub generics: Generics,
952969
pub bounds: Vec<TyParamBound>,
970+
/// An optional default bound not required for `Self`, like `Sized?`
971+
pub default_unbound: Option<Type>
953972
}
954973

955974
impl Clean<Item> for doctree::Trait {
@@ -965,6 +984,7 @@ impl Clean<Item> for doctree::Trait {
965984
items: self.items.clean(cx),
966985
generics: self.generics.clean(cx),
967986
bounds: self.bounds.clean(cx),
987+
default_unbound: self.default_unbound.clean(cx)
968988
}),
969989
}
970990
}
@@ -2258,7 +2278,8 @@ impl Clean<Item> for ty::AssociatedType {
22582278
node: ast::DUMMY_NODE_ID
22592279
},
22602280
bounds: vec![],
2261-
default: None
2281+
default: None,
2282+
default_unbound: None
22622283
}),
22632284
visibility: None,
22642285
def_id: self.def_id,

src/librustdoc/doctree.rs

+1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ pub struct Trait {
177177
pub whence: Span,
178178
pub vis: ast::Visibility,
179179
pub stab: Option<attr::Stability>,
180+
pub default_unbound: Option<ast::TraitRef> // FIXME(tomjakubowski)
180181
}
181182

182183
pub struct Impl {

src/librustdoc/html/format.rs

+3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ impl fmt::Show for clean::Generics {
9494
if i > 0 {
9595
try!(f.write(", ".as_bytes()))
9696
}
97+
if let Some(ref unbound) = tp.default_unbound {
98+
try!(write!(f, "{}? ", unbound));
99+
};
97100
try!(f.write(tp.name.as_bytes()));
98101

99102
if tp.bounds.len() > 0 {

src/librustdoc/html/render.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1670,7 +1670,13 @@ fn item_function(w: &mut fmt::Formatter, it: &clean::Item,
16701670
fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
16711671
t: &clean::Trait) -> fmt::Result {
16721672
let mut bounds = String::new();
1673+
if let Some(ref ty) = t.default_unbound {
1674+
bounds.push_str(format!(" for {}?", ty).as_slice());
1675+
}
16731676
if t.bounds.len() > 0 {
1677+
if bounds.len() > 0 {
1678+
bounds.push(' ');
1679+
}
16741680
bounds.push_str(": ");
16751681
for (i, p) in t.bounds.iter().enumerate() {
16761682
if i > 0 { bounds.push_str(" + "); }

src/librustdoc/visit_ast.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
322322
};
323323
om.constants.push(s);
324324
},
325-
ast::ItemTrait(ref gen, _, ref b, ref items) => {
325+
ast::ItemTrait(ref gen, ref def_ub, ref b, ref items) => {
326326
let t = Trait {
327327
name: name,
328328
items: items.clone(),
@@ -333,6 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
333333
whence: item.span,
334334
vis: item.vis,
335335
stab: self.stability(item.id),
336+
default_unbound: def_ub.clone()
336337
};
337338
om.traits.push(t);
338339
},

0 commit comments

Comments
 (0)