Skip to content

Commit 2dd3f94

Browse files
committed
---
yaml --- r: 152195 b: refs/heads/try2 c: 7ec6df5 h: refs/heads/master i: 152193: 4bf1120 152191: f215946 v: v3
1 parent 0e3316b commit 2dd3f94

File tree

7 files changed

+99
-31
lines changed

7 files changed

+99
-31
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: c5830a954e3be1cc19f7ec4700599fcb0030b1fd
8+
refs/heads/try2: 7ec6df5f458c599e16641ec3d1265622743054ff
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/doc/guide-unsafe.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ function is never called.
511511
With the above techniques, we've got a bare-metal executable running some Rust
512512
code. There is a good deal of functionality provided by the standard library,
513513
however, that is necessary to be productive in Rust. If the standard library is
514-
not sufficient, then [libcore](../core/index.html) is designed to be used
514+
not sufficient, then [libcore](core/index.html) is designed to be used
515515
instead.
516516

517517
The core library has very few dependencies and is much more portable than the

branches/try2/src/librustdoc/clean/mod.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,27 @@ impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
104104
let id = link::find_crate_id(self.attrs.as_slice(),
105105
t_outputs.out_filestem.as_slice());
106106

107-
// Clean the module, translating the entire libsyntax AST to one that is
107+
// Clean the crate, translating the entire libsyntax AST to one that is
108108
// understood by rustdoc.
109109
let mut module = self.module.clean();
110110

111111
// Collect all inner modules which are tagged as implementations of
112112
// primitives.
113+
//
114+
// Note that this loop only searches the top-level items of the crate,
115+
// and this is intentional. If we were to search the entire crate for an
116+
// item tagged with `#[doc(primitive)]` then we we would also have to
117+
// search the entirety of external modules for items tagged
118+
// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
119+
// all that metadata unconditionally).
120+
//
121+
// In order to keep the metadata load under control, the
122+
// `#[doc(primitive)]` feature is explicitly designed to only allow the
123+
// primitive tags to show up as the top level items in a crate.
124+
//
125+
// Also note that this does not attempt to deal with modules tagged
126+
// duplicately for the same primitive. This is handled later on when
127+
// rendering by delegating everything to a hash map.
113128
let mut primitives = Vec::new();
114129
{
115130
let m = match module.inner {

branches/try2/src/librustdoc/html/format.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,8 @@ impl fmt::Show for clean::Type {
424424
decl.decl)
425425
}
426426
clean::Tuple(ref typs) => {
427-
try!(f.write("(".as_bytes()));
428-
for (i, typ) in typs.iter().enumerate() {
429-
if i > 0 {
430-
try!(f.write(", ".as_bytes()))
431-
}
432-
try!(write!(f, "{}", *typ));
433-
}
434-
f.write(")".as_bytes())
427+
primitive_link(f, clean::PrimitiveTuple,
428+
format!("({:#})", typs).as_slice())
435429
}
436430
clean::Vector(ref t) => {
437431
primitive_link(f, clean::Slice, format!("[{}]", **t).as_slice())

branches/try2/src/librustdoc/html/layout.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,17 @@ r##"<!DOCTYPE html>
130130
fn nonestr<'a>(s: &'a str) -> &'a str {
131131
if s == "" { "none" } else { s }
132132
}
133+
134+
pub fn redirect(dst: &mut io::Writer, url: &str) -> io::IoResult<()> {
135+
write!(dst,
136+
r##"<!DOCTYPE html>
137+
<html lang="en">
138+
<head>
139+
<meta http-equiv="refresh" content="0;URL={url}">
140+
</head>
141+
<body>
142+
</body>
143+
</html>"##,
144+
url = url,
145+
)
146+
}

