-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix EmissionGuarantee
#119097
Fix EmissionGuarantee
#119097
Conversation
This commit replaces this pattern: ``` err.into_diagnostic(dcx) ``` with this pattern: ``` dcx.create_err(err) ``` in a lot of places. It's a little shorter, makes the error level explicit, avoids some `IntoDiagnostic` imports, and is a necessary prerequisite for the next commit which will add a `level` arg to `into_diagnostic`. This requires adding `track_caller` on `create_err` to avoid mucking up the output of `tests/ui/track-diagnostics/track4.rs`. It probably should have been there already.
Presumably these are a hangover from an earlier time when they were necessary.
First, it is parameterized by the name of the diagnostic and the DiagCtxt. These are given to `session_diagnostic_derive` and `lint_diagnostic_derive`. But the names are hard-wired as "diag" and "handler" (should be "dcx"), and there's no clear reason for the parameterization. So this commit removes the parameterization and hard-wires the names internally. Once that is done `DiagnosticDeriveBuilder` is reduced to a trivial wrapper around `DiagnosticDeriveKind`, and can be removed. Also, `DiagnosticDerive` and `LintDiagnosticDerive` don't need the `builder` field, because it has been reduced to a kind, and they know their own kind. This avoids the need for some `let`/`else`/`unreachable!` kind checks And `DiagnosticDeriveVariantBuilder` no longer needs a lifetime, because the `parent` field is changed to `kind`, which is now a trivial copy type.
And make all hand-written `IntoDiagnostic` impls generic, by using `DiagnosticBuilder::new(dcx, level, ...)` instead of e.g. `dcx.struct_err(...)`. This means the `create_*` functions are the source of the error level. This change will let us remove `struct_diagnostic`. Note: `#[rustc_lint_diagnostics]` is added to `DiagnosticBuilder::new`, it's necessary to pass diagnostics tests now that it's used in `into_diagnostic` functions.
`EmissionGuarantee` no longer determines the error level, the `create_*` functions do.
This lets different error levels share the same return type from `emit_*`. - A lot of inconsistencies in the `DiagCtxt` API are removed. - `Noted` is removed. - `FatalAbort` is introduced for fatal errors (abort via `raise`), replacing the `EmissionGuarantee` impl for `!`. - `Bug` is renamed `BugAbort` (to avoid clashing with `Level::Bug` and to mirror `FatalAbort`), and modified to work in the new way with bug errors (abort via panic). - Various diagnostic creators and emitters updated to the new, better signatures. Note that `DiagCtxt::bug` no longer needs to call `panic_any`, because `emit` handles that. Also shorten the obnoxiously long `diagnostic_builder_emit_producing_guarantee` name.
This makes `DiagCtxt::bug` look like the other similar functions.
Some changes occurred in compiler/rustc_codegen_gcc Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred in need_type_info.rs cc @lcnr
|
Here's an explanation of what this PR is doing. Apologies for the length, but Let's look at the
But two are different:
The problem is that warnings and notes both want to return This isn't so bad for notes; you can just ignore (This is a genuine problem. While working on #118933 I accidentally broke ICE handling completely by making a change that caused bug level errors to behave like fatal errors!) So it would be nice to get rid of So, can we break this one-EmissionGuarantee-per-level constraint? Can we eliminate This leads to an interesting question: for diagnostics defined via Consider a trivial error diagnostic:
Here's how it would likely be implemented by hand:
This must be an error.
So it can only be used via
Here's how it is generated for
The only difference is that the error level is unspecified.
So it can be used at any level, via any
A final possibility:
This can also only be used as an error, despite using Back to the original question: for diagnostics defined via
This inconsistency is bad. We should make them all generic or non-generic. And the whole
I prefer the generic approach. All diagnostics (both hand-written and derived) would look like this:
Why does this matter? Well, consistency and simplicity. But also, we now have a
Either way, This fixes the notes case: we can remove Bugs are a little trickier, because we need to distinguish between a Here are the APIs that would be changed (showing before and after):
This fixes the original problems, yay! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes in cg_gcc look good to me, thanks!
Also big 👍 for the detailed explanations, it was really pleasant to read and made it easy to understand the changes!
The easter egg ICE on `break rust` is weird: it's the one ICE in the entire compiler that doesn't immediately abort, which makes it annoyingly inconsistent. This commit changes it to abort. As part of this, the extra notes are now appended onto the bug dignostic, rather than being printed as individual note diagnostics, which changes the output format a bit. These changes don't interferes with the joke, but they do help with my ongoing cleanups to error handling.
d93bad8
to
006446e
Compare
A TL;DR for the wall of text above: Each diagnostic emitted by the compiler has a level (and a corresponding
For For diagnostics with hand-written This PR changes hand-written diagnostics to be generic, which changes the answer to 2 for all diagnostics. This has the knock-on benefit of removing the need for |
compiler/rustc_errors/src/lib.rs
Outdated
@@ -1101,8 +1105,7 @@ impl DiagCtxt { | |||
} | |||
|
|||
pub fn bug(&self, msg: impl Into<DiagnosticMessage>) -> ! { | |||
DiagnosticBuilder::<diagnostic_builder::Bug>::new(self, Bug, msg).emit(); | |||
panic::panic_any(ExplicitBug); | |||
DiagnosticBuilder::<BugAbort>::new(self, Bug, msg).emit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yay
@bors r+ |
@bors rollup=never |
…=compiler-errors Fix `EmissionGuarantee` There are some problems with the `DiagCtxt` API related to `EmissionGuarantee`. This PR fixes them. r? `@compiler-errors`
@bors retry Yield priority to the stable release. |
…=compiler-errors Fix `EmissionGuarantee` There are some problems with the `DiagCtxt` API related to `EmissionGuarantee`. This PR fixes them. r? `@compiler-errors`
@bors retry Yield priority to the release. |
☀️ Test successful - checks-actions |
Finished benchmarking commit (cee794e): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 674.232s -> 672.574s (-0.25%) |
PR rust-lang#119097 made the decision to make all `IntoDiagnostic` impls generic, because this allowed a bunch of nice cleanups. But four hand-written impls were unintentionally overlooked. This commit makes them generic.
There are some problems with the
DiagCtxt
API related toEmissionGuarantee
. This PR fixes them.r? @compiler-errors