@@ -27,7 +27,7 @@ use rustc::ty::{self, ParamEnv, TyCtxt, Ty};
2727
2828use rustc_errors:: { Applicability , Diagnostic , DiagnosticBuilder , Level } ;
2929use rustc_data_structures:: graph:: dominators:: Dominators ;
30- use rustc_data_structures:: fx:: FxHashSet ;
30+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
3131use rustc_data_structures:: indexed_set:: IdxSet ;
3232use rustc_data_structures:: indexed_vec:: Idx ;
3333use smallvec:: SmallVec ;
@@ -38,6 +38,7 @@ use syntax_pos::Span;
3838
3939use dataflow:: indexes:: BorrowIndex ;
4040use dataflow:: move_paths:: { HasMoveData , LookupResult , MoveData , MoveError , MovePathIndex } ;
41+ use dataflow:: move_paths:: indexes:: MoveOutIndex ;
4142use dataflow:: Borrows ;
4243use dataflow:: DataflowResultsConsumer ;
4344use dataflow:: FlowAtLocation ;
@@ -247,7 +248,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
247248 } ,
248249 access_place_error_reported : FxHashSet ( ) ,
249250 reservation_error_reported : FxHashSet ( ) ,
250- moved_error_reported : FxHashSet ( ) ,
251+ move_error_reported : FxHashMap ( ) ,
252+ uninitialized_error_reported : FxHashSet ( ) ,
251253 errors_buffer,
252254 nonlexical_regioncx : regioncx,
253255 used_mut : FxHashSet ( ) ,
@@ -325,6 +327,11 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
325327 }
326328 }
327329
330+ // Buffer any move errors that we collected and de-duplicated.
331+ for ( _, ( _, diag) ) in mbcx. move_error_reported . drain ( ) {
332+ diag. buffer ( & mut mbcx. errors_buffer ) ;
333+ }
334+
328335 if mbcx. errors_buffer . len ( ) > 0 {
329336 mbcx. errors_buffer . sort_by_key ( |diag| diag. span . primary_span ( ) ) ;
330337
@@ -400,9 +407,20 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
400407 /// but it is currently inconvenient to track down the BorrowIndex
401408 /// at the time we detect and report a reservation error.
402409 reservation_error_reported : FxHashSet < Place < ' tcx > > ,
403- /// This field keeps track of errors reported in the checking of moved variables,
410+ /// This field keeps track of move errors that are to be reported for given move indicies.
411+ ///
412+ /// There are situations where many errors can be reported for a single move out (see #53807)
413+ /// and we want only the best of those errors.
414+ ///
415+ /// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the
416+ /// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of the
417+ /// `Place` of the previous most diagnostic. This happens instead of buffering the error. Once
418+ /// all move errors have been reported, any diagnostics in this map are added to the buffer
419+ /// to be emitted.
420+ move_error_reported : FxHashMap < Vec < MoveOutIndex > , ( Place < ' tcx > , DiagnosticBuilder < ' cx > ) > ,
421+ /// This field keeps track of errors reported in the checking of uninitialized variables,
404422 /// so that we don't report seemingly duplicate errors.
405- moved_error_reported : FxHashSet < Place < ' tcx > > ,
423+ uninitialized_error_reported : FxHashSet < Place < ' tcx > > ,
406424 /// Errors to be reported buffer
407425 errors_buffer : Vec < Diagnostic > ,
408426 /// This field keeps track of all the local variables that are declared mut and are mutated.
@@ -793,7 +811,7 @@ enum LocalMutationIsAllowed {
793811 No ,
794812}
795813
796- #[ derive( Copy , Clone ) ]
814+ #[ derive( Copy , Clone , Debug ) ]
797815enum InitializationRequiringAction {
798816 Update ,
799817 Borrow ,
0 commit comments