@@ -27,7 +27,7 @@ use rustc::ty::{self, ParamEnv, TyCtxt, Ty};
27
27
28
28
use rustc_errors:: { Applicability , Diagnostic , DiagnosticBuilder , Level } ;
29
29
use rustc_data_structures:: graph:: dominators:: Dominators ;
30
- use rustc_data_structures:: fx:: FxHashSet ;
30
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
31
31
use rustc_data_structures:: indexed_set:: IdxSet ;
32
32
use rustc_data_structures:: indexed_vec:: Idx ;
33
33
use smallvec:: SmallVec ;
@@ -38,6 +38,7 @@ use syntax_pos::Span;
38
38
39
39
use dataflow:: indexes:: BorrowIndex ;
40
40
use dataflow:: move_paths:: { HasMoveData , LookupResult , MoveData , MoveError , MovePathIndex } ;
41
+ use dataflow:: move_paths:: indexes:: MoveOutIndex ;
41
42
use dataflow:: Borrows ;
42
43
use dataflow:: DataflowResultsConsumer ;
43
44
use dataflow:: FlowAtLocation ;
@@ -247,7 +248,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
247
248
} ,
248
249
access_place_error_reported : FxHashSet ( ) ,
249
250
reservation_error_reported : FxHashSet ( ) ,
250
- moved_error_reported : FxHashSet ( ) ,
251
+ move_error_reported : FxHashMap ( ) ,
252
+ uninitialized_error_reported : FxHashSet ( ) ,
251
253
errors_buffer,
252
254
nonlexical_regioncx : regioncx,
253
255
used_mut : FxHashSet ( ) ,
@@ -325,6 +327,11 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
325
327
}
326
328
}
327
329
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
+
328
335
if mbcx. errors_buffer . len ( ) > 0 {
329
336
mbcx. errors_buffer . sort_by_key ( |diag| diag. span . primary_span ( ) ) ;
330
337
@@ -400,9 +407,20 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
400
407
/// but it is currently inconvenient to track down the BorrowIndex
401
408
/// at the time we detect and report a reservation error.
402
409
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,
404
422
/// so that we don't report seemingly duplicate errors.
405
- moved_error_reported : FxHashSet < Place < ' tcx > > ,
423
+ uninitialized_error_reported : FxHashSet < Place < ' tcx > > ,
406
424
/// Errors to be reported buffer
407
425
errors_buffer : Vec < Diagnostic > ,
408
426
/// This field keeps track of all the local variables that are declared mut and are mutated.
@@ -793,7 +811,7 @@ enum LocalMutationIsAllowed {
793
811
No ,
794
812
}
795
813
796
- #[ derive( Copy , Clone ) ]
814
+ #[ derive( Copy , Clone , Debug ) ]
797
815
enum InitializationRequiringAction {
798
816
Update ,
799
817
Borrow ,
0 commit comments