@@ -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:: bit_set:: BitSet ;
30
- use rustc_data_structures:: fx:: FxHashSet ;
30
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
31
31
use rustc_data_structures:: graph:: dominators:: Dominators ;
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 ;
@@ -255,7 +256,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
255
256
locals_are_invalidated_at_exit,
256
257
access_place_error_reported : FxHashSet ( ) ,
257
258
reservation_error_reported : FxHashSet ( ) ,
258
- moved_error_reported : FxHashSet ( ) ,
259
+ move_error_reported : FxHashMap ( ) ,
260
+ uninitialized_error_reported : FxHashSet ( ) ,
259
261
errors_buffer,
260
262
nonlexical_regioncx : regioncx,
261
263
used_mut : FxHashSet ( ) ,
@@ -333,6 +335,11 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
333
335
}
334
336
}
335
337
338
+ // Buffer any move errors that we collected and de-duplicated.
339
+ for ( _, ( _, diag) ) in mbcx. move_error_reported . drain ( ) {
340
+ diag. buffer ( & mut mbcx. errors_buffer ) ;
341
+ }
342
+
336
343
if mbcx. errors_buffer . len ( ) > 0 {
337
344
mbcx. errors_buffer . sort_by_key ( |diag| diag. span . primary_span ( ) ) ;
338
345
@@ -408,9 +415,20 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
408
415
/// but it is currently inconvenient to track down the BorrowIndex
409
416
/// at the time we detect and report a reservation error.
410
417
reservation_error_reported : FxHashSet < Place < ' tcx > > ,
411
- /// This field keeps track of errors reported in the checking of moved variables,
418
+ /// This field keeps track of move errors that are to be reported for given move indicies.
419
+ ///
420
+ /// There are situations where many errors can be reported for a single move out (see #53807)
421
+ /// and we want only the best of those errors.
422
+ ///
423
+ /// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the
424
+ /// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of the
425
+ /// `Place` of the previous most diagnostic. This happens instead of buffering the error. Once
426
+ /// all move errors have been reported, any diagnostics in this map are added to the buffer
427
+ /// to be emitted.
428
+ move_error_reported : FxHashMap < Vec < MoveOutIndex > , ( Place < ' tcx > , DiagnosticBuilder < ' cx > ) > ,
429
+ /// This field keeps track of errors reported in the checking of uninitialized variables,
412
430
/// so that we don't report seemingly duplicate errors.
413
- moved_error_reported : FxHashSet < Place < ' tcx > > ,
431
+ uninitialized_error_reported : FxHashSet < Place < ' tcx > > ,
414
432
/// Errors to be reported buffer
415
433
errors_buffer : Vec < Diagnostic > ,
416
434
/// This field keeps track of all the local variables that are declared mut and are mutated.
@@ -801,7 +819,7 @@ enum LocalMutationIsAllowed {
801
819
No ,
802
820
}
803
821
804
- #[ derive( Copy , Clone ) ]
822
+ #[ derive( Copy , Clone , Debug ) ]
805
823
enum InitializationRequiringAction {
806
824
Update ,
807
825
Borrow ,
0 commit comments