1
Fork 0

Tighten up ErrorGuaranteed handling.

- In `emit_producing_error_guaranteed`, only allow `Level::Error`.
- In `emit_diagnostic`, only produce `ErrorGuaranteed` for `Level` and
  `DelayedBug`. (Not `Bug` or `Fatal`. They don't need it, because the
  relevant `emit` methods abort.)
- Add/update various comments.
This commit is contained in:
Nicholas Nethercote 2024-02-07 10:26:50 +11:00
parent 83adf883a2
commit 97c157fe1e
3 changed files with 22 additions and 13 deletions

View file

@ -99,16 +99,20 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
}
/// `ErrorGuaranteed::emit_producing_guarantee` uses this.
// FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
fn emit_producing_error_guaranteed(mut self) -> ErrorGuaranteed {
let diag = self.take_diag();
// Only allow a guarantee if the `level` wasn't switched to a
// non-error. The field isn't `pub`, but the whole `Diagnostic` can be
// overwritten with a new one, thanks to `DerefMut`.
// The only error levels that produce `ErrorGuaranteed` are
// `Error` and `DelayedBug`. But `DelayedBug` should never occur here
// because delayed bugs have their level changed to `Bug` when they are
// actually printed, so they produce an ICE.
//
// (Also, even though `level` isn't `pub`, the whole `Diagnostic` could
// be overwritten with a new one thanks to `DerefMut`. So this assert
// protects against that, too.)
assert!(
diag.is_error(),
"emitted non-error ({:?}) diagnostic from `DiagnosticBuilder<ErrorGuaranteed>`",
matches!(diag.level, Level::Error | Level::DelayedBug),
"invalid diagnostic level ({:?})",
diag.level,
);