Skip to content

Commit 48ca6d1

Browse files
committedNov 25, 2014
auto merge of #19174 : tomjakubowski/rust/rustdoc-assoc-types, r=alexcrichton
Render associated types on traits and impls, and qualified paths in types. r? @alexcrichton
2 parents 2264049 + de94f0a commit 48ca6d1

File tree

6 files changed

+115
-40
lines changed

6 files changed

+115
-40
lines changed
 

‎src/librustdoc/clean/mod.rs

+37-3
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ pub enum ItemEnum {
336336
ForeignStaticItem(Static),
337337
MacroItem(Macro),
338338
PrimitiveItem(PrimitiveType),
339-
AssociatedTypeItem,
339+
AssociatedTypeItem(TyParam),
340340
}
341341

342342
#[deriving(Clone, Encodable, Decodable)]
@@ -982,6 +982,8 @@ impl Clean<Type> for ast::PolyTraitRef {
982982
}
983983
}
984984

985+
/// An item belonging to a trait, whether a method or associated. Could be named
986+
/// TraitItem except that's already taken by an exported enum variant.
985987
#[deriving(Clone, Encodable, Decodable)]
986988
pub enum TraitMethod {
987989
RequiredMethod(Item),
@@ -1002,6 +1004,12 @@ impl TraitMethod {
10021004
_ => false,
10031005
}
10041006
}
1007+
pub fn is_type(&self) -> bool {
1008+
match self {
1009+
&TypeTraitItem(..) => true,
1010+
_ => false,
1011+
}
1012+
}
10051013
pub fn item<'a>(&'a self) -> &'a Item {
10061014
match *self {
10071015
RequiredMethod(ref item) => item,
@@ -1127,6 +1135,11 @@ pub enum Type {
11271135
mutability: Mutability,
11281136
type_: Box<Type>,
11291137
},
1138+
QPath {
1139+
name: String,
1140+
self_type: Box<Type>,
1141+
trait_: Box<Type>
1142+
},
11301143
// region, raw, other boxes, mutable
11311144
}
11321145

@@ -1252,6 +1265,7 @@ impl Clean<Type> for ast::Ty {
12521265
TyProc(ref c) => Proc(box c.clean(cx)),
12531266
TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
12541267
TyParen(ref ty) => ty.clean(cx),
1268+
TyQPath(ref qp) => qp.clean(cx),
12551269
ref x => panic!("Unimplemented type {}", x),
12561270
}
12571271
}
@@ -1354,6 +1368,16 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
13541368
}
13551369
}
13561370

1371+
impl Clean<Type> for ast::QPath {
1372+
fn clean(&self, cx: &DocContext) -> Type {
1373+
Type::QPath {
1374+
name: self.item_name.clean(cx),
1375+
self_type: box self.self_type.clean(cx),
1376+
trait_: box self.trait_ref.clean(cx)
1377+
}
1378+
}
1379+
}
1380+
13571381
#[deriving(Clone, Encodable, Decodable)]
13581382
pub enum StructField {
13591383
HiddenStructField, // inserted later by strip passes
@@ -2211,7 +2235,7 @@ impl Clean<Item> for ast::AssociatedType {
22112235
source: self.ty_param.span.clean(cx),
22122236
name: Some(self.ty_param.ident.clean(cx)),
22132237
attrs: self.attrs.clean(cx),
2214-
inner: AssociatedTypeItem,
2238+
inner: AssociatedTypeItem(self.ty_param.clean(cx)),
22152239
visibility: None,
22162240
def_id: ast_util::local_def(self.ty_param.id),
22172241
stability: None,
@@ -2225,7 +2249,17 @@ impl Clean<Item> for ty::AssociatedType {
22252249
source: DUMMY_SP.clean(cx),
22262250
name: Some(self.name.clean(cx)),
22272251
attrs: Vec::new(),
2228-
inner: AssociatedTypeItem,
2252+
// FIXME(#18048): this is wrong, but cross-crate associated types are broken
2253+
// anyway, for the time being.
2254+
inner: AssociatedTypeItem(TyParam {
2255+
name: self.name.clean(cx),
2256+
did: ast::DefId {
2257+
krate: 0,
2258+
node: ast::DUMMY_NODE_ID
2259+
},
2260+
bounds: vec![],
2261+
default: None
2262+
}),
22292263
visibility: None,
22302264
def_id: self.def_id,
22312265
stability: None,

‎src/librustdoc/html/format.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,8 @@ pub struct Stability<'a>(pub &'a Option<clean::Stability>);
4646
pub struct ConciseStability<'a>(pub &'a Option<clean::Stability>);
4747
/// Wrapper struct for emitting a where clause from Generics.
4848
pub struct WhereClause<'a>(pub &'a clean::Generics);
49-
5049
/// Wrapper struct for emitting type parameter bounds.
51-
struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
50+
pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
5251

5352
impl VisSpace {
5453
pub fn get(&self) -> Option<ast::Visibility> {
@@ -486,6 +485,9 @@ impl fmt::Show for clean::Type {
486485
}
487486
}
488487
}
488+
clean::QPath { ref name, ref self_type, ref trait_ } => {
489+
write!(f, "&lt;{} as {}&gt;::{}", self_type, trait_, name)
490+
}
489491
clean::Unique(..) => {
490492
panic!("should have been cleaned")
491493
}

