Rollup merge of #120573 - nnethercote:rm-BorrowckErrors-tainted_by_errors, r=oli-obk

Remove `BorrowckErrors::tainted_by_errors`

This PR removes one of the `tainted_by_errors` occurrences, replacing it with direct use of `ErrorGuaranteed`.

r? `@oli-obk`
This commit is contained in:
Matthias Krüger 2024-02-03 21:29:43 +01:00 committed by GitHub
commit 019d28151d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 88 additions and 91 deletions

View File

@ -130,7 +130,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
noun_old: &str,
old_opt_via: &str,
previous_end_span: Option<Span>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
@ -162,7 +162,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
old_opt_via: &str,
previous_end_span: Option<Span>,
second_borrow_desc: &str,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
@ -194,7 +194,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
kind_old: &str,
msg_old: &str,
old_load_end_span: Option<Span>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") };
let mut err = struct_span_code_err!(
self.dcx(),
@ -235,7 +235,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
span: Span,
borrow_span: Span,
desc: &str,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
struct_span_code_err!(
self.dcx(),
span,
@ -252,7 +252,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
span: Span,
desc: &str,
is_arg: bool,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc)
}
@ -265,7 +265,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
&self,
move_from_span: Span,
move_from_desc: &str,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
struct_span_code_err!(
self.dcx(),
move_from_span,
@ -283,7 +283,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
move_from_span: Span,
ty: Ty<'_>,
is_index: Option<bool>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let type_name = match (&ty.kind(), is_index) {
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
(&ty::Slice(_), _) => "slice",
@ -304,7 +304,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
&self,
move_from_span: Span,
container_ty: Ty<'_>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
struct_span_code_err!(
self.dcx(),
move_from_span,

View File

@ -327,7 +327,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&mut self,
mpi: MovePathIndex,
move_span: Span,
err: &mut DiagnosticBuilder<'_>,
err: &mut DiagnosticBuilder<'tcx>,
in_pattern: &mut bool,
move_spans: UseSpans<'_>,
) {
@ -486,7 +486,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
desired_action: InitializationRequiringAction,
span: Span,
use_spans: UseSpans<'tcx>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
// We need all statements in the body where the binding was assigned to later find all
// the branching code paths where the binding *wasn't* assigned to.
let inits = &self.move_data.init_path_map[mpi];
@ -880,7 +880,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location,
(place, _span): (Place<'tcx>, Span),
borrow: &BorrowData<'tcx>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let borrow_spans = self.retrieve_borrow_spans(borrow);
let borrow_span = borrow_spans.args_or_use();
@ -930,7 +930,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(place, span): (Place<'tcx>, Span),
gen_borrow_kind: BorrowKind,
issued_borrow: &BorrowData<'tcx>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let issued_spans = self.retrieve_borrow_spans(issued_borrow);
let issued_span = issued_spans.args_or_use();
@ -2129,7 +2129,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
drop_span: Span,
borrow_spans: UseSpans<'tcx>,
explanation: BorrowExplanation<'tcx>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
debug!(
"report_local_value_does_not_live_long_enough(\
{:?}, {:?}, {:?}, {:?}, {:?}\
@ -2304,7 +2304,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&mut self,
drop_span: Span,
borrow_span: Span,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
debug!(
"report_thread_local_value_does_not_live_long_enough(\
{:?}, {:?}\
@ -2329,7 +2329,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_spans: UseSpans<'tcx>,
proper_span: Span,
explanation: BorrowExplanation<'tcx>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
explanation
{
@ -2496,7 +2496,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return_span: Span,
category: ConstraintCategory<'tcx>,
opt_place_desc: Option<&String>,
) -> Option<DiagnosticBuilder<'cx>> {
) -> Option<DiagnosticBuilder<'tcx>> {
let return_kind = match category {
ConstraintCategory::Return(_) => "return",
ConstraintCategory::Yield => "yield",
@ -2591,7 +2591,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
constraint_span: Span,
captured_var: &str,
scope: &str,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let tcx = self.infcx.tcx;
let args_span = use_span.args_or_use();
@ -2699,7 +2699,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
upvar_span: Span,
upvar_name: Symbol,
escape_span: Span,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let tcx = self.infcx.tcx;
let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id());

View File

@ -288,7 +288,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&mut self,
place: Place<'tcx>,
span: Span,
) -> DiagnosticBuilder<'a> {
) -> DiagnosticBuilder<'tcx> {
let description = if place.projection.len() == 1 {
format!("static item {}", self.describe_any_place(place.as_ref()))
} else {
@ -310,7 +310,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
deref_target_place: Place<'tcx>,
span: Span,
use_spans: Option<UseSpans<'tcx>>,
) -> DiagnosticBuilder<'a> {
) -> DiagnosticBuilder<'tcx> {
// Inspect the type of the content behind the
// borrow to provide feedback about why this
// was a move rather than a copy.

View File

@ -251,6 +251,6 @@ impl OutlivesSuggestionBuilder {
diag.sort_span = mir_span.shrink_to_hi();
// Buffer the diagnostic
mbcx.buffer_non_error_diag(diag);
mbcx.buffer_non_error(diag);
}
}

View File

@ -19,7 +19,7 @@ extern crate tracing;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_errors::{Diagnostic, DiagnosticBuilder};
use rustc_errors::DiagnosticBuilder;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::{BitSet, ChunkedBitSet};
@ -173,12 +173,11 @@ fn do_mir_borrowck<'tcx>(
}
}
let mut errors = error::BorrowckErrors::new(infcx.tcx);
let mut diags = diags::BorrowckDiags::new();
// Gather the upvars of a closure, if any.
if let Some(e) = input_body.tainted_by_errors {
infcx.set_tainted_by_errors(e);
errors.set_tainted_by_errors(e);
}
// Replace all regions with fresh inference variables. This
@ -244,7 +243,7 @@ fn do_mir_borrowck<'tcx>(
&regioncx,
&opt_closure_req,
&opaque_type_values,
&mut errors,
&mut diags,
);
// The various `flow_*` structures can be large. We drop `flow_inits` here
@ -305,11 +304,11 @@ fn do_mir_borrowck<'tcx>(
next_region_name: RefCell::new(1),
polonius_output: None,
move_errors: Vec::new(),
errors,
diags,
};
MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body);
promoted_mbcx.report_move_errors();
errors = promoted_mbcx.errors;
diags = promoted_mbcx.diags;
struct MoveVisitor<'a, 'cx, 'tcx> {
ctxt: &'a mut MirBorrowckCtxt<'cx, 'tcx>,
@ -346,7 +345,7 @@ fn do_mir_borrowck<'tcx>(
next_region_name: RefCell::new(1),
polonius_output,
move_errors: Vec::new(),
errors,
diags,
};
// Compute and report region errors, if any.
@ -574,7 +573,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
/// Results of Polonius analysis.
polonius_output: Option<Rc<PoloniusOutput>>,
errors: error::BorrowckErrors<'tcx>,
diags: diags::BorrowckDiags<'tcx>,
move_errors: Vec<MoveError<'tcx>>,
}
@ -2125,7 +2124,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
| WriteKind::MutableBorrow(BorrowKind::Fake),
) => {
if self.is_mutable(place.as_ref(), is_local_mutation_allowed).is_err()
&& !self.has_buffered_errors()
&& !self.has_buffered_diags()
{
// rust-lang/rust#46908: In pure NLL mode this code path should be
// unreachable, but we use `span_delayed_bug` because we can hit this when
@ -2383,17 +2382,30 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
mod error {
mod diags {
use rustc_errors::ErrorGuaranteed;
use super::*;
pub struct BorrowckErrors<'tcx> {
tcx: TyCtxt<'tcx>,
enum BufferedDiag<'tcx> {
Error(DiagnosticBuilder<'tcx>),
NonError(DiagnosticBuilder<'tcx, ()>),
}
impl<'tcx> BufferedDiag<'tcx> {
fn sort_span(&self) -> Span {
match self {
BufferedDiag::Error(diag) => diag.sort_span,
BufferedDiag::NonError(diag) => diag.sort_span,
}
}
}
pub struct BorrowckDiags<'tcx> {
/// This field keeps track of move errors that are to be reported for given move indices.
///
/// There are situations where many errors can be reported for a single move out (see #53807)
/// and we want only the best of those errors.
/// There are situations where many errors can be reported for a single move out (see
/// #53807) and we want only the best of those errors.
///
/// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the
/// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of
@ -2406,51 +2418,38 @@ mod error {
/// same primary span come out in a consistent order.
buffered_move_errors:
BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>)>,
buffered_mut_errors: FxIndexMap<Span, (DiagnosticBuilder<'tcx>, usize)>,
/// Buffer of diagnostics to be reported. Uses `Diagnostic` rather than `DiagnosticBuilder`
/// because it has a mixture of error diagnostics and non-error diagnostics.
buffered: Vec<Diagnostic>,
/// Set to Some if we emit an error during borrowck
tainted_by_errors: Option<ErrorGuaranteed>,
/// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics.
buffered_diags: Vec<BufferedDiag<'tcx>>,
}
impl<'tcx> BorrowckErrors<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
BorrowckErrors {
tcx,
impl<'tcx> BorrowckDiags<'tcx> {
pub fn new() -> Self {
BorrowckDiags {
buffered_move_errors: BTreeMap::new(),
buffered_mut_errors: Default::default(),
buffered: Default::default(),
tainted_by_errors: None,
buffered_diags: Default::default(),
}
}
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_>) {
if let None = self.tainted_by_errors {
self.tainted_by_errors = Some(self.tcx.dcx().span_delayed_bug(
t.span.clone_ignoring_labels(),
"diagnostic buffered but not emitted",
))
}
self.buffered.push(t.into_diagnostic());
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'tcx>) {
self.buffered_diags.push(BufferedDiag::Error(t));
}
pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) {
self.buffered.push(t.into_diagnostic());
}
pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
self.tainted_by_errors = Some(e);
pub fn buffer_non_error(&mut self, t: DiagnosticBuilder<'tcx, ()>) {
self.buffered_diags.push(BufferedDiag::NonError(t));
}
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_>) {
self.errors.buffer_error(t);
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'tcx>) {
self.diags.buffer_error(t);
}
pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) {
self.errors.buffer_non_error_diag(t);
pub fn buffer_non_error(&mut self, t: DiagnosticBuilder<'tcx, ()>) {
self.diags.buffer_non_error(t);
}
pub fn buffer_move_error(
@ -2459,7 +2458,7 @@ mod error {
place_and_err: (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>),
) -> bool {
if let Some((_, diag)) =
self.errors.buffered_move_errors.insert(move_out_indices, place_and_err)
self.diags.buffered_move_errors.insert(move_out_indices, place_and_err)
{
// Cancel the old diagnostic so we don't ICE
diag.cancel();
@ -2473,47 +2472,50 @@ mod error {
&mut self,
span: Span,
) -> Option<(DiagnosticBuilder<'tcx>, usize)> {
self.errors.buffered_mut_errors.remove(&span)
self.diags.buffered_mut_errors.remove(&span)
}
pub fn buffer_mut_error(&mut self, span: Span, t: DiagnosticBuilder<'tcx>, count: usize) {
self.errors.buffered_mut_errors.insert(span, (t, count));
self.diags.buffered_mut_errors.insert(span, (t, count));
}
pub fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
let mut res = None;
// Buffer any move errors that we collected and de-duplicated.
for (_, (_, diag)) in std::mem::take(&mut self.errors.buffered_move_errors) {
for (_, (_, diag)) in std::mem::take(&mut self.diags.buffered_move_errors) {
// We have already set tainted for this error, so just buffer it.
self.errors.buffered.push(diag.into_diagnostic());
self.diags.buffered_diags.push(BufferedDiag::Error(diag));
}
for (_, (mut diag, count)) in std::mem::take(&mut self.errors.buffered_mut_errors) {
for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) {
if count > 10 {
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
}
self.errors.buffered.push(diag.into_diagnostic());
self.diags.buffered_diags.push(BufferedDiag::Error(diag));
}
if !self.errors.buffered.is_empty() {
self.errors.buffered.sort_by_key(|diag| diag.sort_span);
let dcx = self.dcx();
for diag in self.errors.buffered.drain(..) {
dcx.emit_diagnostic(diag);
if !self.diags.buffered_diags.is_empty() {
self.diags.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span());
for buffered_diag in self.diags.buffered_diags.drain(..) {
match buffered_diag {
BufferedDiag::Error(diag) => res = Some(diag.emit()),
BufferedDiag::NonError(diag) => diag.emit(),
}
}
}
self.errors.tainted_by_errors
res
}
pub fn has_buffered_errors(&self) -> bool {
self.errors.buffered.is_empty()
pub(crate) fn has_buffered_diags(&self) -> bool {
self.diags.buffered_diags.is_empty()
}
pub fn has_move_error(
&self,
move_out_indices: &[MoveOutIndex],
) -> Option<&(PlaceRef<'tcx>, DiagnosticBuilder<'cx>)> {
self.errors.buffered_move_errors.get(move_out_indices)
) -> Option<&(PlaceRef<'tcx>, DiagnosticBuilder<'tcx>)> {
self.diags.buffered_move_errors.get(move_out_indices)
}
}
}

View File

@ -264,7 +264,7 @@ pub(super) fn dump_annotation<'tcx>(
regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
errors: &mut crate::error::BorrowckErrors<'tcx>,
diags: &mut crate::diags::BorrowckDiags<'tcx>,
) {
let tcx = infcx.tcx;
let base_def_id = tcx.typeck_root_def_id(body.source.def_id());
@ -310,7 +310,7 @@ pub(super) fn dump_annotation<'tcx>(
err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}"));
}
errors.buffer_non_error_diag(err);
diags.buffer_non_error(err);
}
fn for_each_region_constraint<'tcx>(

View File

@ -255,13 +255,8 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// Stashes diagnostic for possible later improvement in a different,
/// later stage of the compiler. The diagnostic can be accessed with
/// the provided `span` and `key` through [`DiagCtxt::steal_diagnostic()`].
pub fn stash(self, span: Span, key: StashKey) {
self.dcx.stash_diagnostic(span, key, self.into_diagnostic());
}
/// Converts the builder to a `Diagnostic` for later emission.
pub fn into_diagnostic(mut self) -> Diagnostic {
self.take_diag()
pub fn stash(mut self, span: Span, key: StashKey) {
self.dcx.stash_diagnostic(span, key, self.take_diag());
}
/// Delay emission of this diagnostic as a bug.