1
Fork 0

Avoid a span_delayed_bug in compute_regions.

By storing error guarantees in `RegionErrors`.
This commit is contained in:
Nicholas Nethercote 2024-02-19 08:42:04 +11:00
parent 9f82563718
commit 62b4e55112
2 changed files with 13 additions and 12 deletions

View file

@ -1,7 +1,7 @@
//! Error reporting machinery for lifetime errors. //! Error reporting machinery for lifetime errors.
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res::Def; use rustc_hir::def::Res::Def;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -73,7 +73,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
/// ///
/// Usually we expect this to either be empty or contain a small number of items, so we can avoid /// Usually we expect this to either be empty or contain a small number of items, so we can avoid
/// allocation most of the time. /// allocation most of the time.
pub(crate) struct RegionErrors<'tcx>(Vec<RegionErrorKind<'tcx>>, TyCtxt<'tcx>); pub(crate) struct RegionErrors<'tcx>(Vec<(RegionErrorKind<'tcx>, ErrorGuaranteed)>, TyCtxt<'tcx>);
impl<'tcx> RegionErrors<'tcx> { impl<'tcx> RegionErrors<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>) -> Self { pub fn new(tcx: TyCtxt<'tcx>) -> Self {
@ -82,15 +82,18 @@ impl<'tcx> RegionErrors<'tcx> {
#[track_caller] #[track_caller]
pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) { pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
let val = val.into(); let val = val.into();
self.1.sess.dcx().delayed_bug(format!("{val:?}")); let guar = self.1.sess.dcx().delayed_bug(format!("{val:?}"));
self.0.push(val); self.0.push((val, guar));
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.is_empty() self.0.is_empty()
} }
pub fn into_iter(self) -> impl Iterator<Item = RegionErrorKind<'tcx>> { pub fn into_iter(self) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
self.0.into_iter() self.0.into_iter()
} }
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
self.0.get(0).map(|x| x.1)
}
} }
impl std::fmt::Debug for RegionErrors<'_> { impl std::fmt::Debug for RegionErrors<'_> {
@ -304,10 +307,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> = let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
None; None;
for nll_error in nll_errors.into_iter() { for (nll_error, _) in nll_errors.into_iter() {
match nll_error { match nll_error {
RegionErrorKind::TypeTestError { type_test } => { RegionErrorKind::TypeTestError { type_test } => {
// Try to convert the lower-bound region into something named we can print for the user. // Try to convert the lower-bound region into something named we can print for
// the user.
let lower_bound_region = self.to_error_region(type_test.lower_bound); let lower_bound_region = self.to_error_region(type_test.lower_bound);
let type_test_span = type_test.span; let type_test_span = type_test.span;

View file

@ -184,12 +184,9 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
let (closure_region_requirements, nll_errors) = let (closure_region_requirements, nll_errors) =
regioncx.solve(infcx, body, polonius_output.clone()); regioncx.solve(infcx, body, polonius_output.clone());
if !nll_errors.is_empty() { if let Some(guar) = nll_errors.has_errors() {
// Suppress unhelpful extra errors in `infer_opaque_types`. // Suppress unhelpful extra errors in `infer_opaque_types`.
infcx.set_tainted_by_errors(infcx.dcx().span_delayed_bug( infcx.set_tainted_by_errors(guar);
body.span,
"`compute_regions` tainted `infcx` with errors but did not emit any errors",
));
} }
let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values); let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values);