‎src/librustdoc/html/item_type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub fn shortty(item: &clean::Item) -> ItemType {
9595
clean::ForeignStaticItem(..) => ForeignStatic,
9696
clean::MacroItem(..) => Macro,
9797
clean::PrimitiveItem(..) => Primitive,
98-
clean::AssociatedTypeItem => AssociatedType,
98+
clean::AssociatedTypeItem(..) => AssociatedType,
9999
}
100100
}
101101

‎src/librustdoc/html/render.rs

+65-27
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use clean;
5959
use doctree;
6060
use fold::DocFolder;
6161
use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability};
62-
use html::format::{ConciseStability, WhereClause};
62+
use html::format::{ConciseStability, TyParamBounds, WhereClause};
6363
use html::highlight;
6464
use html::item_type::{ItemType, shortty};
6565
use html::item_type;
@@ -1685,27 +1685,23 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
16851685
t.generics,
16861686
bounds,
16871687
WhereClause(&t.generics)));
1688-
let required = t.items.iter()
1689-
.filter(|m| {
1690-
match **m {
1691-
clean::RequiredMethod(_) => true,
1692-
_ => false,
1693-
}
1694-
})
1695-
.collect::<Vec<&clean::TraitMethod>>();
1696-
let provided = t.items.iter()
1697-
.filter(|m| {
1698-
match **m {
1699-
clean::ProvidedMethod(_) => true,
1700-
_ => false,
1701-
}
1702-
})
1703-
.collect::<Vec<&clean::TraitMethod>>();
1688+
1689+
let types = t.items.iter().filter(|m| m.is_type()).collect::<Vec<_>>();
1690+
let required = t.items.iter().filter(|m| m.is_req()).collect::<Vec<_>>();
1691+
let provided = t.items.iter().filter(|m| m.is_def()).collect::<Vec<_>>();
17041692

