Stop using DiagnosticBuilder::buffer in Checker.

This requires cancelling the "secondary" errors when they're not
emitted, to prevent panics due to unconsumed `DiagnosticBuilder`s.
This commit is contained in:
Nicholas Nethercote 2024-01-11 10:45:56 +11:00
parent 2668270dfb
commit 29c601aa0b

View File

@ -1,6 +1,6 @@
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
@ -214,7 +214,7 @@ pub struct Checker<'mir, 'tcx> {
local_has_storage_dead: Option<BitSet<Local>>, local_has_storage_dead: Option<BitSet<Local>>,
error_emitted: Option<ErrorGuaranteed>, error_emitted: Option<ErrorGuaranteed>,
secondary_errors: Vec<Diagnostic>, secondary_errors: Vec<DiagnosticBuilder<'tcx>>,
} }
impl<'mir, 'tcx> Deref for Checker<'mir, 'tcx> { impl<'mir, 'tcx> Deref for Checker<'mir, 'tcx> {
@ -272,14 +272,17 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
} }
// If we got through const-checking without emitting any "primary" errors, emit any // If we got through const-checking without emitting any "primary" errors, emit any
// "secondary" errors if they occurred. // "secondary" errors if they occurred. Otherwise, cancel the "secondary" errors.
let secondary_errors = mem::take(&mut self.secondary_errors); let secondary_errors = mem::take(&mut self.secondary_errors);
if self.error_emitted.is_none() { if self.error_emitted.is_none() {
for error in secondary_errors { for error in secondary_errors {
self.tcx.dcx().emit_diagnostic(error); error.emit();
} }
} else { } else {
assert!(self.tcx.dcx().has_errors().is_some()); assert!(self.tcx.dcx().has_errors().is_some());
for error in secondary_errors {
error.cancel();
}
} }
} }
@ -347,7 +350,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
self.error_emitted = Some(reported); self.error_emitted = Some(reported);
} }
ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors), ops::DiagnosticImportance::Secondary => self.secondary_errors.push(err),
} }
} }