about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/lib.rs')
-rw-r--r--compiler/rustc_borrowck/src/lib.rs124
1 files changed, 63 insertions, 61 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index ea48e78509b..8b5e548345c 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -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,
-            }
-        }
-
-        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",
-                ))
+                buffered_diags: Default::default(),
             }
-            self.buffered.push(t.into_diagnostic());
         }
 
-        pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_, ()>) {
-            self.buffered.push(t.into_diagnostic());
+        pub fn buffer_error(&mut self, t: DiagnosticBuilder<'tcx>) {
+            self.buffered_diags.push(BufferedDiag::Error(t));
         }
 
-        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)
         }
     }
 }