Only invoke decorate if the diag can eventually be emitted#122578
Only invoke decorate if the diag can eventually be emitted#122578bors merged 3 commits intorust-lang:masterfrom
decorate if the diag can eventually be emitted#122578Conversation
|
r? @fee1-dead rustbot has assigned @fee1-dead. Use r? to explicitly pick a reviewer |
compiler/rustc_middle/src/lint.rs
Outdated
| // Finally, run `decorate`. This is guarded by a `can_emit_warnings()` check so that any | ||
| // `def_path_str` called within `decorate` won't trigger a `must_produce_diag` ICE if the | ||
| // `err` isn't eventually emitted (e.g. due to `-A warnings`). If an `err` is force-warn, | ||
| // it's going to be emitted anyway. | ||
| if matches!(err_level, rustc_errors::Level::ForceWarning(_)) | ||
| || sess.dcx().can_emit_warnings() | ||
| { | ||
| decorate(&mut err); | ||
| } | ||
|
|
There was a problem hiding this comment.
This isn't entirely correct. The test attached below ICEs after your PR because decorate is incorrectly skipped. can_emit_warnings is only relevant when the error level is Warning.
//@ compile-flags: -Dunused_must_use -Awarnings --crate-type=lib
//@ check-pass
#[must_use]
fn f() {}
pub fn g() {
f();
}There was a problem hiding this comment.
Also please add a test with --force-warn as well.
There was a problem hiding this comment.
This isn't entirely correct. The test attached below ICEs after your PR because decorate is incorrectly skipped.
can_emit_warningsis only relevant when the error level isWarning.
Thanks for pointing that out. I forgor to also invoke decorate for the actual Level::Error case (which lint levels Deny and Forbid correspond to).
There was a problem hiding this comment.
Added a test case with --force-warn.
| // Checks that compiling this file with | ||
| // `-Dunused_must_use -Awarnings --cap-lints=warn --crate-type=lib` does not ICE when emitting | ||
| // diagnostics. |
There was a problem hiding this comment.
Seems a bit redundant given compile-flags below. It would probably be better to write some notes explaining why there is an ICE.
There was a problem hiding this comment.
I added some notes explaining why the ICE is triggered in the tests/ui/lint/decorate-ice/decorate-def-path-str-ice.rs test instead of repeating what the compile-flags say (lol).
This comment has been minimized.
This comment has been minimized.
|
I need to think about how to guard the |
714fbd3 to
0bb5722
Compare
compiler/rustc_middle/src/lint.rs
Outdated
| if matches!(err_level, ELevel::ForceWarning(_) | ELevel::Error) | ||
| || sess.dcx().can_emit_warnings() |
There was a problem hiding this comment.
This check seems to pass the ui test suite including the -Dunused_must_use case, but I'm still not very confident in this check.
There was a problem hiding this comment.
I think it would be best if we instead used an if statement to consider when to skip calling decorate.
Something like
let skip = err_level == rustc_errors::Warning && !sess.dcx().can_emit_warnings();
if !skip {
decorate(&mut err);
}Which would have better maintainability.
|
@rustbot ready |
compiler/rustc_middle/src/lint.rs
Outdated
| if matches!(err_level, ELevel::ForceWarning(_) | ELevel::Error) | ||
| || sess.dcx().can_emit_warnings() |
There was a problem hiding this comment.
I think it would be best if we instead used an if statement to consider when to skip calling decorate.
Something like
let skip = err_level == rustc_errors::Warning && !sess.dcx().can_emit_warnings();
if !skip {
decorate(&mut err);
}Which would have better maintainability.
0bb5722 to
bdab02c
Compare
|
Changed the guard for |
|
@bors r+ |
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#120640 (Mark UEFI std support as WIP) - rust-lang#121862 (Add release notes for 1.77.0) - rust-lang#122572 (add test for rust-lang#122301 to cover behavior that's on stable) - rust-lang#122578 (Only invoke `decorate` if the diag can eventually be emitted) - rust-lang#122615 (Mention Zalathar for coverage changes) - rust-lang#122636 (some minor code simplifications) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#122578 - jieyouxu:guard-decorate, r=fee1-dead Only invoke `decorate` if the diag can eventually be emitted Lints can call [`trimmed_def_paths`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/print/fn.trimmed_def_paths.html#), such as through manual implementations of `LintDiagnostic` and calling `def_path_str`. https://github.com/rust-lang/rust/blob/05a2be3def211255dc7640b006ac10f0f02baf5c/compiler/rustc_lint/src/lints.rs#L1834-L1839 The emission of a lint eventually relies on [`TyCtxt::node_lint`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.node_lint), which has a `decorate` closure which is responsible for decorating the diagnostic with "lint stuff". `node_lint` in turn relies on [`lint_level`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/fn.lint_level.html). Within `lint_level`, `decorate` is eventually called just before `Diag::emit` is called to decorate the diagnostic. However, if `-A warnings` or `--cap-lint=allow` are set, or if the unused_must_use lint is explicitly allowed, then `decorate` would be called, which would call `def_path_str`, but the diagnostic would never be emitted and hence would trigger the `must_produce_diag` ICE. To avoid calling `decorate` when we don't eventually emit the diagnostic, we check that: - if `--force-warn` is specified, then call `decorate`; otherwise - if we can emit warnings (or higher), then call `decorate`. Fixes rust-lang#121774.
Lints can call
trimmed_def_paths, such as through manual implementations ofLintDiagnosticand callingdef_path_str.rust/compiler/rustc_lint/src/lints.rs
Lines 1834 to 1839 in 05a2be3
The emission of a lint eventually relies on
TyCtxt::node_lint, which has adecorateclosure which is responsible for decorating the diagnostic with "lint stuff".node_lintin turn relies onlint_level. Withinlint_level,decorateis eventually called just beforeDiag::emitis called to decorate the diagnostic. However, if-A warningsor--cap-lint=alloware set, or if the unused_must_use lint is explicitly allowed, thendecoratewould be called, which would calldef_path_str, but the diagnostic would never be emitted and hence would trigger themust_produce_diagICE.To avoid calling
decoratewhen we don't eventually emit the diagnostic, we check that:--force-warnis specified, then calldecorate; otherwisedecorate.Fixes #121774.