about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2018-12-22 15:32:44 +0100
committerDavid Wood <david@davidtw.co>2018-12-30 14:30:59 +0100
commitc20ba65a0b3142bbd88031fbf6eb7ef46bc1f7b3 (patch)
treee81d2c7e6713b8178a1e9a7ba55fc1e408a15399 /src
parent0bfe184b1ad14db4b002c3a272adf44e1839822f (diff)
downloadrust-c20ba65a0b3142bbd88031fbf6eb7ef46bc1f7b3.tar.gz
rust-c20ba65a0b3142bbd88031fbf6eb7ef46bc1f7b3.zip
Guarantee `rustc_dump_user_substs` error order.
This commit buffers the errors output by the `rustc_dump_user_substs`
attribute so that they can be output in order of span and would
therefore be consistent.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/writeback.rs17
-rw-r--r--src/test/ui/nll/user-annotations/dump-fn-method.stderr16
2 files changed, 24 insertions, 9 deletions
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 53ea497f01a..38de936a027 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -3,6 +3,7 @@
 // substitutions.
 
 use check::FnCtxt;
+use errors::DiagnosticBuilder;
 use rustc::hir;
 use rustc::hir::def_id::{DefId, DefIndex};
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -357,6 +358,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
         debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
         let common_local_id_root = fcx_tables.local_id_root.unwrap();
 
+        let mut errors_buffer = Vec::new();
         for (&local_id, c_ty) in fcx_tables.user_provided_types().iter() {
             let hir_id = hir::HirId {
                 owner: common_local_id_root.index,
@@ -382,10 +384,23 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                     // This is a unit-testing mechanism.
                     let node_id = self.tcx().hir().hir_to_node_id(hir_id);
                     let span = self.tcx().hir().span(node_id);
-                    self.tcx().sess.span_err(span, &format!("user substs: {:?}", user_substs));
+                    // We need to buffer the errors in order to guarantee a consistent
+                    // order when emitting them.
+                    let err = self.tcx().sess.struct_span_err(
+                        span,
+                        &format!("user substs: {:?}", user_substs)
+                    );
+                    err.buffer(&mut errors_buffer);
                 }
             }
         }
+
+        if !errors_buffer.is_empty() {
+            errors_buffer.sort_by_key(|diag| diag.span.primary_span());
+            for diag in errors_buffer.drain(..) {
+                DiagnosticBuilder::new_diagnostic(self.tcx().sess.diagnostic(), diag).emit();
+            }
+        }
     }
 
     fn visit_user_provided_sigs(&mut self) {
diff --git a/src/test/ui/nll/user-annotations/dump-fn-method.stderr b/src/test/ui/nll/user-annotations/dump-fn-method.stderr
index fc4544437c5..a1a4e43e8a3 100644
--- a/src/test/ui/nll/user-annotations/dump-fn-method.stderr
+++ b/src/test/ui/nll/user-annotations/dump-fn-method.stderr
@@ -1,8 +1,8 @@
-error: user substs: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None }
-  --> $DIR/dump-fn-method.rs:44:5
+error: user substs: UserSubsts { substs: [u32], user_self_ty: None }
+  --> $DIR/dump-fn-method.rs:26:13
    |
-LL |     y.method::<u32>(44, 66); //~ ERROR [^0, ^1, u32]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let x = foo::<u32>; //~ ERROR [u32]
+   |             ^^^^^^^^^^
 
 error: user substs: UserSubsts { substs: [^0, u32, ^1], user_self_ty: None }
   --> $DIR/dump-fn-method.rs:32:13
@@ -16,11 +16,11 @@ error: user substs: UserSubsts { substs: [u8, u16, u32], user_self_ty: None }
 LL |     let x = <u8 as Bazoom<u16>>::method::<u32>; //~ ERROR [u8, u16, u32]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: user substs: UserSubsts { substs: [u32], user_self_ty: None }
-  --> $DIR/dump-fn-method.rs:26:13
+error: user substs: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None }
+  --> $DIR/dump-fn-method.rs:44:5
    |
-LL |     let x = foo::<u32>; //~ ERROR [u32]
-   |             ^^^^^^^^^^
+LL |     y.method::<u32>(44, 66); //~ ERROR [^0, ^1, u32]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors