Skip to content

Commit c0fa876

Browse files
committed
auto merge of #15982 : alexcrichton/rust/rustdoc-fixes, r=brson
Sadly there's still a lot of open issues, but this tackles some of the more pressing ones. Each commit has its own description along with the issues it closes.
2 parents 34a6a8f + 98f4863 commit c0fa876

File tree

8 files changed

+158
-83
lines changed

8 files changed

+158
-83
lines changed

src/libcore/fmt/num.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use iter::Iterator; // NOTE(stage0): Remove after snapshot.
2626
use option::{Some, None}; // NOTE(stage0): Remove after snapshot.
2727

2828
/// A type that represents a specific radix
29+
#[doc(hidden)]
2930
trait GenericRadix {
3031
/// The number of digits.
3132
fn base(&self) -> u8;

src/librustdoc/clean/inline.rs

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc::metadata::csearch;
1818
use rustc::metadata::decoder;
1919
use rustc::middle::def;
2020
use rustc::middle::ty;
21+
use rustc::middle::subst;
2122
use rustc::middle::stability;
2223

2324
use core;
@@ -38,7 +39,8 @@ use super::Clean;
3839
///
3940
/// The returned value is `None` if the `id` could not be inlined, and `Some`
4041
/// of a vector of items if it was successfully expanded.
41-
pub fn try_inline(id: ast::NodeId) -> Option<Vec<clean::Item>> {
42+
pub fn try_inline(id: ast::NodeId, into: Option<ast::Ident>)
43+
-> Option<Vec<clean::Item>> {
4244
let cx = ::ctxtkey.get().unwrap();
4345
let tcx = match cx.maybe_typed {
4446
core::Typed(ref tycx) => tycx,
@@ -50,7 +52,17 @@ pub fn try_inline(id: ast::NodeId) -> Option<Vec<clean::Item>> {
5052
};
5153
let did = def.def_id();
5254
if ast_util::is_local(did) { return None }
53-
try_inline_def(&**cx, tcx, def)
55+
try_inline_def(&**cx, tcx, def).map(|vec| {
56+
vec.move_iter().map(|mut item| {
57+
match into {
58+
Some(into) if item.name.is_some() => {
59+
item.name = Some(into.clean());
60+
}
61+
_ => {}
62+
}
63+
item
64+
}).collect()
65+
})
5466
}
5567

5668
fn try_inline_def(cx: &core::DocContext,
@@ -163,7 +175,7 @@ pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
163175
});
164176

165177
clean::Trait {
166-
generics: def.generics.clean(),
178+
generics: (&def.generics, subst::TypeSpace).clean(),
167179
methods: methods.collect(),
168180
parents: parents.collect()
169181
}
@@ -178,7 +190,7 @@ fn build_external_function(tcx: &ty::ctxt,
178190
ty::ty_bare_fn(ref f) => (did, &f.sig).clean(),
179191
_ => fail!("bad function"),
180192
},
181-
generics: t.generics.clean(),
193+
generics: (&t.generics, subst::FnSpace).clean(),
182194
fn_style: style,
183195
}
184196
}
@@ -196,7 +208,7 @@ fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
196208
[ref f, ..] if f.name == unnamed_field.name => doctree::Tuple,
197209
_ => doctree::Plain,
198210
},
199-
generics: t.generics.clean(),
211+
generics: (&t.generics, subst::TypeSpace).clean(),
200212
fields: fields.iter().map(|f| f.clean()).collect(),
201213
fields_stripped: false,
202214
}
@@ -207,7 +219,7 @@ fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
207219
match ty::get(t.ty).sty {
208220
ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
209221
return clean::EnumItem(clean::Enum {
210-
generics: t.generics.clean(),
222+
generics: (&t.generics, subst::TypeSpace).clean(),
211223
variants_stripped: false,
212224
variants: ty::enum_variants(tcx, edid).clean(),
213225
})
@@ -217,7 +229,7 @@ fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
217229

218230
clean::TypedefItem(clean::Typedef {
219231
type_: t.ty.clean(),
220-
generics: t.generics.clean(),
232+
generics: (&t.generics, subst::TypeSpace).clean(),
221233
})
222234
}
223235