branches/try2/src/librustdoc/html/render.rs

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ use html::markdown;
7070
pub struct Context {
7171
/// Current hierarchy of components leading down to what's currently being
7272
/// rendered
73-
pub current: Vec<String> ,
73+
pub current: Vec<String>,
7474
/// String representation of how to get back to the root path of the 'doc/'
7575
/// folder in terms of a relative URL.
7676
pub root_path: String,
@@ -90,6 +90,10 @@ pub struct Context {
9090
/// the source files are present in the html rendering, then this will be
9191
/// `true`.
9292
pub include_sources: bool,
93+
/// A flag, which when turned off, will render pages which redirect to the
94+
/// real location of an item. This is used to allow external links to
95+
/// publicly reused items to redirect to the right location.
96+
pub render_redirect_pages: bool,
9397
}
9498

9599
/// Indicates where an external crate can be found.
@@ -227,6 +231,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
227231
krate: krate.name.clone(),
228232
},
229233
include_sources: true,
234+
render_redirect_pages: false,
230235
};
231236
try!(mkdir(&cx.dst));
232237

@@ -493,7 +498,17 @@ fn write_shared(cx: &Context,
493498
let dst = cx.dst.join("implementors");
494499
try!(mkdir(&dst));
495500
for (&did, imps) in cache.implementors.iter() {
496-
let &(ref remote_path, remote_item_type) = cache.paths.get(&did);
501+
// Private modules can leak through to this phase of rustdoc, which
502+
// could contain implementations for otherwise private types. In some
503+
// rare cases we could find an implementation for an item which wasn't
504+
// indexed, so we just skip this step in that case.
505+
//
506+
// FIXME: this is a vague explanation for why this can't be a `get`, in
507+
// theory it should be...
508+
let &(ref remote_path, remote_item_type) = match cache.paths.find(&did) {
509+
Some(p) => p,
510+
None => continue,
511+
};
497512

498513
let mut mydst = dst.clone();
499514
for part in remote_path.slice_to(remote_path.len() - 1).iter() {
@@ -823,7 +838,7 @@ impl DocFolder for Cache {
823838
clean::StructItem(..) | clean::EnumItem(..) |
824839
clean::TypedefItem(..) | clean::TraitItem(..) |
825840
clean::FunctionItem(..) | clean::ModuleItem(..) |
826-
clean::ForeignFunctionItem(..) => {
841+
clean::ForeignFunctionItem(..) if !self.privmod => {
827842
// Reexported items mean that the same id can show up twice
828843
// in the rustdoc ast that we're looking at. We know,
829844
// however, that a reexported item doesn't show up in the
@@ -840,7 +855,7 @@ impl DocFolder for Cache {
840855
}
841856
// link variants to their parent enum because pages aren't emitted
842857
// for each variant
843-
clean::VariantItem(..) => {
858+
clean::VariantItem(..) if !self.privmod => {
844859
let mut stack = self.stack.clone();
845860
stack.pop();
846861
self.paths.insert(item.def_id, (stack, item_type::Enum));
@@ -932,14 +947,6 @@ impl DocFolder for Cache {
932947
}
933948
None
934949
}
935-
// Private modules may survive the strip-private pass if
936-
// they contain impls for public types, but those will get
937-
// stripped here
938-
clean::Item { inner: clean::ModuleItem(ref m),
939-
visibility, .. }
940-
if (m.items.len() == 0 &&
941-
item.doc_value().is_none()) ||
942-
visibility != Some(ast::Public) => None,
943950

944951
i => Some(i),
945952
}
@@ -1020,7 +1027,7 @@ impl Context {
10201027
/// The rendering driver uses this closure to queue up more work.
10211028
fn item(&mut self, item: clean::Item,
10221029
f: |&mut Context, clean::Item|) -> io::IoResult<()> {
1023-
fn render(w: io::File, cx: &mut Context, it: &clean::Item,
1030+
fn render(w: io::File, cx: &Context, it: &clean::Item,
10241031
pushname: bool) -> io::IoResult<()> {
10251032
info!("Rendering an item to {}", w.path().display());
10261033
// A little unfortunate that this is done like this, but it sure
@@ -1047,16 +1054,42 @@ impl Context {
10471054
// of the pain by using a buffered writer instead of invoking the
10481055
// write sycall all the time.
10491056
let mut writer = BufferedWriter::new(w);
1050-
try!(layout::render(&mut writer as &mut Writer, &cx.layout, &page,
1051-
&Sidebar{ cx: cx, item: it },
1052-
&Item{ cx: cx, item: it }));
1057+
if !cx.render_redirect_pages {
1058+
try!(layout::render(&mut writer, &cx.layout, &page,
1059+
&Sidebar{ cx: cx, item: it },
1060+
&Item{ cx: cx, item: it }));
1061+
} else {
1062+
let mut url = "../".repeat(cx.current.len());
1063+
match cache_key.get().unwrap().paths.find(&it.def_id) {
1064+
Some(&(ref names, _)) => {
1065+
for name in names.slice_to(names.len() - 1).iter() {
1066+
url.push_str(name.as_slice());
1067+
url.push_str("/");
1068+
}
1069+
url.push_str(item_path(it).as_slice());
1070+
try!(layout::redirect(&mut writer, url.as_slice()));
1071+
}
1072+
None => {}
1073+
}
1074+
}
10531075
writer.flush()
10541076
}
10551077

10561078
match item.inner {
10571079
// modules are special because they add a namespace. We also need to
10581080
// recurse into the items of the module as well.
10591081
clean::ModuleItem(..) => {
1082+
// Private modules may survive the strip-private pass if they
1083+
// contain impls for public types. These modules can also
1084+
// contain items such as publicly reexported structures.
1085+
//
1086+
// External crates will provide links to these structures, so
1087+
// these modules are recursed into, but not rendered normally (a
1088+
// flag on the context).
1089+
if !self.render_redirect_pages {
1090+
self.render_redirect_pages = ignore_private_module(&item);
1091+
}
1092+
10601093
let name = item.name.get_ref().to_string();
10611094
let mut item = Some(item);
10621095
self.recurse(name, |this| {
@@ -1289,8 +1322,9 @@ fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
12891322
fn item_module(w: &mut fmt::Formatter, cx: &Context,
12901323
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
12911324
try!(document(w, item));
1292-
debug!("{:?}", items);
1293-
let mut indices = Vec::from_fn(items.len(), |i| i);
1325+
let mut indices = range(0, items.len()).filter(|i| {
1326+
!ignore_private_module(&items[*i])
1327+
}).collect::<Vec<uint>>();
12941328

12951329
fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering {
12961330
if shortty(i1) == shortty(i2) {
@@ -1332,7 +1366,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
13321366
}
13331367
}
13341368

1335-
debug!("{:?}", indices);
13361369
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
13371370

13381371
debug!("{:?}", indices);
@@ -1976,6 +2009,8 @@ impl<'a> fmt::Show for Sidebar<'a> {
19762009
fn build_sidebar(m: &clean::Module) -> HashMap<String, Vec<String>> {
19772010
let mut map = HashMap::new();
19782011
for item in m.items.iter() {
2012+
if ignore_private_module(item) { continue }
2013+
19792014
let short = shortty(item).to_static_str();
19802015
let myname = match item.name {
19812016
None => continue,
@@ -2023,3 +2058,13 @@ fn item_primitive(w: &mut fmt::Formatter,
20232058
try!(document(w, it));
20242059
render_methods(w, it)
20252060
}
2061+
2062+
fn ignore_private_module(it: &clean::Item) -> bool {
2063+
match it.inner {
2064+
clean::ModuleItem(ref m) => {
2065+
(m.items.len() == 0 && it.doc_value().is_none()) ||
2066+
it.visibility != Some(ast::Public)
2067+
}
2068+
_ => false,
2069+
}
2070+
}

branches/try2/src/librustdoc/passes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
7070
for_: clean::ResolvedPath{ did, .. },
7171
ref trait_, ..
7272
}) => {
73-
// Impls for stripped don't need to exist
73+
// Impls for stripped types don't need to exist
7474
if self.stripped.contains(&did.node) {
7575
return None;
7676
}

0 commit comments

Comments
 (0)