about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/borrow_check/mod.rs13
-rw-r--r--src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr16
2 files changed, 17 insertions, 12 deletions
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 668f05da89e..c7e53714e3e 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -27,12 +27,13 @@ use rustc::ty::{self, ParamEnv, TyCtxt, Ty};
 
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, Level};
 use rustc_data_structures::bit_set::BitSet;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_data_structures::indexed_vec::Idx;
 use smallvec::SmallVec;
 
 use std::rc::Rc;
+use std::collections::BTreeMap;
 
 use syntax_pos::Span;
 
@@ -256,7 +257,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         locals_are_invalidated_at_exit,
         access_place_error_reported: FxHashSet(),
         reservation_error_reported: FxHashSet(),
-        move_error_reported: FxHashMap(),
+        move_error_reported: BTreeMap::new(),
         uninitialized_error_reported: FxHashSet(),
         errors_buffer,
         nonlexical_regioncx: regioncx,
@@ -336,7 +337,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     }
 
     // Buffer any move errors that we collected and de-duplicated.
-    for (_, (_, diag)) in mbcx.move_error_reported.drain() {
+    for (_, (_, diag)) in mbcx.move_error_reported {
         diag.buffer(&mut mbcx.errors_buffer);
     }
 
@@ -425,7 +426,11 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     /// `Place` of the previous most diagnostic. This happens instead of buffering the error. Once
     /// all move errors have been reported, any diagnostics in this map are added to the buffer
     /// to be emitted.
-    move_error_reported: FxHashMap<Vec<MoveOutIndex>, (Place<'tcx>, DiagnosticBuilder<'cx>)>,
+    ///
+    /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary
+    /// when errors in the map are being re-added to the error buffer so that errors with the
+    /// same primary span come out in a consistent order.
+    move_error_reported: BTreeMap<Vec<MoveOutIndex>, (Place<'tcx>, DiagnosticBuilder<'cx>)>,
     /// This field keeps track of errors reported in the checking of uninitialized variables,
     /// so that we don't report seemingly duplicate errors.
     uninitialized_error_reported: FxHashSet<Place<'tcx>>,
diff --git a/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr b/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr
index 79cfbc5a360..ce1880c584a 100644
--- a/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-multiple-captures.nll.stderr
@@ -26,31 +26,31 @@ LL |         drop(x2); //~ ERROR cannot move `x2` into closure because it is bor
 LL |     borrow(&*p2);
    |            ---- borrow later used here
 
-error[E0382]: use of moved value: `x2`
+error[E0382]: use of moved value: `x1`
   --> $DIR/borrowck-multiple-captures.rs:35:19
    |
-LL |     drop(x2);
+LL |     drop(x1);
    |          -- value moved here
+...
 LL |     thread::spawn(move|| {
    |                   ^^^^^^ value used here after move
 LL |         drop(x1); //~ ERROR capture of moved value: `x1`
-LL |         drop(x2); //~ ERROR capture of moved value: `x2`
    |              -- use occurs due to use in closure
    |
-   = note: move occurs because `x2` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
+   = note: move occurs because `x1` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
-error[E0382]: use of moved value: `x1`
+error[E0382]: use of moved value: `x2`
   --> $DIR/borrowck-multiple-captures.rs:35:19
    |
-LL |     drop(x1);
+LL |     drop(x2);
    |          -- value moved here
-...
 LL |     thread::spawn(move|| {
    |                   ^^^^^^ value used here after move
 LL |         drop(x1); //~ ERROR capture of moved value: `x1`
+LL |         drop(x2); //~ ERROR capture of moved value: `x2`
    |              -- use occurs due to use in closure
    |
-   = note: move occurs because `x1` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
+   = note: move occurs because `x2` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `x`
   --> $DIR/borrowck-multiple-captures.rs:46:14