about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2024-02-07 10:26:50 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2024-02-07 18:57:47 +1100
commit97c157fe1e52eeabe14a64865b4731794a23393a (patch)
tree6bed5941a6942e7992566ca79aded91819779fab /compiler/rustc_errors/src
parent83adf883a20fc7531e886996ce07b8555c943fba (diff)
downloadrust-97c157fe1e52eeabe14a64865b4731794a23393a.tar.gz
rust-97c157fe1e52eeabe14a64865b4731794a23393a.zip
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.
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs16
-rw-r--r--compiler/rustc_errors/src/lib.rs14
2 files changed, 20 insertions, 10 deletions
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index faff7f0b526..e484bef0e0b 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -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,
         );
 
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 7c62e3aa422..74cccda6cbf 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -931,6 +931,7 @@ impl DiagCtxt {
     /// This excludes lint errors and delayed bugs.
     pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
         self.inner.borrow().has_errors().then(|| {
+            // FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
             #[allow(deprecated)]
             ErrorGuaranteed::unchecked_claim_error_was_emitted()
         })
@@ -942,6 +943,7 @@ impl DiagCtxt {
         let inner = self.inner.borrow();
         let result = inner.has_errors() || inner.lint_err_count > 0;
         result.then(|| {
+            // FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
             #[allow(deprecated)]
             ErrorGuaranteed::unchecked_claim_error_was_emitted()
         })
@@ -954,6 +956,7 @@ impl DiagCtxt {
         let result =
             inner.has_errors() || inner.lint_err_count > 0 || !inner.delayed_bugs.is_empty();
         result.then(|| {
+            // FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
             #[allow(deprecated)]
             ErrorGuaranteed::unchecked_claim_error_was_emitted()
         })
@@ -1238,6 +1241,7 @@ impl DiagCtxtInner {
         }
     }
 
+    // Return value is only `Some` if the level is `Error` or `DelayedBug`.
     fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
         assert!(diagnostic.level.can_be_top_or_sub().0);
 
@@ -1316,6 +1320,7 @@ impl DiagCtxtInner {
                 !self.emitted_diagnostics.insert(diagnostic_hash)
             };
 
+            let level = diagnostic.level;
             let is_error = diagnostic.is_error();
             let is_lint = diagnostic.is_lint.is_some();
 
@@ -1352,6 +1357,7 @@ impl DiagCtxtInner {
 
                 self.emitter.emit_diagnostic(diagnostic);
             }
+
             if is_error {
                 if is_lint {
                     self.lint_err_count += 1;
@@ -1359,11 +1365,11 @@ impl DiagCtxtInner {
                     self.err_count += 1;
                 }
                 self.panic_if_treat_err_as_bug();
+            }
 
-                #[allow(deprecated)]
-                {
-                    guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
-                }
+            #[allow(deprecated)]
+            if level == Level::Error {
+                guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
             }
         });