@@ -278,6 +290,17 @@ fn build_impl(cx: &core::DocContext,
278290
}
279291

280292
let associated_trait = csearch::get_impl_trait(tcx, did);
293+
// If this is an impl for a #[doc(hidden)] trait, be sure to not inline it.
294+
match associated_trait {
295+
Some(ref t) => {
296+
let trait_attrs = load_attrs(tcx, t.def_id);
297+
if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
298+
return None
299+
}
300+
}
301+
None => {}
302+
}
303+
281304
let attrs = load_attrs(tcx, did);
282305
let ty = ty::lookup_item_type(tcx, did);
283306
let methods = csearch::get_impl_methods(&tcx.sess.cstore,
@@ -302,7 +325,7 @@ fn build_impl(cx: &core::DocContext,
302325
};
303326
Some(item)
304327
}).collect();
305-
Some(clean::Item {
328+
return Some(clean::Item {
306329
inner: clean::ImplItem(clean::Impl {
307330
derived: clean::detect_derived(attrs.as_slice()),
308331
trait_: associated_trait.clean().map(|bound| {
@@ -312,7 +335,7 @@ fn build_impl(cx: &core::DocContext,
312335
}
313336
}),
314337
for_: ty.ty.clean(),
315-
generics: ty.generics.clean(),
338+
generics: (&ty.generics, subst::TypeSpace).clean(),
316339
methods: methods,
317340
}),
318341
source: clean::Span::empty(),
@@ -321,33 +344,53 @@ fn build_impl(cx: &core::DocContext,
321344
visibility: Some(ast::Inherited),
322345
stability: stability::lookup(tcx, did).clean(),
323346
def_id: did,
324-
})
347+
});
348+
349+
fn is_doc_hidden(a: &clean::Attribute) -> bool {
350+
match *a {
351+
clean::List(ref name, ref inner) if name.as_slice() == "doc" => {
352+
inner.iter().any(|a| {
353+
match *a {
354+
clean::Word(ref s) => s.as_slice() == "hidden",
355+
_ => false,
356+
}
357+
})
358+
}
359+
_ => false
360+
}
361+
}
325362
}
326363

