std: Deprecate std::old_io::fs

This commit deprecates the majority of std::old_io::fs in favor of std::fs and
its new functionality. Some functions remain non-deprecated but are now behind a
feature gate called `old_fs`. These functions will be deprecated once
suitable replacements have been implemented.

The compiler has been migrated to new `std::fs` and `std::path` APIs where
appropriate as part of this change.
This commit is contained in:
Alex Crichton 2015-02-26 21:00:43 -08:00
parent 3b3bb0e682
commit 95d904625b
80 changed files with 1430 additions and 1209 deletions

View file

@ -49,7 +49,7 @@ use rustc::middle::stability;
use std::rc::Rc;
use std::u32;
use std::old_path::Path as FsPath; // Conflicts with Path struct
use std::path::PathBuf;
use core::DocContext;
use doctree;
@ -118,7 +118,7 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::owned_slice::OwnedSlice<T> {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Crate {
pub name: String,
pub src: FsPath,
pub src: PathBuf,
pub module: Option<Item>,
pub externs: Vec<(ast::CrateNum, ExternalCrate)>,
pub primitives: Vec<PrimitiveType>,
@ -191,7 +191,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
let src = match cx.input {
Input::File(ref path) => path.clone(),
Input::Str(_) => FsPath::new("") // FIXME: this is wrong
Input::Str(_) => PathBuf::new("") // FIXME: this is wrong
};
Crate {

View file

@ -8,7 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::{old_io, str};
use std::fs::File;
use std::io::prelude::*;
use std::io;
use std::old_io;
use std::path::{PathBuf, Path};
use std::str;
#[derive(Clone)]
pub struct ExternalHtml{
@ -33,16 +38,17 @@ impl ExternalHtml {
}
}
pub fn load_string(input: &Path) -> old_io::IoResult<Option<String>> {
let mut f = try!(old_io::File::open(input));
let d = try!(f.read_to_end());
pub fn load_string(input: &Path) -> io::Result<Option<String>> {
let mut f = try!(File::open(input));
let mut d = Vec::new();
try!(f.read_to_end(&mut d));
Ok(str::from_utf8(&d).map(|s| s.to_string()).ok())
}
macro_rules! load_or_return {
($input: expr, $cant_read: expr, $not_utf8: expr) => {
{
let input = Path::new($input);
let input = PathBuf::new($input);
match ::externalfiles::load_string(&input) {
Err(e) => {
let _ = writeln!(&mut old_io::stderr(),

View file

@ -20,7 +20,9 @@ pub use self::imp::Lock;
#[cfg(unix)]
mod imp {
use std::ffi::CString;
use std::ffi::{AsOsStr, CString};
use std::os::unix::prelude::*;
use std::path::Path;
use libc;
use std::os as stdos;
@ -114,7 +116,7 @@ mod imp {
impl Lock {
pub fn new(p: &Path) -> Lock {
let buf = CString::new(p.as_vec()).unwrap();
let buf = CString::new(p.as_os_str().as_bytes()).unwrap();
let fd = unsafe {
libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
libc::S_IRWXU)
@ -163,8 +165,11 @@ mod imp {
#[cfg(windows)]
mod imp {
use libc;
use std::ffi::AsOsStr;
use std::mem;
use std::os::windows::prelude::*;
use std::os;
use std::path::Path;
use std::ptr;
const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
@ -190,7 +195,7 @@ mod imp {
impl Lock {
pub fn new(p: &Path) -> Lock {
let mut p_16: Vec<u16> = p.as_str().unwrap().utf16_units().collect();
let mut p_16: Vec<_> = p.as_os_str().encode_wide().collect();
p_16.push(0);
let handle = unsafe {
libc::CreateFileW(p_16.as_ptr(),

View file

@ -9,7 +9,8 @@
// except according to those terms.
use std::fmt;
use std::old_io;
use std::io::prelude::*;
use std::io;
use externalfiles::ExternalHtml;
@ -31,8 +32,8 @@ pub struct Page<'a> {
}
pub fn render<T: fmt::Display, S: fmt::Display>(
dst: &mut old_io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
-> old_io::IoResult<()>
dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
-> io::Result<()>
{
write!(dst,
r##"<!DOCTYPE html>
@ -159,7 +160,7 @@ r##"<!DOCTYPE html>
)
}
pub fn redirect(dst: &mut old_io::Writer, url: &str) -> old_io::IoResult<()> {
pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
// <script> triggers a redirect before refresh, so this is fine.
write!(dst,
r##"<!DOCTYPE html>

View file

@ -38,11 +38,13 @@ use std::cell::RefCell;
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::ffi::OsStr;
use std::fmt;
use std::old_io::fs::PathExtensions;
use std::old_io::{fs, File, BufferedWriter, BufferedReader};
use std::old_io;
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, BufWriter, BufReader};
use std::iter::repeat;
use std::path::{PathBuf, Path};
use std::str;
use std::sync::Arc;
@ -89,10 +91,10 @@ pub struct Context {
pub root_path: String,
/// The path to the crate root source minus the file name.
/// Used for simplifying paths to the highlighted source code files.
pub src_root: Path,
pub src_root: PathBuf,
/// The current destination folder of where HTML artifacts should be placed.
/// This changes as the context descends into the module hierarchy.
pub dst: Path,
pub dst: PathBuf,
/// This describes the layout of each page, and is not modified after
/// creation of the context (contains info like the favicon and added html).
pub layout: layout::Layout,
@ -220,7 +222,7 @@ struct SourceCollector<'a> {
/// Processed source-file paths
seen: HashSet<String>,
/// Root destination to place all HTML output into
dst: Path,
dst: PathBuf,
}
/// Wrapper struct to render the source code of a file. This will do things like
@ -257,11 +259,15 @@ thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> =
/// Generates the documentation for `crate` into the directory `dst`
pub fn run(mut krate: clean::Crate,
external_html: &ExternalHtml,
dst: Path,
passes: HashSet<String>) -> old_io::IoResult<()> {
dst: PathBuf,
passes: HashSet<String>) -> io::Result<()> {
let src_root = match krate.src.parent() {
Some(p) => p.to_path_buf(),
None => PathBuf::new(""),
};
let mut cx = Context {
dst: dst,
src_root: krate.src.dir_path(),
src_root: src_root,
passes: passes,
current: Vec::new(),
root_path: String::new(),
@ -392,7 +398,7 @@ pub fn run(mut krate: clean::Crate,
cx.krate(krate, summary)
}
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<String> {
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
// Build the search index from the collected metadata
let mut nodeid_to_pathid = HashMap::new();
let mut pathid_to_nodeid = Vec::new();
@ -437,7 +443,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
}
// Collect the index into a string
let mut w = Vec::new();
let mut w = io::Cursor::new(Vec::new());
try!(write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name));
let mut lastpath = "".to_string();
@ -480,13 +486,13 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
try!(write!(&mut w, "]}};"));
Ok(String::from_utf8(w).unwrap())
Ok(String::from_utf8(w.into_inner()).unwrap())
}
fn write_shared(cx: &Context,
krate: &clean::Crate,
cache: &Cache,
search_index: String) -> old_io::IoResult<()> {
search_index: String) -> io::Result<()> {
// Write out the shared files. Note that these are shared among all rustdoc
// docs placed in the output directory, so this needs to be a synchronized
// operation with respect to all other rustdocs running around.
@ -518,10 +524,10 @@ fn write_shared(cx: &Context,
include_bytes!("static/SourceCodePro-Semibold.woff")));
fn collect(path: &Path, krate: &str,
key: &str) -> old_io::IoResult<Vec<String>> {
key: &str) -> io::Result<Vec<String>> {
let mut ret = Vec::new();
if path.exists() {
for line in BufferedReader::new(File::open(path)).lines() {
for line in BufReader::new(try!(File::open(path))).lines() {
let line = try!(line);
if !line.starts_with(key) {
continue
@ -567,14 +573,14 @@ fn write_shared(cx: &Context,
mydst.push(part);
try!(mkdir(&mydst));
}
mydst.push(format!("{}.{}.js",
remote_item_type.to_static_str(),
remote_path[remote_path.len() - 1]));
mydst.push(&format!("{}.{}.js",
remote_item_type.to_static_str(),
remote_path[remote_path.len() - 1]));
let all_implementors = try!(collect(&mydst, &krate.name,
"implementors"));
try!(mkdir(&mydst.dir_path()));
let mut f = BufferedWriter::new(try!(File::create(&mydst)));
try!(mkdir(mydst.parent().unwrap()));
let mut f = BufWriter::new(try!(File::create(&mydst)));
try!(writeln!(&mut f, "(function() {{var implementors = {{}};"));
for implementor in &all_implementors {
@ -606,7 +612,7 @@ fn write_shared(cx: &Context,
}
fn render_sources(cx: &mut Context,
krate: clean::Crate) -> old_io::IoResult<clean::Crate> {
krate: clean::Crate) -> io::Result<clean::Crate> {
info!("emitting source files");
let dst = cx.dst.join("src");
try!(mkdir(&dst));
@ -624,15 +630,15 @@ fn render_sources(cx: &mut Context,
/// Writes the entire contents of a string to a destination, not attempting to
/// catch any errors.
fn write(dst: Path, contents: &[u8]) -> old_io::IoResult<()> {
File::create(&dst).write_all(contents)
fn write(dst: PathBuf, contents: &[u8]) -> io::Result<()> {
try!(File::create(&dst)).write_all(contents)
}
/// Makes a directory on the filesystem, failing the task if an error occurs and
/// skipping if the directory already exists.
fn mkdir(path: &Path) -> old_io::IoResult<()> {
fn mkdir(path: &Path) -> io::Result<()> {
if !path.exists() {
fs::mkdir(path, old_io::USER_RWX)
fs::create_dir(path)
} else {
Ok(())
}
@ -648,21 +654,17 @@ fn shortty(item: &clean::Item) -> ItemType {
/// static HTML tree.
// FIXME (#9639): The closure should deal with &[u8] instead of &str
// FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths
fn clean_srcpath<F>(src_root: &Path, src: &[u8], mut f: F) where
fn clean_srcpath<F>(src_root: &Path, p: &Path, mut f: F) where
F: FnMut(&str),
{
let p = Path::new(src);
// make it relative, if possible
let p = p.path_relative_from(src_root).unwrap_or(p);
let p = p.relative_from(src_root).unwrap_or(p);
if p.as_vec() != b"." {
for c in p.str_components().map(|x|x.unwrap()) {
if ".." == c {
f("up");
} else {
f(c)
}
for c in p.iter().map(|x| x.to_str().unwrap()) {
if ".." == c {
f("up");
} else {
f(c)
}
}
}
@ -733,13 +735,14 @@ impl<'a> DocFolder for SourceCollector<'a> {
impl<'a> SourceCollector<'a> {
/// Renders the given filename into its corresponding HTML source file.
fn emit_source(&mut self, filename: &str) -> old_io::IoResult<()> {
let p = Path::new(filename);
fn emit_source(&mut self, filename: &str) -> io::Result<()> {
let p = PathBuf::new(filename);
// If we couldn't open this file, then just returns because it
// probably means that it's some standard library macro thing and we
// can't have the source to it anyway.
let contents = match File::open(&p).read_to_end() {
let mut contents = Vec::new();
match File::open(&p).and_then(|mut f| f.read_to_end(&mut contents)) {
Ok(r) => r,
// macros from other libraries get special filenames which we can
// safely ignore
@ -759,18 +762,20 @@ impl<'a> SourceCollector<'a> {
// Create the intermediate directories
let mut cur = self.dst.clone();
let mut root_path = String::from_str("../../");
clean_srcpath(&self.cx.src_root, p.dirname(), |component| {
clean_srcpath(&self.cx.src_root, &p, |component| {
cur.push(component);
mkdir(&cur).unwrap();
root_path.push_str("../");
});
let mut fname = p.filename().expect("source has no filename").to_vec();
fname.extend(".html".bytes());
cur.push(fname);
let mut w = BufferedWriter::new(try!(File::create(&cur)));
let mut fname = p.file_name().expect("source has no filename")
.to_os_string();
fname.push_os_str(OsStr::from_str(".html"));
cur.push(&fname);
let mut w = BufWriter::new(try!(File::create(&cur)));
let title = format!("{} -- source", cur.filename_display());
let title = format!("{} -- source", cur.file_name().unwrap()
.to_string_lossy());
let desc = format!("Source to the Rust file `{}`.", filename);
let page = layout::Page {
title: &title,
@ -779,7 +784,7 @@ impl<'a> SourceCollector<'a> {
description: &desc,
keywords: get_basic_keywords(),
};
try!(layout::render(&mut w as &mut Writer, &self.cx.layout,
try!(layout::render(&mut w, &self.cx.layout,
&page, &(""), &Source(contents)));
try!(w.flush());
return Ok(());
@ -1081,7 +1086,7 @@ impl Context {
/// This currently isn't parallelized, but it'd be pretty easy to add
/// parallelization to this function.
fn krate(mut self, mut krate: clean::Crate,
stability: stability_summary::ModuleSummary) -> old_io::IoResult<()> {
stability: stability_summary::ModuleSummary) -> io::Result<()> {
let mut item = match krate.module.take() {
Some(i) => i,
None => return Ok(())
@ -1091,7 +1096,7 @@ impl Context {
// render stability dashboard
try!(self.recurse(stability.name.clone(), |this| {
let json_dst = &this.dst.join("stability.json");
let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
let mut json_out = BufWriter::new(try!(File::create(json_dst)));
try!(write!(&mut json_out, "{}", json::as_json(&stability)));
let mut title = stability.name.clone();
@ -1106,7 +1111,7 @@ impl Context {
keywords: get_basic_keywords(),
};
let html_dst = &this.dst.join("stability.html");
let mut html_out = BufferedWriter::new(try!(File::create(html_dst)));
let mut html_out = BufWriter::new(try!(File::create(html_dst)));
layout::render(&mut html_out, &this.layout, &page,
&Sidebar{ cx: this, item: &item },
&stability)
@ -1131,12 +1136,12 @@ impl Context {
/// all sub-items which need to be rendered.
///
/// The rendering driver uses this closure to queue up more work.
fn item<F>(&mut self, item: clean::Item, mut f: F) -> old_io::IoResult<()> where
fn item<F>(&mut self, item: clean::Item, mut f: F) -> io::Result<()> where
F: FnMut(&mut Context, clean::Item),
{
fn render(w: old_io::File, cx: &Context, it: &clean::Item,
pushname: bool) -> old_io::IoResult<()> {
info!("Rendering an item to {}", w.path().display());
fn render(w: File, cx: &Context, it: &clean::Item,
pushname: bool) -> io::Result<()> {
info!("Rendering an item to {}", w.path().unwrap().display());
// A little unfortunate that this is done like this, but it sure
// does make formatting *a lot* nicer.
CURRENT_LOCATION_KEY.with(|slot| {
@ -1177,7 +1182,7 @@ impl Context {
// We have a huge number of calls to write, so try to alleviate some
// of the pain by using a buffered writer instead of invoking the
// write syscall all the time.
let mut writer = BufferedWriter::new(w);
let mut writer = BufWriter::new(w);
if !cx.render_redirect_pages {
try!(layout::render(&mut writer, &cx.layout, &page,
&Sidebar{ cx: cx, item: it },
@ -1238,7 +1243,7 @@ impl Context {
// Things which don't have names (like impls) don't get special
// pages dedicated to them.
_ if item.name.is_some() => {
let dst = self.dst.join(item_path(&item));
let dst = self.dst.join(&item_path(&item));
let dst = try!(File::create(&dst));
render(dst, self, &item, true)
}
@ -1307,7 +1312,7 @@ impl<'a> Item<'a> {
// has anchors for the line numbers that we're linking to.
if ast_util::is_local(self.item.def_id) {
let mut path = Vec::new();
clean_srcpath(&cx.src_root, self.item.source.filename.as_bytes(),
clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename),
|component| {
path.push(component.to_string());
});

View file

@ -34,6 +34,10 @@
#![feature(test)]
#![feature(unicode)]
#![feature(str_words)]
#![feature(io)]
#![feature(fs)]
#![feature(path)]
#![feature(tempdir)]
extern crate arena;
extern crate getopts;
@ -53,10 +57,12 @@ extern crate "serialize" as rustc_serialize; // used by deriving
use std::cell::RefCell;
use std::collections::HashMap;
use std::env;
use std::old_io::File;
use std::old_io;
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::mpsc::channel;
use externalfiles::ExternalHtml;
use serialize::Decodable;
use serialize::json::{self, Json};
@ -242,7 +248,7 @@ pub fn main_args(args: &[String]) -> int {
let should_test = matches.opt_present("test");
let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
let output = matches.opt_str("o").map(|s| Path::new(s));
let output = matches.opt_str("o").map(|s| PathBuf::new(&s));
let cfgs = matches.opt_strs("cfg");
let external_html = match ExternalHtml::load(
@ -261,7 +267,8 @@ pub fn main_args(args: &[String]) -> int {
(true, false) => {
return test::run(input, cfgs, libs, externs, test_args, crate_name)
}
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
(false, true) => return markdown::render(input,
output.unwrap_or(PathBuf::new("doc")),
&matches, &external_html,
!matches.opt_present("markdown-no-toc")),
(false, false) => {}
@ -278,7 +285,8 @@ pub fn main_args(args: &[String]) -> int {
info!("going to format");
match matches.opt_str("w").as_ref().map(|s| &**s) {
Some("html") | None => {
match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc")),
match html::render::run(krate, &external_html,
output.unwrap_or(PathBuf::new("doc")),
passes.into_iter().collect()) {
Ok(()) => {}
Err(e) => panic!("failed to generate documentation: {}", e),
@ -286,7 +294,7 @@ pub fn main_args(args: &[String]) -> int {
}
Some("json") => {
match json_output(krate, json_plugins,
output.unwrap_or(Path::new("doc.json"))) {
output.unwrap_or(PathBuf::new("doc.json"))) {
Ok(()) => {}
Err(e) => panic!("failed to write json: {}", e),
}
@ -364,15 +372,15 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
let cfgs = matches.opt_strs("cfg");
let triple = matches.opt_str("target");
let cr = Path::new(cratefile);
let cr = PathBuf::new(cratefile);
info!("starting to run rustc");
let (tx, rx) = channel();
std::thread::spawn(move || {
use rustc::session::config::Input;
let cr = cr;
tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), triple)).unwrap();
tx.send(core::run_core(paths, cfgs, externs, Input::File(cr),
triple)).unwrap();
}).join().map_err(|_| "rustc failed").unwrap();
let (mut krate, analysis) = rx.recv().unwrap();
info!("finished with rustc");
@ -451,13 +459,12 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
/// This input format purely deserializes the json output file. No passes are
/// run over the deserialized output.
fn json_input(input: &str) -> Result<Output, String> {
let mut input = match File::open(&Path::new(input)) {
Ok(f) => f,
Err(e) => {
return Err(format!("couldn't open {}: {}", input, e))
}
let mut bytes = Vec::new();
match File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
Ok(()) => {}
Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
};
match json::from_reader(&mut input) {
match json::from_reader(&mut &bytes[..]) {
Err(s) => Err(format!("{:?}", s)),
Ok(Json::Object(obj)) => {
let mut obj = obj;
@ -495,7 +502,7 @@ fn json_input(input: &str) -> Result<Output, String> {
/// Outputs the crate/plugin json as a giant json blob at the specified
/// destination.
fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
dst: Path) -> old_io::IoResult<()> {
dst: PathBuf) -> io::Result<()> {
// {
// "schema": version,
// "crate": { parsed crate ... },

View file

@ -8,7 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::fs::File;
use std::io::Write;
use std::old_io;
use std::path::{PathBuf, Path};
use core;
use getopts;
@ -40,10 +43,10 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
/// (e.g. output = "bar" => "bar/foo.html").
pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
external_html: &ExternalHtml, include_toc: bool) -> int {
let input_p = Path::new(input);
output.push(input_p.filestem().unwrap());
output.push(input_p.file_stem().unwrap());
output.set_extension("html");
let mut css = String::new();
@ -59,7 +62,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
}
let playground = playground.unwrap_or("".to_string());
let mut out = match old_io::File::create(&output) {
let mut out = match File::create(&output) {
Err(e) => {
let _ = writeln!(&mut old_io::stderr(),
"error opening `{}` for writing: {}",

View file

@ -9,16 +9,20 @@
// except according to those terms.
use std::cell::RefCell;
use std::sync::mpsc::channel;
use std::collections::{HashSet, HashMap};
use std::dynamic_lib::DynamicLibrary;
use std::old_io::{Command, TempDir};
use std::env;
use std::ffi::OsString;
use std::fs::TempDir;
use std::old_io;
use std::os;
use std::io;
use std::path::PathBuf;
use std::process::Command;
use std::str;
use std::sync::mpsc::channel;
use std::thread;
use std::thunk::Thunk;
use std::collections::{HashSet, HashMap};
use testing;
use rustc_lint;
use rustc::session::{self, config};
@ -43,11 +47,12 @@ pub fn run(input: &str,
mut test_args: Vec<String>,
crate_name: Option<String>)
-> int {
let input_path = Path::new(input);
let input_path = PathBuf::new(input);
let input = config::Input::File(input_path.clone());
let sessopts = config::Options {
maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()),
maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
.parent().unwrap().to_path_buf()),
search_paths: libs.clone(),
crate_types: vec!(config::CrateTypeDylib),
externs: externs.clone(),
@ -115,7 +120,8 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
let input = config::Input::Str(test.to_string());
let sessopts = config::Options {
maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()),
maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
.parent().unwrap().to_path_buf()),
search_paths: libs,
crate_types: vec!(config::CrateTypeExecutable),
output_types: vec!(config::OutputTypeExe),
@ -170,7 +176,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
let out = Some(outdir.path().clone());
let out = Some(outdir.path().to_path_buf());
let cfg = config::build_configuration(&sess);
let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
let mut control = driver::CompileController::basic();
@ -187,17 +193,19 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
// environment to ensure that the target loads the right libraries at
// runtime. It would be a sad day if the *host* libraries were loaded as a
// mistake.
let mut cmd = Command::new(outdir.path().join("rust-out"));
let mut cmd = Command::new(&outdir.path().join("rust-out"));
let var = DynamicLibrary::envvar();
let newpath = {
let mut path = DynamicLibrary::search_path();
let path = env::var_os(var).unwrap_or(OsString::new());
let mut path = env::split_paths(&path).collect::<Vec<_>>();
path.insert(0, libdir.clone());
DynamicLibrary::create_path(&path)
env::join_paths(path.iter()).unwrap()
};
cmd.env(DynamicLibrary::envvar(), newpath);
cmd.env(var, &newpath);
match cmd.output() {
Err(e) => panic!("couldn't run the test: {}{}", e,
if e.kind == old_io::PermissionDenied {
if e.kind() == io::ErrorKind::PermissionDenied {
" - maybe your tempdir is mounted with noexec?"
} else { "" }),
Ok(out) => {
@ -205,7 +213,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
panic!("test executable succeeded when it should have failed");
} else if !should_fail && !out.status.success() {
panic!("test executable failed:\n{:?}",
str::from_utf8(&out.error));
str::from_utf8(&out.stdout));
}
}
}