Skip to content

Commit 97c157f

Browse files
committed
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.
1 parent 83adf88 commit 97c157f

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

compiler/rustc_errors/src/diagnostic_builder.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,20 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
9999
}
100100

101101
/// `ErrorGuaranteed::emit_producing_guarantee` uses this.
102-
// FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
103102
fn emit_producing_error_guaranteed(mut self) -> ErrorGuaranteed {
104103
let diag = self.take_diag();
105104

106-
// Only allow a guarantee if the `level` wasn't switched to a
107-
// non-error. The field isn't `pub`, but the whole `Diagnostic` can be
108-
// overwritten with a new one, thanks to `DerefMut`.
105+
// The only error levels that produce `ErrorGuaranteed` are
106+
// `Error` and `DelayedBug`. But `DelayedBug` should never occur here
107+
// because delayed bugs have their level changed to `Bug` when they are
108+
// actually printed, so they produce an ICE.
109+
//
110+
// (Also, even though `level` isn't `pub`, the whole `Diagnostic` could
111+
// be overwritten with a new one thanks to `DerefMut`. So this assert
112+
// protects against that, too.)
109113
assert!(
110-
diag.is_error(),
111-
"emitted non-error ({:?}) diagnostic from `DiagnosticBuilder<ErrorGuaranteed>`",
114+
matches!(diag.level, Level::Error | Level::DelayedBug),
115+
"invalid diagnostic level ({:?})",
112116
diag.level,
113117
);
114118

compiler/rustc_errors/src/lib.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,7 @@ impl DiagCtxt {
931931
/// This excludes lint errors and delayed bugs.
932932
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
933933
self.inner.borrow().has_errors().then(|| {
934+
// FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
934935
#[allow(deprecated)]
935936
ErrorGuaranteed::unchecked_claim_error_was_emitted()
936937
})
@@ -942,6 +943,7 @@ impl DiagCtxt {
942943
let inner = self.inner.borrow();
943944
let result = inner.has_errors() || inner.lint_err_count > 0;
944945
result.then(|| {
946+
// FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
945947
#[allow(deprecated)]
946948
ErrorGuaranteed::unchecked_claim_error_was_emitted()
947949
})
@@ -954,6 +956,7 @@ impl DiagCtxt {
954956
let result =
955957
inner.has_errors() || inner.lint_err_count > 0 || !inner.delayed_bugs.is_empty();
956958
result.then(|| {
959+
// FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
957960
#[allow(deprecated)]
958961
ErrorGuaranteed::unchecked_claim_error_was_emitted()
959962
})
@@ -1238,6 +1241,7 @@ impl DiagCtxtInner {
12381241
}
12391242
}
12401243

1244+
// Return value is only `Some` if the level is `Error` or `DelayedBug`.
12411245
fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
12421246
assert!(diagnostic.level.can_be_top_or_sub().0);
12431247

@@ -1316,6 +1320,7 @@ impl DiagCtxtInner {
13161320
!self.emitted_diagnostics.insert(diagnostic_hash)
13171321
};
13181322

1323+
let level = diagnostic.level;
13191324
let is_error = diagnostic.is_error();
13201325
let is_lint = diagnostic.is_lint.is_some();
13211326

@@ -1352,18 +1357,19 @@ impl DiagCtxtInner {
13521357

13531358
self.emitter.emit_diagnostic(diagnostic);
13541359
}
1360+
13551361
if is_error {
13561362
if is_lint {
13571363
self.lint_err_count += 1;
13581364
} else {
13591365
self.err_count += 1;
13601366
}
13611367
self.panic_if_treat_err_as_bug();
1368+
}
13621369

1363-
#[allow(deprecated)]
1364-
{
1365-
guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
1366-
}
1370+
#[allow(deprecated)]
1371+
if level == Level::Error {
1372+
guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
13671373
}
13681374
});
13691375

compiler/rustc_span/src/lib.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2477,9 +2477,8 @@ where
24772477
pub struct ErrorGuaranteed(());
24782478

24792479
impl ErrorGuaranteed {
2480-
/// To be used only if you really know what you are doing... ideally, we would find a way to
2481-
/// eliminate all calls to this method.
2482-
#[deprecated = "`Session::span_delayed_bug` should be preferred over this function"]
2480+
/// Don't use this outside of `DiagCtxtInner::emit_diagnostic`!
2481+
#[deprecated = "should only be used in `DiagCtxtInner::emit_diagnostic`"]
24832482
pub fn unchecked_claim_error_was_emitted() -> Self {
24842483
ErrorGuaranteed(())
24852484
}

0 commit comments

Comments
 (0)