Skip to content

Commit cfb4ad2

Browse files
committed
rustdoc: Don't generate empty files for stripped items
We need to traverse stripped modules to generate redirect pages, but we shouldn't generate anything else for them. This now renders the file contents to a Vec before writing it to a file in one go. I think that's probably a better strategy anyway.
1 parent 433d70c commit cfb4ad2

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

src/librustdoc/html/render.rs

+24-17
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,6 @@ impl Context {
12551255

12561256
info!("Recursing into {}", self.dst.display());
12571257

1258-
mkdir(&self.dst).unwrap();
12591258
let ret = f(self);
12601259

12611260
info!("Recursed; leaving {}", self.dst.display());
@@ -1299,7 +1298,7 @@ impl Context {
12991298
fn item<F>(&mut self, item: clean::Item, mut f: F) -> Result<(), Error> where
13001299
F: FnMut(&mut Context, clean::Item),
13011300
{
1302-
fn render(w: File, cx: &Context, it: &clean::Item,
1301+
fn render(writer: &mut io::Write, cx: &Context, it: &clean::Item,
13031302
pushname: bool) -> io::Result<()> {
13041303
// A little unfortunate that this is done like this, but it sure
13051304
// does make formatting *a lot* nicer.
@@ -1334,12 +1333,8 @@ impl Context {
13341333

13351334
reset_ids(true);
13361335

1337-
// We have a huge number of calls to write, so try to alleviate some
1338-
// of the pain by using a buffered writer instead of invoking the
1339-
// write syscall all the time.
1340-
let mut writer = BufWriter::new(w);
13411336
if !cx.render_redirect_pages {
1342-
layout::render(&mut writer, &cx.shared.layout, &page,
1337+
layout::render(writer, &cx.shared.layout, &page,
13431338
&Sidebar{ cx: cx, item: it },
13441339
&Item{ cx: cx, item: it },
13451340
cx.shared.css_file_extension.is_some())?;
@@ -1352,10 +1347,10 @@ impl Context {
13521347
url.push_str("/");
13531348
}
13541349
url.push_str(&item_path(it));
1355-
layout::redirect(&mut writer, &url)?;
1350+
layout::redirect(writer, &url)?;
13561351
}
13571352
}
1358-
writer.flush()
1353+
Ok(())
13591354
}
13601355

13611356
// Stripped modules survive the rustdoc passes (i.e. `strip-private`)
@@ -1376,9 +1371,16 @@ impl Context {
13761371
let mut item = Some(item);
13771372
self.recurse(name, |this| {
13781373
let item = item.take().unwrap();
1379-
let joint_dst = this.dst.join("index.html");
1380-
let dst = try_err!(File::create(&joint_dst), &joint_dst);
1381-
try_err!(render(dst, this, &item, false), &joint_dst);
1374+
1375+
let mut buf = Vec::new();
1376+
render(&mut buf, this, &item, false).unwrap();
1377+
// buf will be empty if the module is stripped and there is no redirect for it
1378+
if !buf.is_empty() {
1379+
let joint_dst = this.dst.join("index.html");
1380+
try_err!(fs::create_dir_all(&this.dst), &this.dst);
1381+
let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
1382+
try_err!(dst.write_all(&buf), &joint_dst);
1383+
}
13821384

13831385
let m = match item.inner {
13841386
clean::StrippedItem(box clean::ModuleItem(m)) |
@@ -1387,7 +1389,7 @@ impl Context {
13871389
};
13881390

13891391
// render sidebar-items.js used throughout this module
1390-
{
1392+
if !this.render_redirect_pages {
13911393
let items = this.build_sidebar_items(&m);
13921394
let js_dst = this.dst.join("sidebar-items.js");
13931395
let mut js_out = BufWriter::new(try_err!(File::create(&js_dst), &js_dst));
@@ -1401,10 +1403,15 @@ impl Context {
14011403
Ok(())
14021404
})
14031405
} else if item.name.is_some() {
1404-
let joint_dst = self.dst.join(&item_path(&item));
1405-
1406-
let dst = try_err!(File::create(&joint_dst), &joint_dst);
1407-
try_err!(render(dst, self, &item, true), &joint_dst);
1406+
let mut buf = Vec::new();
1407+
render(&mut buf, self, &item, true).unwrap();
1408+
// buf will be empty if the item is stripped and there is no redirect for it
1409+
if !buf.is_empty() {
1410+
let joint_dst = self.dst.join(&item_path(&item));
1411+
try_err!(fs::create_dir_all(&self.dst), &self.dst);
1412+
let mut dst = try_err!(File::create(&joint_dst), &joint_dst);
1413+
try_err!(dst.write_all(&buf), &joint_dst);
1414+
}
14081415
Ok(())
14091416
} else {
14101417
Ok(())

src/test/rustdoc/issue-34025.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_name = "foo"]
12+
13+
// @!has 'foo/sys/index.html'
14+
// @!has 'foo/sys/sidebar-items.js'
15+
#[doc(hidden)]
16+
pub mod sys {
17+
extern "C" {
18+
// @!has 'foo/sys/fn.foo.html'
19+
#[doc(hidden)]
20+
pub fn foo();
21+
}
22+
}

0 commit comments

Comments
 (0)