diff options
| author | king6cong <king6cong@gmail.com> | 2017-02-03 17:42:01 +0800 |
|---|---|---|
| committer | king6cong <king6cong@gmail.com> | 2017-02-03 17:54:34 +0800 |
| commit | 768f6a9b57c83030919adb30565918f1b520596f (patch) | |
| tree | c734cea7aeb8e8e2e772f051e233f87d247c4bea | |
| parent | 5e41ec2cccb86db1a9677d2bfb9d2f623755f3de (diff) | |
add and use rename_or_copy_remove fn that fallback to copy & remove
| -rw-r--r-- | src/librustc/util/fs.rs | 25 | ||||
| -rw-r--r-- | src/librustc_driver/driver.rs | 3 |
2 files changed, 27 insertions, 1 deletions
diff --git a/src/librustc/util/fs.rs b/src/librustc/util/fs.rs index c290d8f893e..7f8a69de607 100644 --- a/src/librustc/util/fs.rs +++ b/src/librustc/util/fs.rs @@ -82,6 +82,31 @@ pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<Li } } +#[derive(Debug)] +pub enum RenameOrCopyRemove { + Rename, + CopyRemove +} + +/// Rename `p` into `q`, preferring to use `rename` if possible. +/// If `rename` fails (rename may fail for reasons such as crossing filesystem), fallback to copy & remove +pub fn rename_or_copy_remove<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<RenameOrCopyRemove> { + let p = p.as_ref(); + let q = q.as_ref(); + match fs::rename(p, q) { + Ok(()) => Ok(RenameOrCopyRemove::Rename), + Err(_) => { + match fs::copy(p, q) { + Ok(_) => { + fs::remove_file(p)?; + Ok(RenameOrCopyRemove::CopyRemove) + }, + Err(e) => Err(e) + } + } + } +} + // Like std::fs::create_dir_all, except handles concurrent calls among multiple // threads or processes. pub fn create_dir_racy(path: &Path) -> io::Result<()> { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 6fe6541c1d9..33bf4d5276a 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -22,6 +22,7 @@ use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas}; use rustc::util::common::time; use rustc::util::nodemap::{NodeSet, NodeMap}; +use rustc::util::fs::rename_or_copy_remove; use rustc_borrowck as borrowck; use rustc_incremental::{self, IncrementalHashesMap}; use rustc_incremental::ich::Fingerprint; @@ -1084,7 +1085,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session, // are going to build an executable if sess.opts.output_types.contains_key(&OutputType::Exe) { let f = outputs.path(OutputType::Object); - fs::rename(&f, + rename_or_copy_remove(&f, f.with_file_name(format!("{}.0.o", f.file_stem().unwrap().to_string_lossy()))).unwrap(); } |
