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, + pub clang_path: Option, // The llvm binaries path - pub llvm_bin_path: Option, + pub llvm_bin_path: Option, // The valgrind path pub valgrind_path: Option, @@ -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, // Write out a parseable log of tests that were run - pub logfile: Option, + pub logfile: Option, // A command line to prefix program execution with, // for running under valgrind @@ -133,7 +134,7 @@ pub struct Config { pub lldb_version: Option, // 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 ) -> 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 ) -> 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 ) -> 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 { 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 { - 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, // If present, the name of a file that this test should match when // pretty-printed - pub pp_exact: Option, + pub pp_exact: Option, // Modules from aux directory that should be compiled pub aux_builds: Vec , // 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(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 { +fn parse_pp_exact(line: &str, testfile: &Path) -> Option { 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) -> Option { 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) -> Option { + input: Option) -> Option { 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 { +fn find_rust_src_root(config: &Config) -> Option { 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 { } 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 , let prefixes = expected_errors.iter().map(|ee| { format!("{}:{}:", testfile.display(), ee.line) - }).collect:: >(); + }).collect::>(); - #[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 ) + 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 { + 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(config: &Config, @@ -1265,9 +1280,9 @@ fn make_compile_args(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(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(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, + dylib: Option, 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)> { + -> Vec<(ast::CrateNum, Option)> { let mut ordering = Vec::new(); fn visit(cstore: &CStore, cnum: ast::CrateNum, ordering: &mut Vec) { 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 { } 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 { 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::>(); 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 { + pub fn get_dylib_search_paths(&self) -> Vec { 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 { - 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 { + 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) -> Option { - path.and_then(|path| + fn canonicalize(path: Option) -> Option { + 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 { /// $HOME/.rust /// DIR/.rust for any DIR that's the current working directory /// or an ancestor of it -pub fn rust_path() -> Vec { - let mut env_rust_path: Vec = match get_rust_path() { +pub fn rust_path() -> Vec { + let mut env_rust_path: Vec = 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 { 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 + 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.set_filename(".rust"); - if !env_rust_path.contains(&cwd) && cwd.exists() { - env_rust_path.push(cwd.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, - pub rlib: Option + pub dylib: Option, + pub rlib: Option } impl CratePaths { - fn paths(&self) -> Vec { + fn paths(&self) -> Vec { 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, flavor: &str, - slot: &mut Option) -> Option<(Path, PathKind)> { - let mut ret = None::<(Path, PathKind)>; + fn extract_one(&mut self, m: HashMap, flavor: &str, + slot: &mut Option) -> 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 {}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 Result &'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, - blk: &ast::Block) -> old_io::IoResult<()> { + fn pretty_print_to<'b>(&self, wr: Box, + 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>; 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, + pub maybe_sysroot: Option, 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), + pub write_dependency_info: (bool, Option), pub prints: Vec, 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, + pub single_output_file: Option, 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>, pub entry_type: Cell>, pub plugin_registrar_fn: Cell>, - pub default_sysroot: Option, + pub default_sysroot: Option, // 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, - pub working_dir: Path, + pub local_crate_source_file: Option, + pub working_dir: PathBuf, pub lint_store: RefCell, pub lints: RefCell>>, pub crate_types: RefCell>, @@ -310,7 +311,7 @@ fn split_msg_into_multilines(msg: &str) -> Option { } pub fn build_session(sopts: config::Options, - local_crate_source_file: Option, + local_crate_source_file: Option, 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, + local_crate_source_file: Option, 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(cache: &RefCell>, 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, + pub dst: PathBuf, + pub lib_search_paths: Vec, pub slib_prefix: String, pub slib_suffix: String, pub maybe_ar_prog: Option @@ -31,8 +32,8 @@ pub struct ArchiveConfig<'a> { pub struct Archive<'a> { handler: &'a ErrorHandler, - dst: Path, - lib_search_paths: Vec, + dst: PathBuf, + lib_search_paths: Vec, slib_prefix: String, slib_suffix: String, maybe_ar_prog: Option @@ -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, + members: Vec, should_update_symbols: bool, } fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option, 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, 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, } 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 { 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(&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 { - const MAX_LINKS_FOLLOWED: uint = 256; +#[allow(deprecated)] // readlink is deprecated +pub fn realpath(original: &Path) -> io::Result { + 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 { + 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 { 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 where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result, -{ - pub used_crates: Vec<(ast::CrateNum, Option)>, - pub out_filename: Path, +pub struct RPathConfig<'a> { + pub used_crates: Vec<(ast::CrateNum, Option)>, + 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, } -pub fn get_rpath_flags(config: RPathConfig) -> Vec where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result, -{ +pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec { // No rpath on windows if !config.has_rpath { return Vec::new(); @@ -54,10 +48,7 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec { return ret; } -fn get_rpaths(mut config: RPathConfig, libs: &[Path]) -> Vec where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result, -{ +fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec { debug!("output: {:?}", config.out_filename.display()); debug!("libs:"); for libpath in libs { @@ -67,7 +58,7 @@ fn get_rpaths(mut config: RPathConfig, libs: &[Path]) -> Vec // 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(mut config: RPathConfig, libs: &[Path]) -> Vec return rpaths; } -fn get_rpaths_relative_to_output(config: &mut RPathConfig, - libs: &[Path]) -> Vec where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result, -{ +fn get_rpaths_relative_to_output(config: &mut RPathConfig, + libs: &[PathBuf]) -> Vec { libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect() } -fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result, -{ +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(config: &mut RPathConfig, 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(config: RPathConfig) -> String where - F: FnOnce() -> Path, - G: FnMut(&Path) -> Result, -{ +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 { 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 { 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 { - 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, - output: &Option, + outdir: &Option, + output: &Option, addl_plugins: Option>, 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) + out_dir: &'a Option) -> 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, + out_dir: &'a Option, 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, + out_dir: &'a Option, 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, + out_dir: &'a Option, 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, + out_dir: &'a Option, 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, + out_dir: &'a Option, 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 = 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, - ofile: &Option, + odir: &Option, + ofile: &Option, 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, Option) { - 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, Option) { + 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)> { +fn make_input(free_matches: &[String]) -> Option<(Input, Option)> { 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)> { 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, - &Option) + &Option, + &Option) -> 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) -> (Input, Option) { + fn some_input(&mut self, input: Input, input_path: Option) + -> (Input, Option) { (input, input_path) } @@ -234,10 +238,10 @@ pub trait CompilerCalls<'a> { fn no_input(&mut self, &getopts::Matches, &config::Options, - &Option, - &Option, + &Option, + &Option, &diagnostics::registry::Registry) - -> Option<(Input, Option)>; + -> Option<(Input, Option)>; // 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, - ofile: &Option, + odir: &Option, + ofile: &Option, descriptions: &diagnostics::registry::Registry) - -> Option<(Input, Option)> { + -> Option<(Input, Option)> { 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, - ofile: &Option) + odir: &Option, + ofile: &Option) -> 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, - ofile: &Option) + odir: &Option, + ofile: &Option) -> 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, - ofile: Option) { + ofile: Option) { 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, - Some(p) => { - let r = old_io::File::create(&p); - match r { - Ok(w) => box w as Box, - 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(variants: Vec, 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(variants: Vec, } } - 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 { - 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 { + crate_name: &str) -> Vec { 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 { +fn archive_search_paths(sess: &Session) -> Vec { 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(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(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, + 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, + pub out: Box, 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, U> Clean> for syntax::owned_slice::OwnedSlice { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Crate { pub name: String, - pub src: FsPath, + pub src: PathBuf, pub module: Option, pub externs: Vec<(ast::CrateNum, ExternalCrate)>, pub primitives: Vec, @@ -191,7 +191,7 @@ impl<'a, 'tcx> Clean 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> { - let mut f = try!(old_io::File::open(input)); - let d = try!(f.read_to_end()); +pub fn load_string(input: &Path) -> io::Result> { + 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 = 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( - 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##" @@ -159,7 +160,7 @@ r##" ) } -pub fn redirect(dst: &mut old_io::Writer, url: &str) -> old_io::IoResult<()> { +pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> { //