feat: Don't stop at first error when emitting lints and warnings (#15889)

While emitting warnings, if `cargo` encounters a critical warning or an
error while linting, it returns early, potentially before all packages
could emit their warnings or be linted. This could make it so users have
to run a `cargo` command more than once before seeing all of the
relevant output. Beyond this, having an error caused by a lint be a
"stop the world" event seems wrong, as it (currently) doesn't inhibit
outputting other warnings or linting other packages.

To address this, I made it so that `cargo` waits until the end of
`emit_warnings` to return an error if one was encountered. To keep the
cause of the error the same as before, `cargo` saves off the first error
it encounters, and returns it at the end.
This commit is contained in:
Weihang Lo 2025-09-01 00:01:55 +00:00 committed by GitHub
commit d2a66d6910
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1205,10 +1205,15 @@ impl<'gctx> Workspace<'gctx> {
}
pub fn emit_warnings(&self) -> CargoResult<()> {
let mut first_emitted_error = None;
for (path, maybe_pkg) in &self.packages.packages {
if let MaybePackage::Package(pkg) = maybe_pkg {
if self.gctx.cli_unstable().cargo_lints {
self.emit_lints(pkg, &path)?
if let Err(e) = self.emit_lints(pkg, &path)
&& first_emitted_error.is_none()
{
first_emitted_error = Some(e);
}
}
}
let warnings = match maybe_pkg {
@ -1220,7 +1225,9 @@ impl<'gctx> Workspace<'gctx> {
let err = anyhow::format_err!("{}", warning.message);
let cx =
anyhow::format_err!("failed to parse manifest at `{}`", path.display());
return Err(err.context(cx));
if first_emitted_error.is_none() {
first_emitted_error = Some(err.context(cx));
}
} else {
let msg = if self.root_manifest.is_none() {
warning.message.to_string()
@ -1233,7 +1240,12 @@ impl<'gctx> Workspace<'gctx> {
}
}
}
Ok(())
if let Some(error) = first_emitted_error {
Err(error)
} else {
Ok(())
}
}
pub fn emit_lints(&self, pkg: &Package, path: &Path) -> CargoResult<()> {