about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2023-09-18 21:11:14 +1000
committerZalathar <Zalathar@users.noreply.github.com>2023-09-18 21:28:56 +1000
commit4690f97099c2f01a07a8fa272e94e3e5cba61f12 (patch)
treebec7eca4753da04fe62f1fbd9f9b8de97802f084 /compiler/rustc_mir_transform/src
parent078eb1120a3f576598b976d9470701363f48fccc (diff)
downloadrust-4690f97099c2f01a07a8fa272e94e3e5cba61f12.tar.gz
rust-4690f97099c2f01a07a8fa272e94e3e5cba61f12.zip
coverage: Fix an unstable-sort inconsistency in coverage spans
This code was calling `sort_unstable_by`, but failed to impose a total order on
the initial spans. That resulted in unpredictable handling of closure spans,
producing inconsistencies in the coverage maps and in user-visible coverage
reports.

This patch fixes the problem by always sorting closure spans before
otherwise-identical non-closure spans, and also switches to a stable sort in
case the ordering is still not total.
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs5
1 files changed, 4 insertions, 1 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 717763a94a0..d254c1662e4 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -333,7 +333,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
 
         initial_spans.push(CoverageSpan::for_fn_sig(self.fn_sig_span));
 
-        initial_spans.sort_unstable_by(|a, b| {
+        initial_spans.sort_by(|a, b| {
             if a.span.lo() == b.span.lo() {
                 if a.span.hi() == b.span.hi() {
                     if a.is_in_same_bcb(b) {
@@ -357,6 +357,9 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
                 a.span.lo().partial_cmp(&b.span.lo())
             }
             .unwrap()
+            // If two spans are otherwise identical, put closure spans first,
+            // as this seems to be what the refinement step expects.
+            .then_with(|| Ord::cmp(&a.is_closure, &b.is_closure).reverse())
         });
 
         initial_spans