327364
fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,
328365
did: ast::DefId) -> clean::Module {
329366
let mut items = Vec::new();
367+
fill_in(cx, tcx, did, &mut items);
368+
return clean::Module {
369+
items: items,
370+
is_crate: false,
371+
};
330372

331373
// FIXME: this doesn't handle reexports inside the module itself.
332374
// Should they be handled?
333-
csearch::each_child_of_item(&tcx.sess.cstore, did, |def, _, vis| {
334-
if vis != ast::Public { return }
335-
match def {
336-
decoder::DlDef(def) => {
337-
match try_inline_def(cx, tcx, def) {
338-
Some(i) => items.extend(i.move_iter()),
339-
None => {}
375+
fn fill_in(cx: &core::DocContext, tcx: &ty::ctxt, did: ast::DefId,
376+
items: &mut Vec<clean::Item>) {
377+
csearch::each_child_of_item(&tcx.sess.cstore, did, |def, _, vis| {
378+
match def {
379+
decoder::DlDef(def::DefForeignMod(did)) => {
380+
fill_in(cx, tcx, did, items);
340381
}
382+
decoder::DlDef(def) if vis == ast::Public => {
383+
match try_inline_def(cx, tcx, def) {
384+
Some(i) => items.extend(i.move_iter()),
385+
None => {}
386+
}
387+
}
388+
decoder::DlDef(..) => {}
389+
// All impls were inlined above
390+
decoder::DlImpl(..) => {}
391+
decoder::DlField => fail!("unimplemented field"),
341392
}
342-
// All impls were inlined above
343-
decoder::DlImpl(..) => {}
344-
decoder::DlField => fail!("unimplemented field"),
345-
}
346-
});
347-
348-
clean::Module {
349-
items: items,
350-
is_crate: false,
393+
});
351394
}
352395
}
353396

src/librustdoc/clean/mod.rs

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -653,35 +653,12 @@ impl Clean<Generics> for ast::Generics {
653653
}
654654
}
655655

656-
impl Clean<Generics> for ty::Generics {
656+
impl<'a> Clean<Generics> for (&'a ty::Generics, subst::ParamSpace) {
657657
fn clean(&self) -> Generics {
658-
// In the type space, generics can come in one of multiple
659-
// namespaces. This means that e.g. for fn items the type
660-
// parameters will live in FnSpace, but for types the
661-
// parameters will live in TypeSpace (trait definitions also
662-
// define a parameter in SelfSpace). *Method* definitions are
663-
// the one exception: they combine the TypeSpace parameters
664-
// from the enclosing impl/trait with their own FnSpace
665-
// parameters.
666-
//
667-
// In general, when we clean, we are trying to produce the
668-
// "user-facing" generics. Hence we select the most specific
669-
// namespace that is occupied, ignoring SelfSpace because it
670-
// is implicit.
671-
672-
let space = {
673-
if !self.types.is_empty_in(subst::FnSpace) ||
674-
!self.regions.is_empty_in(subst::FnSpace)
675-
{
676-
subst::FnSpace
677-
} else {
678-
subst::TypeSpace
679-
}
680-
};
681-
658+
let (me, space) = *self;
682659
Generics {
683-
type_params: Vec::from_slice(self.types.get_slice(space)).clean(),
684-
lifetimes: Vec::from_slice(self.regions.get_slice(space)).clean(),
660+
type_params: Vec::from_slice(me.types.get_slice(space)).clean(),
661+
lifetimes: Vec::from_slice(me.regions.get_slice(space)).clean(),
685662
}
686663
}
687664
}
@@ -770,7 +747,6 @@ pub enum SelfTy {
770747
SelfStatic,
771748
SelfValue,
772749
SelfBorrowed(Option<Lifetime>, Mutability),
773-
SelfOwned,
774750
SelfExplicit(Type),
775751
}
776752

@@ -994,28 +970,27 @@ impl Clean<Item> for ty::Method {
994970
fn clean(&self) -> Item {
995971
let cx = get_cx();
996972
let (self_, sig) = match self.explicit_self {
997-
ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(), self.fty.sig.clone()),
973+
ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(),
974+
self.fty.sig.clone()),
998975
s => {
999976
let sig = ty::FnSig {
1000977
inputs: Vec::from_slice(self.fty.sig.inputs.slice_from(1)),
1001978
..self.fty.sig.clone()
1002979
};
1003980
let s = match s {
981+
ty::ByValueExplicitSelfCategory => SelfValue,
1004982
ty::ByReferenceExplicitSelfCategory(..) => {
1005983
match ty::get(self.fty.sig.inputs[0]).sty {
1006984
ty::ty_rptr(r, mt) => {
1007985
SelfBorrowed(r.clean(), mt.mutbl.clean())
1008986
}
1009-
_ => {
1010-
// FIXME(pcwalton): This is wrong.
1011-
SelfStatic
1012-
}
987+
_ => unreachable!(),
1013988
}
1014989
}
1015-
_ => {
1016-
// FIXME(pcwalton): This is wrong.
1017-
SelfStatic
990+
ty::ByBoxExplicitSelfCategory => {
991+
SelfExplicit(self.fty.sig.inputs[0].clean())
1018992
}
993+
ty::StaticExplicitSelfCategory => unreachable!(),
1019994
};
1020995
(s, sig)
1021996
}
@@ -1030,7 +1005,7 @@ impl Clean<Item> for ty::Method {
10301005
source: Span::empty(),
10311006
inner: TyMethodItem(TyMethod {
10321007
fn_style: self.fty.fn_style,
1033-
generics: self.generics.clean(),
1008+
generics: (&self.generics, subst::FnSpace).clean(),
10341009
self_: self_,
10351010
decl: (self.def_id, &sig).clean(),
10361011
})
@@ -1236,8 +1211,18 @@ impl Clean<Type> for ty::t {
12361211
ty::ty_float(ast::TyF32) => Primitive(F32),
12371212
ty::ty_float(ast::TyF64) => Primitive(F64),
12381213
ty::ty_str => Primitive(Str),
1239-
ty::ty_box(t) => Managed(box t.clean()),
1240-
ty::ty_uniq(t) => Unique(box t.clean()),
1214+
ty::ty_box(t) => {
1215+
let gc_did = get_cx().tcx_opt().and_then(|tcx| {
1216+
tcx.lang_items.gc()
1217+
});
1218+
lang_struct(gc_did, t, "Gc", Managed)
1219+
}
1220+
ty::ty_uniq(t) => {
1221+
let box_did = get_cx().tcx_opt().and_then(|tcx| {
1222+
tcx.lang_items.owned_box()
1223+
});
1224+
lang_struct(box_did, t, "Box", Unique)
1225+
}
12411226
ty::ty_vec(mt, None) => Vector(box mt.ty.clean()),
12421227
ty::ty_vec(mt, Some(i)) => FixedVector(box mt.ty.clean(),
12431228
format!("{}", i)),
@@ -1778,7 +1763,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
17781763
// to keep any non-inlineable reexports so they can be
17791764
// listed in the documentation.
17801765
let remaining = list.iter().filter(|path| {
1781-
match inline::try_inline(path.node.id()) {
1766+
match inline::try_inline(path.node.id(), None) {
17821767
Some(items) => {
17831768
ret.extend(items.move_iter()); false
17841769
}
@@ -1793,8 +1778,8 @@ impl Clean<Vec<Item>> for ast::ViewItem {
17931778
ret.push(convert(&ast::ViewItemUse(box(GC) path)));
17941779
}
17951780
}
1796-
ast::ViewPathSimple(_, _, id) => {
1797-
match inline::try_inline(id) {
1781+
ast::ViewPathSimple(ident, _, id) => {
1782+
match inline::try_inline(id, Some(ident)) {
17981783
Some(items) => ret.extend(items.move_iter()),
17991784
None => ret.push(convert(&self.node)),
18001785
}
@@ -2117,3 +2102,29 @@ impl Clean<Stability> for attr::Stability {
21172102
}
21182103
}
21192104
}
2105+
2106+
fn lang_struct(did: Option<ast::DefId>, t: ty::t, name: &str,
2107+
fallback: fn(Box<Type>) -> Type) -> Type {
2108+
let did = match did {
2109+
Some(did) => did,
2110+
None => return fallback(box t.clean()),
2111+
};
2112+
let fqn = csearch::get_item_path(get_cx().tcx(), did);
2113+
let fqn: Vec<String> = fqn.move_iter().map(|i| {
2114+
i.to_string()
2115+
}).collect();
2116+
get_cx().external_paths.borrow_mut().get_mut_ref()
2117+
.insert(did, (fqn, TypeStruct));
2118+
ResolvedPath {
2119+
typarams: None,
2120+
did: did,
2121+
path: Path {
2122+
global: false,
2123+
segments: vec![PathSegment {
2124+
name: name.to_string(),
2125+
lifetimes: vec![],
2126+
types: vec![t.clean()],
2127+
}],
2128+
},
2129+
}
2130+
}

src/librustdoc/core.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ pub struct CrateAnalysis {
8080
pub type Externs = HashMap<String, Vec<String>>;
8181

8282
/// Parses, resolves, and typechecks the given crate
83-
fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>, externs: Externs)
83+
fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>,
84+
externs: Externs, triple: Option<String>)
8485
-> (DocContext, CrateAnalysis) {
8586
use syntax::codemap::dummy_spanned;
8687
use rustc::driver::driver::{FileInput,
@@ -99,6 +100,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>, ext
99100
crate_types: vec!(driver::config::CrateTypeRlib),
100101
lint_opts: vec!((warning_lint, lint::Allow)),
101102
externs: externs,
103+
target_triple: triple.unwrap_or(driver::driver::host_triple().to_string()),
102104
..rustc::driver::config::basic_options().clone()
103105
};
104106

@@ -151,9 +153,10 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>, ext
151153
})
152154
}
153155

154-
pub fn run_core(libs: HashSet<Path>, cfgs: Vec<String>, externs: Externs, path: &Path)
156+
pub fn run_core(libs: HashSet<Path>, cfgs: Vec<String>, externs: Externs,
157+
path: &Path, triple: Option<String>)
155158
-> (clean::Crate, CrateAnalysis) {
156-
let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs, externs);
159+
let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs, externs, triple);
157160
let ctxt = box(GC) ctxt;
158161
super::ctxtkey.replace(Some(ctxt));
159162

0 commit comments

Comments
 (0)