diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-02-26 21:00:43 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-03-04 15:59:30 -0800 |
| commit | 95d904625b4d45af80b4e40d51a3a0fde1abaa8a (patch) | |
| tree | b0872e63b8d75543ce5141ceba44c12c459474f2 | |
| parent | 3b3bb0e682c2d252e9f62dd9df5cff9552af91ad (diff) | |
| download | rust-95d904625b4d45af80b4e40d51a3a0fde1abaa8a.tar.gz rust-95d904625b4d45af80b4e40d51a3a0fde1abaa8a.zip | |
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.
80 files changed, 1430 insertions, 1209 deletions
diff --git a/mk/docs.mk b/mk/docs.mk index 743032f676d..f7ab86d3a29 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -273,11 +273,13 @@ compiler-docs: $(COMPILER_DOC_TARGETS) trpl: doc/book/index.html doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/ + @$(call E, rustbook: $@) $(Q)rm -rf doc/book $(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book style: doc/style/index.html doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/ + @$(call E, rustbook: $@) $(Q)rm -rf doc/style $(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index 2c046d25279..fe556cecef6 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -11,6 +11,7 @@ pub use self::Mode::*; use std::fmt; use std::str::FromStr; +use std::path::PathBuf; #[derive(Clone, Copy, PartialEq, Debug)] pub enum Mode { @@ -68,13 +69,13 @@ pub struct Config { pub run_lib_path: String, // The rustc executable - pub rustc_path: Path, + pub rustc_path: PathBuf, // The clang executable - pub clang_path: Option<Path>, + pub clang_path: Option<PathBuf>, // The llvm binaries path - pub llvm_bin_path: Option<Path>, + pub llvm_bin_path: Option<PathBuf>, // The valgrind path pub valgrind_path: Option<String>, @@ -84,13 +85,13 @@ pub struct Config { pub force_valgrind: bool, // The directory containing the tests to run - pub src_base: Path, + pub src_base: PathBuf, // The directory where programs should be built - pub build_base: Path, + pub build_base: PathBuf, // Directory for auxiliary libraries - pub aux_base: Path, + pub aux_base: PathBuf, // The name of the stage being built (stage1, etc) pub stage_id: String, @@ -105,7 +106,7 @@ pub struct Config { pub filter: Option<String>, // Write out a parseable log of tests that were run - pub logfile: Option<Path>, + pub logfile: Option<PathBuf>, // A command line to prefix program execution with, // for running under valgrind @@ -133,7 +134,7 @@ pub struct Config { pub lldb_version: Option<String>, // Path to the android tools - pub android_cross_path: Path, + pub android_cross_path: PathBuf, // Extra parameter to run adb on arm-linux-androideabi pub adb_path: String, diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 4993dd140d3..b9e6f1842ee 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -21,6 +21,11 @@ #![feature(test)] #![feature(unicode)] #![feature(core)] +#![feature(path)] +#![feature(os)] +#![feature(io)] +#![feature(fs)] +#![feature(net)] #![deny(warnings)] @@ -31,8 +36,9 @@ extern crate getopts; extern crate log; use std::env; +use std::fs; use std::old_io; -use std::old_io::fs; +use std::path::{Path, PathBuf}; use std::thunk::Thunk; use getopts::{optopt, optflag, reqopt}; use common::Config; @@ -114,9 +120,9 @@ pub fn parse_config(args: Vec<String> ) -> Config { panic!() } - fn opt_path(m: &getopts::Matches, nm: &str) -> Path { + fn opt_path(m: &getopts::Matches, nm: &str) -> PathBuf { match m.opt_str(nm) { - Some(s) => Path::new(s), + Some(s) => PathBuf::new(&s), None => panic!("no option (=path) found for {}", nm), } } @@ -131,10 +137,10 @@ pub fn parse_config(args: Vec<String> ) -> Config { compile_lib_path: matches.opt_str("compile-lib-path").unwrap(), run_lib_path: matches.opt_str("run-lib-path").unwrap(), rustc_path: opt_path(matches, "rustc-path"), - clang_path: matches.opt_str("clang-path").map(|s| Path::new(s)), + clang_path: matches.opt_str("clang-path").map(|s| PathBuf::new(&s)), valgrind_path: matches.opt_str("valgrind-path"), force_valgrind: matches.opt_present("force-valgrind"), - llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| Path::new(s)), + llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::new(&s)), src_base: opt_path(matches, "src-base"), build_base: opt_path(matches, "build-base"), aux_base: opt_path(matches, "aux-base"), @@ -142,7 +148,7 @@ pub fn parse_config(args: Vec<String> ) -> Config { mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"), run_ignored: matches.opt_present("ignored"), filter: filter, - logfile: matches.opt_str("logfile").map(|s| Path::new(s)), + logfile: matches.opt_str("logfile").map(|s| PathBuf::new(&s)), runtool: matches.opt_str("runtool"), host_rustcflags: matches.opt_str("host-rustcflags"), target_rustcflags: matches.opt_str("target-rustcflags"), @@ -276,9 +282,9 @@ pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> { debug!("making tests from {:?}", config.src_base.display()); let mut tests = Vec::new(); - let dirs = fs::readdir(&config.src_base).unwrap(); - for file in &dirs { - let file = file.clone(); + let dirs = fs::read_dir(&config.src_base).unwrap(); + for file in dirs { + let file = file.unwrap().path(); debug!("inspecting file {:?}", file.display()); if is_test(config, &file) { let t = make_test(config, &file, || { @@ -301,7 +307,7 @@ pub fn is_test(config: &Config, testfile: &Path) -> bool { _ => vec!(".rc".to_string(), ".rs".to_string()) }; let invalid_prefixes = vec!(".".to_string(), "#".to_string(), "~".to_string()); - let name = testfile.filename_str().unwrap(); + let name = testfile.file_name().unwrap().to_str().unwrap(); let mut valid = false; @@ -337,9 +343,9 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName { // Try to elide redundant long paths fn shorten(path: &Path) -> String { - let filename = path.filename_str(); - let p = path.dir_path(); - let dir = p.filename_str(); + let filename = path.file_name().unwrap().to_str(); + let p = path.parent().unwrap(); + let dir = p.file_name().unwrap().to_str(); format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or("")) } @@ -348,19 +354,17 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName { pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); - // FIXME (#9639): This needs to handle non-utf8 paths - let testfile = testfile.as_str().unwrap().to_string(); + let testfile = testfile.to_path_buf(); test::DynTestFn(Thunk::new(move || { - runtest::run(config, testfile) + runtest::run(config, &testfile) })) } pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); - // FIXME (#9639): This needs to handle non-utf8 paths - let testfile = testfile.as_str().unwrap().to_string(); + let testfile = testfile.to_path_buf(); test::DynMetricFn(box move |mm: &mut test::MetricMap| { - runtest::run_metrics(config, testfile, mm) + runtest::run_metrics(config, &testfile, mm) }) } diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 7411a9b48d4..25f962c5785 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -9,7 +9,10 @@ // except according to those terms. use self::WhichLine::*; -use std::old_io::{BufferedReader, File}; +use std::fs::File; +use std::io::BufReader; +use std::io::prelude::*; +use std::path::Path; pub struct ExpectedError { pub line: uint, @@ -29,7 +32,7 @@ enum WhichLine { ThisLine, FollowPrevious(uint), AdjustBackward(uint) } /// //~| ERROR message two for that same line. // Load any test directives embedded in the file pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> { - let mut rdr = BufferedReader::new(File::open(testfile).unwrap()); + let rdr = BufReader::new(File::open(testfile).unwrap()); // `last_nonfollow_error` tracks the most recently seen // line with an error template that did not use the diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index e5570fe0b8f..21cebc61b3a 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -9,6 +9,10 @@ // except according to those terms. use std::env; +use std::fs::File; +use std::io::BufReader; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; use common::Config; use common; @@ -23,7 +27,7 @@ pub struct TestProps { pub run_flags: Option<String>, // If present, the name of a file that this test should match when // pretty-printed - pub pp_exact: Option<Path>, + pub pp_exact: Option<PathBuf>, // Modules from aux directory that should be compiled pub aux_builds: Vec<String> , // Environment settings to use during execution @@ -62,7 +66,7 @@ pub fn load_props(testfile: &Path) -> TestProps { let mut pretty_mode = None; let mut pretty_compare_only = false; let mut forbid_output = Vec::new(); - iter_header(testfile, |ln| { + iter_header(testfile, &mut |ln| { match parse_error_pattern(ln) { Some(ep) => error_patterns.push(ep), None => () @@ -219,7 +223,7 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool { } } - let val = iter_header(testfile, |ln| { + let val = iter_header(testfile, &mut |ln| { !parse_name_directive(ln, "ignore-test") && !parse_name_directive(ln, &ignore_target(config)) && !parse_name_directive(ln, &ignore_stage(config)) && @@ -232,12 +236,8 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool { !val } -fn iter_header<F>(testfile: &Path, mut it: F) -> bool where - F: FnMut(&str) -> bool, -{ - use std::old_io::{BufferedReader, File}; - - let mut rdr = BufferedReader::new(File::open(testfile).unwrap()); +fn iter_header(testfile: &Path, it: &mut FnMut(&str) -> bool) -> bool { + let rdr = BufReader::new(File::open(testfile).unwrap()); for ln in rdr.lines() { // Assume that any directives will be found before the first // module or function. This doesn't seem to be an optimization @@ -322,12 +322,12 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> { }) } -fn parse_pp_exact(line: &str, testfile: &Path) -> Option<Path> { +fn parse_pp_exact(line: &str, testfile: &Path) -> Option<PathBuf> { match parse_name_value_directive(line, "pp-exact") { - Some(s) => Some(Path::new(s)), + Some(s) => Some(PathBuf::new(&s)), None => { if parse_name_directive(line, "pp-exact") { - testfile.filename().map(|s| Path::new(s)) + testfile.file_name().map(|s| PathBuf::new(s)) } else { None } diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 148a43e6c78..b684dbcface 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::process::{ProcessExit, Command, Process, ProcessOutput}; +use std::process::{ExitStatus, Command, Child, Output, Stdio}; +use std::io::prelude::*; use std::dynamic_lib::DynamicLibrary; fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { @@ -25,10 +26,10 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) { let var = DynamicLibrary::envvar(); let newpath = DynamicLibrary::create_path(&path); let newpath = String::from_utf8(newpath).unwrap(); - cmd.env(var.to_string(), newpath); + cmd.env(var, &newpath); } -pub struct Result {pub status: ProcessExit, pub out: String, pub err: String} +pub struct Result {pub status: ExitStatus, pub out: String, pub err: String} pub fn run(lib_path: &str, prog: &str, @@ -38,10 +39,13 @@ pub fn run(lib_path: &str, input: Option<String>) -> Option<Result> { let mut cmd = Command::new(prog); - cmd.args(args); + cmd.args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); add_target_env(&mut cmd, lib_path, aux_path); for (key, val) in env { - cmd.env(key, val); + cmd.env(&key, &val); } match cmd.spawn() { @@ -49,13 +53,13 @@ pub fn run(lib_path: &str, if let Some(input) = input { process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap(); } - let ProcessOutput { status, output, error } = + let Output { status, stdout, stderr } = process.wait_with_output().unwrap(); Some(Result { status: status, - out: String::from_utf8(output).unwrap(), - err: String::from_utf8(error).unwrap() + out: String::from_utf8(stdout).unwrap(), + err: String::from_utf8(stderr).unwrap() }) }, Err(..) => None @@ -67,13 +71,16 @@ pub fn run_background(lib_path: &str, aux_path: Option<&str>, args: &[String], env: Vec<(String, String)> , - input: Option<String>) -> Option<Process> { + input: Option<String>) -> Option<Child> { let mut cmd = Command::new(prog); - cmd.args(args); + cmd.args(args) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); add_target_env(&mut cmd, lib_path, aux_path); for (key, val) in env { - cmd.env(key, val); + cmd.env(&key, &val); } match cmd.spawn() { diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 7ac8a9b041c..7fb1a436ba3 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -11,35 +11,30 @@ use self::TargetLocation::*; use common::Config; -use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb}; -use common::{Codegen, DebugInfoLldb}; +use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind}; +use common::{Codegen, DebugInfoLldb, DebugInfoGdb}; use errors; use header::TestProps; use header; use procsrv; use util::logv; -#[cfg(target_os = "windows")] -use util; - -#[cfg(target_os = "windows")] -use std::ascii::AsciiExt; -use std::old_io::File; -use std::old_io::fs::PathExtensions; -use std::old_io::fs; -use std::old_io::net::tcp; -use std::old_io::process::ProcessExit; -use std::old_io::process; -use std::old_io::timer; -use std::old_io; + use std::env; +use std::ffi::OsStr; +use std::fmt; +use std::fs::{self, File}; +use std::io::BufReader; +use std::io::prelude::*; use std::iter::repeat; +use std::net::TcpStream; +use std::old_io::timer; +use std::path::{Path, PathBuf}; +use std::process::{Command, Output, ExitStatus}; use std::str; -use std::string::String; -use std::thread; use std::time::Duration; use test::MetricMap; -pub fn run(config: Config, testfile: String) { +pub fn run(config: Config, testfile: &Path) { match &*config.target { "arm-linux-androideabi" | "aarch64-linux-android" => { @@ -55,12 +50,11 @@ pub fn run(config: Config, testfile: String) { run_metrics(config, testfile, &mut _mm); } -pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) { +pub fn run_metrics(config: Config, testfile: &Path, mm: &mut MetricMap) { if config.verbose { // We're going to be dumping a lot of info. Start on a new line. print!("\n\n"); } - let testfile = Path::new(testfile); debug!("running {:?}", testfile.display()); let props = header::load_props(&testfile); debug!("loaded props"); @@ -127,8 +121,8 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { }; // The value our Makefile configures valgrind to return on failure - const VALGRIND_ERR: int = 100; - if proc_res.status.matches_exit_status(VALGRIND_ERR) { + const VALGRIND_ERR: i32 = 100; + if proc_res.status.code() == Some(VALGRIND_ERR) { fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res); } @@ -139,10 +133,10 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { fn check_correct_failure_status(proc_res: &ProcRes) { // The value the rust runtime returns on failure - const RUST_ERR: int = 101; - if !proc_res.status.matches_exit_status(RUST_ERR) { + const RUST_ERR: i32 = 101; + if proc_res.status.code() != Some(RUST_ERR) { fatal_proc_rec( - &format!("failure produced the wrong error: {:?}", + &format!("failure produced the wrong error: {}", proc_res.status), proc_res); } @@ -201,8 +195,8 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { let rounds = match props.pp_exact { Some(_) => 1, None => 2 }; - let src = File::open(testfile).read_to_end().unwrap(); - let src = String::from_utf8(src.clone()).unwrap(); + let mut src = String::new(); + File::open(testfile).unwrap().read_to_string(&mut src).unwrap(); let mut srcs = vec!(src); let mut round = 0; @@ -226,9 +220,10 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { let mut expected = match props.pp_exact { Some(ref file) => { - let filepath = testfile.dir_path().join(file); - let s = File::open(&filepath).read_to_end().unwrap(); - String::from_utf8(s).unwrap() + let filepath = testfile.parent().unwrap().join(file); + let mut s = String::new(); + File::open(&filepath).unwrap().read_to_string(&mut s).unwrap(); + s } None => { srcs[srcs.len() - 2].clone() } }; @@ -283,7 +278,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { pretty_type.to_string()), props.exec_env.clone(), &config.compile_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), Some(src)) } @@ -299,11 +294,11 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { pretty_type, format!("--target={}", config.target), "-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); args.extend(split_maybe_args(&config.target_rustcflags).into_iter()); args.extend(split_maybe_args(&props.compile_flags).into_iter()); return ProcArgs { - prog: config.rustc_path.as_str().unwrap().to_string(), + prog: config.rustc_path.to_str().unwrap().to_string(), args: args, }; } @@ -345,14 +340,14 @@ actual:\n\ "--crate-type=lib".to_string(), format!("--target={}", target), "-L".to_string(), - config.build_base.as_str().unwrap().to_string(), + config.build_base.to_str().unwrap().to_string(), "-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); args.extend(split_maybe_args(&config.target_rustcflags).into_iter()); args.extend(split_maybe_args(&props.compile_flags).into_iter()); // FIXME (#9639): This needs to handle non-utf8 paths return ProcArgs { - prog: config.rustc_path.as_str().unwrap().to_string(), + prog: config.rustc_path.to_str().unwrap().to_string(), args: args, }; } @@ -390,18 +385,19 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { // write debugger script let mut script_str = String::with_capacity(2048); script_str.push_str("set charset UTF-8\n"); - script_str.push_str(&format!("file {}\n", exe_file.as_str().unwrap())); + script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap())); script_str.push_str("target remote :5039\n"); script_str.push_str(&format!("set solib-search-path \ ./{}/stage2/lib/rustlib/{}/lib/\n", config.host, config.target)); for line in breakpoint_lines.iter() { script_str.push_str(&format!("break {:?}:{}\n", - testfile.filename_display(), + testfile.file_name().unwrap() + .to_string_lossy(), *line)[..]); } script_str.push_str(&cmds); - script_str.push_str("quit\n"); + script_str.push_str("\nquit\n"); debug!("script_str = {}", script_str); dump_output_file(config, @@ -415,7 +411,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { None, &[ "push".to_string(), - exe_file.as_str().unwrap().to_string(), + exe_file.to_str().unwrap().to_string(), config.adb_test_dir.clone() ], vec!(("".to_string(), "".to_string())), @@ -440,9 +436,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { if config.target.contains("aarch64") {"64"} else {""}, config.adb_test_dir.clone(), - str::from_utf8( - exe_file.filename() - .unwrap()).unwrap()); + exe_file.file_name().unwrap().to_str() + .unwrap()); let mut process = procsrv::run_background("", &config.adb_path @@ -459,16 +454,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { loop { //waiting 1 second for gdbserver start timer::sleep(Duration::milliseconds(1000)); - let result = thread::spawn(move || { - tcp::TcpStream::connect("127.0.0.1:5039").unwrap(); - }).join(); - if result.is_err() { - continue; + if TcpStream::connect("127.0.0.1:5039").is_ok() { + break } - break; } - let tool_path = match config.android_cross_path.as_str() { + let tool_path = match config.android_cross_path.to_str() { Some(x) => x.to_string(), None => fatal("cannot find android cross path") }; @@ -479,7 +470,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { vec!("-quiet".to_string(), "-batch".to_string(), "-nx".to_string(), - format!("-command={}", debugger_script.as_str().unwrap())); + format!("-command={}", debugger_script.to_str().unwrap())); let mut gdb_path = tool_path; gdb_path.push_str(&format!("/bin/{}-gdb", config.target)); @@ -503,12 +494,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { }; debugger_run_result = ProcRes { - status: status, + status: Status::Normal(status), stdout: out, stderr: err, cmdline: cmdline }; - if process.signal_kill().is_err() { + if process.kill().is_err() { println!("Adb process is already finished."); } } @@ -518,7 +509,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { .expect("Could not find Rust source root"); let rust_pp_module_rel_path = Path::new("./src/etc"); let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path) - .as_str() + .to_str() .unwrap() .to_string(); // write debugger script @@ -538,7 +529,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { // GDB's script auto loading safe path script_str.push_str( &format!("add-auto-load-safe-path {}\n", - rust_pp_module_abs_path.replace("\\", "\\\\")) + rust_pp_module_abs_path.replace(r"\", r"\\")) ); } } @@ -553,21 +544,24 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { script_str.push_str("set print pretty off\n"); // Add the pretty printer directory to GDB's source-file search path - script_str.push_str(&format!("directory {}\n", rust_pp_module_abs_path)[..]); + script_str.push_str(&format!("directory {}\n", + rust_pp_module_abs_path)); // Load the target executable script_str.push_str(&format!("file {}\n", - exe_file.as_str().unwrap().replace("\\", "\\\\"))[..]); + exe_file.to_str().unwrap() + .replace(r"\", r"\\"))); // Add line breakpoints for line in &breakpoint_lines { script_str.push_str(&format!("break '{}':{}\n", - testfile.filename_display(), - *line)[..]); + testfile.file_name().unwrap() + .to_string_lossy(), + *line)); } script_str.push_str(&cmds); - script_str.push_str("quit\n"); + script_str.push_str("\nquit\n"); debug!("script_str = {}", script_str); dump_output_file(config, @@ -576,13 +570,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { "debugger.script"); // run debugger script with gdb - #[cfg(windows)] - fn debugger() -> String { - "gdb.exe".to_string() - } - #[cfg(unix)] - fn debugger() -> String { - "gdb".to_string() + fn debugger() -> &'static str { + if cfg!(windows) {"gdb.exe"} else {"gdb"} } let debugger_script = make_out_name(config, testfile, "debugger.script"); @@ -592,10 +581,10 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { vec!("-quiet".to_string(), "-batch".to_string(), "-nx".to_string(), - format!("-command={}", debugger_script.as_str().unwrap())); + format!("-command={}", debugger_script.to_str().unwrap())); let proc_args = ProcArgs { - prog: debugger(), + prog: debugger().to_string(), args: debugger_opts, }; @@ -618,7 +607,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { check_debugger_output(&debugger_run_result, &check_lines); } -fn find_rust_src_root(config: &Config) -> Option<Path> { +fn find_rust_src_root(config: &Config) -> Option<PathBuf> { let mut path = config.src_base.clone(); let path_postfix = Path::new("src/etc/lldb_batchmode.py"); @@ -632,8 +621,6 @@ fn find_rust_src_root(config: &Config) -> Option<Path> { } fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) { - use std::old_io::process::{Command, ProcessOutput}; - if config.lldb_python_dir.is_none() { fatal("Can't run LLDB test because LLDB's python path is not set."); } @@ -685,11 +672,12 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) .expect("Could not find Rust source root"); let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py"); let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path) - .as_str() + .to_str() .unwrap() .to_string(); - script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]); + script_str.push_str(&format!("command script import {}\n", + &rust_pp_module_abs_path[..])[..]); script_str.push_str("type summary add --no-value "); script_str.push_str("--python-function lldb_rust_formatters.print_val "); script_str.push_str("-x \".*\" --category Rust\n"); @@ -707,7 +695,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) } // Finally, quit the debugger - script_str.push_str("quit\n"); + script_str.push_str("\nquit\n"); // Write the script into a file debug!("script_str = {}", script_str); @@ -735,22 +723,19 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) rust_src_root: &Path) -> ProcRes { // Prepare the lldb_batchmode which executes the debugger script - let lldb_script_path = rust_src_root.join(Path::new("./src/etc/lldb_batchmode.py")); + let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py"); let mut cmd = Command::new("python"); - cmd.arg(lldb_script_path) + cmd.arg(&lldb_script_path) .arg(test_executable) .arg(debugger_script) - .env_set_all(&[("PYTHONPATH", config.lldb_python_dir.clone().unwrap())]); - - let (status, out, err) = match cmd.spawn() { - Ok(process) => { - let ProcessOutput { status, output, error } = - process.wait_with_output().unwrap(); + .env("PYTHONPATH", config.lldb_python_dir.as_ref().unwrap()); + let (status, out, err) = match cmd.output() { + Ok(Output { status, stdout, stderr }) => { (status, - String::from_utf8(output).unwrap(), - String::from_utf8(error).unwrap()) + String::from_utf8(stdout).unwrap(), + String::from_utf8(stderr).unwrap()) }, Err(e) => { fatal(&format!("Failed to setup Python process for \ @@ -760,7 +745,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) dump_output(config, test_executable, &out, &err); return ProcRes { - status: status, + status: Status::Normal(status), stdout: out, stderr: err, cmdline: format!("{:?}", cmd) @@ -776,8 +761,6 @@ struct DebuggerCommands { fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) -> DebuggerCommands { - use std::old_io::{BufferedReader, File}; - let command_directive = format!("{}-command", debugger_prefix); let check_directive = format!("{}-check", debugger_prefix); @@ -785,7 +768,7 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) let mut commands = vec!(); let mut check_lines = vec!(); let mut counter = 1; - let mut reader = BufferedReader::new(File::open(file_path).unwrap()); + let reader = BufReader::new(File::open(file_path).unwrap()); for line in reader.lines() { match line { Ok(line) => { @@ -963,16 +946,17 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> , let prefixes = expected_errors.iter().map(|ee| { format!("{}:{}:", testfile.display(), ee.line) - }).collect::<Vec<String> >(); - - #[cfg(windows)] - fn prefix_matches( line : &str, prefix : &str ) -> bool { - line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase()) - } - - #[cfg(unix)] - fn prefix_matches( line : &str, prefix : &str ) -> bool { - line.starts_with( prefix ) + }).collect::<Vec<String>>(); + + fn prefix_matches(line: &str, prefix: &str) -> bool { + use std::ascii::AsciiExt; + // On windows just translate all '\' path separators to '/' + let line = line.replace(r"\", "/"); + if cfg!(windows) { + line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase()) + } else { + line.starts_with(prefix) + } } // A multi-line error will have followup lines which will always @@ -1113,12 +1097,42 @@ struct ProcArgs { } struct ProcRes { - status: ProcessExit, + status: Status, stdout: String, stderr: String, cmdline: String, } +enum Status { + Parsed(i32), + Normal(ExitStatus), +} + +impl Status { + fn code(&self) -> Option<i32> { + match *self { + Status::Parsed(i) => Some(i), + Status::Normal(ref e) => e.code(), + } + } + + fn success(&self) -> bool { + match *self { + Status::Parsed(i) => i == 0, + Status::Normal(ref e) => e.success(), + } + } +} + +impl fmt::Display for Status { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Status::Parsed(i) => write!(f, "exit code: {}", i), + Status::Normal(ref e) => e.fmt(f), + } + } +} + fn compile_test(config: &Config, props: &TestProps, testfile: &Path) -> ProcRes { compile_test_(config, props, testfile, &[]) @@ -1133,7 +1147,7 @@ fn compile_test_(config: &Config, props: &TestProps, let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths let mut link_args = vec!("-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); link_args.extend(extra_args.iter().cloned()); let args = make_compile_args(config, props, @@ -1160,7 +1174,7 @@ fn exec_compiled_test(config: &Config, props: &TestProps, make_run_args(config, props, testfile), env, &config.run_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), None) } } @@ -1179,7 +1193,7 @@ fn compose_and_run_compiler( let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths - let extra_link_args = vec!("-L".to_string(), aux_dir.as_str().unwrap().to_string()); + let extra_link_args = vec!("-L".to_string(), aux_dir.to_str().unwrap().to_string()); for rel_ab in &props.aux_builds { let abs_ab = config.aux_base.join(rel_ab); @@ -1196,7 +1210,8 @@ fn compose_and_run_compiler( crate_type, |a,b| { let f = make_lib_name(a, b, testfile); - TargetLocation::ThisDirectory(f.dir_path()) + let parent = f.parent().unwrap(); + TargetLocation::ThisDirectory(parent.to_path_buf()) }, &abs_ab); let auxres = compose_and_run(config, @@ -1204,7 +1219,7 @@ fn compose_and_run_compiler( aux_args, Vec::new(), &config.compile_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), None); if !auxres.status.success() { fatal_proc_rec( @@ -1226,13 +1241,13 @@ fn compose_and_run_compiler( args, Vec::new(), &config.compile_lib_path, - Some(aux_dir.as_str().unwrap()), + Some(aux_dir.to_str().unwrap()), input) } fn ensure_dir(path: &Path) { if path.is_dir() { return; } - fs::mkdir(path, old_io::USER_RWX).unwrap(); + fs::create_dir(path).unwrap(); } fn compose_and_run(config: &Config, testfile: &Path, @@ -1246,8 +1261,8 @@ fn compose_and_run(config: &Config, testfile: &Path, } enum TargetLocation { - ThisFile(Path), - ThisDirectory(Path), + ThisFile(PathBuf), + ThisDirectory(PathBuf), } fn make_compile_args<F>(config: &Config, @@ -1265,9 +1280,9 @@ fn make_compile_args<F>(config: &Config, &*config.target }; // FIXME (#9639): This needs to handle non-utf8 paths - let mut args = vec!(testfile.as_str().unwrap().to_string(), + let mut args = vec!(testfile.to_str().unwrap().to_string(), "-L".to_string(), - config.build_base.as_str().unwrap().to_string(), + config.build_base.to_str().unwrap().to_string(), format!("--target={}", target)); args.push_all(&extras); if !props.no_prefer_dynamic { @@ -1284,7 +1299,7 @@ fn make_compile_args<F>(config: &Config, path } }; - args.push(path.as_str().unwrap().to_string()); + args.push(path.to_str().unwrap().to_string()); if props.force_host { args.extend(split_maybe_args(&config.host_rustcflags).into_iter()); } else { @@ -1292,24 +1307,24 @@ fn make_compile_args<F>(config: &Config, } args.extend(split_maybe_args(&props.compile_flags).into_iter()); return ProcArgs { - prog: config.rustc_path.as_str().unwrap().to_string(), + prog: config.rustc_path.to_str().unwrap().to_string(), args: args, }; } -fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> Path { +fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> PathBuf { // what we return here is not particularly important, as it // happens; rustc ignores everything except for the directory. let auxname = output_testname(auxfile); aux_output_dir_name(config, testfile).join(&auxname) } -fn make_exe_name(config: &Config, testfile: &Path) -> Path { +fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf { let mut f = output_base_name(config, testfile); if !env::consts::EXE_SUFFIX.is_empty() { - let mut fname = f.filename().unwrap().to_vec(); - fname.extend(env::consts::EXE_SUFFIX.bytes()); - f.set_filename(fname); + let mut fname = f.file_name().unwrap().to_os_string(); + fname.push_os_str(OsStr::from_str(env::consts::EXE_SUFFIX)); + f.set_file_name(&fname); } f } @@ -1322,7 +1337,7 @@ fn make_run_args(config: &Config, props: &TestProps, testfile: &Path) -> let exe_file = make_exe_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths - args.push(exe_file.as_str().unwrap().to_string()); + args.push(exe_file.to_str().unwrap().to_string()); // Add the arguments in the run_flags directive args.extend(split_maybe_args(&props.run_flags).into_iter()); @@ -1375,29 +1390,28 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String input).expect(&format!("failed to exec `{}`", prog)); dump_output(config, testfile, &out, &err); return ProcRes { - status: status, + status: Status::Normal(status), stdout: out, stderr: err, cmdline: cmdline, }; } -// Linux and mac don't require adjusting the library search path -#[cfg(unix)] -fn make_cmdline(_libpath: &str, prog: &str, args: &[String]) -> String { - format!("{} {}", prog, args.connect(" ")) -} - -#[cfg(windows)] fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String { + use util; - // Build the LD_LIBRARY_PATH variable as it would be seen on the command line - // for diagnostic purposes - fn lib_path_cmd_prefix(path: &str) -> String { - format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path)) - } + // Linux and mac don't require adjusting the library search path + if cfg!(unix) { + format!("{} {}", prog, args.connect(" ")) + } else { + // Build the LD_LIBRARY_PATH variable as it would be seen on the command line + // for diagnostic purposes + fn lib_path_cmd_prefix(path: &str) -> String { + format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path)) + } - format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" ")) + format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" ")) + } } fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) { @@ -1409,25 +1423,25 @@ fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) { fn dump_output_file(config: &Config, testfile: &Path, out: &str, extension: &str) { let outfile = make_out_name(config, testfile, extension); - File::create(&outfile).write_all(out.as_bytes()).unwrap(); + File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap(); } -fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> Path { +fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf { output_base_name(config, testfile).with_extension(extension) } -fn aux_output_dir_name(config: &Config, testfile: &Path) -> Path { +fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf { let f = output_base_name(config, testfile); - let mut fname = f.filename().unwrap().to_vec(); - fname.extend("libaux".bytes()); - f.with_filename(fname) + let mut fname = f.file_name().unwrap().to_os_string(); + fname.push_os_str(OsStr::from_str("libaux")); + f.with_file_name(&fname) } -fn output_testname(testfile: &Path) -> Path { - Path::new(testfile.filestem().unwrap()) +fn output_testname(testfile: &Path) -> PathBuf { + PathBuf::new(testfile.file_stem().unwrap()) } -fn output_base_name(config: &Config, testfile: &Path) -> Path { +fn output_base_name(config: &Config, testfile: &Path) -> PathBuf { config.build_base .join(&output_testname(testfile)) .with_extension(&config.stage_id) @@ -1542,11 +1556,11 @@ fn _arm_exec_compiled_test(config: &Config, Some("".to_string())) .expect(&format!("failed to exec `{}`", config.adb_path)); - let mut exitcode: int = 0; + let mut exitcode: i32 = 0; for c in exitcode_out.chars() { if !c.is_numeric() { break; } exitcode = exitcode * 10 + match c { - '0' ... '9' => c as int - ('0' as int), + '0' ... '9' => c as i32 - ('0' as i32), _ => 101, } } @@ -1587,7 +1601,7 @@ fn _arm_exec_compiled_test(config: &Config, &stderr_out); ProcRes { - status: process::ProcessExit::ExitStatus(exitcode), + status: Status::Parsed(exitcode), stdout: stdout_out, stderr: stderr_out, cmdline: cmdline @@ -1597,16 +1611,17 @@ fn _arm_exec_compiled_test(config: &Config, fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) { let tdir = aux_output_dir_name(config, testfile); - let dirs = fs::readdir(&tdir).unwrap(); - for file in &dirs { - if file.extension_str() == Some("so") { + let dirs = fs::read_dir(&tdir).unwrap(); + for file in dirs { + let file = file.unwrap().path(); + if file.extension().and_then(|s| s.to_str()) == Some("so") { // FIXME (#9639): This needs to handle non-utf8 paths let copy_result = procsrv::run("", &config.adb_path, None, &[ "push".to_string(), - file.as_str() + file.to_str() .unwrap() .to_string(), config.adb_test_dir.to_string(), @@ -1627,14 +1642,14 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) { // codegen tests (vs. clang) -fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path { +fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf { if suffix.len() == 0 { - (*p).clone() + p.to_path_buf() } else { - let mut stem = p.filestem().unwrap().to_vec(); - stem.extend("-".bytes()); - stem.extend(suffix.bytes()); - p.with_filename(stem) + let mut stem = p.file_stem().unwrap().to_os_string(); + stem.push_os_str(OsStr::from_str("-")); + stem.push_os_str(OsStr::from_str(suffix)); + p.with_file_name(&stem) } } @@ -1643,7 +1658,7 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps, let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths let mut link_args = vec!("-L".to_string(), - aux_dir.as_str().unwrap().to_string()); + aux_dir.to_str().unwrap().to_string()); let llvm_args = vec!("--emit=llvm-bc,obj".to_string(), "--crate-type=lib".to_string()); link_args.extend(llvm_args.into_iter()); @@ -1651,7 +1666,8 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps, props, link_args, |a, b| TargetLocation::ThisDirectory( - output_base_name(a, b).dir_path()), + output_base_name(a, b).parent() + .unwrap().to_path_buf()), testfile); compose_and_run_compiler(config, props, testfile, args, None) } @@ -1663,12 +1679,12 @@ fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps, let testcc = testfile.with_extension("cc"); let proc_args = ProcArgs { // FIXME (#9639): This needs to handle non-utf8 paths - prog: config.clang_path.as_ref().unwrap().as_str().unwrap().to_string(), + prog: config.clang_path.as_ref().unwrap().to_str().unwrap().to_string(), args: vec!("-c".to_string(), "-emit-llvm".to_string(), "-o".to_string(), - bitcodefile.as_str().unwrap().to_string(), - testcc.as_str().unwrap().to_string()) + bitcodefile.to_str().unwrap().to_string(), + testcc.to_str().unwrap().to_string()) }; compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None) } @@ -1682,10 +1698,10 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps, let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-extract"); let proc_args = ProcArgs { // FIXME (#9639): This needs to handle non-utf8 paths - prog: prog.as_str().unwrap().to_string(), + prog: prog.to_str().unwrap().to_string(), args: vec!(format!("-func={}", fname), - format!("-o={}", extracted_bc.as_str().unwrap()), - bitcodefile.as_str().unwrap().to_string()) + format!("-o={}", extracted_bc.to_str().unwrap()), + bitcodefile.to_str().unwrap().to_string()) }; compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None) } @@ -1699,16 +1715,17 @@ fn disassemble_extract(config: &Config, _props: &TestProps, let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-dis"); let proc_args = ProcArgs { // FIXME (#9639): This needs to handle non-utf8 paths - prog: prog.as_str().unwrap().to_string(), - args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()), - extracted_bc.as_str().unwrap().to_string()) + prog: prog.to_str().unwrap().to_string(), + args: vec!(format!("-o={}", extracted_ll.to_str().unwrap()), + extracted_bc.to_str().unwrap().to_string()) }; compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None) } fn count_extracted_lines(p: &Path) -> uint { - let x = File::open(&p.with_extension("ll")).read_to_end().unwrap(); + let mut x = Vec::new(); + File::open(&p.with_extension("ll")).unwrap().read_to_end(&mut x).unwrap(); let x = str::from_utf8(&x).unwrap(); x.lines().count() } diff --git a/src/compiletest/util.rs b/src/compiletest/util.rs index c0d7c59ef6a..16e2806f72c 100644 --- a/src/compiletest/util.rs +++ b/src/compiletest/util.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use common::Config; - -#[cfg(target_os = "windows")] use std::env; +use common::Config; /// Conversion table from triple OS name to Rust SYSNAME const OS_TABLE: &'static [(&'static str, &'static str)] = &[ @@ -36,24 +34,20 @@ pub fn get_os(triple: &str) -> &'static str { panic!("Cannot determine OS from triple"); } -#[cfg(target_os = "windows")] pub fn make_new_path(path: &str) -> String { - + assert!(cfg!(windows)); // Windows just uses PATH as the library search path, so we have to // maintain the current value while adding our own match env::var(lib_path_env_var()) { - Ok(curr) => { - format!("{}{}{}", path, path_div(), curr) - } - Err(..) => path.to_string() + Ok(curr) => { + format!("{}{}{}", path, path_div(), curr) + } + Err(..) => path.to_string() } } -#[cfg(target_os = "windows")] pub fn lib_path_env_var() -> &'static str { "PATH" } - -#[cfg(target_os = "windows")] -pub fn path_div() -> &'static str { ";" } +fn path_div() -> &'static str { ";" } pub fn logv(config: &Config, s: String) { debug!("{}", s); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 7c65a99d4b0..b1fdf139b0c 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -73,6 +73,7 @@ #![feature(unboxed_closures)] #![feature(unsafe_no_drop_flag)] #![feature(core)] +#![feature(unique)] #![cfg_attr(test, feature(test, alloc, rustc_private))] #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")), feature(libc))] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 6240b0e6afd..6b9d6cb0000 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -93,6 +93,7 @@ #![feature(int_uint)] #![feature(staged_api)] #![feature(str_words)] +#![feature(core)] #![cfg_attr(test, feature(rustc_private))] #[cfg(test)] #[macro_use] extern crate log; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index aa51320ee7f..2d542eafbe1 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -39,6 +39,9 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(os)] +#![feature(path)] +#![feature(fs)] +#![feature(io)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index bc3071d8db2..a19ccceb057 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -21,6 +21,7 @@ use metadata::decoder; use metadata::loader; use metadata::loader::CratePaths; +use std::path::{Path, PathBuf}; use std::rc::Rc; use syntax::ast; use syntax::abi; @@ -126,7 +127,7 @@ fn register_native_lib(sess: &Session, // Extra info about a crate loaded for plugins or exported macros. struct ExtensionCrate { metadata: PMDSource, - dylib: Option<Path>, + dylib: Option<PathBuf>, target_only: bool, } @@ -551,7 +552,8 @@ impl<'a> CrateReader<'a> { } /// Look for a plugin registrar. Returns library path and symbol name. - pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path, String)> { + pub fn find_plugin_registrar(&mut self, span: Span, name: &str) + -> Option<(PathBuf, String)> { let ekrate = self.read_extension_crate(span, &CrateInfo { name: name.to_string(), ident: name.to_string(), @@ -574,7 +576,7 @@ impl<'a> CrateReader<'a> { .map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id)); match (ekrate.dylib.as_ref(), registrar) { - (Some(dylib), Some(reg)) => Some((dylib.clone(), reg)), + (Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)), (None, Some(_)) => { let message = format!("plugin `{}` only found in rlib format, \ but must be available in dylib format", diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 62098733023..47ec31c0f1a 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -25,6 +25,7 @@ use util::nodemap::{FnvHashMap, NodeMap}; use std::cell::RefCell; use std::rc::Rc; +use std::path::PathBuf; use flate::Bytes; use syntax::ast; use syntax::codemap; @@ -78,8 +79,8 @@ pub enum NativeLibraryKind { // must be non-None. #[derive(PartialEq, Clone)] pub struct CrateSource { - pub dylib: Option<(Path, PathKind)>, - pub rlib: Option<(Path, PathKind)>, + pub dylib: Option<(PathBuf, PathKind)>, + pub rlib: Option<(PathBuf, PathKind)>, pub cnum: ast::CrateNum, } @@ -172,7 +173,7 @@ impl CStore { // topological sort of all crates putting the leaves at the right-most // positions. pub fn get_used_crates(&self, prefer: LinkagePreference) - -> Vec<(ast::CrateNum, Option<Path>)> { + -> Vec<(ast::CrateNum, Option<PathBuf>)> { let mut ordering = Vec::new(); fn visit(cstore: &CStore, cnum: ast::CrateNum, ordering: &mut Vec<ast::CrateNum>) { diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 994cb3f0f25..90046398c59 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -34,9 +34,9 @@ use middle::astencode::vtable_decoder_helpers; use std::collections::HashMap; use std::hash::{self, Hash, SipHasher}; -use std::num::FromPrimitive; -use std::num::Int; -use std::old_io; +use std::io::prelude::*; +use std::io; +use std::num::{FromPrimitive, Int}; use std::rc::Rc; use std::slice::bytes; use std::str; @@ -1191,7 +1191,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> { } fn list_crate_attributes(md: rbml::Doc, hash: &Svh, - out: &mut old_io::Writer) -> old_io::IoResult<()> { + out: &mut io::Write) -> io::Result<()> { try!(write!(out, "=Crate Attributes ({})=\n", *hash)); let r = get_attributes(md); @@ -1236,7 +1236,7 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> { return deps; } -fn list_crate_deps(data: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> { +fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> { try!(write!(out, "=External Dependencies=\n")); for dep in &get_crate_deps(data) { try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash)); @@ -1275,7 +1275,7 @@ pub fn get_crate_name(data: &[u8]) -> String { maybe_get_crate_name(data).expect("no crate name in crate") } -pub fn list_crate_metadata(bytes: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> { +pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> { let hash = get_crate_hash(bytes); let md = rbml::Doc::new(bytes); try!(list_crate_attributes(md, &hash, out)); diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index d1091b1d3f7..22a4a6fc978 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -14,9 +14,9 @@ pub use self::FileMatch::*; use std::collections::HashSet; use std::env; -use std::os; -use std::old_io::fs::PathExtensions; -use std::old_io::fs; +use std::fs; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; use util::fs as myfs; use session::search_paths::{SearchPaths, PathKind}; @@ -50,20 +50,20 @@ impl<'a> FileSearch<'a> { FileMatches => found = true, FileDoesntMatch => () } - visited_dirs.insert(path.as_vec().to_vec()); + visited_dirs.insert(path.to_path_buf()); } debug!("filesearch: searching lib path"); let tlib_path = make_target_lib_path(self.sysroot, self.triple); - if !visited_dirs.contains(tlib_path.as_vec()) { + if !visited_dirs.contains(&tlib_path) { match f(&tlib_path, PathKind::All) { FileMatches => found = true, FileDoesntMatch => () } } - visited_dirs.insert(tlib_path.as_vec().to_vec()); + visited_dirs.insert(tlib_path); // Try RUST_PATH if !found { let rustpath = rust_path(); @@ -71,10 +71,10 @@ impl<'a> FileSearch<'a> { let tlib_path = make_rustpkg_lib_path( self.sysroot, path, self.triple); debug!("is {} in visited_dirs? {}", tlib_path.display(), - visited_dirs.contains(&tlib_path.as_vec().to_vec())); + visited_dirs.contains(&tlib_path)); - if !visited_dirs.contains(tlib_path.as_vec()) { - visited_dirs.insert(tlib_path.as_vec().to_vec()); + if !visited_dirs.contains(&tlib_path) { + visited_dirs.insert(tlib_path.clone()); // Don't keep searching the RUST_PATH if one match turns up -- // if we did, we'd get a "multiple matching crates" error match f(&tlib_path, PathKind::All) { @@ -88,7 +88,7 @@ impl<'a> FileSearch<'a> { } } - pub fn get_lib_path(&self) -> Path { + pub fn get_lib_path(&self) -> PathBuf { make_target_lib_path(self.sysroot, self.triple) } @@ -97,11 +97,13 @@ impl<'a> FileSearch<'a> { { self.for_each_lib_search_path(|lib_search_path, kind| { debug!("searching {}", lib_search_path.display()); - match fs::readdir(lib_search_path) { + match fs::read_dir(lib_search_path) { Ok(files) => { + let files = files.filter_map(|p| p.ok().map(|s| s.path())) + .collect::<Vec<_>>(); let mut rslt = FileDoesntMatch; - fn is_rlib(p: & &Path) -> bool { - p.extension_str() == Some("rlib") + fn is_rlib(p: &Path) -> bool { + p.extension().and_then(|s| s.to_str()) == Some("rlib") } // Reading metadata out of rlibs is faster, and if we find both // an rlib and a dylib we only read one of the files of @@ -143,59 +145,60 @@ impl<'a> FileSearch<'a> { } // Returns a list of directories where target-specific dylibs might be located. - pub fn get_dylib_search_paths(&self) -> Vec<Path> { + pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> { let mut paths = Vec::new(); self.for_each_lib_search_path(|lib_search_path, _| { - paths.push(lib_search_path.clone()); + paths.push(lib_search_path.to_path_buf()); FileDoesntMatch }); paths } // Returns a list of directories where target-specific tool binaries are located. - pub fn get_tools_search_paths(&self) -> Vec<Path> { - let mut p = Path::new(self.sysroot); - p.push(find_libdir(self.sysroot)); - p.push(rustlibdir()); - p.push(self.triple); + pub fn get_tools_search_paths(&self) -> Vec<PathBuf> { + let mut p = PathBuf::new(self.sysroot); + p.push(&find_libdir(self.sysroot)); + p.push(&rustlibdir()); + p.push(&self.triple); p.push("bin"); vec![p] } } -pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path { - let mut p = Path::new(find_libdir(sysroot)); +pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { + let mut p = PathBuf::new(&find_libdir(sysroot)); assert!(p.is_relative()); - p.push(rustlibdir()); + p.push(&rustlibdir()); p.push(target_triple); p.push("lib"); p } fn make_target_lib_path(sysroot: &Path, - target_triple: &str) -> Path { + target_triple: &str) -> PathBuf { sysroot.join(&relative_target_lib_path(sysroot, target_triple)) } fn make_rustpkg_lib_path(sysroot: &Path, dir: &Path, - triple: &str) -> Path { - let mut p = dir.join(find_libdir(sysroot)); + triple: &str) -> PathBuf { + let mut p = dir.join(&find_libdir(sysroot)); p.push(triple); p } -pub fn get_or_default_sysroot() -> Path { +pub fn get_or_default_sysroot() -> PathBuf { // Follow symlinks. If the resolved path is relative, make it absolute. - fn canonicalize(path: Option<Path>) -> Option<Path> { - path.and_then(|path| + fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> { + path.and_then(|path| { match myfs::realpath(&path) { Ok(canon) => Some(canon), Err(e) => panic!("failed to get realpath: {}", e), - }) + } + }) } - match canonicalize(os::self_exe_name()) { + match canonicalize(env::current_exe().ok()) { Some(mut p) => { p.pop(); p.pop(); p } None => panic!("can't determine value for sysroot") } @@ -216,16 +219,16 @@ pub fn get_rust_path() -> Option<String> { /// $HOME/.rust /// DIR/.rust for any DIR that's the current working directory /// or an ancestor of it -pub fn rust_path() -> Vec<Path> { - let mut env_rust_path: Vec<Path> = match get_rust_path() { +pub fn rust_path() -> Vec<PathBuf> { + let mut env_rust_path: Vec<PathBuf> = match get_rust_path() { Some(env_path) => { let env_path_components = env_path.split(PATH_ENTRY_SEPARATOR); - env_path_components.map(|s| Path::new(s)).collect() + env_path_components.map(|s| PathBuf::new(s)).collect() } None => Vec::new() }; - let mut cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); // now add in default entries let cwd_dot_rust = cwd.join(".rust"); if !env_rust_path.contains(&cwd_dot_rust) { @@ -234,17 +237,15 @@ pub fn rust_path() -> Vec<Path> { if !env_rust_path.contains(&cwd) { env_rust_path.push(cwd.clone()); } - loop { - if { let f = cwd.filename(); f.is_none() || f.unwrap() == b".." } { - break - } - cwd.set_filename(".rust"); - if !env_rust_path.contains(&cwd) && cwd.exists() { - env_rust_path.push(cwd.clone()); + let mut cur = &*cwd; + while let Some(parent) = cur.parent() { + let candidate = parent.join(".rust"); + if !env_rust_path.contains(&candidate) && candidate.exists() { + env_rust_path.push(candidate.clone()); } - cwd.pop(); + cur = parent; } - if let Some(h) = os::homedir() { + if let Some(h) = env::home_dir() { let p = h.join(".rust"); if !env_rust_path.contains(&p) && p.exists() { env_rust_path.push(p); @@ -267,7 +268,7 @@ fn find_libdir(sysroot: &Path) -> String { match option_env!("CFG_LIBDIR_RELATIVE") { Some(libdir) if libdir != "lib" => return libdir.to_string(), - _ => if sysroot.join(primary_libdir_name()).join(rustlibdir()).exists() { + _ => if sysroot.join(&primary_libdir_name()).join(&rustlibdir()).exists() { return primary_libdir_name(); } else { return secondary_libdir_name(); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 07082d81876..d83470354ac 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -226,13 +226,14 @@ use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use syntax::codemap::Span; use syntax::diagnostic::SpanHandler; use util::fs; +use util::common; use rustc_back::target::Target; -use std::ffi::CString; use std::cmp; use std::collections::HashMap; -use std::old_io::fs::PathExtensions; -use std::old_io; +use std::io::prelude::*; +use std::io; +use std::path::{Path, PathBuf}; use std::ptr; use std::slice; use std::time::Duration; @@ -240,7 +241,7 @@ use std::time::Duration; use flate; pub struct CrateMismatch { - path: Path, + path: PathBuf, got: String, } @@ -262,8 +263,8 @@ pub struct Context<'a> { } pub struct Library { - pub dylib: Option<(Path, PathKind)>, - pub rlib: Option<(Path, PathKind)>, + pub dylib: Option<(PathBuf, PathKind)>, + pub rlib: Option<(PathBuf, PathKind)>, pub metadata: MetadataBlob, } @@ -275,12 +276,12 @@ pub struct ArchiveMetadata { pub struct CratePaths { pub ident: String, - pub dylib: Option<Path>, - pub rlib: Option<Path> + pub dylib: Option<PathBuf>, + pub rlib: Option<PathBuf> } impl CratePaths { - fn paths(&self) -> Vec<Path> { + fn paths(&self) -> Vec<PathBuf> { match (&self.dylib, &self.rlib) { (&None, &None) => vec!(), (&Some(ref p), &None) | @@ -400,7 +401,7 @@ impl<'a> Context<'a> { // // The goal of this step is to look at as little metadata as possible. self.filesearch.search(|path, kind| { - let file = match path.filename_str() { + let file = match path.file_name().and_then(|s| s.to_str()) { None => return FileDoesntMatch, Some(file) => file, }; @@ -416,7 +417,7 @@ impl<'a> Context<'a> { if file.starts_with(&staticlib_prefix[..]) && file.ends_with(".a") { staticlibs.push(CrateMismatch { - path: path.clone(), + path: path.to_path_buf(), got: "static".to_string() }); } @@ -506,9 +507,9 @@ impl<'a> Context<'a> { // read the metadata from it if `*slot` is `None`. If the metadata couldn't // be read, it is assumed that the file isn't a valid rust library (no // errors are emitted). - fn extract_one(&mut self, m: HashMap<Path, PathKind>, flavor: &str, - slot: &mut Option<MetadataBlob>) -> Option<(Path, PathKind)> { - let mut ret = None::<(Path, PathKind)>; + fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: &str, + slot: &mut Option<MetadataBlob>) -> Option<(PathBuf, PathKind)> { + let mut ret = None::<(PathBuf, PathKind)>; let mut error = 0; if slot.is_some() { @@ -587,7 +588,7 @@ impl<'a> Context<'a> { if triple != self.triple { info!("Rejecting via crate triple: expected {} got {}", self.triple, triple); self.rejected_via_triple.push(CrateMismatch { - path: libpath.clone(), + path: libpath.to_path_buf(), got: triple.to_string() }); return false; @@ -599,7 +600,7 @@ impl<'a> Context<'a> { if *myhash != hash { info!("Rejecting via hash: expected {} got {}", *myhash, hash); self.rejected_via_hash.push(CrateMismatch { - path: libpath.clone(), + path: libpath.to_path_buf(), got: myhash.as_str().to_string() }); false @@ -627,13 +628,13 @@ impl<'a> Context<'a> { let mut rlibs = HashMap::new(); let mut dylibs = HashMap::new(); { - let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| { + let locs = locs.iter().map(|l| PathBuf::new(&l[..])).filter(|loc| { if !loc.exists() { sess.err(&format!("extern location for {} does not exist: {}", self.crate_name, loc.display())); return false; } - let file = match loc.filename_str() { + let file = match loc.file_name().and_then(|s| s.to_str()) { Some(file) => file, None => { sess.err(&format!("extern location for {} is not a file: {}", @@ -658,7 +659,7 @@ impl<'a> Context<'a> { // Now that we have an iterator of good candidates, make sure // there's at most one rlib and at most one dylib. for loc in locs { - if loc.filename_str().unwrap().ends_with(".rlib") { + if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { rlibs.insert(fs::realpath(&loc).unwrap(), PathKind::ExternFlag); } else { @@ -714,7 +715,7 @@ fn get_metadata_section(is_osx: bool, filename: &Path) -> Result<MetadataBlob, S let dur = Duration::span(|| { ret = Some(get_metadata_section_imp(is_osx, filename)); }); - info!("reading {} => {}ms", filename.filename_display(), + info!("reading {:?} => {}ms", filename.file_name().unwrap(), dur.num_milliseconds()); return ret.unwrap();; } @@ -723,7 +724,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo if !filename.exists() { return Err(format!("no such file: '{}'", filename.display())); } - if filename.filename_str().unwrap().ends_with(".rlib") { + if filename.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // internally to read the file. We also avoid even using a memcpy by // just keeping the archive along while the metadata is in use. @@ -742,7 +743,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo }; } unsafe { - let buf = CString::new(filename.as_vec()).unwrap(); + let buf = common::path2cstr(filename); let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); if mb as int == 0 { return Err(format!("error reading library: '{}'", @@ -811,7 +812,7 @@ pub fn read_meta_section_name(is_osx: bool) -> &'static str { // A diagnostic function for dumping crate metadata to an output stream pub fn list_file_metadata(is_osx: bool, path: &Path, - out: &mut old_io::Writer) -> old_io::IoResult<()> { + out: &mut io::Write) -> io::Result<()> { match get_metadata_section(is_osx, path) { Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out), Err(msg) => { diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index faed3f5977f..a1ce8d18184 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -19,7 +19,7 @@ pub use self::EntryOrExit::*; use middle::cfg; use middle::cfg::CFGIndex; use middle::ty; -use std::old_io; +use std::io; use std::usize; use std::iter::repeat; use syntax::ast; @@ -103,7 +103,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> { fn pre(&self, ps: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { let id = match node { pprust::NodeIdent(_) | pprust::NodeName(_) => 0, pprust::NodeExpr(expr) => expr.id, @@ -485,13 +485,15 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { debug!("Dataflow result for {}:", self.analysis_name); debug!("{}", { - self.pretty_print_to(box old_io::stderr(), blk).unwrap(); + let mut v = Vec::new(); + self.pretty_print_to(box &mut v, blk).unwrap(); + println!("{}", String::from_utf8(v).unwrap()); "" }); } - fn pretty_print_to(&self, wr: Box<old_io::Writer+'static>, - blk: &ast::Block) -> old_io::IoResult<()> { + fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>, + blk: &ast::Block) -> io::Result<()> { let mut ps = pprust::rust_printer_annotated(wr, self); try!(ps.cbox(pprust::indent_unit)); try!(ps.ibox(0)); diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs index 43cd1fc8edb..6211fde7919 100644 --- a/src/librustc/middle/infer/region_inference/graphviz.rs +++ b/src/librustc/middle/infer/region_inference/graphviz.rs @@ -28,8 +28,10 @@ use util::ppaux::Repr; use std::borrow::Cow; use std::collections::hash_map::Entry::Vacant; -use std::old_io::{self, File}; use std::env; +use std::fs::File; +use std::io; +use std::io::prelude::*; use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT}; use syntax::ast; @@ -256,10 +258,11 @@ pub type ConstraintMap<'tcx> = FnvHashMap<Constraint, SubregionOrigin<'tcx>>; fn dump_region_constraints_to<'a, 'tcx:'a >(tcx: &'a ty::ctxt<'tcx>, map: &ConstraintMap<'tcx>, - path: &str) -> old_io::IoResult<()> { + path: &str) -> io::Result<()> { debug!("dump_region_constraints map (len: {}) path: {}", map.len(), path); let g = ConstraintGraph::new(tcx, format!("region_constraints"), map); - let mut f = File::create(&Path::new(path)); debug!("dump_region_constraints calling render"); - dot::render(&g, &mut f) + let mut v = Vec::new(); + dot::render(&g, &mut v).unwrap(); + File::create(path).and_then(|mut f| f.write_all(&v)) } diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index a419d4134b4..8267b79ff9e 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -14,10 +14,12 @@ use session::Session; use metadata::creader::CrateReader; use plugin::registry::Registry; -use std::mem; -use std::os; -use std::dynamic_lib::DynamicLibrary; use std::borrow::ToOwned; +use std::dynamic_lib::DynamicLibrary; +use std::env; +use std::mem; +use std::old_path; +use std::path::PathBuf; use syntax::ast; use syntax::codemap::{Span, COMMAND_LINE_SP}; use syntax::ptr::P; @@ -100,10 +102,11 @@ impl<'a> PluginLoader<'a> { // Dynamically link a registrar function into the compiler process. fn dylink_registrar(&mut self, span: Span, - path: Path, + path: PathBuf, symbol: String) -> PluginRegistrarFun { // Make sure the path contains a / or the linker will search for it. - let path = os::getcwd().unwrap().join(&path); + let path = env::current_dir().unwrap().join(&path); + let path = old_path::Path::new(path.to_str().unwrap()); let lib = match DynamicLibrary::open(Some(&path)) { Ok(lib) => lib, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 536caece21f..a4355803f4a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -38,6 +38,7 @@ use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::env; use std::fmt; +use std::path::PathBuf; use llvm; @@ -89,7 +90,7 @@ pub struct Options { // this. pub search_paths: SearchPaths, pub libs: Vec<(String, cstore::NativeLibraryKind)>, - pub maybe_sysroot: Option<Path>, + pub maybe_sysroot: Option<PathBuf>, pub target_triple: String, // User-specified cfg meta items. The compiler itself will add additional // items to the crate config, and during parsing the entire crate config @@ -103,7 +104,7 @@ pub struct Options { pub no_analysis: bool, pub debugging_opts: DebuggingOptions, /// Whether to write dependency files. It's (enabled, optional filename). - pub write_dependency_info: (bool, Option<Path>), + pub write_dependency_info: (bool, Option<PathBuf>), pub prints: Vec<PrintRequest>, pub cg: CodegenOptions, pub color: ColorConfig, @@ -142,7 +143,7 @@ pub enum PrintRequest { pub enum Input { /// Load source from file - File(Path), + File(PathBuf), /// The string is the source Str(String) } @@ -150,7 +151,8 @@ pub enum Input { impl Input { pub fn filestem(&self) -> String { match *self { - Input::File(ref ifile) => ifile.filestem_str().unwrap().to_string(), + Input::File(ref ifile) => ifile.file_stem().unwrap() + .to_str().unwrap().to_string(), Input::Str(_) => "rust_out".to_string(), } } @@ -158,14 +160,14 @@ impl Input { #[derive(Clone)] pub struct OutputFilenames { - pub out_directory: Path, + pub out_directory: PathBuf, pub out_filestem: String, - pub single_output_file: Option<Path>, + pub single_output_file: Option<PathBuf>, pub extra: String, } impl OutputFilenames { - pub fn path(&self, flavor: OutputType) -> Path { + pub fn path(&self, flavor: OutputType) -> PathBuf { match self.single_output_file { Some(ref path) => return path.clone(), None => {} @@ -173,8 +175,8 @@ impl OutputFilenames { self.temp_path(flavor) } - pub fn temp_path(&self, flavor: OutputType) -> Path { - let base = self.out_directory.join(self.filestem()); + pub fn temp_path(&self, flavor: OutputType) -> PathBuf { + let base = self.out_directory.join(&self.filestem()); match flavor { OutputTypeBitcode => base.with_extension("bc"), OutputTypeAssembly => base.with_extension("s"), @@ -185,8 +187,8 @@ impl OutputFilenames { } } - pub fn with_extension(&self, extension: &str) -> Path { - self.out_directory.join(self.filestem()).with_extension(extension) + pub fn with_extension(&self, extension: &str) -> PathBuf { + self.out_directory.join(&self.filestem()).with_extension(extension) } pub fn filestem(&self) -> String { @@ -897,7 +899,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let cg = build_codegen_options(matches); - let sysroot_opt = matches.opt_str("sysroot").map(|m| Path::new(m)); + let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::new(&m)); let target = matches.opt_str("target").unwrap_or( host_triple().to_string()); let opt_level = { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 67c39bcca81..a478cb79796 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -26,8 +26,9 @@ use syntax::{ast, codemap}; use rustc_back::target::Target; +use std::path::{Path, PathBuf}; use std::cell::{Cell, RefCell}; -use std::os; +use std::env; pub mod config; pub mod search_paths; @@ -44,11 +45,11 @@ pub struct Session { pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>, pub entry_type: Cell<Option<config::EntryFnType>>, pub plugin_registrar_fn: Cell<Option<ast::NodeId>>, - pub default_sysroot: Option<Path>, + pub default_sysroot: Option<PathBuf>, // The name of the root source file of the crate, in the local file system. The path is always // expected to be absolute. `None` means that there is no source file. - pub local_crate_source_file: Option<Path>, - pub working_dir: Path, + pub local_crate_source_file: Option<PathBuf>, + pub working_dir: PathBuf, pub lint_store: RefCell<lint::LintStore>, pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>, pub crate_types: RefCell<Vec<config::CrateType>>, @@ -310,7 +311,7 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> { } pub fn build_session(sopts: config::Options, - local_crate_source_file: Option<Path>, + local_crate_source_file: Option<PathBuf>, registry: diagnostics::registry::Registry) -> Session { // FIXME: This is not general enough to make the warning lint completely override @@ -333,7 +334,7 @@ pub fn build_session(sopts: config::Options, } pub fn build_session_(sopts: config::Options, - local_crate_source_file: Option<Path>, + local_crate_source_file: Option<PathBuf>, span_diagnostic: diagnostic::SpanHandler) -> Session { let host = match Target::search(config::host_triple()) { @@ -355,7 +356,7 @@ pub fn build_session_(sopts: config::Options, if path.is_absolute() { path.clone() } else { - os::getcwd().unwrap().join(&path) + env::current_dir().unwrap().join(&path) } ); @@ -378,7 +379,7 @@ pub fn build_session_(sopts: config::Options, plugin_registrar_fn: Cell::new(None), default_sysroot: default_sysroot, local_crate_source_file: local_crate_source_file, - working_dir: os::getcwd().unwrap(), + working_dir: env::current_dir().unwrap(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap()), crate_types: RefCell::new(Vec::new()), diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index c314a999f24..f85fb303910 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -9,15 +9,16 @@ // except according to those terms. use std::slice; +use std::path::{Path, PathBuf}; #[derive(Clone, Debug)] pub struct SearchPaths { - paths: Vec<(PathKind, Path)>, + paths: Vec<(PathKind, PathBuf)>, } pub struct Iter<'a> { kind: PathKind, - iter: slice::Iter<'a, (PathKind, Path)>, + iter: slice::Iter<'a, (PathKind, PathBuf)>, } #[derive(Eq, PartialEq, Clone, Copy, Debug)] @@ -49,7 +50,7 @@ impl SearchPaths { } else { (PathKind::All, path) }; - self.paths.push((kind, Path::new(path))); + self.paths.push((kind, PathBuf::new(path))); } pub fn iter(&self, kind: PathKind) -> Iter { diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index ca740f53782..0b32f7f69eb 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -12,11 +12,13 @@ use std::cell::{RefCell, Cell}; use std::collections::HashMap; +use std::collections::hash_state::HashState; +use std::ffi::CString; use std::fmt::Debug; use std::hash::Hash; use std::iter::repeat; +use std::path::Path; use std::time::Duration; -use std::collections::hash_state::HashState; use syntax::ast; use syntax::visit; @@ -222,3 +224,14 @@ pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> } } } + +#[cfg(unix)] +pub fn path2cstr(p: &Path) -> CString { + use std::os::unix::prelude::*; + use std::ffi::AsOsStr; + CString::new(p.as_os_str().as_bytes()).unwrap() +} +#[cfg(windows)] +pub fn path2cstr(p: &Path) -> CString { + CString::new(p.to_str().unwrap()).unwrap() +} diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index 97b1a8aaaba..a6994387f8d 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -10,11 +10,12 @@ //! A helper class for dealing with static archives -use std::old_io::fs::PathExtensions; -use std::old_io::process::{Command, ProcessOutput}; -use std::old_io::{fs, TempDir}; -use std::old_io; -use std::os; +use std::env; +use std::fs::{self, TempDir}; +use std::io::prelude::*; +use std::io; +use std::path::{Path, PathBuf}; +use std::process::{Command, Output, Stdio}; use std::str; use syntax::diagnostic::Handler as ErrorHandler; @@ -22,8 +23,8 @@ pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; pub struct ArchiveConfig<'a> { pub handler: &'a ErrorHandler, - pub dst: Path, - pub lib_search_paths: Vec<Path>, + pub dst: PathBuf, + pub lib_search_paths: Vec<PathBuf>, pub slib_prefix: String, pub slib_suffix: String, pub maybe_ar_prog: Option<String> @@ -31,8 +32,8 @@ pub struct ArchiveConfig<'a> { pub struct Archive<'a> { handler: &'a ErrorHandler, - dst: Path, - lib_search_paths: Vec<Path>, + dst: PathBuf, + lib_search_paths: Vec<PathBuf>, slib_prefix: String, slib_suffix: String, maybe_ar_prog: Option<String> @@ -45,25 +46,25 @@ pub struct ArchiveBuilder<'a> { archive: Archive<'a>, work_dir: TempDir, /// Filename of each member that should be added to the archive. - members: Vec<Path>, + members: Vec<PathBuf>, should_update_symbols: bool, } fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>, args: &str, cwd: Option<&Path>, - paths: &[&Path]) -> ProcessOutput { + paths: &[&Path]) -> Output { let ar = match *maybe_ar_prog { Some(ref ar) => &ar[..], None => "ar" }; let mut cmd = Command::new(ar); - cmd.arg(args).args(paths); + cmd.arg(args).args(paths).stdout(Stdio::piped()).stderr(Stdio::piped()); debug!("{:?}", cmd); match cwd { Some(p) => { - cmd.cwd(p); + cmd.current_dir(p); debug!("inside {:?}", p.display()); } None => {} @@ -75,9 +76,9 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>, if !o.status.success() { handler.err(&format!("{:?} failed with: {}", cmd, o.status)); handler.note(&format!("stdout ---\n{}", - str::from_utf8(&o.output).unwrap())); + str::from_utf8(&o.stdout).unwrap())); handler.note(&format!("stderr ---\n{}", - str::from_utf8(&o.error).unwrap()) + str::from_utf8(&o.stderr).unwrap()) ); handler.abort_if_errors(); } @@ -93,14 +94,15 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>, } pub fn find_library(name: &str, osprefix: &str, ossuffix: &str, - search_paths: &[Path], handler: &ErrorHandler) -> Path { + search_paths: &[PathBuf], + handler: &ErrorHandler) -> PathBuf { // On Windows, static libraries sometimes show up as libfoo.a and other // times show up as foo.lib let oslibname = format!("{}{}{}", osprefix, name, ossuffix); let unixlibname = format!("lib{}.a", name); for path in search_paths { - debug!("looking for {} inside {:?}", name, path.display()); + debug!("looking for {} inside {:?}", name, path); let test = path.join(&oslibname[..]); if test.exists() { return test } if oslibname != unixlibname { @@ -142,7 +144,7 @@ impl<'a> Archive<'a> { /// Lists all files in an archive pub fn files(&self) -> Vec<String> { let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, &[&self.dst]); - let output = str::from_utf8(&output.output).unwrap(); + let output = str::from_utf8(&output.stdout).unwrap(); // use lines_any because windows delimits output with `\r\n` instead of // just `\n` output.lines_any().map(|s| s.to_string()).collect() @@ -172,7 +174,7 @@ impl<'a> ArchiveBuilder<'a> { /// Adds all of the contents of a native library to this archive. This will /// search in the relevant locations for a library named `name`. - pub fn add_native_library(&mut self, name: &str) -> old_io::IoResult<()> { + pub fn add_native_library(&mut self, name: &str) -> io::Result<()> { let location = find_library(name, &self.archive.slib_prefix, &self.archive.slib_suffix, @@ -187,7 +189,7 @@ impl<'a> ArchiveBuilder<'a> { /// This ignores adding the bytecode from the rlib, and if LTO is enabled /// then the object file also isn't added. pub fn add_rlib(&mut self, rlib: &Path, name: &str, - lto: bool) -> old_io::IoResult<()> { + lto: bool) -> io::Result<()> { // Ignoring obj file starting with the crate name // as simple comparison is not enough - there // might be also an extra name suffix @@ -205,11 +207,11 @@ impl<'a> ArchiveBuilder<'a> { } /// Adds an arbitrary file to this archive - pub fn add_file(&mut self, file: &Path) -> old_io::IoResult<()> { - let filename = Path::new(file.filename().unwrap()); + pub fn add_file(&mut self, file: &Path) -> io::Result<()> { + let filename = Path::new(file.file_name().unwrap()); let new_file = self.work_dir.path().join(&filename); try!(fs::copy(file, &new_file)); - self.members.push(filename); + self.members.push(filename.to_path_buf()); Ok(()) } @@ -224,10 +226,10 @@ impl<'a> ArchiveBuilder<'a> { pub fn build(self) -> Archive<'a> { // Get an absolute path to the destination, so `ar` will work even // though we run it from `self.work_dir`. - let abs_dst = os::getcwd().unwrap().join(&self.archive.dst); + let abs_dst = env::current_dir().unwrap().join(&self.archive.dst); assert!(!abs_dst.is_relative()); - let mut args = vec![&abs_dst]; - let mut total_len = abs_dst.as_vec().len(); + let mut args = vec![&*abs_dst]; + let mut total_len = abs_dst.to_string_lossy().len(); if self.members.is_empty() { // OSX `ar` does not allow using `r` with no members, but it does @@ -245,7 +247,7 @@ impl<'a> ArchiveBuilder<'a> { const ARG_LENGTH_LIMIT: uint = 32_000; for member_name in &self.members { - let len = member_name.as_vec().len(); + let len = member_name.to_string_lossy().len(); // `len + 1` to account for the space that's inserted before each // argument. (Windows passes command-line arguments as a single @@ -258,7 +260,7 @@ impl<'a> ArchiveBuilder<'a> { args.clear(); args.push(&abs_dst); - total_len = abs_dst.as_vec().len(); + total_len = abs_dst.to_string_lossy().len(); } args.push(member_name); @@ -275,7 +277,7 @@ impl<'a> ArchiveBuilder<'a> { } fn add_archive<F>(&mut self, archive: &Path, name: &str, - mut skip: F) -> old_io::IoResult<()> + mut skip: F) -> io::Result<()> where F: FnMut(&str) -> bool, { let loc = TempDir::new("rsar").unwrap(); @@ -283,7 +285,7 @@ impl<'a> ArchiveBuilder<'a> { // First, extract the contents of the archive to a temporary directory. // We don't unpack directly into `self.work_dir` due to the possibility // of filename collisions. - let archive = os::getcwd().unwrap().join(archive); + let archive = env::current_dir().unwrap().join(archive); run_ar(self.archive.handler, &self.archive.maybe_ar_prog, "x", Some(loc.path()), &[&archive]); @@ -296,9 +298,10 @@ impl<'a> ArchiveBuilder<'a> { // We skip any files explicitly desired for skipping, and we also skip // all SYMDEF files as these are just magical placeholders which get // re-created when we make a new archive anyway. - let files = try!(fs::readdir(loc.path())); - for file in &files { - let filename = file.filename_str().unwrap(); + let files = try!(fs::read_dir(loc.path())); + for file in files { + let file = try!(file).path(); + let filename = file.file_name().unwrap().to_str().unwrap(); if skip(filename) { continue } if filename.contains(".SYMDEF") { continue } @@ -313,8 +316,8 @@ impl<'a> ArchiveBuilder<'a> { filename }; let new_filename = self.work_dir.path().join(&filename[..]); - try!(fs::rename(file, &new_filename)); - self.members.push(Path::new(filename)); + try!(fs::rename(&file, &new_filename)); + self.members.push(PathBuf::new(&filename)); } Ok(()) } diff --git a/src/librustc_back/fs.rs b/src/librustc_back/fs.rs index 56d71820176..c00c33d4c2f 100644 --- a/src/librustc_back/fs.rs +++ b/src/librustc_back/fs.rs @@ -8,14 +8,29 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io; +use std::io; use std::old_io::fs; +use std::old_io; +use std::old_path; use std::os; +use std::path::{Path, PathBuf}; /// Returns an absolute path in the filesystem that `path` points to. The /// returned path does not contain any symlinks in its hierarchy. -pub fn realpath(original: &Path) -> old_io::IoResult<Path> { - const MAX_LINKS_FOLLOWED: uint = 256; +#[allow(deprecated)] // readlink is deprecated +pub fn realpath(original: &Path) -> io::Result<PathBuf> { + let old = old_path::Path::new(original.to_str().unwrap()); + match old_realpath(&old) { + Ok(p) => Ok(PathBuf::new(p.as_str().unwrap())), + Err(e) => Err(io::Error::new(io::ErrorKind::Other, + "realpath error", + Some(e.to_string()))) + } +} + +#[allow(deprecated)] +fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> { + const MAX_LINKS_FOLLOWED: usize = 256; let original = try!(os::getcwd()).join(original); // Right now lstat on windows doesn't work quite well @@ -55,7 +70,7 @@ pub fn realpath(original: &Path) -> old_io::IoResult<Path> { mod test { use std::old_io; use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive}; - use super::realpath; + use super::old_realpath as realpath; use std::old_io::TempDir; #[test] diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 9005c666afb..2b028a5c626 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -33,14 +33,18 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] +#![feature(old_fs)] +#![feature(fs)] #![feature(hash)] #![feature(int_uint)] +#![feature(io)] #![feature(old_io)] -#![feature(os)] #![feature(old_path)] +#![feature(os)] +#![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(path)] +#![feature(tempdir)] extern crate syntax; extern crate serialize; diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 943ff52925a..4f9f1447d8a 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -10,26 +10,20 @@ use std::collections::HashSet; use std::env; -use std::old_io::IoError; -use std::os; +use std::io; +use std::path::{Path, PathBuf}; use syntax::ast; -pub struct RPathConfig<F, G> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ - pub used_crates: Vec<(ast::CrateNum, Option<Path>)>, - pub out_filename: Path, +pub struct RPathConfig<'a> { + pub used_crates: Vec<(ast::CrateNum, Option<PathBuf>)>, + pub out_filename: PathBuf, pub is_like_osx: bool, pub has_rpath: bool, - pub get_install_prefix_lib_path: F, - pub realpath: G, + pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf, + pub realpath: &'a mut FnMut(&Path) -> io::Result<PathBuf>, } -pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> { // No rpath on windows if !config.has_rpath { return Vec::new(); @@ -54,10 +48,7 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> { return ret; } -fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> { debug!("output: {:?}", config.out_filename.display()); debug!("libs:"); for libpath in libs { @@ -67,7 +58,7 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> // Use relative paths to the libraries. Binaries can be moved // as long as they maintain the relative relationship to the // crates they depend on. - let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs); + let rel_rpaths = get_rpaths_relative_to_output(config, libs); // And a final backup rpath to the global library location. let fallback_rpaths = vec!(get_install_prefix_rpath(config)); @@ -90,18 +81,12 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> return rpaths; } -fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, - libs: &[Path]) -> Vec<String> where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn get_rpaths_relative_to_output(config: &mut RPathConfig, + libs: &[PathBuf]) -> Vec<String> { libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect() } -fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String { // Mac doesn't appear to support $ORIGIN let prefix = if config.is_like_osx { "@loader_path" @@ -109,23 +94,36 @@ fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path "$ORIGIN" }; - let cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); let mut lib = (config.realpath)(&cwd.join(lib)).unwrap(); lib.pop(); let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap(); output.pop(); - let relative = lib.path_relative_from(&output); - let relative = relative.expect("could not create rpath relative to output"); + let relative = relativize(&lib, &output); // FIXME (#9639): This needs to handle non-utf8 paths - format!("{}/{}", - prefix, - relative.as_str().expect("non-utf8 component in path")) + format!("{}/{}", prefix, + relative.to_str().expect("non-utf8 component in path")) } -fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result<Path, IoError>, -{ +fn relativize(path: &Path, rel: &Path) -> PathBuf { + let mut res = PathBuf::new(""); + let mut cur = rel; + while !path.starts_with(cur) { + res.push(".."); + match cur.parent() { + Some(p) => cur = p, + None => panic!("can't create relative paths across filesystems"), + } + } + match path.relative_from(cur) { + Some(s) => { res.push(s); res } + None => panic!("couldn't create relative path from {:?} to {:?}", + rel, path), + } + +} + +fn get_install_prefix_rpath(config: &mut RPathConfig) -> String { let path = (config.get_install_prefix_lib_path)(); let path = env::current_dir().unwrap().join(&path); // FIXME (#9639): This needs to handle non-utf8 paths @@ -147,6 +145,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> { mod test { use super::{RPathConfig}; use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output}; + use std::path::{Path, PathBuf}; #[test] fn test_rpaths_to_flags() { @@ -195,50 +194,31 @@ mod test { } #[test] - #[cfg(any(target_os = "linux", target_os = "android"))] fn test_rpath_relative() { - let config = &mut RPathConfig { - used_crates: Vec::new(), - out_filename: Path::new("bin/rustc"), - get_install_prefix_lib_path: || panic!(), - has_rpath: true, - is_like_osx: false, - realpath: |p| Ok(p.clone()) - }; - let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so")); - assert_eq!(res, "$ORIGIN/../lib"); - } - - #[test] - #[cfg(any(target_os = "freebsd", - target_os = "dragonfly", - target_os = "bitrig", - target_os = "openbsd"))] - fn test_rpath_relative() { - let config = &mut RPathConfig { - used_crates: Vec::new(), - has_rpath: true, - is_like_osx: false, - out_filename: Path::new("bin/rustc"), - get_install_prefix_lib_path: || panic!(), - realpath: |p| Ok(p.clone()) - }; - let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so")); - assert_eq!(res, "$ORIGIN/../lib"); - } - - #[test] - #[cfg(target_os = "macos")] - fn test_rpath_relative() { - let config = &mut RPathConfig { - used_crates: Vec::new(), - has_rpath: true, - is_like_osx: true, - out_filename: Path::new("bin/rustc"), - get_install_prefix_lib_path: || panic!(), - realpath: |p| Ok(p.clone()) - }; - let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so")); - assert_eq!(res, "@loader_path/../lib"); + if cfg!(target_os = "macos") { + let config = &mut RPathConfig { + used_crates: Vec::new(), + has_rpath: true, + is_like_osx: true, + out_filename: PathBuf::new("bin/rustc"), + get_install_prefix_lib_path: &mut || panic!(), + realpath: &mut |p| Ok(p.to_path_buf()), + }; + let res = get_rpath_relative_to_output(config, + Path::new("lib/libstd.so")); + assert_eq!(res, "@loader_path/../lib"); + } else { + let config = &mut RPathConfig { + used_crates: Vec::new(), + out_filename: PathBuf::new("bin/rustc"), + get_install_prefix_lib_path: &mut || panic!(), + has_rpath: true, + is_like_osx: false, + realpath: &mut |p| Ok(p.to_path_buf()), + }; + let res = get_rpath_relative_to_output(config, + Path::new("lib/libstd.so")); + assert_eq!(res, "$ORIGIN/../lib"); + } } } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index d09a7c355d3..4663901a7b4 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -48,7 +48,7 @@ use serialize::json::Json; use syntax::{diagnostic, abi}; use std::default::Default; -use std::old_io::fs::PathExtensions; +use std::io::prelude::*; mod windows_base; mod linux_base; @@ -302,23 +302,26 @@ impl Target { base } - /// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it - /// could also just be a bare filename already, so also check for that. If one of the hardcoded - /// targets we know about, just return it directly. + /// Search RUST_TARGET_PATH for a JSON file specifying the given target + /// triple. Note that it could also just be a bare filename already, so also + /// check for that. If one of the hardcoded targets we know about, just + /// return it directly. /// - /// The error string could come from any of the APIs called, including filesystem access and - /// JSON decoding. + /// The error string could come from any of the APIs called, including + /// filesystem access and JSON decoding. pub fn search(target: &str) -> Result<Target, String> { use std::env; - use std::os; use std::ffi::OsString; - use std::old_io::File; - use std::old_path::Path; + use std::fs::File; + use std::path::{Path, PathBuf}; use serialize::json; fn load_file(path: &Path) -> Result<Target, String> { - let mut f = try!(File::open(path).map_err(|e| format!("{:?}", e))); - let obj = try!(json::from_reader(&mut f).map_err(|e| format!("{:?}", e))); + let mut f = try!(File::open(path).map_err(|e| e.to_string())); + let mut contents = Vec::new(); + try!(f.read_to_end(&mut contents).map_err(|e| e.to_string())); + let obj = try!(json::from_reader(&mut &contents[..]) + .map_err(|e| e.to_string())); Ok(Target::from_json(obj)) } @@ -390,15 +393,16 @@ impl Target { let path = { let mut target = target.to_string(); target.push_str(".json"); - Path::new(target) + PathBuf::new(&target) }; - let target_path = env::var_os("RUST_TARGET_PATH").unwrap_or(OsString::from_str("")); + let target_path = env::var_os("RUST_TARGET_PATH") + .unwrap_or(OsString::from_str("")); // FIXME 16351: add a sane default search path? - for dir in os::split_paths(target_path.to_str().unwrap()).iter() { - let p = dir.join(path.clone()); + for dir in env::split_paths(&target_path) { + let p = dir.join(&path); if p.is_file() { return load_file(&p); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 425ec7ec452..73682faf1a7 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -32,10 +32,10 @@ use super::Compilation; use serialize::json; use std::env; -use std::os; use std::ffi::OsString; -use std::old_io::fs; -use std::old_io; +use std::fs; +use std::io::{self, Write}; +use std::path::{Path, PathBuf}; use syntax::ast; use syntax::ast_map; use syntax::attr; @@ -48,8 +48,8 @@ use syntax; pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input, - outdir: &Option<Path>, - output: &Option<Path>, + outdir: &Option<PathBuf>, + output: &Option<PathBuf>, addl_plugins: Option<Vec<String>>, control: CompileController) { macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({ @@ -166,7 +166,7 @@ pub fn anon_src() -> String { pub fn source_name(input: &Input) -> String { match *input { // FIXME (#9639): This needs to handle non-utf8 paths - Input::File(ref ifile) => ifile.as_str().unwrap().to_string(), + Input::File(ref ifile) => ifile.to_str().unwrap().to_string(), Input::Str(_) => anon_src() } } @@ -243,12 +243,12 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> { impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn empty(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>) + out_dir: &'a Option<PathBuf>) -> CompileState<'a, 'ast, 'tcx> { CompileState { input: input, session: session, - out_dir: out_dir.as_ref(), + out_dir: out_dir.as_ref().map(|s| &**s), cfg: None, krate: None, crate_name: None, @@ -263,7 +263,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_parse(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, krate: &'a ast::Crate) -> CompileState<'a, 'ast, 'tcx> { CompileState { @@ -274,7 +274,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_expand(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, expanded_crate: &'a ast::Crate, crate_name: &'a str) -> CompileState<'a, 'ast, 'tcx> { @@ -287,7 +287,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_write_deps(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, ast_map: &'a ast_map::Map<'ast>, expanded_crate: &'a ast::Crate, crate_name: &'a str) @@ -302,7 +302,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_analysis(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, expanded_crate: &'a ast::Crate, analysis: &'a ty::CrateAnalysis<'tcx>, tcx: &'a ty::ctxt<'tcx>) @@ -318,7 +318,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { fn state_after_llvm(input: &'a Input, session: &'a Session, - out_dir: &'a Option<Path>, + out_dir: &'a Option<PathBuf>, trans: &'a trans::CrateTranslation) -> CompileState<'a, 'ast, 'tcx> { CompileState { @@ -472,7 +472,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, if cfg!(windows) { _old_path = env::var_os("PATH").unwrap_or(_old_path); let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths(); - new_path.extend(os::split_paths(_old_path.to_str().unwrap()).into_iter()); + new_path.extend(env::split_paths(&_old_path)); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); } let features = sess.features.borrow(); @@ -717,7 +717,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session, // Remove assembly source, unless --save-temps was specified if !sess.opts.cg.save_temps { - fs::unlink(&outputs.temp_path(config::OutputTypeAssembly)).unwrap(); + fs::remove_file(&outputs.temp_path(config::OutputTypeAssembly)).unwrap(); } } else { time(sess.time_passes(), "LLVM passes", (), |_| @@ -737,7 +737,7 @@ pub fn phase_6_link_output(sess: &Session, outputs: &OutputFilenames) { let old_path = env::var_os("PATH").unwrap_or(OsString::from_str("")); let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(); - new_path.extend(os::split_paths(old_path.to_str().unwrap()).into_iter()); + new_path.extend(env::split_paths(&old_path)); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); time(sess.time_passes(), "linking", (), |_| @@ -793,17 +793,17 @@ fn write_out_deps(sess: &Session, _ => return, }; - let result = (|| -> old_io::IoResult<()> { + let result = (|| -> io::Result<()> { // Build a list of files used to compile the output and // write Makefile-compatible dependency rules let files: Vec<String> = sess.codemap().files.borrow() .iter().filter(|fmap| fmap.is_real_file()) .map(|fmap| escape_dep_filename(&fmap.name)) .collect(); - let mut file = try!(old_io::File::create(&deps_filename)); + let mut file = try!(fs::File::create(&deps_filename)); for path in &out_filenames { - try!(write!(&mut file as &mut Writer, - "{}: {}\n\n", path.display(), files.connect(" "))); + try!(write!(&mut file, + "{}: {}\n\n", path.display(), files.connect(" "))); } Ok(()) })(); @@ -896,8 +896,8 @@ pub fn collect_crate_metadata(session: &Session, } pub fn build_output_filenames(input: &Input, - odir: &Option<Path>, - ofile: &Option<Path>, + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>, attrs: &[ast::Attribute], sess: &Session) -> OutputFilenames { @@ -908,7 +908,7 @@ pub fn build_output_filenames(input: &Input, // We want to toss everything after the final '.' let dirpath = match *odir { Some(ref d) => d.clone(), - None => Path::new(".") + None => PathBuf::new(".") }; // If a crate name is present, we use it as the link name @@ -936,8 +936,9 @@ pub fn build_output_filenames(input: &Input, sess.warn("ignoring --out-dir flag due to -o flag."); } OutputFilenames { - out_directory: out_file.dir_path(), - out_filestem: out_file.filestem_str().unwrap().to_string(), + out_directory: out_file.parent().unwrap().to_path_buf(), + out_filestem: out_file.file_stem().unwrap() + .to_str().unwrap().to_string(), single_output_file: ofile, extra: sess.opts.cg.extra_filename.clone(), } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 15fae351ddb..aa8b7c7785d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -30,7 +30,6 @@ #![feature(old_io)] #![feature(libc)] #![feature(os)] -#![feature(old_path)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] @@ -38,6 +37,9 @@ #![feature(staged_api)] #![feature(unicode)] #![feature(exit_status)] +#![feature(path)] +#![feature(io)] +#![feature(fs)] extern crate arena; extern crate flate; @@ -73,9 +75,10 @@ use rustc::metadata; use rustc::util::common::time; use std::cmp::Ordering::Equal; -use std::old_io::{self, stdio}; -use std::iter::repeat; use std::env; +use std::iter::repeat; +use std::old_io::{self, stdio}; +use std::path::PathBuf; use std::sync::mpsc::channel; use std::thread; @@ -159,14 +162,14 @@ pub fn run_compiler<'a>(args: &[String], } // Extract output directory and file from matches. -fn make_output(matches: &getopts::Matches) -> (Option<Path>, Option<Path>) { - let odir = matches.opt_str("out-dir").map(|o| Path::new(o)); - let ofile = matches.opt_str("o").map(|o| Path::new(o)); +fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) { + let odir = matches.opt_str("out-dir").map(|o| PathBuf::new(&o)); + let ofile = matches.opt_str("o").map(|o| PathBuf::new(&o)); (odir, ofile) } // Extract input (string or file and optional path) from matches. -fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> { +fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> { if free_matches.len() == 1 { let ifile = &free_matches[0][..]; if ifile == "-" { @@ -174,7 +177,7 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> { let src = String::from_utf8(contents).unwrap(); Some((Input::Str(src), None)) } else { - Some((Input::File(Path::new(ifile)), Some(Path::new(ifile)))) + Some((Input::File(PathBuf::new(ifile)), Some(PathBuf::new(ifile)))) } } else { None @@ -215,14 +218,15 @@ pub trait CompilerCalls<'a> { &getopts::Matches, &Session, &Input, - &Option<Path>, - &Option<Path>) + &Option<PathBuf>, + &Option<PathBuf>) -> Compilation; // Called after we extract the input from the arguments. Gives the implementer // an opportunity to change the inputs or to add some custom input handling. // The default behaviour is to simply pass through the inputs. - fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) { + fn some_input(&mut self, input: Input, input_path: Option<PathBuf>) + -> (Input, Option<PathBuf>) { (input, input_path) } @@ -234,10 +238,10 @@ pub trait CompilerCalls<'a> { fn no_input(&mut self, &getopts::Matches, &config::Options, - &Option<Path>, - &Option<Path>, + &Option<PathBuf>, + &Option<PathBuf>, &diagnostics::registry::Registry) - -> Option<(Input, Option<Path>)>; + -> Option<(Input, Option<PathBuf>)>; // Parse pretty printing information from the arguments. The implementer can // choose to ignore this (the default will return None) which will skip pretty @@ -293,10 +297,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { fn no_input(&mut self, matches: &getopts::Matches, sopts: &config::Options, - odir: &Option<Path>, - ofile: &Option<Path>, + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>, descriptions: &diagnostics::registry::Registry) - -> Option<(Input, Option<Path>)> { + -> Option<(Input, Option<PathBuf>)> { match matches.free.len() { 0 => { if sopts.describe_lints { @@ -346,8 +350,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { matches: &getopts::Matches, sess: &Session, input: &Input, - odir: &Option<Path>, - ofile: &Option<Path>) + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>) -> Compilation { RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile).and_then( || RustcDefaultCalls::list_metadata(sess, matches, input)) @@ -400,11 +404,12 @@ impl RustcDefaultCalls { if r.contains(&("ls".to_string())) { match input { &Input::File(ref ifile) => { - let mut stdout = old_io::stdout(); let path = &(*ifile); + let mut v = Vec::new(); metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx, path, - &mut stdout).unwrap(); + &mut v).unwrap(); + println!("{}", String::from_utf8(v).unwrap()); } &Input::Str(_) => { early_error("cannot list metadata for stdin"); @@ -419,8 +424,8 @@ impl RustcDefaultCalls { fn print_crate_info(sess: &Session, input: Option<&Input>, - odir: &Option<Path>, - ofile: &Option<Path>) + odir: &Option<PathBuf>, + ofile: &Option<PathBuf>) -> Compilation { if sess.opts.prints.len() == 0 { return Compilation::Continue; @@ -457,7 +462,8 @@ impl RustcDefaultCalls { style, &id, &t_outputs.with_extension("")); - println!("{}", fname.filename_display()); + println!("{}", fname.file_name().unwrap() + .to_string_lossy()); } } } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index f433e67d878..ffb2a05e437 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -38,8 +38,11 @@ use syntax::ptr::P; use graphviz as dot; -use std::old_io::{self, MemReader}; +use std::fs::File; +use std::io::{self, Write}; +use std::old_io; use std::option; +use std::path::PathBuf; use std::str::FromStr; #[derive(Copy, PartialEq, Debug)] @@ -208,7 +211,7 @@ impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> { impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> { fn pre(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeExpr(_) => s.popen(), _ => Ok(()) @@ -216,7 +219,7 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> { } fn post(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeIdent(_) | pprust::NodeName(_) => Ok(()), @@ -259,7 +262,7 @@ impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> { impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> { fn post(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeIdent(&ast::Ident { name: ast::Name(nm), ctxt }) => { try!(pp::space(&mut s.s)); @@ -294,7 +297,7 @@ impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> { impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> { fn pre(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeExpr(_) => s.popen(), _ => Ok(()) @@ -302,7 +305,7 @@ impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> { } fn post(&self, s: &mut pprust::State, - node: pprust::AnnNode) -> old_io::IoResult<()> { + node: pprust::AnnNode) -> io::Result<()> { let tcx = &self.analysis.ty_cx; match node { pprust::NodeExpr(expr) => { @@ -507,7 +510,7 @@ pub fn pretty_print_input(sess: Session, input: &Input, ppm: PpMode, opt_uii: Option<UserIdentifiedItem>, - ofile: Option<Path>) { + ofile: Option<PathBuf>) { let krate = driver::phase_1_parse_input(&sess, cfg, input); let krate = if let PpmSource(PpmEveryBodyLoops) = ppm { @@ -547,24 +550,15 @@ pub fn pretty_print_input(sess: Session, .unwrap() .as_bytes() .to_vec(); - let mut rdr = MemReader::new(src); + let mut rdr = &src[..]; - let out = match ofile { - None => box old_io::stdout() as Box<Writer+'static>, - Some(p) => { - let r = old_io::File::create(&p); - match r { - Ok(w) => box w as Box<Writer+'static>, - Err(e) => panic!("print-print failed to open {} due to {}", - p.display(), e), - } - } - }; + let mut out = Vec::new(); match (ppm, opt_uii) { - (PpmSource(s), None) => + (PpmSource(s), None) => { + let out: &mut Write = &mut out; s.call_with_pp_support( - sess, ast_map, &arenas, id, out, |annotation, out| { + sess, ast_map, &arenas, id, box out, |annotation, out| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); pprust::print_crate(sess.codemap(), @@ -575,9 +569,11 @@ pub fn pretty_print_input(sess: Session, out, annotation.pp_ann(), is_expanded) - }), + }) + } - (PpmSource(s), Some(uii)) => + (PpmSource(s), Some(uii)) => { + let out: &mut Write = &mut out; s.call_with_pp_support( sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| { debug!("pretty printing source code {:?}", s); @@ -589,7 +585,7 @@ pub fn pretty_print_input(sess: Session, sess.diagnostic(), src_name.to_string(), &mut rdr, - out, + box out, annotation.pp_ann(), is_expanded); for node_id in uii.all_matching_node_ids(ast_map) { @@ -600,7 +596,8 @@ pub fn pretty_print_input(sess: Session, try!(pp::hardbreak(&mut pp_state.s)); } pp::eof(&mut pp_state.s) - }), + }) + } (PpmFlowGraph(mode), opt_uii) => { debug!("pretty printing flow graph for {:?}", opt_uii); @@ -618,6 +615,7 @@ pub fn pretty_print_input(sess: Session, }); let code = blocks::Code::from_node(node); + let out: &mut Writer = &mut out; match code { Some(code) => { let variants = gather_flowgraph_variants(&sess); @@ -642,14 +640,25 @@ pub fn pretty_print_input(sess: Session, } } } - }.unwrap() + }.unwrap(); + + match ofile { + None => print!("{}", String::from_utf8(out).unwrap()), + Some(p) => { + match File::create(&p) { + Ok(mut w) => w.write_all(&out).unwrap(), + Err(e) => panic!("print-print failed to open {} due to {}", + p.display(), e), + } + } + } } fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>, analysis: ty::CrateAnalysis, code: blocks::Code, mode: PpFlowGraphMode, - mut out: W) -> old_io::IoResult<()> { + mut out: W) -> io::Result<()> { let ty_cx = &analysis.ty_cx; let cfg = match code { blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block), @@ -689,17 +698,10 @@ fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>, } } - fn expand_err_details(r: old_io::IoResult<()>) -> old_io::IoResult<()> { + fn expand_err_details(r: old_io::IoResult<()>) -> io::Result<()> { r.map_err(|ioerr| { - let orig_detail = ioerr.detail.clone(); - let m = "graphviz::render failed"; - old_io::IoError { - detail: Some(match orig_detail { - None => m.to_string(), - Some(d) => format!("{}: {}", m, d) - }), - ..ioerr - } + io::Error::new(io::ErrorKind::Other, "graphviz::render failed", + Some(ioerr.to_string())) }) } } diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs index 14a99026aac..f54480e3e52 100644 --- a/src/librustc_llvm/archive_ro.rs +++ b/src/librustc_llvm/archive_ro.rs @@ -16,6 +16,7 @@ use ArchiveRef; use std::ffi::CString; use std::mem; use std::raw; +use std::path::Path; pub struct ArchiveRO { ptr: ArchiveRef, @@ -29,14 +30,25 @@ impl ArchiveRO { /// If this archive is used with a mutable method, then an error will be /// raised. pub fn open(dst: &Path) -> Option<ArchiveRO> { - unsafe { - let s = CString::new(dst.as_vec()).unwrap(); + return unsafe { + let s = path2cstr(dst); let ar = ::LLVMRustOpenArchive(s.as_ptr()); if ar.is_null() { None } else { Some(ArchiveRO { ptr: ar }) } + }; + + #[cfg(unix)] + fn path2cstr(p: &Path) -> CString { + use std::os::unix::prelude::*; + use std::ffi::AsOsStr; + CString::new(p.as_os_str().as_bytes()).unwrap() + } + #[cfg(windows)] + fn path2cstr(p: &Path) -> CString { + CString::new(p.to_str().unwrap()).unwrap() } } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 09a187befb2..0a1416ff566 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -28,9 +28,9 @@ #![feature(int_uint)] #![feature(libc)] #![feature(link_args)] -#![feature(old_path)] #![feature(staged_api)] #![feature(std_misc)] +#![feature(path)] extern crate libc; #[macro_use] #[no_link] extern crate rustc_bitflags; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 7b377ac3611..1e84bc4b8e0 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -27,12 +27,13 @@ use util::common::time; use util::ppaux; use util::sha2::{Digest, Sha256}; -use std::old_io::fs::PathExtensions; -use std::old_io::{fs, TempDir, Command}; -use std::old_io; +use std::ffi::{AsOsStr, OsString}; +use std::fs::{self, TempDir, PathExt}; +use std::io::{self, Read, Write}; use std::mem; +use std::path::{Path, PathBuf}; +use std::process::Command; use std::str; -use std::string::String; use flate; use serialize::hex::ToHex; use syntax::ast; @@ -156,7 +157,7 @@ pub fn find_crate_name(sess: Option<&Session>, return validate(s.to_string(), Some(attr.span)); } if let Input::File(ref path) = *input { - if let Some(s) = path.filestem_str() { + if let Some(s) = path.file_stem().and_then(|s| s.to_str()) { return validate(s.to_string(), None); } } @@ -356,7 +357,7 @@ pub fn get_cc_prog(sess: &Session) -> String { } pub fn remove(sess: &Session, path: &Path) { - match fs::unlink(path) { + match fs::remove_file(path) { Ok(..) => {} Err(e) => { sess.err(&format!("failed to remove {}: {}", @@ -371,7 +372,7 @@ pub fn remove(sess: &Session, path: &Path) { pub fn link_binary(sess: &Session, trans: &CrateTranslation, outputs: &OutputFilenames, - crate_name: &str) -> Vec<Path> { + crate_name: &str) -> Vec<PathBuf> { let mut out_filenames = Vec::new(); for &crate_type in &*sess.crate_types.borrow() { if invalid_output_for_target(sess, crate_type) { @@ -425,35 +426,35 @@ pub fn invalid_output_for_target(sess: &Session, } fn is_writeable(p: &Path) -> bool { - match p.stat() { + match p.metadata() { Err(..) => true, - Ok(m) => m.perm & old_io::USER_WRITE == old_io::USER_WRITE + Ok(m) => !m.permissions().readonly() } } pub fn filename_for_input(sess: &Session, crate_type: config::CrateType, name: &str, - out_filename: &Path) -> Path { + out_filename: &Path) -> PathBuf { let libname = format!("{}{}", name, sess.opts.cg.extra_filename); match crate_type { config::CrateTypeRlib => { - out_filename.with_filename(format!("lib{}.rlib", libname)) + out_filename.with_file_name(&format!("lib{}.rlib", libname)) } config::CrateTypeDylib => { let (prefix, suffix) = (&sess.target.target.options.dll_prefix, &sess.target.target.options.dll_suffix); - out_filename.with_filename(format!("{}{}{}", - prefix, - libname, - suffix)) + out_filename.with_file_name(&format!("{}{}{}", + prefix, + libname, + suffix)) } config::CrateTypeStaticlib => { - out_filename.with_filename(format!("lib{}.a", libname)) + out_filename.with_file_name(&format!("lib{}.a", libname)) } config::CrateTypeExecutable => { let suffix = &sess.target.target.options.exe_suffix; - out_filename.with_filename(format!("{}{}", libname, suffix)) + out_filename.with_file_name(&format!("{}{}", libname, suffix)) } } } @@ -462,7 +463,7 @@ fn link_binary_output(sess: &Session, trans: &CrateTranslation, crate_type: config::CrateType, outputs: &OutputFilenames, - crate_name: &str) -> Path { + crate_name: &str) -> PathBuf { let obj_filename = outputs.temp_path(OutputTypeObject); let out_filename = match outputs.single_output_file { Some(ref file) => file.clone(), @@ -507,10 +508,10 @@ fn link_binary_output(sess: &Session, out_filename } -fn archive_search_paths(sess: &Session) -> Vec<Path> { +fn archive_search_paths(sess: &Session) -> Vec<PathBuf> { let mut search = Vec::new(); sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| { - search.push(path.clone()); + search.push(path.to_path_buf()); FileDoesntMatch }); return search; @@ -529,7 +530,7 @@ fn link_rlib<'a>(sess: &'a Session, let handler = &sess.diagnostic().handler; let config = ArchiveConfig { handler: handler, - dst: out_filename.clone(), + dst: out_filename.to_path_buf(), lib_search_paths: archive_search_paths(sess), slib_prefix: sess.target.target.options.staticlib_prefix.clone(), slib_suffix: sess.target.target.options.staticlib_suffix.clone(), @@ -588,7 +589,9 @@ fn link_rlib<'a>(sess: &'a Session, // the same filename for metadata (stomping over one another) let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir"); let metadata = tmpdir.path().join(METADATA_FILENAME); - match fs::File::create(&metadata).write_all(&trans.metadata) { + match fs::File::create(&metadata).and_then(|mut f| { + f.write_all(&trans.metadata) + }) { Ok(..) => {} Err(e) => { sess.err(&format!("failed to write {}: {}", @@ -613,28 +616,32 @@ fn link_rlib<'a>(sess: &'a Session, let bc_deflated_filename = obj_filename.with_extension( &format!("{}.bytecode.deflate", i)); - let bc_data = match fs::File::open(&bc_filename).read_to_end() { - Ok(buffer) => buffer, + let mut bc_data = Vec::new(); + match fs::File::open(&bc_filename).and_then(|mut f| { + f.read_to_end(&mut bc_data) + }) { + Ok(..) => {} Err(e) => sess.fatal(&format!("failed to read bytecode: {}", e)) - }; + } let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) { Some(compressed) => compressed, - None => sess.fatal(&format!("failed to compress bytecode from {}", - bc_filename.display())) + None => sess.fatal(&format!("failed to compress bytecode \ + from {}", + bc_filename.display())) }; let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) { Ok(file) => file, Err(e) => { - sess.fatal(&format!("failed to create compressed bytecode \ - file: {}", e)) + sess.fatal(&format!("failed to create compressed \ + bytecode file: {}", e)) } }; match write_rlib_bytecode_object_v1(&mut bc_file_deflated, - bc_data_deflated.as_slice()) { + &bc_data_deflated) { Ok(()) => {} Err(e) => { sess.err(&format!("failed to write compressed bytecode: \ @@ -670,15 +677,23 @@ fn link_rlib<'a>(sess: &'a Session, ab } -fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T, - bc_data_deflated: &[u8]) - -> ::std::old_io::IoResult<()> { +fn write_rlib_bytecode_object_v1(writer: &mut Write, + bc_data_deflated: &[u8]) -> io::Result<()> { let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64; - try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) }; - try! { writer.write_le_u32(1) }; - try! { writer.write_le_u64(bc_data_deflated_size) }; - try! { writer.write_all(&bc_data_deflated[..]) }; + try!(writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC)); + try!(writer.write_all(&[1, 0, 0, 0])); + try!(writer.write_all(&[ + (bc_data_deflated_size >> 0) as u8, + (bc_data_deflated_size >> 8) as u8, + (bc_data_deflated_size >> 16) as u8, + (bc_data_deflated_size >> 24) as u8, + (bc_data_deflated_size >> 32) as u8, + (bc_data_deflated_size >> 40) as u8, + (bc_data_deflated_size >> 48) as u8, + (bc_data_deflated_size >> 56) as u8, + ])); + try!(writer.write_all(&bc_data_deflated)); let number_of_bytes_written_so_far = RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id @@ -690,7 +705,7 @@ fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T, // padding byte to make it even. This works around a crash bug in LLDB // (see issue #15950) if number_of_bytes_written_so_far % 2 == 1 { - try! { writer.write_u8(0) }; + try!(writer.write_all(&[0])); } return Ok(()); @@ -796,13 +811,13 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool, pname, prog.status)); sess.note(&format!("{:?}", &cmd)); - let mut output = prog.error.clone(); - output.push_all(&prog.output); + let mut output = prog.stderr.clone(); + output.push_all(&prog.stdout); sess.note(str::from_utf8(&output[..]).unwrap()); sess.abort_if_errors(); } - debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap()); - debug!("linker stdout:\n{}", String::from_utf8(prog.output).unwrap()); + debug!("linker stderr:\n{}", String::from_utf8(prog.stderr).unwrap()); + debug!("linker stdout:\n{}", String::from_utf8(prog.stdout).unwrap()); }, Err(e) => { sess.err(&format!("could not exec the linker `{}`: {}", @@ -866,9 +881,9 @@ fn link_args(cmd: &mut Command, if t.options.is_like_osx { let morestack = lib_path.join("libmorestack.a"); - let mut v = b"-Wl,-force_load,".to_vec(); - v.push_all(morestack.as_vec()); - cmd.arg(&v[..]); + let mut v = OsString::from_str("-Wl,-force_load,"); + v.push_os_str(morestack.as_os_str()); + cmd.arg(&v); } else { cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]); } @@ -878,7 +893,7 @@ fn link_args(cmd: &mut Command, // executable. This metadata is in a separate object file from the main // object file, so we link that in here. if dylib { - cmd.arg(obj_filename.with_extension("metadata.o")); + cmd.arg(&obj_filename.with_extension("metadata.o")); } if t.options.is_like_osx { @@ -991,9 +1006,9 @@ fn link_args(cmd: &mut Command, cmd.args(&["-dynamiclib", "-Wl,-dylib"]); if sess.opts.cg.rpath { - let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec(); - v.push_all(out_filename.filename().unwrap()); - cmd.arg(&v[..]); + let mut v = OsString::from_str("-Wl,-install_name,@rpath/"); + v.push_os_str(out_filename.file_name().unwrap()); + cmd.arg(&v); } } else { cmd.arg("-shared"); @@ -1006,23 +1021,23 @@ fn link_args(cmd: &mut Command, if sess.opts.cg.rpath { let sysroot = sess.sysroot(); let target_triple = &sess.opts.target_triple; - let get_install_prefix_lib_path = || { + let mut get_install_prefix_lib_path = || { let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX"); let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); - let mut path = Path::new(install_prefix); + let mut path = PathBuf::new(install_prefix); path.push(&tlib); path }; - let rpath_config = RPathConfig { + let mut rpath_config = RPathConfig { used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic), - out_filename: out_filename.clone(), + out_filename: out_filename.to_path_buf(), has_rpath: sess.target.target.options.has_rpath, is_like_osx: sess.target.target.options.is_like_osx, - get_install_prefix_lib_path: get_install_prefix_lib_path, - realpath: ::util::fs::realpath + get_install_prefix_lib_path: &mut get_install_prefix_lib_path, + realpath: &mut ::util::fs::realpath }; - cmd.args(&rpath::get_rpath_flags(rpath_config)); + cmd.args(&rpath::get_rpath_flags(&mut rpath_config)); } // Finally add all the linker arguments provided on the command line along @@ -1082,7 +1097,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { let search_path = archive_search_paths(sess); for l in staticlibs { if takes_hints { - cmd.arg(format!("-l{}", l)); + cmd.arg(&format!("-l{}", l)); } else { // -force_load is the OSX equivalent of --whole-archive, but it // involves passing the full path to the library to link. @@ -1091,9 +1106,9 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { &sess.target.target.options.staticlib_suffix, &search_path[..], &sess.diagnostic().handler); - let mut v = b"-Wl,-force_load,".to_vec(); - v.push_all(lib.as_vec()); - cmd.arg(&v[..]); + let mut v = OsString::from_str("-Wl,-force_load,"); + v.push_os_str(lib.as_os_str()); + cmd.arg(&v); } } if takes_hints { @@ -1103,7 +1118,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) { for &(ref l, kind) in others { match kind { cstore::NativeUnknown => { - cmd.arg(format!("-l{}", l)); + cmd.arg(&format!("-l{}", l)); } cstore::NativeFramework => { cmd.arg("-framework").arg(&l[..]); @@ -1150,18 +1165,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, let src = sess.cstore.get_used_crate_source(cnum).unwrap(); match kind { cstore::RequireDynamic => { - add_dynamic_crate(cmd, sess, src.dylib.unwrap().0) + add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0) } cstore::RequireStatic => { - add_static_crate(cmd, sess, tmpdir, src.rlib.unwrap().0) + add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0) } } } // Converts a library file-stem into a cc -l argument - fn unlib<'a>(config: &config::Config, stem: &'a [u8]) -> &'a [u8] { - if stem.starts_with("lib".as_bytes()) && !config.target.options.is_like_windows { + fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str { + if stem.starts_with("lib") && !config.target.options.is_like_windows { &stem[3..] } else { stem @@ -1170,7 +1185,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, // Adds the static "rlib" versions of all crates to the command line. fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path, - cratepath: Path) { + cratepath: &Path) { // When performing LTO on an executable output, all of the // bytecode from the upstream libraries has already been // included in our object file output. We need to modify all of @@ -1186,12 +1201,12 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, // If we're not doing LTO, then our job is simply to just link // against the archive. if sess.lto() { - let name = cratepath.filename_str().unwrap(); + let name = cratepath.file_name().unwrap().to_str().unwrap(); let name = &name[3..name.len() - 5]; // chop off lib/.rlib time(sess.time_passes(), &format!("altering {}.rlib", name), (), |()| { - let dst = tmpdir.join(cratepath.filename().unwrap()); + let dst = tmpdir.join(cratepath.file_name().unwrap()); match fs::copy(&cratepath, &dst) { Ok(..) => {} Err(e) => { @@ -1205,7 +1220,11 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, // Fix up permissions of the copy, as fs::copy() preserves // permissions, but the original file may have been installed // by a package manager and may be read-only. - match fs::chmod(&dst, old_io::USER_READ | old_io::USER_WRITE) { + match fs::metadata(&dst).and_then(|m| { + let mut perms = m.permissions(); + perms.set_readonly(false); + fs::set_permissions(&dst, perms) + }) { Ok(..) => {} Err(e) => { sess.err(&format!("failed to chmod {} when preparing \ @@ -1227,7 +1246,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, archive.remove_file(&format!("{}.o", name)); let files = archive.files(); if files.iter().any(|s| s.ends_with(".o")) { - cmd.arg(dst); + cmd.arg(&dst); } }); } else { @@ -1236,19 +1255,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, } // Same thing as above, but for dynamic crates instead of static crates. - fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: Path) { + fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: &Path) { // If we're performing LTO, then it should have been previously required // that all upstream rust dependencies were available in an rlib format. assert!(!sess.lto()); // Just need to tell the linker about where the library lives and // what its name is - let dir = cratepath.dirname(); - if !dir.is_empty() { cmd.arg("-L").arg(dir); } - - let mut v = "-l".as_bytes().to_vec(); - v.push_all(unlib(&sess.target, cratepath.filestem().unwrap())); - cmd.arg(&v[..]); + if let Some(dir) = cratepath.parent() { + cmd.arg("-L").arg(dir); + } + let filestem = cratepath.file_stem().unwrap().to_str().unwrap(); + cmd.arg(&format!("-l{}", unlib(&sess.target, filestem))); } } @@ -1286,7 +1304,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) { for &(kind, ref lib) in &libs { match kind { cstore::NativeUnknown => { - cmd.arg(format!("-l{}", *lib)); + cmd.arg(&format!("-l{}", *lib)); } cstore::NativeFramework => { cmd.arg("-framework"); diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index d8a296bf041..db9966e0548 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -59,7 +59,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, }; let archive = ArchiveRO::open(&path).expect("wanted an rlib"); - let file = path.filename_str().unwrap(); + let file = path.file_name().unwrap().to_str().unwrap(); let file = &file[3..file.len() - 5]; // chop off lib/.rlib debug!("reading {}", file); for i in iter::count(0, 1) { diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index cd14fe529b1..156cfa6c4b2 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -18,17 +18,19 @@ use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, Conte use llvm::SMDiagnosticRef; use trans::{CrateTranslation, ModuleTranslation}; use util::common::time; +use util::common::path2cstr; use syntax::codemap; use syntax::diagnostic; use syntax::diagnostic::{Emitter, Handler, Level, mk_handler}; use std::ffi::{CStr, CString}; -use std::old_io::Command; -use std::old_io::fs; +use std::fs; use std::iter::Unfold; +use std::mem; +use std::path::Path; +use std::process::{Command, Stdio}; use std::ptr; use std::str; -use std::mem; use std::sync::{Arc, Mutex}; use std::sync::mpsc::channel; use std::thread; @@ -67,7 +69,7 @@ pub fn write_output_file( output: &Path, file_type: llvm::FileType) { unsafe { - let output_c = CString::new(output.as_vec()).unwrap(); + let output_c = path2cstr(output); let result = llvm::LLVMRustWriteOutputFile( target, pm, m, output_c.as_ptr(), file_type); if !result { @@ -424,7 +426,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_no_opt_bc { let ext = format!("{}.no-opt.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -477,7 +479,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_lto_bc { let name = format!("{}.lto.bc", name_extra); let out = output_names.with_extension(&name); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } }, @@ -511,7 +513,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_bc { let ext = format!("{}.bc", name_extra); let out = output_names.with_extension(&ext); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()); } @@ -519,7 +521,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, if config.emit_ir { let ext = format!("{}.ll", name_extra); let out = output_names.with_extension(&ext); - let out = CString::new(out.as_vec()).unwrap(); + let out = path2cstr(&out); with_codegen(tm, llmod, config.no_builtins, |cpm| { llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr()); }) @@ -717,12 +719,11 @@ pub fn run_passes(sess: &Session, cmd.arg("-nostdlib"); for index in 0..trans.modules.len() { - cmd.arg(crate_output.with_extension(&format!("{}.o", index))); + cmd.arg(&crate_output.with_extension(&format!("{}.o", index))); } - cmd.arg("-r") - .arg("-o") - .arg(windows_output_path.as_ref().unwrap_or(output_path)); + cmd.arg("-r").arg("-o") + .arg(windows_output_path.as_ref().map(|s| &**s).unwrap_or(output_path)); cmd.args(&sess.target.target.options.post_link_args); @@ -730,9 +731,7 @@ pub fn run_passes(sess: &Session, println!("{:?}", &cmd); } - cmd.stdin(::std::old_io::process::Ignored) - .stdout(::std::old_io::process::InheritFd(1)) - .stderr(::std::old_io::process::InheritFd(2)); + cmd.stdin(Stdio::null()); match cmd.status() { Ok(status) => { if !status.success() { @@ -964,9 +963,9 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { let pname = get_cc_prog(sess); let mut cmd = Command::new(&pname[..]); - cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject)) - .arg(outputs.temp_path(config::OutputTypeAssembly)); - debug!("{:?}", &cmd); + cmd.arg("-c").arg("-o").arg(&outputs.path(config::OutputTypeObject)) + .arg(&outputs.temp_path(config::OutputTypeAssembly)); + debug!("{:?}", cmd); match cmd.output() { Ok(prog) => { @@ -975,8 +974,8 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { pname, prog.status)); sess.note(&format!("{:?}", &cmd)); - let mut note = prog.error.clone(); - note.push_all(&prog.output); + let mut note = prog.stderr.clone(); + note.push_all(&prog.stdout); sess.note(str::from_utf8(¬e[..]).unwrap()); sess.abort_if_errors(); } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 71317d5875b..dcc79e90cc5 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -29,9 +29,7 @@ #![feature(collections)] #![feature(core)] #![feature(int_uint)] -#![feature(old_io)] #![feature(libc)] -#![feature(old_path)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] @@ -39,6 +37,11 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(io)] +#![feature(fs)] +#![feature(path)] +#![feature(os)] +#![feature(tempdir)] extern crate arena; extern crate flate; diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 371b9268fba..3c6cb5f9de9 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -33,8 +33,9 @@ use middle::def; use middle::ty::{self, Ty}; use std::cell::Cell; -use std::old_io::{self, File, fs}; use std::env; +use std::fs::{self, File}; +use std::path::{Path, PathBuf}; use syntax::ast_util::{self, PostExpansionMethod}; use syntax::ast::{self, NodeId, DefId}; @@ -1537,6 +1538,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { } } +#[allow(deprecated)] pub fn process_crate(sess: &Session, krate: &ast::Crate, analysis: &ty::CrateAnalysis, @@ -1557,15 +1559,15 @@ pub fn process_crate(sess: &Session, info!("Dumping crate {}", cratename); // find a path to dump our data to - let mut root_path = match env::var("DXR_RUST_TEMP_FOLDER") { - Ok(val) => Path::new(val), - Err(..) => match odir { + let mut root_path = match env::var_os("DXR_RUST_TEMP_FOLDER") { + Some(val) => PathBuf::new(&val), + None => match odir { Some(val) => val.join("dxr"), - None => Path::new("dxr-temp"), + None => PathBuf::new("dxr-temp"), }, }; - match fs::mkdir_recursive(&root_path, old_io::USER_RWX) { + match fs::create_dir_all(&root_path) { Err(e) => sess.err(&format!("Could not create directory {}: {}", root_path.display(), e)), _ => (), @@ -1579,7 +1581,7 @@ pub fn process_crate(sess: &Session, // Create output file. let mut out_name = cratename.clone(); out_name.push_str(".csv"); - root_path.push(out_name); + root_path.push(&out_name); let output_file = match File::create(&root_path) { Ok(f) => box f, Err(e) => { @@ -1595,7 +1597,7 @@ pub fn process_crate(sess: &Session, collected_paths: vec!(), collecting: false, fmt: FmtStrs::new(box Recorder { - out: output_file as Box<Writer+'static>, + out: output_file, dump_spans: false, }, SpanUtils { diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs index 937f2d07677..f7c0d6a983f 100644 --- a/src/librustc_trans/save/recorder.rs +++ b/src/librustc_trans/save/recorder.rs @@ -13,7 +13,7 @@ pub use self::Row::*; use super::escape; use super::span_utils::SpanUtils; -use std::vec::Vec; +use std::io::Write; use syntax::ast; use syntax::ast::{NodeId,DefId}; @@ -23,7 +23,7 @@ const ZERO_DEF_ID: DefId = DefId { node: 0, krate: 0 }; pub struct Recorder { // output file - pub out: Box<Writer+'static>, + pub out: Box<Write+'static>, pub dump_spans: bool, } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index f3b7058336b..142262a25bd 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -206,10 +206,12 @@ use middle::pat_util; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; use util::ppaux; +use util::common::path2cstr; use libc::{c_uint, c_longlong}; -use std::ffi::CString; use std::cell::{Cell, RefCell}; +use std::ffi::CString; +use std::path::Path; use std::ptr; use std::rc::{Rc, Weak}; use syntax::util::interner::Interner; @@ -1588,20 +1590,13 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { cx.sess().warn("debuginfo: Invalid path to crate's local root source file!"); fallback_path(cx) } else { - match abs_path.path_relative_from(work_dir) { + match abs_path.relative_from(work_dir) { Some(ref p) if p.is_relative() => { - // prepend "./" if necessary - let dotdot = b".."; - let prefix: &[u8] = &[dotdot[0], ::std::old_path::SEP_BYTE]; - let mut path_bytes = p.as_vec().to_vec(); - - if &path_bytes[..2] != prefix && - &path_bytes[..2] != dotdot { - path_bytes.insert(0, prefix[0]); - path_bytes.insert(1, prefix[1]); + if p.starts_with(Path::new("./")) { + path2cstr(p) + } else { + path2cstr(&Path::new(".").join(p)) } - - CString::new(path_bytes).unwrap() } _ => fallback_path(cx) } @@ -1614,7 +1609,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { (option_env!("CFG_VERSION")).expect("CFG_VERSION")); let compile_unit_name = compile_unit_name.as_ptr(); - let work_dir = CString::new(work_dir.as_vec()).unwrap(); + let work_dir = path2cstr(&work_dir); let producer = CString::new(producer).unwrap(); let flags = "\0"; let split_name = "\0"; @@ -1716,7 +1711,7 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile { debug!("file_metadata: {}", full_path); // FIXME (#9639): This needs to handle non-utf8 paths - let work_dir = cx.sess().working_dir.as_str().unwrap(); + let work_dir = cx.sess().working_dir.to_str().unwrap(); let file_name = if full_path.starts_with(work_dir) { &full_path[work_dir.len() + 1..full_path.len()] diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 36d39fa58ba..c39451b15ad 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 { diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 942aec7d22f..6cfe7a33dd4 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -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(), diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index 79e348cb03e..51c58861b4b 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -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(), diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index c537e370723..3acd17dedd5 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -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> diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 735487611dc..add44769bab 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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()); }); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index fc304884ec9..b4522ad680b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -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 ... }, diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index d64d9becc0c..7d635c8b232 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -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: {}", diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 43e8f44244e..9fd38ecb136 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -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)); } } } diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index d476fd72abc..bfc6b1bf0ef 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -35,6 +35,7 @@ Core encoding and decoding interfaces. #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(path)] #![cfg_attr(test, feature(test))] // test harness access diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 70f0ba4bb23..f287229e083 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -15,6 +15,7 @@ Core encoding and decoding interfaces. */ use std::old_path; +use std::path; use std::rc::Rc; use std::cell::{Cell, RefCell}; use std::sync::Arc; @@ -564,6 +565,19 @@ impl Decodable for old_path::windows::Path { } } +impl Encodable for path::PathBuf { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { + self.to_str().unwrap().encode(e) + } +} + +impl Decodable for path::PathBuf { + fn decode<D: Decoder>(d: &mut D) -> Result<path::PathBuf, D::Error> { + let bytes: String = try!(Decodable::decode(d)); + Ok(path::PathBuf::new(&bytes)) + } +} + impl<T: Encodable + Copy> Encodable for Cell<T> { fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { self.get().encode(s) diff --git a/src/libstd/old_io/fs.rs b/src/libstd/old_io/fs.rs index 4e9c1b36055..9a34ec4b026 100644 --- a/src/libstd/old_io/fs.rs +++ b/src/libstd/old_io/fs.rs @@ -82,6 +82,8 @@ use sys_common; /// attempted against it for which its underlying file descriptor was not /// configured at creation time, via the `FileAccess` parameter to /// `File::open_mode()`. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::File")] +#[unstable(feature = "old_io")] pub struct File { fd: fs_imp::FileDesc, path: Path, @@ -94,6 +96,8 @@ impl sys_common::AsInner<fs_imp::FileDesc> for File { } } +#[deprecated(since = "1.0.0", reason = "replaced with std::fs")] +#[unstable(feature = "old_io")] impl File { /// Open a file at `path` in the mode specified by the `mode` and `access` /// arguments @@ -133,6 +137,8 @@ impl File { /// * Attempting to open a file with a `FileAccess` that the user lacks /// permissions for /// * Filesystem-level errors (full disk, etc) + #[deprecated(since = "1.0.0", reason = "replaced with std::fs::OpenOptions")] + #[unstable(feature = "old_io")] pub fn open_mode(path: &Path, mode: FileMode, access: FileAccess) -> IoResult<File> { @@ -174,6 +180,8 @@ impl File { /// /// let contents = File::open(&Path::new("foo.txt")).read_to_end(); /// ``` + #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::open")] + #[unstable(feature = "old_io")] pub fn open(path: &Path) -> IoResult<File> { File::open_mode(path, Open, Read) } @@ -195,12 +203,16 @@ impl File { /// # drop(f); /// # ::std::old_io::fs::unlink(&Path::new("foo.txt")); /// ``` + #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::create")] + #[unstable(feature = "old_io")] pub fn create(path: &Path) -> IoResult<File> { File::open_mode(path, Truncate, Write) .update_desc("couldn't create file") } /// Returns the original path that was used to open this file. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn path<'a>(&'a self) -> &'a Path { &self.path } @@ -208,6 +220,8 @@ impl File { /// Synchronizes all modifications to this file to its permanent storage /// device. This will flush any internal buffers necessary to perform this /// operation. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn fsync(&mut self) -> IoResult<()> { self.fd.fsync() .update_err("couldn't fsync file", @@ -218,6 +232,8 @@ impl File { /// file metadata to the filesystem. This is intended for use cases that /// must synchronize content, but don't need the metadata on disk. The goal /// of this method is to reduce disk operations. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn datasync(&mut self) -> IoResult<()> { self.fd.datasync() .update_err("couldn't datasync file", @@ -232,6 +248,8 @@ impl File { /// be shrunk. If it is greater than the current file's size, then the file /// will be extended to `size` and have all of the intermediate data filled /// in with 0s. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn truncate(&mut self, size: i64) -> IoResult<()> { self.fd.truncate(size) .update_err("couldn't truncate file", |e| @@ -247,11 +265,15 @@ impl File { /// until you have attempted to read past the end of the file, so if /// you've read _exactly_ the number of bytes in the file, this will /// return `false`, not `true`. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn eof(&self) -> bool { self.last_nread == 0 } /// Queries information about the underlying file. + #[deprecated(since = "1.0.0", reason = "replaced with std::fs")] + #[unstable(feature = "old_io")] pub fn stat(&self) -> IoResult<FileStat> { self.fd.fstat() .update_err("couldn't fstat file", |e| @@ -280,6 +302,8 @@ impl File { /// This function will return an error if `path` points to a directory, if the /// user lacks permissions to remove the file, or if some other filesystem-level /// error occurs. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_file")] +#[unstable(feature = "old_io")] pub fn unlink(path: &Path) -> IoResult<()> { fs_imp::unlink(path) .update_err("couldn't unlink path", |e| @@ -307,6 +331,8 @@ pub fn unlink(path: &Path) -> IoResult<()> { /// This function will return an error if the user lacks the requisite permissions /// to perform a `stat` call on the given `path` or if there is no entry in the /// filesystem at the provided path. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::metadata")] +#[unstable(feature = "old_io")] pub fn stat(path: &Path) -> IoResult<FileStat> { fs_imp::stat(path) .update_err("couldn't stat path", |e| @@ -321,6 +347,7 @@ pub fn stat(path: &Path) -> IoResult<FileStat> { /// # Error /// /// See `stat` +#[unstable(feature = "old_fs")] pub fn lstat(path: &Path) -> IoResult<FileStat> { fs_imp::lstat(path) .update_err("couldn't lstat path", |e| @@ -343,6 +370,8 @@ pub fn lstat(path: &Path) -> IoResult<FileStat> { /// This function will return an error if the provided `from` doesn't exist, if /// the process lacks permissions to view the contents, or if some other /// intermittent I/O error occurs. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::rename")] +#[unstable(feature = "old_io")] pub fn rename(from: &Path, to: &Path) -> IoResult<()> { fs_imp::rename(from, to) .update_err("couldn't rename path", |e| @@ -377,6 +406,8 @@ pub fn rename(from: &Path, to: &Path) -> IoResult<()> { /// Note that this copy is not atomic in that once the destination is /// ensured to not exist, there is nothing preventing the destination from /// being created and then destroyed by this operation. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::copy")] +#[unstable(feature = "old_io")] pub fn copy(from: &Path, to: &Path) -> IoResult<()> { fn update_err<T>(result: IoResult<T>, from: &Path, to: &Path) -> IoResult<T> { result.update_err("couldn't copy path", |e| { @@ -421,6 +452,8 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> { /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to change the attributes of the file, or if /// some other I/O error is encountered. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_permissions")] +#[unstable(feature = "old_io")] pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> { fs_imp::chmod(path, mode.bits() as uint) .update_err("couldn't chmod path", |e| @@ -428,6 +461,7 @@ pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> { } /// Change the user and group owners of a file at the specified path. +#[unstable(feature = "old_fs")] pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> { fs_imp::chown(path, uid, gid) .update_err("couldn't chown path", |e| @@ -437,6 +471,8 @@ pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> { /// Creates a new hard link on the filesystem. The `dst` path will be a /// link pointing to the `src` path. Note that systems often require these /// two paths to both be located on the same filesystem. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::hard_link")] +#[unstable(feature = "old_io")] pub fn link(src: &Path, dst: &Path) -> IoResult<()> { fs_imp::link(src, dst) .update_err("couldn't link path", |e| @@ -445,6 +481,8 @@ pub fn link(src: &Path, dst: &Path) -> IoResult<()> { /// Creates a new symbolic link on the filesystem. The `dst` path will be a /// symlink pointing to the `src` path. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::soft_link")] +#[unstable(feature = "old_io")] pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> { fs_imp::symlink(src, dst) .update_err("couldn't symlink path", |e| @@ -457,6 +495,8 @@ pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> { /// /// This function will return an error on failure. Failure conditions include /// reading a file that does not exist or reading a file that is not a symlink. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_link")] +#[unstable(feature = "old_io")] pub fn readlink(path: &Path) -> IoResult<Path> { fs_imp::readlink(path) .update_err("couldn't resolve symlink for path", |e| @@ -480,6 +520,7 @@ pub fn readlink(path: &Path) -> IoResult<Path> { /// /// This function will return an error if the user lacks permissions to make a /// new directory at the provided `path`, or if the directory already exists. +#[unstable(feature = "old_fs")] pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> { fs_imp::mkdir(path, mode.bits() as uint) .update_err("couldn't create directory", |e| @@ -502,6 +543,8 @@ pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> { /// /// This function will return an error if the user lacks permissions to remove /// the directory at the provided `path`, or if the directory isn't empty. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir")] +#[unstable(feature = "old_io")] pub fn rmdir(path: &Path) -> IoResult<()> { fs_imp::rmdir(path) .update_err("couldn't remove directory", |e| @@ -542,6 +585,8 @@ pub fn rmdir(path: &Path) -> IoResult<()> { /// This function will return an error if the provided `path` doesn't exist, if /// the process lacks permissions to view the contents or if the `path` points /// at a non-directory file +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_dir")] +#[unstable(feature = "old_io")] pub fn readdir(path: &Path) -> IoResult<Vec<Path>> { fs_imp::readdir(path) .update_err("couldn't read directory", @@ -552,6 +597,8 @@ pub fn readdir(path: &Path) -> IoResult<Vec<Path>> { /// rooted at `path`. The path given will not be iterated over, and this will /// perform iteration in some top-down order. The contents of unreadable /// subdirectories are ignored. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::walk_dir")] +#[unstable(feature = "old_io")] pub fn walk_dir(path: &Path) -> IoResult<Directories> { Ok(Directories { stack: try!(readdir(path).update_err("couldn't walk directory", @@ -561,6 +608,8 @@ pub fn walk_dir(path: &Path) -> IoResult<Directories> { /// An iterator that walks over a directory #[derive(Clone)] +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::ReadDir")] +#[unstable(feature = "old_io")] pub struct Directories { stack: Vec<Path>, } @@ -590,6 +639,7 @@ impl Iterator for Directories { /// # Error /// /// See `fs::mkdir`. +#[unstable(feature = "old_fs")] pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> { // tjc: if directory exists but with different permissions, // should we return false? @@ -627,6 +677,8 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> { /// # Error /// /// See `file::unlink` and `fs::readdir` +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir_all")] +#[unstable(feature = "old_io")] pub fn rmdir_recursive(path: &Path) -> IoResult<()> { let mut rm_stack = Vec::new(); rm_stack.push(path.clone()); @@ -689,6 +741,8 @@ pub fn rmdir_recursive(path: &Path) -> IoResult<()> { /// `atime` and its modification time set to `mtime`. The times specified should /// be in milliseconds. // FIXME(#10301) these arguments should not be u64 +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_file_times")] +#[unstable(feature = "old_io")] pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> { fs_imp::utime(path, atime, mtime) .update_err("couldn't change_file_times", |e| @@ -748,6 +802,8 @@ impl Seek for File { } /// Utility methods for paths. +#[deprecated(since = "1.0.0", reason = "replaced with std::fs::PathExt")] +#[unstable(feature = "old_io")] pub trait PathExtensions { /// Get information on the file, directory, etc at this path. /// diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index 3f9da6e3c51..45042d6f032 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -54,6 +54,7 @@ pub trait AsRawFd { fn as_raw_fd(&self) -> Fd; } +#[allow(deprecated)] impl AsRawFd for old_io::fs::File { fn as_raw_fd(&self) -> Fd { self.as_inner().fd() diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs index ac1006e653f..df18b404f5f 100644 --- a/src/libstd/sys/windows/ext.rs +++ b/src/libstd/sys/windows/ext.rs @@ -39,6 +39,7 @@ pub trait AsRawHandle { fn as_raw_handle(&self) -> Handle; } +#[allow(deprecated)] impl AsRawHandle for old_io::fs::File { fn as_raw_handle(&self) -> Handle { self.as_inner().handle() diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 334cafd3eb1..53a037ef07e 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -17,7 +17,7 @@ use hash::Hash; use libc::{pid_t, c_void}; use libc; use mem; -use old_io::fs::PathExtensions; +#[allow(deprecated)] use old_io::fs::PathExtensions; use old_io::process::{ProcessExit, ExitStatus}; use old_io::{IoResult, IoError}; use old_io; diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index c33158193ce..faa681c0255 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -25,7 +25,7 @@ use visit::{self, Visitor}; use arena::TypedArena; use std::cell::RefCell; use std::fmt; -use std::old_io::IoResult; +use std::io; use std::iter::{self, repeat}; use std::mem; use std::slice; @@ -997,11 +997,11 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, } pub trait NodePrinter { - fn print_node(&mut self, node: &Node) -> IoResult<()>; + fn print_node(&mut self, node: &Node) -> io::Result<()>; } impl<'a> NodePrinter for pprust::State<'a> { - fn print_node(&mut self, node: &Node) -> IoResult<()> { + fn print_node(&mut self, node: &Node) -> io::Result<()> { match *node { NodeItem(a) => self.print_item(&*a), NodeForeignItem(a) => self.print_foreign_item(&*a), diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index ba3743cdb33..62d98be8b85 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -20,7 +20,9 @@ use print::pprust; use ptr::P; use util::small_vector::SmallVector; -use std::old_io::File; +use std::fs::File; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; use std::rc::Rc; // These macros all relate to the file system; they either return @@ -97,7 +99,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree cx.cfg(), &res_rel_file(cx, sp, - &Path::new(file)), + Path::new(&file)), true, None, sp); @@ -136,8 +138,10 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) Some(f) => f, None => return DummyResult::expr(sp) }; - let file = res_rel_file(cx, sp, &Path::new(file)); - let bytes = match File::open(&file).read_to_end() { + let file = res_rel_file(cx, sp, Path::new(&file)); + let mut bytes = Vec::new(); + match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { + Ok(..) => {} Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", @@ -145,7 +149,6 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) e)); return DummyResult::expr(sp); } - Ok(bytes) => bytes, }; match String::from_utf8(bytes) { Ok(src) => { @@ -172,15 +175,15 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) Some(f) => f, None => return DummyResult::expr(sp) }; - let file = res_rel_file(cx, sp, &Path::new(file)); - match File::open(&file).read_to_end() { + let file = res_rel_file(cx, sp, Path::new(&file)); + let mut bytes = Vec::new(); + match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); return DummyResult::expr(sp); } - Ok(bytes) => { - let bytes = bytes.iter().cloned().collect(); + Ok(..) => { base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes)))) } } @@ -188,14 +191,18 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // resolve a file-system path to an absolute file-system path (if it // isn't already) -fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path { +fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> PathBuf { // NB: relative paths are resolved relative to the compilation unit if !arg.is_absolute() { - let mut cu = Path::new(cx.codemap().span_to_filename(sp)); - cu.pop(); + let mut cu = PathBuf::new(&cx.codemap().span_to_filename(sp)); + if cu.parent().is_some() { + cu.pop(); + } else { + cu = PathBuf::new(""); + } cu.push(arg); cu } else { - arg.clone() + arg.to_path_buf() } } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index a556b2dfd2a..959e3bdb314 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1432,7 +1432,7 @@ pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T) #[cfg(test)] mod test { - use std::old_io; + use std::io; use ast; use util::parser_testing::{string_to_crate, matches_codepattern}; use parse::token; @@ -1442,7 +1442,7 @@ mod test { // this version doesn't care about getting comments or docstrings in. fn fake_print_crate(s: &mut pprust::State, - krate: &ast::Crate) -> old_io::IoResult<()> { + krate: &ast::Crate) -> io::Result<()> { s.print_mod(&krate.module, &krate.attrs) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7acbd10ef03..7bd9cc3b855 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -36,6 +36,9 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(path)] +#![feature(fs)] +#![feature(io)] extern crate arena; extern crate fmt_macros; diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index 3ad1d96a45d..fb9e0480ceb 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -19,9 +19,8 @@ use parse::lexer::is_block_doc_comment; use parse::lexer; use print::pprust; -use std::old_io; +use std::io::Read; use std::str; -use std::string::String; use std::usize; #[derive(Clone, Copy, PartialEq)] @@ -337,9 +336,10 @@ pub struct Literal { // probably not a good thing. pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler, path: String, - srdr: &mut old_io::Reader) + srdr: &mut Read) -> (Vec<Comment>, Vec<Literal>) { - let src = srdr.read_to_end().unwrap(); + let mut src = Vec::new(); + srdr.read_to_end(&mut src).unwrap(); let src = String::from_utf8(src).unwrap(); let cm = CodeMap::new(); let filemap = cm.new_filemap(path, src); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 66589d5e3d1..def5963e6f4 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -18,11 +18,13 @@ use parse::parser::Parser; use ptr::P; use std::cell::{Cell, RefCell}; -use std::old_io::File; -use std::rc::Rc; +use std::fs::File; +use std::io::Read; +use std::iter; use std::num::Int; +use std::path::{Path, PathBuf}; +use std::rc::Rc; use std::str; -use std::iter; #[macro_use] pub mod parser; @@ -39,7 +41,7 @@ pub mod obsolete; pub struct ParseSess { pub span_diagnostic: SpanHandler, // better be the same as the one in the reader! /// Used to determine and report recursive mod inclusions - included_mod_stack: RefCell<Vec<Path>>, + included_mod_stack: RefCell<Vec<PathBuf>>, pub node_id: Cell<ast::NodeId>, } @@ -250,24 +252,24 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>) None => sess.span_diagnostic.handler().fatal(msg), } }; - let bytes = match File::open(path).read_to_end() { - Ok(bytes) => bytes, + let mut bytes = Vec::new(); + match File::open(path).and_then(|mut f| f.read_to_end(&mut bytes)) { + Ok(..) => {} Err(e) => { - err(&format!("couldn't read {:?}: {}", - path.display(), e)); - unreachable!() + err(&format!("couldn't read {:?}: {}", path.display(), e)); + unreachable!(); } }; match str::from_utf8(&bytes[..]).ok() { Some(s) => { - return string_to_filemap(sess, s.to_string(), - path.as_str().unwrap().to_string()) + string_to_filemap(sess, s.to_string(), + path.to_str().unwrap().to_string()) } None => { - err(&format!("{:?} is not UTF-8 encoded", path.display())) + err(&format!("{:?} is not UTF-8 encoded", path.display())); + unreachable!(); } } - unreachable!() } /// Given a session and a string, add the string to diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c1acee57cf8..88df6d6d4cd 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -78,10 +78,11 @@ use ptr::P; use owned_slice::OwnedSlice; use std::collections::HashSet; -use std::old_io::fs::PathExtensions; +use std::io::prelude::*; use std::iter; use std::mem; use std::num::Float; +use std::path::{Path, PathBuf}; use std::rc::Rc; use std::slice; @@ -5248,14 +5249,23 @@ impl<'a> Parser<'a> { outer_attrs: &[ast::Attribute], id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) { - let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span)); - prefix.pop(); - let mod_path = Path::new(".").join_many(&self.mod_path_stack); - let dir_path = prefix.join(&mod_path); + let mut prefix = PathBuf::new(&self.sess.span_diagnostic.cm + .span_to_filename(self.span)); + // FIXME(acrichto): right now "a".pop() == "a", but need to confirm with + // aturon whether this is expected or not. + if prefix.parent().is_some() { + prefix.pop(); + } else { + prefix = PathBuf::new(""); + } + let mut dir_path = prefix; + for part in &self.mod_path_stack { + dir_path.push(&**part); + } let mod_string = token::get_ident(id); let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name( outer_attrs, "path") { - Some(d) => (dir_path.join(d), true), + Some(d) => (dir_path.join(&*d), true), None => { let mod_name = mod_string.to_string(); let default_path_str = format!("{}.rs", mod_name); @@ -5319,7 +5329,7 @@ impl<'a> Parser<'a> { } fn eval_src_mod_from_path(&mut self, - path: Path, + path: PathBuf, owns_directory: bool, name: String, id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) { @@ -5329,10 +5339,10 @@ impl<'a> Parser<'a> { let mut err = String::from_str("circular modules: "); let len = included_mod_stack.len(); for p in &included_mod_stack[i.. len] { - err.push_str(&p.display().as_cow()); + err.push_str(&p.to_string_lossy()); err.push_str(" -> "); } - err.push_str(&path.display().as_cow()); + err.push_str(&path.to_string_lossy()); self.span_fatal(id_sp, &err[..]); } None => () diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 4cef7ed469f..640b7d1c91d 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -59,7 +59,7 @@ //! line (which it can't) and so naturally place the content on its own line to //! avoid combining it with other lines and making matters even worse. -use std::old_io; +use std::io; use std::string; use std::iter::repeat; @@ -161,7 +161,7 @@ pub struct PrintStackElem { const SIZE_INFINITY: isize = 0xffff; -pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer { +pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> { // Yes 3, it makes the ring buffers big enough to never // fall behind. let n: usize = 3 * linewidth; @@ -265,8 +265,8 @@ pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer /// In this implementation (following the paper, again) the SCAN process is /// the method called 'pretty_print', and the 'PRINT' process is the method /// called 'print'. -pub struct Printer { - pub out: Box<old_io::Writer+'static>, +pub struct Printer<'a> { + pub out: Box<io::Write+'a>, buf_len: usize, /// Width of lines we're constrained to margin: isize, @@ -303,7 +303,7 @@ pub struct Printer { pending_indentation: isize, } -impl Printer { +impl<'a> Printer<'a> { pub fn last_token(&mut self) -> Token { self.token[self.right].clone() } @@ -311,7 +311,7 @@ impl Printer { pub fn replace_last_token(&mut self, t: Token) { self.token[self.right] = t; } - pub fn pretty_print(&mut self, token: Token) -> old_io::IoResult<()> { + pub fn pretty_print(&mut self, token: Token) -> io::Result<()> { debug!("pp ~[{},{}]", self.left, self.right); match token { Token::Eof => { @@ -385,7 +385,7 @@ impl Printer { } } } - pub fn check_stream(&mut self) -> old_io::IoResult<()> { + pub fn check_stream(&mut self) -> io::Result<()> { debug!("check_stream ~[{}, {}] with left_total={}, right_total={}", self.left, self.right, self.left_total, self.right_total); if self.right_total - self.left_total > self.space { @@ -445,7 +445,7 @@ impl Printer { self.right %= self.buf_len; assert!((self.right != self.left)); } - pub fn advance_left(&mut self) -> old_io::IoResult<()> { + pub fn advance_left(&mut self) -> io::Result<()> { debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right, self.left, self.size[self.left]); @@ -506,7 +506,7 @@ impl Printer { } } } - pub fn print_newline(&mut self, amount: isize) -> old_io::IoResult<()> { + pub fn print_newline(&mut self, amount: isize) -> io::Result<()> { debug!("NEWLINE {}", amount); let ret = write!(self.out, "\n"); self.pending_indentation = 0; @@ -529,14 +529,14 @@ impl Printer { } } } - pub fn print_str(&mut self, s: &str) -> old_io::IoResult<()> { + pub fn print_str(&mut self, s: &str) -> io::Result<()> { while self.pending_indentation > 0 { try!(write!(self.out, " ")); self.pending_indentation -= 1; } write!(self.out, "{}", s) } - pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> { + pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> { debug!("print {} {} (remaining line space={})", tok_str(&token), l, self.space); debug!("{}", buf_str(&self.token, @@ -620,61 +620,61 @@ impl Printer { // Convenience functions to talk to the printer. // // "raw box" -pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> old_io::IoResult<()> { +pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> { p.pretty_print(Token::Begin(BeginToken { offset: indent as isize, breaks: b })) } -pub fn ibox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> { +pub fn ibox(p: &mut Printer, indent: usize) -> io::Result<()> { rbox(p, indent, Breaks::Inconsistent) } -pub fn cbox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> { +pub fn cbox(p: &mut Printer, indent: usize) -> io::Result<()> { rbox(p, indent, Breaks::Consistent) } -pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> old_io::IoResult<()> { +pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> io::Result<()> { p.pretty_print(Token::Break(BreakToken { offset: off, blank_space: n as isize })) } -pub fn end(p: &mut Printer) -> old_io::IoResult<()> { +pub fn end(p: &mut Printer) -> io::Result<()> { p.pretty_print(Token::End) } -pub fn eof(p: &mut Printer) -> old_io::IoResult<()> { +pub fn eof(p: &mut Printer) -> io::Result<()> { p.pretty_print(Token::Eof) } -pub fn word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> { +pub fn word(p: &mut Printer, wrd: &str) -> io::Result<()> { p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as isize)) } -pub fn huge_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> { +pub fn huge_word(p: &mut Printer, wrd: &str) -> io::Result<()> { p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY)) } -pub fn zero_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> { +pub fn zero_word(p: &mut Printer, wrd: &str) -> io::Result<()> { p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0)) } -pub fn spaces(p: &mut Printer, n: usize) -> old_io::IoResult<()> { +pub fn spaces(p: &mut Printer, n: usize) -> io::Result<()> { break_offset(p, n, 0) } -pub fn zerobreak(p: &mut Printer) -> old_io::IoResult<()> { +pub fn zerobreak(p: &mut Printer) -> io::Result<()> { spaces(p, 0) } -pub fn space(p: &mut Printer) -> old_io::IoResult<()> { +pub fn space(p: &mut Printer) -> io::Result<()> { spaces(p, 1) } -pub fn hardbreak(p: &mut Printer) -> old_io::IoResult<()> { +pub fn hardbreak(p: &mut Printer) -> io::Result<()> { spaces(p, SIZE_INFINITY as usize) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index af16e19c9f0..883c2295a36 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -30,7 +30,7 @@ use ptr::P; use std_inject; use std::{ascii, mem}; -use std::old_io::{self, IoResult}; +use std::io::{self, Write, Read}; use std::iter; pub enum AnnNode<'a> { @@ -43,8 +43,8 @@ pub enum AnnNode<'a> { } pub trait PpAnn { - fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) } - fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) } + fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) } + fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) } } #[derive(Copy)] @@ -59,7 +59,7 @@ pub struct CurrentCommentAndLiteral { } pub struct State<'a> { - pub s: pp::Printer, + pub s: pp::Printer<'a>, cm: Option<&'a CodeMap>, comments: Option<Vec<comments::Comment> >, literals: Option<Vec<comments::Literal> >, @@ -69,12 +69,12 @@ pub struct State<'a> { encode_idents_with_hygiene: bool, } -pub fn rust_printer(writer: Box<old_io::Writer+'static>) -> State<'static> { +pub fn rust_printer<'a>(writer: Box<Write+'a>) -> State<'a> { static NO_ANN: NoAnn = NoAnn; rust_printer_annotated(writer, &NO_ANN) } -pub fn rust_printer_annotated<'a>(writer: Box<old_io::Writer+'static>, +pub fn rust_printer_annotated<'a>(writer: Box<Write+'a>, ann: &'a PpAnn) -> State<'a> { State { s: pp::mk_printer(writer, default_columns), @@ -104,10 +104,10 @@ pub fn print_crate<'a>(cm: &'a CodeMap, span_diagnostic: &diagnostic::SpanHandler, krate: &ast::Crate, filename: String, - input: &mut old_io::Reader, - out: Box<old_io::Writer+'static>, + input: &mut Read, + out: Box<Write+'a>, ann: &'a PpAnn, - is_expanded: bool) -> IoResult<()> { + is_expanded: bool) -> io::Result<()> { let mut s = State::new_from_input(cm, span_diagnostic, filename, @@ -143,8 +143,8 @@ impl<'a> State<'a> { pub fn new_from_input(cm: &'a CodeMap, span_diagnostic: &diagnostic::SpanHandler, filename: String, - input: &mut old_io::Reader, - out: Box<old_io::Writer+'static>, + input: &mut Read, + out: Box<Write+'a>, ann: &'a PpAnn, is_expanded: bool) -> State<'a> { let (cmnts, lits) = comments::gather_comments_and_literals( @@ -164,7 +164,7 @@ impl<'a> State<'a> { } pub fn new(cm: &'a CodeMap, - out: Box<old_io::Writer+'static>, + out: Box<Write+'a>, ann: &'a PpAnn, comments: Option<Vec<comments::Comment>>, literals: Option<Vec<comments::Literal>>) -> State<'a> { @@ -185,14 +185,14 @@ impl<'a> State<'a> { } pub fn to_string<F>(f: F) -> String where - F: FnOnce(&mut State) -> IoResult<()>, + F: FnOnce(&mut State) -> io::Result<()>, { use std::raw::TraitObject; let mut s = rust_printer(box Vec::new()); f(&mut s).unwrap(); eof(&mut s.s).unwrap(); let wr = unsafe { - // FIXME(pcwalton): A nasty function to extract the string from an `old_io::Writer` + // FIXME(pcwalton): A nasty function to extract the string from an `Write` // that we "know" to be a `Vec<u8>` that works around the lack of checked // downcasts. let obj: &TraitObject = mem::transmute(&s.s.out); @@ -440,13 +440,13 @@ thing_to_string_impls! { to_string } pub mod with_hygiene { use abi; use ast; - use std::old_io::IoResult; + use std::io; use super::indent_unit; // This function is the trick that all the rest of the routines // hang on. pub fn to_string_hyg<F>(f: F) -> String where - F: FnOnce(&mut super::State) -> IoResult<()>, + F: FnOnce(&mut super::State) -> io::Result<()>, { super::to_string(move |s| { s.encode_idents_with_hygiene = true; @@ -474,44 +474,44 @@ fn needs_parentheses(expr: &ast::Expr) -> bool { } impl<'a> State<'a> { - pub fn ibox(&mut self, u: usize) -> IoResult<()> { + pub fn ibox(&mut self, u: usize) -> io::Result<()> { self.boxes.push(pp::Breaks::Inconsistent); pp::ibox(&mut self.s, u) } - pub fn end(&mut self) -> IoResult<()> { + pub fn end(&mut self) -> io::Result<()> { self.boxes.pop().unwrap(); pp::end(&mut self.s) } - pub fn cbox(&mut self, u: usize) -> IoResult<()> { + pub fn cbox(&mut self, u: usize) -> io::Result<()> { self.boxes.push(pp::Breaks::Consistent); pp::cbox(&mut self.s, u) } // "raw box" - pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> IoResult<()> { + pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> { self.boxes.push(b); pp::rbox(&mut self.s, u, b) } - pub fn nbsp(&mut self) -> IoResult<()> { word(&mut self.s, " ") } + pub fn nbsp(&mut self) -> io::Result<()> { word(&mut self.s, " ") } - pub fn word_nbsp(&mut self, w: &str) -> IoResult<()> { + pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> { try!(word(&mut self.s, w)); self.nbsp() } - pub fn word_space(&mut self, w: &str) -> IoResult<()> { + pub fn word_space(&mut self, w: &str) -> io::Result<()> { try!(word(&mut self.s, w)); space(&mut self.s) } - pub fn popen(&mut self) -> IoResult<()> { word(&mut self.s, "(") } + pub fn popen(&mut self) -> io::Result<()> { word(&mut self.s, "(") } - pub fn pclose(&mut self) -> IoResult<()> { word(&mut self.s, ")") } + pub fn pclose(&mut self) -> io::Result<()> { word(&mut self.s, ")") } - pub fn head(&mut self, w: &str) -> IoResult<()> { + pub fn head(&mut self, w: &str) -> io::Result<()> { // outer-box is consistent try!(self.cbox(indent_unit)); // head-box is inconsistent @@ -523,17 +523,17 @@ impl<'a> State<'a> { Ok(()) } - pub fn bopen(&mut self) -> IoResult<()> { + pub fn bopen(&mut self) -> io::Result<()> { try!(word(&mut self.s, "{")); self.end() // close the head-box } pub fn bclose_(&mut self, span: codemap::Span, - indented: usize) -> IoResult<()> { + indented: usize) -> io::Result<()> { self.bclose_maybe_open(span, indented, true) } pub fn bclose_maybe_open (&mut self, span: codemap::Span, - indented: usize, close_box: bool) -> IoResult<()> { + indented: usize, close_box: bool) -> io::Result<()> { try!(self.maybe_print_comment(span.hi)); try!(self.break_offset_if_not_bol(1, -(indented as isize))); try!(word(&mut self.s, "}")); @@ -542,7 +542,7 @@ impl<'a> State<'a> { } Ok(()) } - pub fn bclose(&mut self, span: codemap::Span) -> IoResult<()> { + pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> { self.bclose_(span, indent_unit) } @@ -572,18 +572,18 @@ impl<'a> State<'a> { } } - pub fn hardbreak_if_not_bol(&mut self) -> IoResult<()> { + pub fn hardbreak_if_not_bol(&mut self) -> io::Result<()> { if !self.is_bol() { try!(hardbreak(&mut self.s)) } Ok(()) } - pub fn space_if_not_bol(&mut self) -> IoResult<()> { + pub fn space_if_not_bol(&mut self) -> io::Result<()> { if !self.is_bol() { try!(space(&mut self.s)); } Ok(()) } pub fn break_offset_if_not_bol(&mut self, n: usize, - off: isize) -> IoResult<()> { + off: isize) -> io::Result<()> { if !self.is_bol() { break_offset(&mut self.s, n, off) } else { @@ -599,7 +599,7 @@ impl<'a> State<'a> { // Synthesizes a comment that was not textually present in the original source // file. - pub fn synth_comment(&mut self, text: String) -> IoResult<()> { + pub fn synth_comment(&mut self, text: String) -> io::Result<()> { try!(word(&mut self.s, "/*")); try!(space(&mut self.s)); try!(word(&mut self.s, &text[..])); @@ -607,8 +607,8 @@ impl<'a> State<'a> { word(&mut self.s, "*/") } - pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where - F: FnMut(&mut State, &T) -> IoResult<()>, + pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> where + F: FnMut(&mut State, &T) -> io::Result<()>, { try!(self.rbox(0, b)); let mut first = true; @@ -624,8 +624,8 @@ impl<'a> State<'a> { b: Breaks, elts: &[T], mut op: F, - mut get_span: G) -> IoResult<()> where - F: FnMut(&mut State, &T) -> IoResult<()>, + mut get_span: G) -> io::Result<()> where + F: FnMut(&mut State, &T) -> io::Result<()>, G: FnMut(&T) -> codemap::Span, { try!(self.rbox(0, b)); @@ -646,12 +646,12 @@ impl<'a> State<'a> { } pub fn commasep_exprs(&mut self, b: Breaks, - exprs: &[P<ast::Expr>]) -> IoResult<()> { + exprs: &[P<ast::Expr>]) -> io::Result<()> { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span) } pub fn print_mod(&mut self, _mod: &ast::Mod, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { try!(self.print_inner_attributes(attrs)); for item in &_mod.items { try!(self.print_item(&**item)); @@ -660,7 +660,7 @@ impl<'a> State<'a> { } pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { try!(self.print_inner_attributes(attrs)); for item in &nmod.items { try!(self.print_foreign_item(&**item)); @@ -669,7 +669,7 @@ impl<'a> State<'a> { } pub fn print_opt_lifetime(&mut self, - lifetime: &Option<ast::Lifetime>) -> IoResult<()> { + lifetime: &Option<ast::Lifetime>) -> io::Result<()> { if let Some(l) = *lifetime { try!(self.print_lifetime(&l)); try!(self.nbsp()); @@ -677,7 +677,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> { + pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> { try!(self.maybe_print_comment(ty.span.lo)); try!(self.ibox(0)); match ty.node { @@ -762,7 +762,7 @@ impl<'a> State<'a> { } pub fn print_foreign_item(&mut self, - item: &ast::ForeignItem) -> IoResult<()> { + item: &ast::ForeignItem) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); try!(self.print_outer_attributes(&item.attrs)); @@ -791,7 +791,7 @@ impl<'a> State<'a> { } fn print_associated_type(&mut self, typedef: &ast::AssociatedType) - -> IoResult<()> + -> io::Result<()> { try!(self.print_outer_attributes(&typedef.attrs)); try!(self.word_space("type")); @@ -799,7 +799,7 @@ impl<'a> State<'a> { word(&mut self.s, ";") } - fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> { + fn print_typedef(&mut self, typedef: &ast::Typedef) -> io::Result<()> { try!(self.word_space("type")); try!(self.print_ident(typedef.ident)); try!(space(&mut self.s)); @@ -809,7 +809,7 @@ impl<'a> State<'a> { } /// Pretty-print an item - pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> { + pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(item.span.lo)); try!(self.print_outer_attributes(&item.attrs)); @@ -1032,11 +1032,11 @@ impl<'a> State<'a> { self.ann.post(self, NodeItem(item)) } - fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> { + fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> { self.print_path(&t.path, false, 0) } - fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> IoResult<()> { + fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> { if !lifetimes.is_empty() { try!(word(&mut self.s, "for<")); let mut comma = false; @@ -1052,7 +1052,7 @@ impl<'a> State<'a> { Ok(()) } - fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> { + fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> { try!(self.print_formal_lifetime_list(&t.bound_lifetimes)); self.print_trait_ref(&t.trait_ref) } @@ -1060,7 +1060,7 @@ impl<'a> State<'a> { pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef, generics: &ast::Generics, ident: ast::Ident, span: codemap::Span, - visibility: ast::Visibility) -> IoResult<()> { + visibility: ast::Visibility) -> io::Result<()> { try!(self.head(&visibility_qualified(visibility, "enum"))); try!(self.print_ident(ident)); try!(self.print_generics(generics)); @@ -1071,7 +1071,7 @@ impl<'a> State<'a> { pub fn print_variants(&mut self, variants: &[P<ast::Variant>], - span: codemap::Span) -> IoResult<()> { + span: codemap::Span) -> io::Result<()> { try!(self.bopen()); for v in variants { try!(self.space_if_not_bol()); @@ -1086,7 +1086,7 @@ impl<'a> State<'a> { self.bclose(span) } - pub fn print_visibility(&mut self, vis: ast::Visibility) -> IoResult<()> { + pub fn print_visibility(&mut self, vis: ast::Visibility) -> io::Result<()> { match vis { ast::Public => self.word_nbsp("pub"), ast::Inherited => Ok(()) @@ -1097,7 +1097,7 @@ impl<'a> State<'a> { struct_def: &ast::StructDef, generics: &ast::Generics, ident: ast::Ident, - span: codemap::Span) -> IoResult<()> { + span: codemap::Span) -> io::Result<()> { try!(self.print_ident(ident)); try!(self.print_generics(generics)); if ast_util::struct_def_is_tuple_like(struct_def) { @@ -1155,7 +1155,7 @@ impl<'a> State<'a> { /// appropriate macro, transcribe back into the grammar we just parsed from, /// and then pretty-print the resulting AST nodes (so, e.g., we print /// expression arguments as expressions). It can be done! I think. - pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> { + pub fn print_tt(&mut self, tt: &ast::TokenTree) -> io::Result<()> { match *tt { ast::TtToken(_, ref tk) => { try!(word(&mut self.s, &token_to_string(tk))); @@ -1193,7 +1193,7 @@ impl<'a> State<'a> { } } - pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> { + pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> { try!(self.ibox(0)); let mut suppress_space = false; for (i, tt) in tts.iter().enumerate() { @@ -1213,7 +1213,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> { + pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> { try!(self.print_visibility(v.node.vis)); match v.node.kind { ast::TupleVariantKind(ref args) => { @@ -1242,7 +1242,7 @@ impl<'a> State<'a> { } } - pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> { + pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(m.span.lo)); try!(self.print_outer_attributes(&m.attrs)); @@ -1256,7 +1256,7 @@ impl<'a> State<'a> { } pub fn print_trait_method(&mut self, - m: &ast::TraitItem) -> IoResult<()> { + m: &ast::TraitItem) -> io::Result<()> { match *m { RequiredMethod(ref ty_m) => self.print_ty_method(ty_m), ProvidedMethod(ref m) => self.print_method(&**m), @@ -1264,14 +1264,14 @@ impl<'a> State<'a> { } } - pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> { + pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> { match *ii { MethodImplItem(ref m) => self.print_method(&**m), TypeImplItem(ref td) => self.print_typedef(&**td), } } - pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> { + pub fn print_method(&mut self, meth: &ast::Method) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(meth.span.lo)); try!(self.print_outer_attributes(&meth.attrs)); @@ -1310,7 +1310,7 @@ impl<'a> State<'a> { } pub fn print_outer_attributes(&mut self, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { let mut count = 0; for attr in attrs { match attr.node.style { @@ -1328,7 +1328,7 @@ impl<'a> State<'a> { } pub fn print_inner_attributes(&mut self, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { let mut count = 0; for attr in attrs { match attr.node.style { @@ -1345,7 +1345,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_attribute(&mut self, attr: &ast::Attribute) -> IoResult<()> { + pub fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(attr.span.lo)); if attr.node.is_sugared_doc { @@ -1361,7 +1361,7 @@ impl<'a> State<'a> { } - pub fn print_stmt(&mut self, st: &ast::Stmt) -> IoResult<()> { + pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> { try!(self.maybe_print_comment(st.span.lo)); match st.node { ast::StmtDecl(ref decl, _) => { @@ -1395,22 +1395,22 @@ impl<'a> State<'a> { self.maybe_print_trailing_comment(st.span, None) } - pub fn print_block(&mut self, blk: &ast::Block) -> IoResult<()> { + pub fn print_block(&mut self, blk: &ast::Block) -> io::Result<()> { self.print_block_with_attrs(blk, &[]) } - pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> IoResult<()> { + pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> io::Result<()> { self.print_block_unclosed_indent(blk, indent_unit) } pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block, - indented: usize) -> IoResult<()> { + indented: usize) -> io::Result<()> { self.print_block_maybe_unclosed(blk, indented, &[], false) } pub fn print_block_with_attrs(&mut self, blk: &ast::Block, - attrs: &[ast::Attribute]) -> IoResult<()> { + attrs: &[ast::Attribute]) -> io::Result<()> { self.print_block_maybe_unclosed(blk, indent_unit, attrs, true) } @@ -1418,7 +1418,7 @@ impl<'a> State<'a> { blk: &ast::Block, indented: usize, attrs: &[ast::Attribute], - close_box: bool) -> IoResult<()> { + close_box: bool) -> io::Result<()> { match blk.rules { ast::UnsafeBlock(..) => try!(self.word_space("unsafe")), ast::DefaultBlock => () @@ -1444,7 +1444,7 @@ impl<'a> State<'a> { self.ann.post(self, NodeBlock(blk)) } - fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> { + fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> { match els { Some(_else) => { match _else.node { @@ -1489,7 +1489,7 @@ impl<'a> State<'a> { } pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block, - elseopt: Option<&ast::Expr>) -> IoResult<()> { + elseopt: Option<&ast::Expr>) -> io::Result<()> { try!(self.head("if")); try!(self.print_expr(test)); try!(space(&mut self.s)); @@ -1498,7 +1498,7 @@ impl<'a> State<'a> { } pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block, - elseopt: Option<&ast::Expr>) -> IoResult<()> { + elseopt: Option<&ast::Expr>) -> io::Result<()> { try!(self.head("if let")); try!(self.print_pat(pat)); try!(space(&mut self.s)); @@ -1510,7 +1510,7 @@ impl<'a> State<'a> { } pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken) - -> IoResult<()> { + -> io::Result<()> { match m.node { // I think it's reasonable to hide the ctxt here: ast::MacInvocTT(ref pth, ref tts, _) => { @@ -1532,13 +1532,13 @@ impl<'a> State<'a> { } - fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> IoResult<()> { + fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> io::Result<()> { try!(self.popen()); try!(self.commasep_exprs(Inconsistent, args)); self.pclose() } - pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> IoResult<()> { + pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> io::Result<()> { let needs_par = needs_parentheses(expr); if needs_par { try!(self.popen()); @@ -1552,7 +1552,7 @@ impl<'a> State<'a> { fn print_expr_box(&mut self, place: &Option<P<ast::Expr>>, - expr: &ast::Expr) -> IoResult<()> { + expr: &ast::Expr) -> io::Result<()> { try!(word(&mut self.s, "box")); try!(word(&mut self.s, "(")); try!(place.as_ref().map_or(Ok(()), |e|self.print_expr(&**e))); @@ -1560,7 +1560,7 @@ impl<'a> State<'a> { self.print_expr(expr) } - fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> { + fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> { try!(self.ibox(indent_unit)); try!(word(&mut self.s, "[")); try!(self.commasep_exprs(Inconsistent, &exprs[..])); @@ -1570,7 +1570,7 @@ impl<'a> State<'a> { fn print_expr_repeat(&mut self, element: &ast::Expr, - count: &ast::Expr) -> IoResult<()> { + count: &ast::Expr) -> io::Result<()> { try!(self.ibox(indent_unit)); try!(word(&mut self.s, "[")); try!(self.print_expr(element)); @@ -1583,7 +1583,7 @@ impl<'a> State<'a> { fn print_expr_struct(&mut self, path: &ast::Path, fields: &[ast::Field], - wth: &Option<P<ast::Expr>>) -> IoResult<()> { + wth: &Option<P<ast::Expr>>) -> io::Result<()> { try!(self.print_path(path, true, 0)); if !(fields.is_empty() && wth.is_none()) { try!(word(&mut self.s, "{")); @@ -1616,7 +1616,7 @@ impl<'a> State<'a> { Ok(()) } - fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> { + fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> { try!(self.popen()); try!(self.commasep_exprs(Inconsistent, &exprs[..])); if exprs.len() == 1 { @@ -1627,7 +1627,7 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &ast::Expr, - args: &[P<ast::Expr>]) -> IoResult<()> { + args: &[P<ast::Expr>]) -> io::Result<()> { try!(self.print_expr_maybe_paren(func)); self.print_call_post(args) } @@ -1635,7 +1635,7 @@ impl<'a> State<'a> { fn print_expr_method_call(&mut self, ident: ast::SpannedIdent, tys: &[P<ast::Ty>], - args: &[P<ast::Expr>]) -> IoResult<()> { + args: &[P<ast::Expr>]) -> io::Result<()> { let base_args = &args[1..]; try!(self.print_expr(&*args[0])); try!(word(&mut self.s, ".")); @@ -1652,7 +1652,7 @@ impl<'a> State<'a> { fn print_expr_binary(&mut self, op: ast::BinOp, lhs: &ast::Expr, - rhs: &ast::Expr) -> IoResult<()> { + rhs: &ast::Expr) -> io::Result<()> { try!(self.print_expr(lhs)); try!(space(&mut self.s)); try!(self.word_space(ast_util::binop_to_string(op.node))); @@ -1661,20 +1661,20 @@ impl<'a> State<'a> { fn print_expr_unary(&mut self, op: ast::UnOp, - expr: &ast::Expr) -> IoResult<()> { + expr: &ast::Expr) -> io::Result<()> { try!(word(&mut self.s, ast_util::unop_to_string(op))); self.print_expr_maybe_paren(expr) } fn print_expr_addr_of(&mut self, mutability: ast::Mutability, - expr: &ast::Expr) -> IoResult<()> { + expr: &ast::Expr) -> io::Result<()> { try!(word(&mut self.s, "&")); try!(self.print_mutability(mutability)); self.print_expr_maybe_paren(expr) } - pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> { + pub fn print_expr(&mut self, expr: &ast::Expr) -> io::Result<()> { try!(self.maybe_print_comment(expr.span.lo)); try!(self.ibox(indent_unit)); try!(self.ann.pre(self, NodeExpr(expr))); @@ -1958,7 +1958,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> { + pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> { try!(self.print_pat(&*loc.pat)); if let Some(ref ty) = loc.ty { try!(self.word_space(":")); @@ -1967,7 +1967,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> { + pub fn print_decl(&mut self, decl: &ast::Decl) -> io::Result<()> { try!(self.maybe_print_comment(decl.span.lo)); match decl.node { ast::DeclLocal(ref loc) => { @@ -1989,7 +1989,7 @@ impl<'a> State<'a> { } } - pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> { + pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> { if self.encode_idents_with_hygiene { let encoded = ident.encode_with_hygiene(); try!(word(&mut self.s, &encoded[..])) @@ -1999,17 +1999,17 @@ impl<'a> State<'a> { self.ann.post(self, NodeIdent(&ident)) } - pub fn print_usize(&mut self, i: usize) -> IoResult<()> { + pub fn print_usize(&mut self, i: usize) -> io::Result<()> { word(&mut self.s, &i.to_string()) } - pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> { + pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { try!(word(&mut self.s, &token::get_name(name))); self.ann.post(self, NodeName(&name)) } pub fn print_for_decl(&mut self, loc: &ast::Local, - coll: &ast::Expr) -> IoResult<()> { + coll: &ast::Expr) -> io::Result<()> { try!(self.print_local_decl(loc)); try!(space(&mut self.s)); try!(self.word_space("in")); @@ -2020,7 +2020,7 @@ impl<'a> State<'a> { path: &ast::Path, colons_before_params: bool, depth: usize) - -> IoResult<()> + -> io::Result<()> { try!(self.maybe_print_comment(path.span.lo)); @@ -2044,7 +2044,7 @@ impl<'a> State<'a> { path: &ast::Path, qself: &ast::QSelf, colons_before_params: bool) - -> IoResult<()> + -> io::Result<()> { try!(word(&mut self.s, "<")); try!(self.print_type(&qself.ty)); @@ -2064,7 +2064,7 @@ impl<'a> State<'a> { fn print_path_parameters(&mut self, parameters: &ast::PathParameters, colons_before_params: bool) - -> IoResult<()> + -> io::Result<()> { if parameters.is_empty() { return Ok(()); @@ -2134,7 +2134,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> { + pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> { try!(self.maybe_print_comment(pat.span.lo)); try!(self.ann.pre(self, NodePat(pat))); /* Pat isn't normalized, but the beauty of it @@ -2253,7 +2253,7 @@ impl<'a> State<'a> { self.ann.post(self, NodePat(pat)) } - fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> { + fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> { // I have no idea why this check is necessary, but here it // is :( if arm.attrs.is_empty() { @@ -2302,7 +2302,7 @@ impl<'a> State<'a> { // Returns whether it printed anything fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf_, - mutbl: ast::Mutability) -> IoResult<bool> { + mutbl: ast::Mutability) -> io::Result<bool> { try!(self.print_mutability(mutbl)); match *explicit_self { ast::SelfStatic => { return Ok(false); } @@ -2331,7 +2331,7 @@ impl<'a> State<'a> { name: ast::Ident, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>, - vis: ast::Visibility) -> IoResult<()> { + vis: ast::Visibility) -> io::Result<()> { try!(self.head("")); try!(self.print_fn_header_info(unsafety, abi, vis)); try!(self.nbsp()); @@ -2343,7 +2343,7 @@ impl<'a> State<'a> { pub fn print_fn_args(&mut self, decl: &ast::FnDecl, opt_explicit_self: Option<&ast::ExplicitSelf_>) - -> IoResult<()> { + -> io::Result<()> { // It is unfortunate to duplicate the commasep logic, but we want the // self type and the args all in the same box. try!(self.rbox(0, Inconsistent)); @@ -2376,7 +2376,7 @@ impl<'a> State<'a> { pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl, opt_explicit_self: Option<&ast::ExplicitSelf_>) - -> IoResult<()> { + -> io::Result<()> { try!(self.popen()); try!(self.print_fn_args(decl, opt_explicit_self)); if decl.variadic { @@ -2390,7 +2390,7 @@ impl<'a> State<'a> { pub fn print_fn_block_args( &mut self, decl: &ast::FnDecl) - -> IoResult<()> { + -> io::Result<()> { try!(word(&mut self.s, "|")); try!(self.print_fn_args(decl, None)); try!(word(&mut self.s, "|")); @@ -2415,7 +2415,7 @@ impl<'a> State<'a> { } pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause) - -> IoResult<()> { + -> io::Result<()> { match capture_clause { ast::CaptureByValue => self.word_space("move"), ast::CaptureByRef => Ok(()), @@ -2425,7 +2425,7 @@ impl<'a> State<'a> { pub fn print_bounds(&mut self, prefix: &str, bounds: &[ast::TyParamBound]) - -> IoResult<()> { + -> io::Result<()> { if !bounds.is_empty() { try!(word(&mut self.s, prefix)); let mut first = true; @@ -2458,14 +2458,14 @@ impl<'a> State<'a> { pub fn print_lifetime(&mut self, lifetime: &ast::Lifetime) - -> IoResult<()> + -> io::Result<()> { self.print_name(lifetime.name) } pub fn print_lifetime_def(&mut self, lifetime: &ast::LifetimeDef) - -> IoResult<()> + -> io::Result<()> { try!(self.print_lifetime(&lifetime.lifetime)); let mut sep = ":"; @@ -2479,7 +2479,7 @@ impl<'a> State<'a> { pub fn print_generics(&mut self, generics: &ast::Generics) - -> IoResult<()> + -> io::Result<()> { let total = generics.lifetimes.len() + generics.ty_params.len(); if total == 0 { @@ -2508,7 +2508,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> { + pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> { try!(self.print_ident(param.ident)); try!(self.print_bounds(":", ¶m.bounds)); match param.default { @@ -2522,7 +2522,7 @@ impl<'a> State<'a> { } pub fn print_where_clause(&mut self, generics: &ast::Generics) - -> IoResult<()> { + -> io::Result<()> { if generics.where_clause.predicates.len() == 0 { return Ok(()) } @@ -2573,7 +2573,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> { + pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> { try!(self.ibox(indent_unit)); match item.node { ast::MetaWord(ref name) => { @@ -2596,7 +2596,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> { + pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> { match vp.node { ast::ViewPathSimple(ident, ref path) => { try!(self.print_path(path, false, 0)); @@ -2640,19 +2640,19 @@ impl<'a> State<'a> { } pub fn print_mutability(&mut self, - mutbl: ast::Mutability) -> IoResult<()> { + mutbl: ast::Mutability) -> io::Result<()> { match mutbl { ast::MutMutable => self.word_nbsp("mut"), ast::MutImmutable => Ok(()), } } - pub fn print_mt(&mut self, mt: &ast::MutTy) -> IoResult<()> { + pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> { try!(self.print_mutability(mt.mutbl)); self.print_type(&*mt.ty) } - pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> { + pub fn print_arg(&mut self, input: &ast::Arg) -> io::Result<()> { try!(self.ibox(indent_unit)); match input.ty.node { ast::TyInfer => try!(self.print_pat(&*input.pat)), @@ -2675,7 +2675,7 @@ impl<'a> State<'a> { self.end() } - pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> { + pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> io::Result<()> { if let ast::DefaultReturn(..) = decl.output { return Ok(()); } @@ -2705,7 +2705,7 @@ impl<'a> State<'a> { id: Option<ast::Ident>, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>) - -> IoResult<()> { + -> io::Result<()> { try!(self.ibox(indent_unit)); try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited)); @@ -2726,7 +2726,7 @@ impl<'a> State<'a> { pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span, next_pos: Option<BytePos>) - -> IoResult<()> { + -> io::Result<()> { let cm = match self.cm { Some(cm) => cm, _ => return Ok(()) @@ -2749,7 +2749,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_remaining_comments(&mut self) -> IoResult<()> { + pub fn print_remaining_comments(&mut self) -> io::Result<()> { // If there aren't any remaining comments, then we need to manually // make sure there is a line break at the end. if self.next_comment().is_none() { @@ -2767,7 +2767,7 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> { + pub fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { try!(self.maybe_print_comment(lit.span.lo)); match self.next_lit(lit.span.lo) { Some(ref ltrl) => { @@ -2848,7 +2848,7 @@ impl<'a> State<'a> { } } - pub fn maybe_print_comment(&mut self, pos: BytePos) -> IoResult<()> { + pub fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> { loop { match self.next_comment() { Some(ref cmnt) => { @@ -2864,7 +2864,7 @@ impl<'a> State<'a> { } pub fn print_comment(&mut self, - cmnt: &comments::Comment) -> IoResult<()> { + cmnt: &comments::Comment) -> io::Result<()> { match cmnt.style { comments::Mixed => { assert_eq!(cmnt.lines.len(), 1); @@ -2915,7 +2915,7 @@ impl<'a> State<'a> { } pub fn print_string(&mut self, st: &str, - style: ast::StrStyle) -> IoResult<()> { + style: ast::StrStyle) -> io::Result<()> { let st = match style { ast::CookedStr => { (format!("\"{}\"", st.escape_default())) @@ -2943,7 +2943,7 @@ impl<'a> State<'a> { } pub fn print_opt_unsafety(&mut self, - opt_unsafety: Option<ast::Unsafety>) -> IoResult<()> { + opt_unsafety: Option<ast::Unsafety>) -> io::Result<()> { match opt_unsafety { Some(unsafety) => self.print_unsafety(unsafety), None => Ok(()) @@ -2952,7 +2952,7 @@ impl<'a> State<'a> { pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option<abi::Abi>) - -> IoResult<()> { + -> io::Result<()> { match opt_abi { Some(abi::Rust) => Ok(()), Some(abi) => { @@ -2964,7 +2964,7 @@ impl<'a> State<'a> { } pub fn print_extern_opt_abi(&mut self, - opt_abi: Option<abi::Abi>) -> IoResult<()> { + opt_abi: Option<abi::Abi>) -> io::Result<()> { match opt_abi { Some(abi) => { try!(self.word_nbsp("extern")); @@ -2977,7 +2977,7 @@ impl<'a> State<'a> { pub fn print_fn_header_info(&mut self, opt_unsafety: Option<ast::Unsafety>, abi: abi::Abi, - vis: ast::Visibility) -> IoResult<()> { + vis: ast::Visibility) -> io::Result<()> { try!(word(&mut self.s, &visibility_qualified(vis, ""))); try!(self.print_opt_unsafety(opt_unsafety)); @@ -2989,7 +2989,7 @@ impl<'a> State<'a> { word(&mut self.s, "fn") } - pub fn print_unsafety(&mut self, s: ast::Unsafety) -> IoResult<()> { + pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> { match s { ast::Unsafety::Normal => Ok(()), ast::Unsafety::Unsafe => self.word_nbsp("unsafe"), diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 756d67b5db1..ba9860ee31f 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -52,14 +52,15 @@ #![feature(box_syntax)] #![feature(collections)] +#![feature(fs)] #![feature(int_uint)] +#![feature(io)] #![feature(old_io)] -#![feature(old_path)] +#![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(unicode)] #![feature(std_misc)] -#![feature(os)] +#![feature(unicode)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index c147e6aa056..cc9a2880b5d 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -13,7 +13,8 @@ //! ncurses-compatible compiled terminfo format parsing (term(5)) use std::collections::HashMap; -use std::old_io; +use std::io::prelude::*; +use std::io; use super::super::TermInfo; // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable. @@ -158,7 +159,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb "box1"]; /// Parse a compiled terminfo entry, using long capability names if `longnames` is true -pub fn parse(file: &mut old_io::Reader, longnames: bool) +pub fn parse(file: &mut Read, longnames: bool) -> Result<Box<TermInfo>, String> { macro_rules! try { ($e:expr) => ( match $e { @@ -182,17 +183,17 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } // Check magic number - let magic = try!(file.read_le_u16()); + let magic = try!(read_le_u16(file)); if magic != 0x011A { return Err(format!("invalid magic number: expected {:x}, found {:x}", 0x011A as usize, magic as usize)); } - let names_bytes = try!(file.read_le_i16()) as int; - let bools_bytes = try!(file.read_le_i16()) as int; - let numbers_count = try!(file.read_le_i16()) as int; - let string_offsets_count = try!(file.read_le_i16()) as int; - let string_table_bytes = try!(file.read_le_i16()) as int; + let names_bytes = try!(read_le_u16(file)) as int; + let bools_bytes = try!(read_le_u16(file)) as int; + let numbers_count = try!(read_le_u16(file)) as int; + let string_offsets_count = try!(read_le_u16(file)) as int; + let string_table_bytes = try!(read_le_u16(file)) as int; assert!(names_bytes > 0); @@ -212,7 +213,7 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } // don't read NUL - let bytes = try!(file.read_exact(names_bytes as uint - 1)); + let bytes = try!(read_exact(file, names_bytes as uint - 1)); let names_str = match String::from_utf8(bytes) { Ok(s) => s, Err(_) => return Err("input not utf-8".to_string()), @@ -222,12 +223,12 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) .map(|s| s.to_string()) .collect(); - try!(file.read_byte()); // consume NUL + try!(read_byte(file)); // consume NUL let mut bools_map = HashMap::new(); if bools_bytes != 0 { for i in 0..bools_bytes { - let b = try!(file.read_byte()); + let b = try!(read_byte(file)); if b == 1 { bools_map.insert(bnames[i as uint].to_string(), true); } @@ -235,13 +236,13 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } if (bools_bytes + names_bytes) % 2 == 1 { - try!(file.read_byte()); // compensate for padding + try!(read_byte(file)); // compensate for padding } let mut numbers_map = HashMap::new(); if numbers_count != 0 { for i in 0..numbers_count { - let n = try!(file.read_le_u16()); + let n = try!(read_le_u16(file)); if n != 0xFFFF { numbers_map.insert(nnames[i as uint].to_string(), n); } @@ -253,10 +254,10 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) if string_offsets_count != 0 { let mut string_offsets = Vec::with_capacity(10); for _ in 0..string_offsets_count { - string_offsets.push(try!(file.read_le_u16())); + string_offsets.push(try!(read_le_u16(file))); } - let string_table = try!(file.read_exact(string_table_bytes as uint)); + let string_table = try!(read_exact(file, string_table_bytes as usize)); if string_table.len() != string_table_bytes as uint { return Err("error: hit EOF before end of string \ @@ -309,6 +310,25 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) }) } +fn read_le_u16<R: Read + ?Sized>(r: &mut R) -> io::Result<u16> { + let mut b = [0; 2]; + assert_eq!(try!(r.read(&mut b)), 2); + Ok((b[0] as u16) | ((b[1] as u16) << 8)) +} + +fn read_byte<R: Read + ?Sized>(r: &mut R) -> io::Result<u8> { + let mut b = [0; 1]; + assert_eq!(try!(r.read(&mut b)), 1); + Ok(b[0]) +} + +fn read_exact<R: Read + ?Sized>(r: &mut R, sz: usize) -> io::Result<Vec<u8>> { + let mut v = Vec::with_capacity(sz); + try!(r.take(sz as u64).read_to_end(&mut v)); + assert_eq!(v.len(), sz); + Ok(v) +} + /// Create a dummy TermInfo struct for msys terminals pub fn msys_terminfo() -> Box<TermInfo> { let mut strings = HashMap::new(); diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index 15f7f3884ec..f47921cbf5e 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -12,26 +12,27 @@ //! //! Does not support hashed database, only filesystem! -use std::old_io::File; -use std::old_io::fs::PathExtensions; use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::path::PathBuf; /// Return path to database entry for `term` #[allow(deprecated)] -pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { +pub fn get_dbpath_for_term(term: &str) -> Option<Box<PathBuf>> { if term.len() == 0 { return None; } - let homedir = ::std::os::homedir(); + let homedir = env::home_dir(); let mut dirs_to_search = Vec::new(); let first_char = term.char_at(0); // Find search directory - match env::var("TERMINFO") { - Ok(dir) => dirs_to_search.push(Path::new(dir)), - Err(..) => { + match env::var_os("TERMINFO") { + Some(dir) => dirs_to_search.push(PathBuf::new(&dir)), + None => { if homedir.is_some() { // ncurses compatibility; dirs_to_search.push(homedir.unwrap().join(".terminfo")) @@ -39,9 +40,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { match env::var("TERMINFO_DIRS") { Ok(dirs) => for i in dirs.split(':') { if i == "" { - dirs_to_search.push(Path::new("/usr/share/terminfo")); + dirs_to_search.push(PathBuf::new("/usr/share/terminfo")); } else { - dirs_to_search.push(Path::new(i)); + dirs_to_search.push(PathBuf::new(i)); } }, // Found nothing in TERMINFO_DIRS, use the default paths: @@ -49,9 +50,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { // ~/.terminfo, ncurses will search /etc/terminfo, then // /lib/terminfo, and eventually /usr/share/terminfo. Err(..) => { - dirs_to_search.push(Path::new("/etc/terminfo")); - dirs_to_search.push(Path::new("/lib/terminfo")); - dirs_to_search.push(Path::new("/usr/share/terminfo")); + dirs_to_search.push(PathBuf::new("/etc/terminfo")); + dirs_to_search.push(PathBuf::new("/lib/terminfo")); + dirs_to_search.push(PathBuf::new("/usr/share/terminfo")); } } } @@ -61,13 +62,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> { for p in &dirs_to_search { if p.exists() { let f = first_char.to_string(); - let newp = p.join_many(&[&f[..], term]); + let newp = p.join(&f).join(term); if newp.exists() { return Some(box newp); } // on some installations the dir is named after the hex of the char (e.g. OS X) let f = format!("{:x}", first_char as uint); - let newp = p.join_many(&[&f[..], term]); + let newp = p.join(&f).join(term); if newp.exists() { return Some(box newp); } @@ -100,7 +101,7 @@ fn test_get_dbpath_for_term() { // FIXME (#9639): This needs to handle non-utf8 paths fn x(t: &str) -> String { let p = get_dbpath_for_term(t).expect("no terminfo entry found"); - p.as_str().unwrap().to_string() + p.to_str().unwrap().to_string() }; assert!(x("screen") == "/usr/share/terminfo/s/screen"); assert!(get_dbpath_for_term("") == None); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 3fbb07d03a8..e309e7a6c22 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -38,10 +38,12 @@ #![feature(core)] #![feature(int_uint)] #![feature(old_io)] -#![feature(old_path)] +#![feature(path)] +#![feature(fs)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(std_misc)] +#![feature(io)] extern crate getopts; extern crate serialize; @@ -65,13 +67,16 @@ use term::color::{Color, RED, YELLOW, GREEN, CYAN}; use std::any::Any; use std::cmp; use std::collections::BTreeMap; +use std::env; use std::fmt; -use std::old_io::stdio::StdWriter; -use std::old_io::{File, ChanReader, ChanWriter}; -use std::old_io; +use std::fs::File; +use std::io::{self, Write}; use std::iter::repeat; use std::num::{Float, Int}; -use std::env; +use std::old_io::stdio::StdWriter; +use std::old_io::{ChanReader, ChanWriter}; +use std::old_io; +use std::path::{PathBuf}; use std::sync::mpsc::{channel, Sender}; use std::thread; use std::thunk::{Thunk, Invoke}; @@ -287,7 +292,7 @@ pub struct TestOpts { pub run_ignored: bool, pub run_tests: bool, pub run_benchmarks: bool, - pub logfile: Option<Path>, + pub logfile: Option<PathBuf>, pub nocapture: bool, pub color: ColorConfig, } @@ -376,7 +381,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> { let run_ignored = matches.opt_present("ignored"); let logfile = matches.opt_str("logfile"); - let logfile = logfile.map(|s| Path::new(s)); + let logfile = logfile.map(|s| PathBuf::new(&s)); let run_benchmarks = matches.opt_present("bench"); let run_tests = ! run_benchmarks || @@ -446,11 +451,19 @@ struct ConsoleTestState<T> { max_name_len: uint, // number of columns to fill when aligning names } +fn new2old(new: io::Error) -> old_io::IoError { + old_io::IoError { + kind: old_io::OtherIoError, + desc: "other error", + detail: Some(new.to_string()), + } +} + impl<T: Writer> ConsoleTestState<T> { pub fn new(opts: &TestOpts, _: Option<T>) -> old_io::IoResult<ConsoleTestState<StdWriter>> { let log_out = match opts.logfile { - Some(ref path) => Some(try!(File::create(path))), + Some(ref path) => Some(try!(File::create(path).map_err(new2old))), None => None }; let out = match term::stdout() { @@ -560,7 +573,7 @@ impl<T: Writer> ConsoleTestState<T> { } pub fn write_log(&mut self, test: &TestDesc, - result: &TestResult) -> old_io::IoResult<()> { + result: &TestResult) -> io::Result<()> { match self.log_out { None => Ok(()), Some(ref mut o) => { @@ -646,7 +659,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> old_io: TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()), TeWait(ref test, padding) => st.write_test_start(test, padding), TeResult(test, result, stdout) => { - try!(st.write_log(&test, &result)); + try!(st.write_log(&test, &result).map_err(new2old)); try!(st.write_result(&result)); match result { TrOk => st.passed += 1, diff --git a/src/rustbook/book.rs b/src/rustbook/book.rs index 8900b60d191..ac7f2f824cb 100644 --- a/src/rustbook/book.rs +++ b/src/rustbook/book.rs @@ -10,14 +10,16 @@ //! Basic data structures for representing a book. -use std::old_io::BufferedReader; +use std::io::prelude::*; +use std::io::BufReader; use std::iter; use std::iter::AdditiveIterator; +use std::path::{Path, PathBuf}; pub struct BookItem { pub title: String, - pub path: Path, - pub path_to_root: Path, + pub path: PathBuf, + pub path_to_root: PathBuf, pub children: Vec<BookItem>, } @@ -76,7 +78,7 @@ impl Book { } /// Construct a book by parsing a summary (markdown table of contents). -pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> { +pub fn parse_summary(input: &mut Read, src: &Path) -> Result<Book, Vec<String>> { fn collapse(stack: &mut Vec<BookItem>, top_items: &mut Vec<BookItem>, to_level: usize) { @@ -100,16 +102,16 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String // always include the introduction top_items.push(BookItem { title: "Introduction".to_string(), - path: Path::new("README.md"), - path_to_root: Path::new("."), + path: PathBuf::new("README.md"), + path_to_root: PathBuf::new("."), children: vec!(), }); - for line_result in BufferedReader::new(input).lines() { + for line_result in BufReader::new(input).lines() { let line = match line_result { Ok(line) => line, Err(err) => { - errors.push(err.desc.to_string()); // FIXME: include detail + errors.push(err.to_string()); return Err(errors); } }; @@ -125,16 +127,16 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String let title = line[start_bracket + 1..end_bracket].to_string(); let indent = &line[..star_idx]; - let path_from_root = match src.join(given_path).path_relative_from(src) { - Some(p) => p, + let path_from_root = match src.join(given_path).relative_from(src) { + Some(p) => p.to_path_buf(), None => { errors.push(format!("paths in SUMMARY.md must be relative, \ but path '{}' for section '{}' is not.", given_path, title)); - Path::new("") + PathBuf::new("") } }; - let path_to_root = Path::new(iter::repeat("../") + let path_to_root = PathBuf::new(&iter::repeat("../") .take(path_from_root.components().count() - 1) .collect::<String>()); let item = BookItem { diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index f36d97d6d12..1fb30e15400 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -11,13 +11,14 @@ //! Implementation of the `build` subcommand, used to compile a book. use std::env; -use std::os; -use std::old_io; -use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult}; +use std::fs::{self, File, TempDir}; +use std::io::prelude::*; +use std::io::{self, BufWriter}; +use std::path::{Path, PathBuf}; use subcommand::Subcommand; use term::Term; -use error::{Error, CliResult, CommandResult}; +use error::{err, CliResult, CommandResult}; use book; use book::{Book, BookItem}; use css; @@ -29,17 +30,17 @@ struct Build; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { if name == "build" { - Some(box Build as Box<Subcommand>) + Some(Box::new(Build)) } else { None } } -fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> { +fn write_toc(book: &Book, path_to_root: &Path, out: &mut Write) -> io::Result<()> { fn walk_items(items: &[BookItem], section: &str, path_to_root: &Path, - out: &mut Writer) -> IoResult<()> { + out: &mut Write) -> io::Result<()> { for (i, item) in items.iter().enumerate() { try!(walk_item(item, &format!("{}{}.", section, i + 1)[..], path_to_root, out)); } @@ -48,9 +49,9 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> fn walk_item(item: &BookItem, section: &str, path_to_root: &Path, - out: &mut Writer) -> IoResult<()> { + out: &mut Write) -> io::Result<()> { try!(writeln!(out, "<li><a href='{}'><b>{}</b> {}</a>", - path_to_root.join(item.path.with_extension("html")).display(), + path_to_root.join(&item.path.with_extension("html")).display(), section, item.title)); if !item.children.is_empty() { @@ -75,30 +76,35 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> fn render(book: &Book, tgt: &Path) -> CliResult<()> { let tmp = try!(TempDir::new("rust-book")); - for (section, item) in book.iter() { - println!("{} {}", section, item.title); - - let out_path = tgt.join(item.path.dirname()); + for (_section, item) in book.iter() { + let out_path = match item.path.parent() { + Some(p) => tgt.join(p), + None => tgt.to_path_buf(), + }; let src; if env::args().len() < 3 { - src = os::getcwd().unwrap().clone(); + src = env::current_dir().unwrap().clone(); } else { - src = Path::new(env::args().nth(2).unwrap().clone()); + src = PathBuf::new(&env::args().nth(2).unwrap()); } // preprocess the markdown, rerouting markdown references to html references - let markdown_data = try!(File::open(&src.join(&item.path)).read_to_string()); - let preprocessed_path = tmp.path().join(item.path.filename().unwrap()); + let mut markdown_data = String::new(); + try!(File::open(&src.join(&item.path)).and_then(|mut f| { + f.read_to_string(&mut markdown_data) + })); + let preprocessed_path = tmp.path().join(item.path.file_name().unwrap()); { let urls = markdown_data.replace(".md)", ".html)"); - try!(File::create(&preprocessed_path) - .write_str(&urls[..])); + try!(File::create(&preprocessed_path).and_then(|mut f| { + f.write_all(urls.as_bytes()) + })); } // write the prelude to a temporary HTML file for rustdoc inclusion let prelude = tmp.path().join("prelude.html"); { - let mut toc = BufferedWriter::new(try!(File::create(&prelude))); + let mut toc = BufWriter::new(try!(File::create(&prelude))); try!(writeln!(&mut toc, r#"<div id="nav"> <button id="toggle-nav"> <span class="sr-only">Toggle navigation</span> @@ -115,12 +121,12 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { // write the postlude to a temporary HTML file for rustdoc inclusion let postlude = tmp.path().join("postlude.html"); { - let mut toc = BufferedWriter::new(try!(File::create(&postlude))); - try!(toc.write_str(javascript::JAVASCRIPT)); + let mut toc = BufWriter::new(try!(File::create(&postlude))); + try!(toc.write_all(javascript::JAVASCRIPT.as_bytes())); try!(writeln!(&mut toc, "</div></div>")); } - try!(fs::mkdir_recursive(&out_path, old_io::USER_DIR)); + try!(fs::create_dir_all(&out_path)); let rustdoc_args: &[String] = &[ "".to_string(), @@ -135,7 +141,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { if output_result != 0 { let message = format!("Could not execute `rustdoc` with {:?}: {}", rustdoc_args, output_result); - return Err(box message as Box<Error>); + return Err(err(&message)); } } @@ -150,28 +156,30 @@ impl Subcommand for Build { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); let src; let tgt; if env::args().len() < 3 { src = cwd.clone(); } else { - src = Path::new(env::args().nth(2).unwrap().clone()); + src = PathBuf::new(&env::args().nth(2).unwrap()); } if env::args().len() < 4 { tgt = cwd.join("_book"); } else { - tgt = Path::new(env::args().nth(3).unwrap().clone()); + tgt = PathBuf::new(&env::args().nth(3).unwrap()); } - try!(fs::mkdir(&tgt, old_io::USER_DIR)); + try!(fs::create_dir(&tgt)); - try!(File::create(&tgt.join("rust-book.css")).write_str(css::STYLE)); + try!(File::create(&tgt.join("rust-book.css")).and_then(|mut f| { + f.write_all(css::STYLE.as_bytes()) + })); - let summary = try!(File::open(&src.join("SUMMARY.md"))); - match book::parse_summary(summary, &src) { + let mut summary = try!(File::open(&src.join("SUMMARY.md"))); + match book::parse_summary(&mut summary, &src) { Ok(book) => { // execute rustdoc on the whole book render(&book, &tgt) @@ -182,7 +190,7 @@ impl Subcommand for Build { term.err(&format!("error: {}", err)[..]); } - Err(box format!("{} errors occurred", n) as Box<Error>) + Err(err(&format!("{} errors occurred", n))) } } } diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs index 43c882c7d5b..294b4e55669 100644 --- a/src/rustbook/error.rs +++ b/src/rustbook/error.rs @@ -10,10 +10,8 @@ //! Error handling utilities. WIP. +use std::error::Error; use std::fmt; -use std::fmt::{Debug, Formatter}; - -use std::old_io::IoError; pub type CliError = Box<Error + 'static>; pub type CliResult<T> = Result<T, CliError>; @@ -21,63 +19,17 @@ pub type CliResult<T> = Result<T, CliError>; pub type CommandError = Box<Error + 'static>; pub type CommandResult<T> = Result<T, CommandError>; -pub trait Error { - fn description(&self) -> &str; - - fn detail(&self) -> Option<&str> { None } - fn cause(&self) -> Option<&Error> { None } -} - -pub trait FromError<E> { - fn from_err(err: E) -> Self; -} - -impl Debug for Box<Error + 'static> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{}", self.description()) - } -} - -impl<E: Error + 'static> FromError<E> for Box<Error + 'static> { - fn from_err(err: E) -> Box<Error + 'static> { - box err as Box<Error> - } -} +pub fn err(s: &str) -> CliError { + struct E(String); -impl<'a> Error for &'a str { - fn description<'b>(&'b self) -> &'b str { - *self + impl Error for E { + fn description(&self) -> &str { &self.0 } } -} - -impl Error for String { - fn description<'a>(&'a self) -> &'a str { - &self[..] + impl fmt::Display for E { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } } -} - -impl<'a> Error for Box<Error + 'a> { - fn description(&self) -> &str { (**self).description() } - fn detail(&self) -> Option<&str> { (**self).detail() } - fn cause(&self) -> Option<&Error> { (**self).cause() } -} - -impl FromError<()> for () { - fn from_err(_: ()) -> () { () } -} -impl FromError<IoError> for IoError { - fn from_err(error: IoError) -> IoError { error } + Box::new(E(s.to_string())) } - -impl Error for IoError { - fn description(&self) -> &str { - self.desc - } - fn detail(&self) -> Option<&str> { - self.detail.as_ref().map(|s| &s[..]) - } -} - - -//fn iter_map_err<T, U, E, I: Iterator<Result<T,E>>>(iter: I, diff --git a/src/rustbook/help.rs b/src/rustbook/help.rs index 7fd8214f731..995d2f2494a 100644 --- a/src/rustbook/help.rs +++ b/src/rustbook/help.rs @@ -19,7 +19,7 @@ struct Help; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { match name { - "help" | "--help" | "-h" | "-?" => Some(box Help as Box<Subcommand>), + "help" | "--help" | "-h" | "-?" => Some(Box::new(Help)), _ => None } } diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs index b9fc011e8b9..848f960839e 100644 --- a/src/rustbook/main.rs +++ b/src/rustbook/main.rs @@ -8,31 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(box_syntax)] -#![feature(collections)] +#![deny(warnings)] + #![feature(core)] +#![feature(exit_status)] +#![feature(fs)] +#![feature(io)] #![feature(old_io)] -#![feature(env)] -#![feature(os)] -#![feature(old_path)] +#![feature(path)] #![feature(rustdoc)] +#![feature(tempdir)] extern crate rustdoc; use std::env; +use std::error::Error; use subcommand::Subcommand; use term::Term; -macro_rules! try ( - ($expr:expr) => ({ - use error; - match $expr { - Ok(val) => val, - Err(err) => return Err(error::FromError::from_err(err)) - } - }) -); - mod term; mod error; mod book; @@ -56,15 +49,12 @@ fn main() { } else { match subcommand::parse_name(&cmd[1][..]) { Some(mut subcmd) => { - match subcmd.parse_args(cmd.tail()) { + match subcmd.parse_args(&cmd[..cmd.len()-1]) { Ok(_) => { match subcmd.execute(&mut term) { Ok(_) => (), Err(err) => { - term.err(&format!("error: {}", err.description())[..]); - err.detail().map(|detail| { - term.err(&format!("detail: {}", detail)[..]); - }); + term.err(&format!("error: {}", err)); } } } diff --git a/src/rustbook/serve.rs b/src/rustbook/serve.rs index 808527dcef9..2fa7b7eed7b 100644 --- a/src/rustbook/serve.rs +++ b/src/rustbook/serve.rs @@ -19,7 +19,7 @@ struct Serve; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { if name == "serve" { - Some(box Serve as Box<Subcommand>) + Some(Box::new(Serve)) } else { None } diff --git a/src/rustbook/term.rs b/src/rustbook/term.rs index 98aa3fca184..06595cb0455 100644 --- a/src/rustbook/term.rs +++ b/src/rustbook/term.rs @@ -21,7 +21,7 @@ pub struct Term { impl Term { pub fn new() -> Term { Term { - err: box stdio::stderr() as Box<Writer>, + err: Box::new(stdio::stderr()) } } diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs index 727a385a8f0..72df0768e7b 100644 --- a/src/rustbook/test.rs +++ b/src/rustbook/test.rs @@ -11,19 +11,19 @@ //! Implementation of the `test` subcommand. Just a stub for now. use subcommand::Subcommand; -use error::CliResult; -use error::CommandResult; -use error::Error; +use error::{err, CliResult, CommandResult}; use term::Term; use book; -use std::old_io::{Command, File}; -use std::os; + +use std::fs::File; +use std::env; +use std::process::Command; struct Test; pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> { if name == "test" { - Some(box Test as Box<Subcommand>) + Some(Box::new(Test)) } else { None } @@ -35,11 +35,11 @@ impl Subcommand for Test { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = os::getcwd().unwrap(); + let cwd = env::current_dir().unwrap(); let src = cwd.clone(); - let summary = File::open(&src.join("SUMMARY.md")); - match book::parse_summary(summary, &src) { + let mut summary = try!(File::open(&src.join("SUMMARY.md"))); + match book::parse_summary(&mut summary, &src) { Ok(book) => { for (_, item) in book.iter() { let output_result = Command::new("rustdoc") @@ -50,15 +50,15 @@ impl Subcommand for Test { Ok(output) => { if !output.status.success() { term.err(&format!("{}\n{}", - String::from_utf8_lossy(&output.output[..]), - String::from_utf8_lossy(&output.error[..]))[..]); - return Err(box "Some tests failed." as Box<Error>); + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr))); + return Err(err("some tests failed")); } } Err(e) => { - let message = format!("Could not execute `rustdoc`: {}", e); - return Err(box message as Box<Error>); + let message = format!("could not execute `rustdoc`: {}", e); + return Err(err(&message)) } } } @@ -67,7 +67,7 @@ impl Subcommand for Test { for err in errors { term.err(&err[..]); } - return Err(box "There was an error." as Box<Error>); + return Err(err("there was an error")) } } Ok(()) // lol diff --git a/src/test/compile-fail/empty-extern-arg.rs b/src/test/compile-fail/empty-extern-arg.rs index 9b7df81a5dc..8791481d9e7 100644 --- a/src/test/compile-fail/empty-extern-arg.rs +++ b/src/test/compile-fail/empty-extern-arg.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags: --extern std= -// error-pattern: is not a file +// error-pattern: can't find crate for `std` fn main() {} diff --git a/src/test/parse-fail/circular_modules_main.rs b/src/test/parse-fail/circular_modules_main.rs index ac5ec1236ff..3e548981f1e 100644 --- a/src/test/parse-fail/circular_modules_main.rs +++ b/src/test/parse-fail/circular_modules_main.rs @@ -9,10 +9,10 @@ // except according to those terms. #[path = "circular_modules_hello.rs"] -mod circular_modules_hello; //~ERROR: circular modules +mod circular_modules_hello; //~ ERROR: circular modules pub fn hi_str() -> String { - "Hi!".to_string() + "Hi!".to_string() } fn main() { diff --git a/src/test/parse-fail/issue-5806.rs b/src/test/parse-fail/issue-5806.rs index 597366a1b35..b2608cc0b92 100644 --- a/src/test/parse-fail/issue-5806.rs +++ b/src/test/parse-fail/issue-5806.rs @@ -8,15 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. +// ignore-windows +// ignore-freebsd #[path = "../compile-fail"] mod foo; //~ ERROR: a directory diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index cff4d44910b..1ed816ed729 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -18,6 +18,8 @@ use rustc::session::config::{basic_options, build_configuration, Input, OutputTy use rustc_driver::driver::{compile_input, CompileController}; use syntax::diagnostics::registry::Registry; +use std::path::PathBuf; + fn main() { let src = r#" fn main() {} @@ -29,9 +31,9 @@ fn main() { panic!("expected rustc path"); } - let tmpdir = Path::new(&args[1]); + let tmpdir = PathBuf::new(&args[1]); - let mut sysroot = Path::new(&args[3]); + let mut sysroot = PathBuf::new(&args[3]); sysroot.pop(); sysroot.pop(); @@ -40,7 +42,7 @@ fn main() { compile(src.to_string(), tmpdir.join("out"), sysroot.clone()); } -fn basic_sess(sysroot: Path) -> Session { +fn basic_sess(sysroot: PathBuf) -> Session { let mut opts = basic_options(); opts.output_types = vec![OutputTypeExe]; opts.maybe_sysroot = Some(sysroot); @@ -51,7 +53,7 @@ fn basic_sess(sysroot: Path) -> Session { sess } -fn compile(code: String, output: Path, sysroot: Path) { +fn compile(code: String, output: PathBuf, sysroot: PathBuf) { let sess = basic_sess(sysroot); let cfg = build_configuration(&sess); let control = CompileController::basic(); diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs index 9e164522d77..75a968c3f81 100644 --- a/src/test/run-pass-fulldeps/compiler-calls.rs +++ b/src/test/run-pass-fulldeps/compiler-calls.rs @@ -25,6 +25,7 @@ use rustc::session::config::{self, Input}; use rustc_driver::{driver, CompilerCalls, Compilation}; use syntax::diagnostics; +use std::path::PathBuf; struct TestCalls { count: u32 @@ -43,14 +44,15 @@ impl<'a> CompilerCalls<'a> for TestCalls { _: &getopts::Matches, _: &Session, _: &Input, - _: &Option<Path>, - _: &Option<Path>) + _: &Option<PathBuf>, + _: &Option<PathBuf>) -> Compilation { self.count *= 3; Compilation::Stop } - fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) { + fn some_input(&mut self, input: Input, input_path: Option<PathBuf>) + -> (Input, Option<PathBuf>) { self.count *= 5; (input, input_path) } @@ -58,10 +60,10 @@ impl<'a> CompilerCalls<'a> for TestCalls { fn no_input(&mut self, _: &getopts::Matches, _: &config::Options, - _: &Option<Path>, - _: &Option<Path>, + _: &Option<PathBuf>, + _: &Option<PathBuf>, _: &diagnostics::registry::Registry) - -> Option<(Input, Option<Path>)> { + -> Option<(Input, Option<PathBuf>)> { panic!("This shouldn't happen"); } |
