diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index 05e5ddd1af3..b72931d19bb 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -66,7 +66,8 @@ pub fn prepare_target<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, } } - Ok(prepare(is_fresh && !missing_outputs, loc, fingerprint)) + let allow_failure = profile.rustc_args.is_some(); + Ok(prepare(is_fresh && !missing_outputs, allow_failure, loc, fingerprint)) } /// A fingerprint can be considered to be a "short string" representing the @@ -256,7 +257,7 @@ pub fn prepare_build_cmd(cx: &mut Context, pkg: &Package, kind: Kind) let is_fresh = try!(is_fresh(&loc, &new_fingerprint)); - Ok(prepare(is_fresh, loc, new_fingerprint)) + Ok(prepare(is_fresh, false, loc, new_fingerprint)) } /// Prepare work for when a package starts to build @@ -284,13 +285,19 @@ pub fn prepare_init(cx: &mut Context, pkg: &Package, kind: Kind) /// Given the data to build and write a fingerprint, generate some Work /// instances to actually perform the necessary work. fn prepare(is_fresh: bool, + allow_failure: bool, loc: PathBuf, fingerprint: Fingerprint) -> Preparation { let write_fingerprint = Work::new(move |_| { debug!("write fingerprint: {}", loc.display()); - let fingerprint = try!(fingerprint.resolve(true).chain_error(|| { + let fingerprint = fingerprint.resolve(true).chain_error(|| { internal("failed to resolve a pending fingerprint") - })); + }); + let fingerprint = match fingerprint { + Ok(f) => f, + Err(..) if allow_failure => return Ok(()), + Err(e) => return Err(e), + }; let mut f = try!(File::create(&loc)); try!(f.write_all(fingerprint.as_bytes())); Ok(()) diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 162930be9a5..44b4f1adba9 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -341,6 +341,7 @@ fn rustc(package: &Package, target: &Target, profile: &Profile, if !show_warnings { rustc.arg("-Awarnings"); } + let has_custom_args = profile.rustc_args.is_some(); let exec_engine = cx.exec_engine.clone(); let filenames = try!(cx.target_filenames(package, target, profile, @@ -407,16 +408,20 @@ fn rustc(package: &Package, target: &Target, profile: &Profile, let src = dst.with_file_name(dst.file_name().unwrap() .to_str().unwrap() .replace(&real_name, &crate_name)); - try!(fs::rename(&src, &dst).chain_error(|| { - internal(format!("could not rename crate {:?}", src)) - })); + if !has_custom_args || fs::metadata(&src).is_ok() { + try!(fs::rename(&src, &dst).chain_error(|| { + internal(format!("could not rename crate {:?}", src)) + })); + } } - try!(fs::rename(&rustc_dep_info_loc, &dep_info_loc).chain_error(|| { - internal(format!("could not rename dep info: {:?}", - rustc_dep_info_loc)) - })); - try!(fingerprint::append_current_dir(&dep_info_loc, &cwd)); + if !has_custom_args || fs::metadata(&rustc_dep_info_loc).is_ok() { + try!(fs::rename(&rustc_dep_info_loc, &dep_info_loc).chain_error(|| { + internal(format!("could not rename dep info: {:?}", + rustc_dep_info_loc)) + })); + try!(fingerprint::append_current_dir(&dep_info_loc, &cwd)); + } Ok(()) diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 448531d676a..02cfa26649f 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -1886,3 +1886,18 @@ test!(custom_target_dir { assert_that(&p.root().join("target/debug").join(&exe_name), existing_file()); }); + +test!(rustc_no_trans { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("src/main.rs", "fn main() {}"); + p.build(); + + assert_that(p.cargo("rustc").arg("-v").arg("--").arg("-Zno-trans"), + execs().with_status(0)); +});