Skip to content

Commit 0da2c99

Browse files
committed
Auto merge of #6312 - alexcrichton:fix-broken, r=ehuss
fix: Don't back out changes with `--broken-code` This commit updates the behavior of `cargo fix` when the `--broken-code` flag is passed to Cargo. Previously Cargo would always back out automatically applied changes to files whenever the fixed code failed to compile. Now, with the `--broken-code` flag, fixed code is left as-is. This means that if the fixed code can be more easily inspected by humans to detect bugs and such. The main use case intended here is that if you're working with a large code base then lints like the edition idiom lints aren't 100% finished yet to work as smoothly as `cargo fix`. The idiom lints are often useful, however, to transition code to be idiomatic (who would have guessed!) in the new edition. To ease the experience of using not-quite-ready lints this flag can be used to hopefully "fix 90% of lint warnings" and then the remaining compiler errors can be sifted through manually. The intention is that we have edition documentation indicating this workflow which also encourages filing bugs for anything that fails to fix, and hopefully this new behavior will make it easier for us to narrow down what the minimal test case is too!
2 parents e07088b + 08dc6da commit 0da2c99

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

src/cargo/ops/fix.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,11 @@ pub fn fix_maybe_exec_rustc() -> CargoResult<bool> {
205205
// user's code with our changes. Back out everything and fall through
206206
// below to recompile again.
207207
if !output.status.success() {
208-
for (path, file) in fixes.files.iter() {
209-
fs::write(path, &file.original_code)
210-
.with_context(|_| format!("failed to write file `{}`", path))?;
208+
if env::var_os(BROKEN_CODE_ENV).is_none() {
209+
for (path, file) in fixes.files.iter() {
210+
fs::write(path, &file.original_code)
211+
.with_context(|_| format!("failed to write file `{}`", path))?;
212+
}
211213
}
212214
log_failed_fix(&output.stderr)?;
213215
}

tests/testsuite/fix.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,3 +1116,74 @@ fn only_warn_for_relevant_crates() {
11161116
")
11171117
.run();
11181118
}
1119+
1120+
#[test]
1121+
fn fix_to_broken_code() {
1122+
if !is_nightly() {
1123+
return;
1124+
}
1125+
let p = project()
1126+
.file(
1127+
"foo/Cargo.toml",
1128+
r#"
1129+
[package]
1130+
name = 'foo'
1131+
version = '0.1.0'
1132+
[workspace]
1133+
"#,
1134+
).file(
1135+
"foo/src/main.rs",
1136+
r##"
1137+
use std::env;
1138+
use std::fs;
1139+
use std::io::Write;
1140+
use std::path::{Path, PathBuf};
1141+
use std::process::{self, Command};
1142+
1143+
fn main() {
1144+
let is_lib_rs = env::args_os()
1145+
.map(PathBuf::from)
1146+
.any(|l| l == Path::new("src/lib.rs"));
1147+
if is_lib_rs {
1148+
let path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
1149+
let path = path.join("foo");
1150+
if path.exists() {
1151+
panic!()
1152+
} else {
1153+
fs::File::create(&path).unwrap();
1154+
}
1155+
}
1156+
1157+
let status = Command::new("rustc")
1158+
.args(env::args().skip(1))
1159+
.status()
1160+
.expect("failed to run rustc");
1161+
process::exit(status.code().unwrap_or(2));
1162+
}
1163+
"##,
1164+
).file(
1165+
"bar/Cargo.toml",
1166+
r#"
1167+
[package]
1168+
name = 'bar'
1169+
version = '0.1.0'
1170+
[workspace]
1171+
"#,
1172+
).file("bar/build.rs", "fn main() {}")
1173+
.file(
1174+
"bar/src/lib.rs",
1175+
"pub fn foo() { let mut x = 3; drop(x); }",
1176+
).build();
1177+
1178+
// Build our rustc shim
1179+
p.cargo("build").cwd(p.root().join("foo")).run();
1180+
1181+
// Attempt to fix code, but our shim will always fail the second compile
1182+
p.cargo("fix --allow-no-vcs --broken-code")
1183+
.cwd(p.root().join("bar"))
1184+
.env("RUSTC", p.root().join("foo/target/debug/foo"))
1185+
.with_status(101)
1186+
.run();
1187+
1188+
assert_eq!(p.read_file("bar/src/lib.rs"), "pub fn foo() { let x = 3; drop(x); }");
1189+
}

0 commit comments

Comments
 (0)