Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/cargo-util-terminal/src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,14 @@ impl Shell {
self.print_report(report, false)
}

/// Prints a cyan 'help' message.
pub fn help<T: fmt::Display>(&mut self, message: T) -> CargoResult<()> {
let report = &[annotate_snippets::Group::with_title(
annotate_snippets::Level::HELP.secondary_title(message.to_string()),
)];
self.print_report(report, false)
}

/// Updates the verbosity of the shell.
pub fn set_verbosity(&mut self, verbosity: Verbosity) {
self.verbosity = verbosity;
Expand Down
25 changes: 22 additions & 3 deletions src/cargo/ops/fix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,10 +791,26 @@ pub fn fix_exec_rustc(gctx: &GlobalContext, lock_addr: &str) -> CargoResult<()>

// If there were any fixes, let the user know that there was a failure
// attempting to apply them, and to ask for a bug report.
//
// FIXME: The error message here is not correct with --broken-code.
// https://github.com/rust-lang/cargo/issues/10955
if fixes.files.is_empty() {
if !fixes.last_output.status.success() {
if allow_broken_code {
gctx.shell()
.warn("no fixes were suggested because the code is already broken")?;
gctx.shell().note(
"cargo fix requires code that compiles successfully to apply automatic fixes",
)?;
gctx.shell()
.note("the broken code was saved due to `--broken-code`")?;
} else {
gctx.shell()
.warn("no fixes were suggested because the code is already broken")?;
gctx.shell().note(
"cargo fix requires code that compiles successfully to apply automatic fixes",
)?;
gctx.shell()
.help("use `--broken-code` to save partial progress")?;
}
}
// No fixes were available. Display whatever errors happened.
emit_output(&fixes.last_output)?;
exit_with(fixes.last_output.status);
Expand All @@ -814,6 +830,7 @@ pub fn fix_exec_rustc(gctx: &GlobalContext, lock_addr: &str) -> CargoResult<()>
krate,
&fixes.last_output.stderr,
fixes.last_output.status,
allow_broken_code,
)?;
// Display the diagnostics that appeared at the start, before the
// fixes failed. This can help with diagnosing which suggestions
Expand Down Expand Up @@ -1171,6 +1188,7 @@ fn log_failed_fix(
krate: Option<String>,
stderr: &[u8],
status: ExitStatus,
allow_broken_code: bool,
) -> CargoResult<()> {
let stderr = str::from_utf8(stderr).context("failed to parse rustc stderr as utf-8")?;

Expand Down Expand Up @@ -1205,6 +1223,7 @@ fn log_failed_fix(
krate,
errors,
abnormal_exit,
allow_broken_code,
}
.post(gctx)?;

Expand Down
52 changes: 31 additions & 21 deletions src/cargo/util/diagnostic_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum Message {
krate: Option<String>,
errors: Vec<String>,
abnormal_exit: Option<String>,
allow_broken_code: bool,
},
ReplaceFailed {
file: String,
Expand Down Expand Up @@ -146,6 +147,7 @@ impl<'a> DiagnosticPrinter<'a> {
krate,
errors,
abnormal_exit,
allow_broken_code,
} => {
let to_crate = if let Some(ref krate) = *krate {
format!(" to crate `{krate}`",)
Expand All @@ -160,28 +162,36 @@ impl<'a> DiagnosticPrinter<'a> {
None
};

let report = &[
Level::ERROR
.secondary_title(format!("errors present after applying fixes{to_crate}"))
.elements(files.iter().map(|f| Origin::path(f)))
.elements(
cause_message
.into_iter()
.map(|err| Level::ERROR.with_name("cause").message(err)),
)
.elements(abnormal_exit.iter().map(|exit| {
Level::ERROR
.with_name("cause")
.message(format!("rustc exited abnormally: {exit}"))
})),
gen_please_report_this_bug_group(issue_link),
gen_suggest_broken_code_group(),
Group::with_title(
Level::NOTE.secondary_title("original diagnostics will follow:"),
),
];
let report = &[Level::ERROR
.secondary_title(format!("errors present after applying fixes{to_crate}"))
.elements(files.iter().map(|f| Origin::path(f)))
.elements(
cause_message
.into_iter()
.map(|err| Level::ERROR.with_name("cause").message(err)),
)
.elements(abnormal_exit.iter().map(|exit| {
Level::ERROR
.with_name("cause")
.message(format!("rustc exited abnormally: {exit}"))
}))];

let mut report = report.to_vec();

if *allow_broken_code {
report.push(Group::with_title(Level::WARNING.secondary_title(
"fixes were applied but the code still does not compile; partially-fixed code was saved due to `--broken-code`"
)));
} else {
report.push(gen_please_report_this_bug_group(issue_link));
report.push(gen_suggest_broken_code_group());
}

self.gctx.shell().print_report(report, false)?;
report.push(Group::with_title(
Level::NOTE.secondary_title("original diagnostics will follow:"),
));

self.gctx.shell().print_report(&report, false)?;
Ok(())
}
Message::EditionAlreadyEnabled { message, edition } => {
Expand Down
6 changes: 4 additions & 2 deletions tests/testsuite/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1435,8 +1435,7 @@ fn fix_to_broken_code() {
= cause: thread 'main' ([..]) panicked at src/main.rs:23:29:
explicit panic
[NOTE] run with `RUST_BACKTRACE=1` environment variable to display a backtrace
[HELP] to report this as a bug, open an issue at https://github.com/rust-lang/rust/issues, quoting the full output of this command
[HELP] to possibly apply more fixes, pass in the `--broken-code` flag
[WARNING] fixes were applied but the code still does not compile; partially-fixed code was saved due to `--broken-code`
[NOTE] original diagnostics will follow:
...

Expand Down Expand Up @@ -2381,6 +2380,9 @@ fn fix_in_rust_src() {
.with_status(101)
.with_stderr_data(str![[r#"
[CHECKING] foo v0.0.0 ([ROOT]/foo)
[WARNING] no fixes were suggested because the code is already broken
[NOTE] cargo fix requires code that compiles successfully to apply automatic fixes
[NOTE] the broken code was saved due to `--broken-code`
error[E0308]: mismatched types
--> lib.rs:5:9
|
Expand Down
9 changes: 7 additions & 2 deletions tests/testsuite/fix_n_times.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ fn starts_with_error() {
},
str![[r#"
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[WARNING] no fixes were suggested because the code is already broken
[NOTE] cargo fix requires code that compiles successfully to apply automatic fixes
[HELP] use `--broken-code` to save partial progress
rustc fix shim error count=1
[ERROR] could not compile `foo` (lib) due to 1 previous error

Expand All @@ -550,6 +553,9 @@ fn broken_code_no_suggestions() {
},
str![[r#"
[CHECKING] foo v0.0.1 ([ROOT]/foo)
[WARNING] no fixes were suggested because the code is already broken
[NOTE] cargo fix requires code that compiles successfully to apply automatic fixes
[NOTE] the broken code was saved due to `--broken-code`
rustc fix shim error count=1
[ERROR] could not compile `foo` (lib) due to 1 previous error

Expand All @@ -571,8 +577,7 @@ fn broken_code_one_suggestion() {
[ERROR] errors present after applying fixes to crate `foo`
--> src/lib.rs
= cause: rustc fix shim error count=2
[HELP] to report this as a bug, open an issue at https://github.com/rust-lang/rust/issues, quoting the full output of this command
[HELP] to possibly apply more fixes, pass in the `--broken-code` flag
[WARNING] fixes were applied but the code still does not compile; partially-fixed code was saved due to `--broken-code`
[NOTE] original diagnostics will follow:
rustc fix shim comment 1
rustc fix shim error count=2
Expand Down