17051693
if t.items.len() == 0 {
17061694
try!(write!(w, "{{ }}"));
17071695
} else {
17081696
try!(write!(w, "{{\n"));
1697+
for t in types.iter() {
1698+
try!(write!(w, " "));
1699+
try!(render_method(w, t.item()));
1700+
try!(write!(w, ";\n"));
1701+
}
1702+
if types.len() > 0 && required.len() > 0 {
1703+
try!(w.write("\n".as_bytes()));
1704+
}
17091705
for m in required.iter() {
17101706
try!(write!(w, " "));
17111707
try!(render_method(w, m.item()));
@@ -1738,6 +1734,17 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
17381734
Ok(())
17391735
}
17401736

1737+
if types.len() > 0 {
1738+
try!(write!(w, "
1739+
<h2 id='associated-types'>Associated Types</h2>
1740+
<div class='methods'>
1741+
"));
1742+
for t in types.iter() {
1743+
try!(trait_item(w, *t));
1744+
}
1745+
try!(write!(w, "</div>"));
1746+
}
1747+
17411748
// Output the documentation for each function individually
17421749
if required.len() > 0 {
17431750
try!(write!(w, "
@@ -1792,7 +1799,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
17921799
}
17931800

17941801
fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
1795-
fn fun(w: &mut fmt::Formatter, it: &clean::Item, fn_style: ast::FnStyle,
1802+
fn method(w: &mut fmt::Formatter, it: &clean::Item, fn_style: ast::FnStyle,
17961803
g: &clean::Generics, selfty: &clean::SelfTy,
17971804
d: &clean::FnDecl) -> fmt::Result {
17981805
write!(w, "{}fn <a href='#{ty}.{name}' class='fnname'>{name}</a>\
@@ -1807,14 +1814,28 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
18071814
decl = Method(selfty, d),
18081815
where_clause = WhereClause(g))
18091816
}
1817+
fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
1818+
typ: &clean::TyParam) -> fmt::Result {
1819+
try!(write!(w, "type {}", it.name.as_ref().unwrap()));
1820+
if typ.bounds.len() > 0 {
1821+
try!(write!(w, ": {}", TyParamBounds(&*typ.bounds)))
1822+
}
1823+
if let Some(ref default) = typ.default {
1824+
try!(write!(w, " = {}", default));
1825+
}
1826+
Ok(())
1827+
}
18101828
match meth.inner {
18111829
clean::TyMethodItem(ref m) => {
1812-
fun(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl)
1830+
method(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl)
18131831
}
18141832
clean::MethodItem(ref m) => {
1815-
fun(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl)
1833+
method(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl)
18161834
}
1817-
_ => unreachable!()
1835+
clean::AssociatedTypeItem(ref typ) => {
1836+
assoc_type(w, meth, typ)
1837+
}
1838+
_ => panic!("render_method called on non-method")
18181839
}
18191840
}
18201841

@@ -2071,11 +2092,26 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
20712092

20722093
fn doctraititem(w: &mut fmt::Formatter, item: &clean::Item, dox: bool)
20732094
-> fmt::Result {
2074-
try!(write!(w, "<h4 id='method.{}' class='method'>{}<code>",
2075-
*item.name.as_ref().unwrap(),
2076-
ConciseStability(&item.stability)));
2077-
try!(render_method(w, item));
2078-
try!(write!(w, "</code></h4>\n"));
2095+
match item.inner {
2096+
clean::MethodItem(..) | clean::TyMethodItem(..) => {
2097+
try!(write!(w, "<h4 id='method.{}' class='{}'>{}<code>",
2098+
*item.name.as_ref().unwrap(),
2099+
shortty(item),
2100+
ConciseStability(&item.stability)));
2101+
try!(render_method(w, item));
2102+
try!(write!(w, "</code></h4>\n"));
2103+
}
2104+
clean::TypedefItem(ref tydef) => {
2105+
let name = item.name.as_ref().unwrap();
2106+
try!(write!(w, "<h4 id='assoc_type.{}' class='{}'>{}<code>",
2107+
*name,
2108+
shortty(item),
2109+
ConciseStability(&item.stability)));
2110+
try!(write!(w, "type {} = {}", name, tydef.type_));
2111+
try!(write!(w, "</code></h4>\n"));
2112+
}
2113+
_ => panic!("can't make docs for trait item with name {}", item.name)
2114+
}
20792115
match item.doc_value() {
20802116
Some(s) if dox => {
20812117
try!(write!(w, "<div class='docblock'>{}</div>", Markdown(s)));
@@ -2085,7 +2121,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
20852121
}
20862122
}
20872123

2088-
try!(write!(w, "<div class='impl-methods'>"));
2124+
try!(write!(w, "<div class='impl-items'>"));
20892125
for trait_item in i.impl_.items.iter() {
20902126
try!(doctraititem(w, trait_item, true));
20912127
}
@@ -2107,6 +2143,8 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
21072143

21082144
// If we've implemented a trait, then also emit documentation for all
21092145
// default methods which weren't overridden in the implementation block.
2146+
// FIXME: this also needs to be done for associated types, whenever defaults
2147+
// for them work.
21102148
match i.impl_.trait_ {
21112149
Some(clean::ResolvedPath { did, .. }) => {
21122150
try!({

‎src/librustdoc/html/static/main.css

+7-6
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ h2 {
8484
h3 {
8585
font-size: 1.3em;
8686
}
87-
h1, h2, h3:not(.impl):not(.method), h4:not(.method) {
87+
h1, h2, h3:not(.impl):not(.method):not(.type), h4:not(.method):not(.type) {
8888
color: black;
8989
font-weight: 500;
9090
margin: 20px 0 15px 0;
@@ -94,15 +94,15 @@ h1.fqn {
9494
border-bottom: 1px dashed #D5D5D5;
9595
margin-top: 0;
9696
}
97-
h2, h3:not(.impl):not(.method), h4:not(.method) {
97+
h2, h3:not(.impl):not(.method):not(.type), h4:not(.method):not(.type) {
9898
border-bottom: 1px solid #DDDDDD;
9999
}
100-
h3.impl, h3.method, h4.method {
100+
h3.impl, h3.method, h4.method, h3.type, h4.type {
101101
font-weight: 600;
102102
margin-top: 10px;
103103
margin-bottom: 10px;
104104
}
105-
h3.impl, h3.method {
105+
h3.impl, h3.method, h3.type {
106106
margin-top: 15px;
107107
}
108108
h1, h2, h3, h4, section.sidebar, a.source, .search-input, .content table :not(code)>a, .collapse-toggle {
@@ -235,6 +235,7 @@ nav.sub {
235235
.content .highlighted.fn { background-color: #c6afb3; }
236236
.content .highlighted.method { background-color: #c6afb3; }
237237
.content .highlighted.tymethod { background-color: #c6afb3; }
238+
.content .highlighted.type { background-color: #c6afb3; }
238239
.content .highlighted.ffi { background-color: #c6afb3; }
239240

240241
.docblock.short.nowrap {
@@ -307,7 +308,7 @@ nav.sub {
307308
}
308309
.content .methods .docblock { margin-left: 40px; }
309310

310-
.content .impl-methods .docblock { margin-left: 40px; }
311+
.content .impl-items .docblock { margin-left: 40px; }
311312

312313
nav {
313314
border-bottom: 1px solid #e0e0e0;
@@ -442,7 +443,7 @@ h1 .stability {
442443
padding: 4px 10px;
443444
}
444445

445-
.impl-methods .stability, .methods .stability {
446+
.impl-items .stability, .methods .stability {
446447
margin-right: 20px;
447448
}
448449

‎src/librustdoc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#![crate_type = "rlib"]
1717

1818
#![allow(unknown_features)]
19-
#![feature(globs, macro_rules, phase, slicing_syntax, tuple_indexing)]
19+
#![feature(globs, if_let, macro_rules, phase, slicing_syntax, tuple_indexing)]
2020

2121
extern crate arena;
2222
extern crate getopts;

0 commit comments

Comments
 (0)
Please sign in to comment.