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::(44, 66); //~ ERROR [^0, ^1, u32] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | let x = foo::; //~ 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 = >::method::; //~ 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::; //~ ERROR [u32] - | ^^^^^^^^^^ +LL | y.method::(44, 66); //~ ERROR [^0, ^1, u32] + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors